Merge branch 'master' of git://github.com/assimp/assimp
This commit is contained in:
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
||||
|
||||
// internal headers
|
||||
#include "TextureTransform.h"
|
||||
@@ -2148,3 +2149,5 @@ void Parser::ParseLV4MeshLong(unsigned int& iOut)
|
||||
// parse the value
|
||||
iOut = strtoul10(filePtr,&filePtr);
|
||||
}
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
|
||||
|
||||
@@ -514,7 +514,8 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
||||
|
||||
// assign the material index
|
||||
dstMesh->mMaterialIndex = matIdx;
|
||||
}
|
||||
dstMesh->mName = mid.mMeshOrController;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1369,9 +1369,11 @@ void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler)
|
||||
int attrTex = GetAttribute( "texture");
|
||||
pSampler.mName = mReader->getAttributeValue( attrTex);
|
||||
|
||||
// get name of UV source channel
|
||||
attrTex = GetAttribute( "texcoord");
|
||||
pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
|
||||
// get name of UV source channel. Specification demands it to be there, but some exporters
|
||||
// don't write it. It will be the default UV channel in case it's missing.
|
||||
attrTex = TestAttribute( "texcoord");
|
||||
if( attrTex >= 0 )
|
||||
pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
|
||||
//SkipElement();
|
||||
}
|
||||
else if( IsElement( "technique"))
|
||||
@@ -1795,14 +1797,13 @@ void ColladaParser::ReadAccessor( const std::string& pID)
|
||||
SkipElement();
|
||||
} else
|
||||
{
|
||||
ThrowException( "Unexpected sub element in tag \"accessor\".");
|
||||
ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <accessor>") % mReader->getNodeName()));
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "accessor") != 0)
|
||||
ThrowException( "Expected end of \"accessor\" element.");
|
||||
|
||||
ThrowException( "Expected end of <accessor> element.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1826,13 +1827,13 @@ void ColladaParser::ReadVertexData( Mesh* pMesh)
|
||||
ReadInputChannel( pMesh->mPerVertexData);
|
||||
} else
|
||||
{
|
||||
ThrowException( "Unexpected sub element in tag \"vertices\".");
|
||||
ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <vertices>") % mReader->getNodeName()));
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( strcmp( mReader->getNodeName(), "vertices") != 0)
|
||||
ThrowException( "Expected end of \"vertices\" element.");
|
||||
ThrowException( "Expected end of <vertices> element.");
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1919,13 +1920,13 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
|
||||
}
|
||||
} else
|
||||
{
|
||||
ThrowException( "Unexpected sub element in tag \"vertices\".");
|
||||
ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <%s>") % mReader->getNodeName() % elementName));
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||
{
|
||||
if( mReader->getNodeName() != elementName)
|
||||
ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % elementName));
|
||||
ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % elementName));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2063,7 +2064,7 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPer
|
||||
{
|
||||
// warn if the vertex channel does not refer to the <vertices> element in the same mesh
|
||||
if( input.mAccessor != pMesh->mVertexID)
|
||||
ThrowException( "Unsupported vertex referencing scheme. I fucking hate Collada.");
|
||||
ThrowException( "Unsupported vertex referencing scheme.");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2230,7 +2231,13 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
|
||||
pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(),
|
||||
pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1));
|
||||
|
||||
pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3]));
|
||||
//pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3]));
|
||||
aiColor4D result(0, 0, 0, 1);
|
||||
for (size_t i = 0; i < pInput.mResolved->mSize; ++i)
|
||||
{
|
||||
result[i] = obj[pInput.mResolved->mSubOffset[i]];
|
||||
}
|
||||
pMesh->mColors[pInput.mIndex].push_back(result);
|
||||
} else
|
||||
{
|
||||
DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping.");
|
||||
|
||||
1887
code/IFCGeometry.cpp
1887
code/IFCGeometry.cpp
File diff suppressed because it is too large
Load Diff
120
code/IFCUtil.cpp
120
code/IFCUtil.cpp
@@ -45,7 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||
|
||||
#include "IFCUtil.h"
|
||||
#include "PolyTools.h"
|
||||
#include "ProcessHelper.h"
|
||||
|
||||
namespace Assimp {
|
||||
@@ -127,6 +129,122 @@ void TempMesh::Append(const TempMesh& other)
|
||||
vertcnt.insert(vertcnt.end(),other.vertcnt.begin(),other.vertcnt.end());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::RemoveDegenerates()
|
||||
{
|
||||
// The strategy is simple: walk the mesh and compute normals using
|
||||
// Newell's algorithm. The length of the normals gives the area
|
||||
// of the polygons, which is close to zero for lines.
|
||||
|
||||
std::vector<IfcVector3> normals;
|
||||
ComputePolygonNormals(normals, false);
|
||||
|
||||
bool drop = false;
|
||||
size_t inor = 0;
|
||||
|
||||
std::vector<IfcVector3>::iterator vit = verts.begin();
|
||||
for (std::vector<unsigned int>::iterator it = vertcnt.begin(); it != vertcnt.end(); ++inor) {
|
||||
const unsigned int pcount = *it;
|
||||
|
||||
if (normals[inor].SquareLength() < 1e-5f) {
|
||||
it = vertcnt.erase(it);
|
||||
vit = verts.erase(vit, vit + pcount);
|
||||
|
||||
drop = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
vit += pcount;
|
||||
++it;
|
||||
}
|
||||
|
||||
if(drop) {
|
||||
IFCImporter::LogDebug("removing degenerate faces");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
|
||||
bool normalize,
|
||||
size_t ofs) const
|
||||
{
|
||||
size_t max_vcount = 0;
|
||||
std::vector<unsigned int>::const_iterator begin = vertcnt.begin()+ofs, end = vertcnt.end(), iit;
|
||||
for(iit = begin; iit != end; ++iit) {
|
||||
max_vcount = std::max(max_vcount,static_cast<size_t>(*iit));
|
||||
}
|
||||
|
||||
std::vector<IfcFloat> temp((max_vcount+2)*4);
|
||||
normals.reserve( normals.size() + vertcnt.size()-ofs );
|
||||
|
||||
// `NewellNormal()` currently has a relatively strange interface and need to
|
||||
// re-structure things a bit to meet them.
|
||||
size_t vidx = std::accumulate(vertcnt.begin(),begin,0);
|
||||
for(iit = begin; iit != end; vidx += *iit++) {
|
||||
if (!*iit) {
|
||||
normals.push_back(IfcVector3());
|
||||
continue;
|
||||
}
|
||||
for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) {
|
||||
const IfcVector3& v = verts[vidx+vofs];
|
||||
temp[cnt++] = v.x;
|
||||
temp[cnt++] = v.y;
|
||||
temp[cnt++] = v.z;
|
||||
#ifdef _DEBUG
|
||||
temp[cnt] = std::numeric_limits<IfcFloat>::quiet_NaN();
|
||||
#endif
|
||||
++cnt;
|
||||
}
|
||||
|
||||
normals.push_back(IfcVector3());
|
||||
NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]);
|
||||
}
|
||||
|
||||
if(normalize) {
|
||||
BOOST_FOREACH(IfcVector3& n, normals) {
|
||||
n.Normalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Compute the normal of the last polygon in the given mesh
|
||||
IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const
|
||||
{
|
||||
size_t total = vertcnt.back(), vidx = verts.size() - total;
|
||||
std::vector<IfcFloat> temp((total+2)*3);
|
||||
for(size_t vofs = 0, cnt = 0; vofs < total; ++vofs) {
|
||||
const IfcVector3& v = verts[vidx+vofs];
|
||||
temp[cnt++] = v.x;
|
||||
temp[cnt++] = v.y;
|
||||
temp[cnt++] = v.z;
|
||||
}
|
||||
IfcVector3 nor;
|
||||
NewellNormal<3,3,3>(nor,total,&temp[0],&temp[1],&temp[2]);
|
||||
return normalize ? nor.Normalize() : nor;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::FixupFaceOrientation()
|
||||
{
|
||||
const IfcVector3 vavg = Center();
|
||||
|
||||
std::vector<IfcVector3> normals;
|
||||
ComputePolygonNormals(normals);
|
||||
|
||||
size_t c = 0, ofs = 0;
|
||||
BOOST_FOREACH(unsigned int cnt, vertcnt) {
|
||||
if (cnt>2){
|
||||
const IfcVector3& thisvert = verts[c];
|
||||
if (normals[ofs]*(thisvert-vavg) < 0) {
|
||||
std::reverse(verts.begin()+c,verts.begin()+cnt+c);
|
||||
}
|
||||
}
|
||||
c += cnt;
|
||||
++ofs;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TempMesh::RemoveAdjacentDuplicates()
|
||||
{
|
||||
@@ -189,7 +307,7 @@ void TempMesh::RemoveAdjacentDuplicates()
|
||||
base += cnt;
|
||||
}
|
||||
if(drop) {
|
||||
IFCImporter::LogDebug("removed duplicate vertices");
|
||||
IFCImporter::LogDebug("removing duplicate vertices");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,12 +76,27 @@ struct delete_fun
|
||||
struct TempMesh;
|
||||
struct TempOpening
|
||||
{
|
||||
const IFC::IfcExtrudedAreaSolid* solid;
|
||||
const IFC::IfcSolidModel* solid;
|
||||
IfcVector3 extrusionDir;
|
||||
boost::shared_ptr<TempMesh> profileMesh;
|
||||
|
||||
// list of points generated for this opening. This is used to
|
||||
// create connections between two opposing holes created
|
||||
// from a single opening instance (two because walls tend to
|
||||
// have two sides). If !empty(), the other side of the wall
|
||||
// has already been processed.
|
||||
std::vector<IfcVector3> wallPoints;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
TempOpening(const IFC::IfcExtrudedAreaSolid* solid,IfcVector3 extrusionDir,boost::shared_ptr<TempMesh> profileMesh)
|
||||
TempOpening()
|
||||
: solid()
|
||||
, extrusionDir()
|
||||
, profileMesh()
|
||||
{
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
TempOpening(const IFC::IfcSolidModel* solid,IfcVector3 extrusionDir,boost::shared_ptr<TempMesh> profileMesh)
|
||||
: solid(solid)
|
||||
, extrusionDir(extrusionDir)
|
||||
, profileMesh(profileMesh)
|
||||
@@ -168,7 +183,19 @@ struct TempMesh
|
||||
void Transform(const IfcMatrix4& mat);
|
||||
IfcVector3 Center() const;
|
||||
void Append(const TempMesh& other);
|
||||
|
||||
bool IsEmpty() const {
|
||||
return verts.empty() && vertcnt.empty();
|
||||
}
|
||||
|
||||
void RemoveAdjacentDuplicates();
|
||||
void RemoveDegenerates();
|
||||
|
||||
void FixupFaceOrientation();
|
||||
IfcVector3 ComputeLastPolygonNormal(bool normalize = true) const;
|
||||
void ComputePolygonNormals(std::vector<IfcVector3>& normals,
|
||||
bool normalize = true,
|
||||
size_t ofs = 0) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
|
||||
#include "IRRLoader.h"
|
||||
#include "ParsingUtils.h"
|
||||
#include "fast_atof.h"
|
||||
@@ -1471,3 +1473,5 @@ void IRRImporter::InternReadFile( const std::string& pFile,
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
|
||||
@@ -43,6 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
|
||||
#include "IRRMeshLoader.h"
|
||||
#include "ParsingUtils.h"
|
||||
#include "fast_atof.h"
|
||||
@@ -509,3 +511,5 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||
delete reader;
|
||||
AI_DEBUG_INVALIDATE_PTR(reader);
|
||||
}
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
|
||||
@@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
|
||||
#include "IRRShared.h"
|
||||
#include "ParsingUtils.h"
|
||||
#include "fast_atof.h"
|
||||
@@ -494,3 +496,5 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
|
||||
DefaultLogger::get()->error("IRRMESH: Unexpected end of file. Material is not complete");
|
||||
return mat;
|
||||
}
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
|
||||
@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
|
||||
|
||||
#include "LWSLoader.h"
|
||||
#include "ParsingUtils.h"
|
||||
@@ -918,3 +919,5 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_LWS_IMPORTER
|
||||
|
||||
@@ -310,7 +310,7 @@ struct Model
|
||||
m_Groups.clear();
|
||||
|
||||
for ( std::map<std::string, Material*>::iterator it = m_MaterialMap.begin(); it != m_MaterialMap.end(); ++it ) {
|
||||
// delete it->second;
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -100,7 +100,7 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
|
||||
|
||||
//Read the Mesh File:
|
||||
boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
|
||||
XmlReader* MeshFile = irr::io::createIrrXMLReader(mIOWrapper.get());
|
||||
boost::scoped_ptr<XmlReader> MeshFile(irr::io::createIrrXMLReader(mIOWrapper.get()));
|
||||
if(!MeshFile)//parse the xml file
|
||||
throw DeadlyImportError("Failed to create XML Reader for "+pFile);
|
||||
|
||||
@@ -108,21 +108,21 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
|
||||
DefaultLogger::get()->debug("Mesh File opened");
|
||||
|
||||
//Read root Node:
|
||||
if(!(XmlRead(MeshFile) && string(MeshFile->getNodeName())=="mesh"))
|
||||
if(!(XmlRead(MeshFile.get()) && string(MeshFile->getNodeName())=="mesh"))
|
||||
{
|
||||
throw DeadlyImportError("Root Node is not <mesh>! "+pFile+" "+MeshFile->getNodeName());
|
||||
}
|
||||
|
||||
//eventually load shared geometry
|
||||
XmlRead(MeshFile);//shared geometry is optional, so we need a reed for the next two if's
|
||||
XmlRead(MeshFile.get());//shared geometry is optional, so we need a reed for the next two if's
|
||||
if(MeshFile->getNodeName()==string("sharedgeometry"))
|
||||
{
|
||||
unsigned int NumVertices=GetAttribute<int>(MeshFile, "vertexcount");;
|
||||
unsigned int NumVertices=GetAttribute<int>(MeshFile.get(), "vertexcount");;
|
||||
|
||||
XmlRead(MeshFile);
|
||||
XmlRead(MeshFile.get());
|
||||
while(MeshFile->getNodeName()==string("vertexbuffer"))
|
||||
{
|
||||
ReadVertexBuffer(m_SharedGeometry, MeshFile, NumVertices);
|
||||
ReadVertexBuffer(m_SharedGeometry, MeshFile.get(), NumVertices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,13 +136,13 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
|
||||
//-------------------Read the submeshs and materials:-----------------------
|
||||
std::list<boost::shared_ptr<SubMesh> > SubMeshes;
|
||||
vector<aiMaterial*> Materials;
|
||||
XmlRead(MeshFile);
|
||||
XmlRead(MeshFile.get());
|
||||
while(MeshFile->getNodeName()==string("submesh"))
|
||||
{
|
||||
SubMesh* theSubMesh=new SubMesh();
|
||||
theSubMesh->MaterialName=GetAttribute<string>(MeshFile, "material");
|
||||
theSubMesh->MaterialName=GetAttribute<string>(MeshFile.get(), "material");
|
||||
DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh->MaterialName);
|
||||
ReadSubMesh(*theSubMesh, MeshFile);
|
||||
ReadSubMesh(*theSubMesh, MeshFile.get());
|
||||
|
||||
//just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n;
|
||||
//so it is important to do this before pushing the mesh in the vector!
|
||||
@@ -170,9 +170,9 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
|
||||
vector<Animation> Animations;
|
||||
if(MeshFile->getNodeName()==string("skeletonlink"))
|
||||
{
|
||||
string SkeletonFile=GetAttribute<string>(MeshFile, "name");
|
||||
string SkeletonFile=GetAttribute<string>(MeshFile.get(), "name");
|
||||
LoadSkeleton(SkeletonFile, Bones, Animations);
|
||||
XmlRead(MeshFile);
|
||||
XmlRead(MeshFile.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -185,7 +185,7 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
|
||||
//now there might be boneassignments for the shared geometry:
|
||||
if(MeshFile->getNodeName()==string("boneassignments"))
|
||||
{
|
||||
ReadBoneWeights(m_SharedGeometry, MeshFile);
|
||||
ReadBoneWeights(m_SharedGeometry, MeshFile.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -148,12 +148,22 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
|
||||
}
|
||||
}
|
||||
}
|
||||
//Fill the stream
|
||||
boost::scoped_ptr<IOStream> MaterialFile(MatFilePtr);
|
||||
vector<char> FileData(MaterialFile->FileSize());
|
||||
MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1);
|
||||
BaseImporter::ConvertToUTF8(FileData);
|
||||
if(MaterialFile->FileSize()>0)
|
||||
{
|
||||
vector<char> FileData(MaterialFile->FileSize());
|
||||
MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1);
|
||||
BaseImporter::ConvertToUTF8(FileData);
|
||||
|
||||
ss << &FileData[0];
|
||||
FileData.push_back('\0');//terminate the string with zero, so that the ss can parse it correctly
|
||||
ss << &FileData[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultLogger::get()->warn("Material " + MaterialName + " seams to be empty");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//create the material
|
||||
|
||||
@@ -640,6 +640,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode
|
||||
std::vector<std::string> supportedExtensions;
|
||||
supportedExtensions.push_back( ".jpg" );
|
||||
supportedExtensions.push_back( ".png" );
|
||||
supportedExtensions.push_back( ".tga" );
|
||||
if ( NULL == pArchive || NULL == pArchive || NULL == pMatHelper )
|
||||
{
|
||||
return false;
|
||||
@@ -670,10 +671,10 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode
|
||||
(void)readSize;
|
||||
ai_assert( readSize == pTexture->mWidth );
|
||||
pTexture->pcData = reinterpret_cast<aiTexel*>( pData );
|
||||
pTexture->achFormatHint[ 0 ] = ext[ 0 ];
|
||||
pTexture->achFormatHint[ 1 ] = ext[ 1 ];
|
||||
pTexture->achFormatHint[ 2 ] = ext[ 2 ];
|
||||
pTexture->achFormatHint[ 2 ] = '\0';
|
||||
pTexture->achFormatHint[ 0 ] = ext[ 1 ];
|
||||
pTexture->achFormatHint[ 1 ] = ext[ 2 ];
|
||||
pTexture->achFormatHint[ 2 ] = ext[ 3 ];
|
||||
pTexture->achFormatHint[ 3 ] = '\0';
|
||||
res = true;
|
||||
|
||||
aiString name;
|
||||
|
||||
@@ -38,6 +38,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||
|
||||
#include "Q3BSPFileParser.h"
|
||||
#include "DefaultIOSystem.h"
|
||||
#include "Q3BSPFileData.h"
|
||||
@@ -273,3 +276,5 @@ void Q3BSPFileParser::getEntities()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||
|
||||
@@ -39,6 +39,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||
|
||||
#include "Q3BSPZipArchive.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@@ -194,3 +197,5 @@ bool Q3BSPZipArchive::mapArchive()
|
||||
|
||||
} // Namespace Q3BSP
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||
|
||||
@@ -684,7 +684,7 @@ void SMDImporter::ParseFile()
|
||||
const char* szCurrent = mBuffer;
|
||||
|
||||
// read line per line ...
|
||||
while (true)
|
||||
for ( ;; )
|
||||
{
|
||||
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
|
||||
|
||||
@@ -750,7 +750,7 @@ unsigned int SMDImporter::GetTextureIndex(const std::string& filename)
|
||||
void SMDImporter::ParseNodesSection(const char* szCurrent,
|
||||
const char** szCurrentOut)
|
||||
{
|
||||
while (true)
|
||||
for ( ;; )
|
||||
{
|
||||
// "end\n" - Ends the nodes section
|
||||
if (0 == ASSIMP_strincmp(szCurrent,"end",3) &&
|
||||
@@ -772,7 +772,7 @@ void SMDImporter::ParseTrianglesSection(const char* szCurrent,
|
||||
{
|
||||
// Parse a triangle, parse another triangle, parse the next triangle ...
|
||||
// and so on until we reach a token that looks quite similar to "end"
|
||||
while (true)
|
||||
for ( ;; )
|
||||
{
|
||||
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
|
||||
|
||||
@@ -790,7 +790,7 @@ void SMDImporter::ParseVASection(const char* szCurrent,
|
||||
const char** szCurrentOut)
|
||||
{
|
||||
unsigned int iCurIndex = 0;
|
||||
while (true)
|
||||
for ( ;; )
|
||||
{
|
||||
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
|
||||
|
||||
@@ -833,7 +833,7 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent,
|
||||
const char** szCurrentOut)
|
||||
{
|
||||
int iTime = 0;
|
||||
while (true)
|
||||
for ( ;; )
|
||||
{
|
||||
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
|
||||
|
||||
@@ -887,7 +887,7 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent,
|
||||
else ++szCurrent;
|
||||
|
||||
const char* szEnd = szCurrent;
|
||||
while (true)
|
||||
for ( ;; )
|
||||
{
|
||||
if (bQuota && '\"' == *szEnd)
|
||||
{
|
||||
|
||||
@@ -192,19 +192,19 @@ namespace STEP {
|
||||
}
|
||||
|
||||
// utilities to deal with SELECT entities, which currently lack automatic
|
||||
// conversion support.
|
||||
template <typename T>
|
||||
const T& ResolveSelect(const DB& db) const {
|
||||
return Couple<T>(db).MustGetObject(To<EXPRESS::ENTITY>())->To<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* ResolveSelectPtr(const DB& db) const {
|
||||
const EXPRESS::ENTITY* e = ToPtr<EXPRESS::ENTITY>();
|
||||
return e?Couple<T>(db).MustGetObject(*e)->ToPtr<T>():(const T*)0;
|
||||
}
|
||||
|
||||
public:
|
||||
// conversion support.
|
||||
template <typename T>
|
||||
const T& ResolveSelect(const DB& db) const {
|
||||
return Couple<T>(db).MustGetObject(To<EXPRESS::ENTITY>())->template To<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* ResolveSelectPtr(const DB& db) const {
|
||||
const EXPRESS::ENTITY* e = ToPtr<EXPRESS::ENTITY>();
|
||||
return e?Couple<T>(db).MustGetObject(*e)->template ToPtr<T>():(const T*)0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/** parse a variable from a string and set 'inout' to the character
|
||||
* behind the last consumed character. An optional schema enables,
|
||||
|
||||
@@ -160,6 +160,30 @@ STEP::DB* STEP::ReadFileHeader(boost::shared_ptr<IOStream> stream)
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// check whether the given line contains an entity definition (i.e. starts with "#<number>=")
|
||||
bool IsEntityDef(const std::string& snext)
|
||||
{
|
||||
if (snext[0] == '#') {
|
||||
// it is only a new entity if it has a '=' after the
|
||||
// entity ID.
|
||||
for(std::string::const_iterator it = snext.begin()+1; it != snext.end(); ++it) {
|
||||
if (*it == '=') {
|
||||
return true;
|
||||
}
|
||||
if (*it < '0' || *it > '9') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
|
||||
const char* const* types_to_track, size_t len,
|
||||
@@ -171,8 +195,9 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
|
||||
|
||||
const DB::ObjectMap& map = db.GetObjects();
|
||||
LineSplitter& splitter = db.GetSplitter();
|
||||
for(; splitter; ++splitter) {
|
||||
const std::string& s = *splitter;
|
||||
while (splitter) {
|
||||
bool has_next = false;
|
||||
std::string s = *splitter;
|
||||
if (s == "ENDSEC;") {
|
||||
break;
|
||||
}
|
||||
@@ -184,6 +209,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
|
||||
ai_assert(s.length());
|
||||
if (s[0] != '#') {
|
||||
DefaultLogger::get()->warn(AddLineNumber("expected token \'#\'",line));
|
||||
++splitter;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -195,25 +221,75 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
|
||||
const std::string::size_type n0 = s.find_first_of('=');
|
||||
if (n0 == std::string::npos) {
|
||||
DefaultLogger::get()->warn(AddLineNumber("expected token \'=\'",line));
|
||||
++splitter;
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint64_t id = strtoul10_64(s.substr(1,n0-1).c_str());
|
||||
if (!id) {
|
||||
DefaultLogger::get()->warn(AddLineNumber("expected positive, numeric entity id",line));
|
||||
++splitter;
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string::size_type n1 = s.find_first_of('(',n0);
|
||||
std::string::size_type n1 = s.find_first_of('(',n0);
|
||||
if (n1 == std::string::npos) {
|
||||
DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line));
|
||||
continue;
|
||||
|
||||
has_next = true;
|
||||
bool ok = false;
|
||||
|
||||
for( ++splitter; splitter; ++splitter) {
|
||||
const std::string& snext = *splitter;
|
||||
if (snext.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// the next line doesn't start an entity, so maybe it is
|
||||
// just a continuation for this line, keep going
|
||||
if (!IsEntityDef(snext)) {
|
||||
s.append(snext);
|
||||
n1 = s.find_first_of('(',n0);
|
||||
ok = (n1 != std::string::npos);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ok) {
|
||||
DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string::size_type n2 = s.find_last_of(')');
|
||||
if (n2 == std::string::npos || n2 < n1) {
|
||||
DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line));
|
||||
continue;
|
||||
std::string::size_type n2 = s.find_last_of(')');
|
||||
if (n2 == std::string::npos || n2 < n1 || n2 == s.length() - 1 || s[n2 + 1] != ';') {
|
||||
|
||||
has_next = true;
|
||||
bool ok = false;
|
||||
|
||||
for( ++splitter; splitter; ++splitter) {
|
||||
const std::string& snext = *splitter;
|
||||
if (snext.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// the next line doesn't start an entity, so maybe it is
|
||||
// just a continuation for this line, keep going
|
||||
if (!IsEntityDef(snext)) {
|
||||
s.append(snext);
|
||||
n2 = s.find_last_of(')');
|
||||
ok = !(n2 == std::string::npos || n2 < n1 || n2 == s.length() - 1 || s[n2 + 1] != ';');
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ok) {
|
||||
DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (map.find(id) != map.end()) {
|
||||
@@ -239,6 +315,10 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
|
||||
|
||||
db.InternInsert(new LazyObject(db,id,line,sz,copysz));
|
||||
}
|
||||
|
||||
if(!has_next) {
|
||||
++splitter;
|
||||
}
|
||||
}
|
||||
|
||||
if (!splitter) {
|
||||
|
||||
@@ -203,7 +203,7 @@ void STLImporter::LoadASCIIFile()
|
||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||
|
||||
unsigned int curFace = 0, curVertex = 3;
|
||||
while (true)
|
||||
for ( ;; )
|
||||
{
|
||||
// go to the next token
|
||||
if(!SkipSpacesAndLineEnd(&sz))
|
||||
|
||||
@@ -87,7 +87,7 @@ inline unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number)
|
||||
// print all future zeroes from now
|
||||
mustPrint = true;
|
||||
|
||||
*out++ = '0'+digit;
|
||||
*out++ = '0'+static_cast<char>(digit);
|
||||
|
||||
++written;
|
||||
number -= digit*cur;
|
||||
|
||||
@@ -188,6 +188,8 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
FILE* fout = fopen(POLY_OUTPUT_FILE,"a");
|
||||
#endif
|
||||
|
||||
const aiVector3D* verts = pMesh->mVertices;
|
||||
|
||||
// use boost::scoped_array to avoid slow std::vector<bool> specialiations
|
||||
boost::scoped_array<bool> done(new bool[max_out]);
|
||||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
|
||||
@@ -216,24 +218,59 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
|
||||
face.mIndices = NULL;
|
||||
continue;
|
||||
} /* does not handle concave quads
|
||||
}
|
||||
// optimized code for quadrilaterals
|
||||
else if ( face.mNumIndices == 4) {
|
||||
|
||||
// quads can have at maximum one concave vertex. Determine
|
||||
// this vertex (if it exists) and start tri-fanning from
|
||||
// it.
|
||||
unsigned int start_vertex = 0;
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
const aiVector3D& v0 = verts[face.mIndices[(i+3) % 4]];
|
||||
const aiVector3D& v1 = verts[face.mIndices[(i+2) % 4]];
|
||||
const aiVector3D& v2 = verts[face.mIndices[(i+1) % 4]];
|
||||
|
||||
const aiVector3D& v = verts[face.mIndices[i]];
|
||||
|
||||
aiVector3D left = (v0-v);
|
||||
aiVector3D diag = (v1-v);
|
||||
aiVector3D right = (v2-v);
|
||||
|
||||
left.Normalize();
|
||||
diag.Normalize();
|
||||
right.Normalize();
|
||||
|
||||
const float angle = acos(left*diag) + acos(right*diag);
|
||||
if (angle > AI_MATH_PI_F) {
|
||||
// this is the concave point
|
||||
start_vertex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned int temp[] = {face.mIndices[0], face.mIndices[1], face.mIndices[2], face.mIndices[3]};
|
||||
|
||||
aiFace& nface = *curOut++;
|
||||
nface.mNumIndices = 3;
|
||||
nface.mIndices = face.mIndices;
|
||||
|
||||
nface.mIndices[0] = temp[start_vertex];
|
||||
nface.mIndices[1] = temp[(start_vertex + 1) % 4];
|
||||
nface.mIndices[2] = temp[(start_vertex + 2) % 4];
|
||||
|
||||
aiFace& sface = *curOut++;
|
||||
sface.mNumIndices = 3;
|
||||
sface.mIndices = new unsigned int[3];
|
||||
|
||||
sface.mIndices[0] = face.mIndices[0];
|
||||
sface.mIndices[1] = face.mIndices[2];
|
||||
sface.mIndices[2] = face.mIndices[3];
|
||||
|
||||
sface.mIndices[0] = temp[start_vertex];
|
||||
sface.mIndices[1] = temp[(start_vertex + 2) % 4];
|
||||
sface.mIndices[2] = temp[(start_vertex + 3) % 4];
|
||||
|
||||
// prevent double deletion of the indices field
|
||||
face.mIndices = NULL;
|
||||
continue;
|
||||
} */
|
||||
}
|
||||
else
|
||||
{
|
||||
// A polygon with more than 3 vertices can be either concave or convex.
|
||||
@@ -246,7 +283,6 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
// We project it onto a plane to get a 2d triangle.
|
||||
|
||||
// Collect all vertices of of the polygon.
|
||||
const aiVector3D* verts = pMesh->mVertices;
|
||||
for (tmp = 0; tmp < max; ++tmp) {
|
||||
temp_verts3d[tmp] = verts[idx[tmp]];
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
using namespace Assimp;
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
"Collada Importer",
|
||||
"Direct3D XFile Importer",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
@@ -594,8 +594,9 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
||||
|
||||
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||
// material colours
|
||||
// FIX: Setup this as ambient not as emissive color
|
||||
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||
// Unclear: there's no ambient colour, but emissive. What to put for ambient?
|
||||
// Probably nothing at all, let the user select a suitable default.
|
||||
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
|
||||
mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
|
||||
mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
|
||||
|
||||
@@ -460,7 +460,7 @@ void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
|
||||
Face& face = pMesh->mPosFaces[a];
|
||||
for( unsigned int b = 0; b < numIndices; b++)
|
||||
face.mIndices.push_back( ReadInt());
|
||||
CheckForSeparator();
|
||||
TestForSeparator();
|
||||
}
|
||||
|
||||
// here, other data objects may follow
|
||||
@@ -583,7 +583,7 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
|
||||
for( unsigned int b = 0; b < numIndices; b++)
|
||||
face.mIndices.push_back( ReadInt());
|
||||
|
||||
CheckForSeparator();
|
||||
TestForSeparator();
|
||||
}
|
||||
|
||||
CheckForClosingBrace();
|
||||
|
||||
Reference in New Issue
Block a user