Kaynağa Gözat

- untabify obj parser.
- bugfix openddl: latest version

Signed-off-by: Kim Kulling <[email protected]>

Kim Kulling 10 yıl önce
ebeveyn
işleme
c3e2fa0761

+ 518 - 518
code/ObjFileImporter.cpp

@@ -48,16 +48,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "ObjFileData.h"
 
 static const aiImporterDesc desc = {
-	"Wavefront Object Importer",
-	"",
-	"",
-	"surfaces not supported",
-	aiImporterFlags_SupportTextFlavour,
-	0,
-	0,
-	0,
-	0,
-	"obj"
+    "Wavefront Object Importer",
+    "",
+    "",
+    "surfaces not supported",
+    aiImporterFlags_SupportTextFlavour,
+    0,
+    0,
+    0,
+    0,
+    "obj"
 };
 
 static const unsigned int ObjMinSize = 16;
@@ -69,99 +69,99 @@ using namespace std;
 // ------------------------------------------------------------------------------------------------
 //	Default constructor
 ObjFileImporter::ObjFileImporter() :
-	m_Buffer(),	
-	m_pRootObject( NULL ),
-	m_strAbsPath( "" )
+    m_Buffer(),	
+    m_pRootObject( NULL ),
+    m_strAbsPath( "" )
 {
     DefaultIOSystem io;
-	m_strAbsPath = io.getOsSeparator();
+    m_strAbsPath = io.getOsSeparator();
 }
 
 // ------------------------------------------------------------------------------------------------
 //	Destructor.
 ObjFileImporter::~ObjFileImporter()
 {
-	delete m_pRootObject;
-	m_pRootObject = NULL;
+    delete m_pRootObject;
+    m_pRootObject = NULL;
 }
 
 // ------------------------------------------------------------------------------------------------
 //	Returns true, if file is an obj file.
 bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem*  pIOHandler , bool checkSig ) const
 {
-	if(!checkSig) //Check File Extension
-	{
-		return SimpleExtensionCheck(pFile,"obj");
-	}
-	else //Check file Header
-	{
-		static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
-		return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 );
-	}
+    if(!checkSig) //Check File Extension
+    {
+        return SimpleExtensionCheck(pFile,"obj");
+    }
+    else //Check file Header
+    {
+        static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
+        return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 );
+    }
 }
 
 // ------------------------------------------------------------------------------------------------
 const aiImporterDesc* ObjFileImporter::GetInfo () const
 {
-	return &desc;
+    return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------
 //	Obj-file import implementation
 void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
 {    
-	// Read file into memory
-	const std::string mode = "rb";
-	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode));
+    // Read file into memory
+    const std::string mode = "rb";
+    boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode));
     if( !file.get() ) {
         throw DeadlyImportError( "Failed to open file " + pFile + "." );
     }
 
-	// Get the file-size and validate it, throwing an exception when fails
-	size_t fileSize = file->FileSize();
+    // Get the file-size and validate it, throwing an exception when fails
+    size_t fileSize = file->FileSize();
     if( fileSize < ObjMinSize ) {
-		throw DeadlyImportError( "OBJ-file is too small.");
+        throw DeadlyImportError( "OBJ-file is too small.");
+    }
+
+    // Allocate buffer and read file into it
+    TextFileToBuffer(file.get(),m_Buffer);
+
+    // Get the model name
+    std::string  strModelName;
+    std::string::size_type pos = pFile.find_last_of( "\\/" );
+    if ( pos != std::string::npos )	
+    {
+        strModelName = pFile.substr(pos+1, pFile.size() - pos - 1);
     }
+    else
+    {
+        strModelName = pFile;
+    }
+
+    // process all '\'
+    std::vector<char> ::iterator iter = m_Buffer.begin();
+    while (iter != m_Buffer.end())
+    {
+        if (*iter == '\\')
+        {
+            // remove '\'
+            iter = m_Buffer.erase(iter);
+            // remove next character
+            while (*iter == '\r' || *iter == '\n')
+                iter = m_Buffer.erase(iter);
+        }
+        else
+            ++iter;
+    }
+
+    // parse the file into a temporary representation
+    ObjFileParser parser(m_Buffer, strModelName, pIOHandler);
+
+    // And create the proper return structures out of it
+    CreateDataFromImport(parser.GetModel(), pScene);
 
-	// Allocate buffer and read file into it
-	TextFileToBuffer(file.get(),m_Buffer);
-
-	// Get the model name
-	std::string  strModelName;
-	std::string::size_type pos = pFile.find_last_of( "\\/" );
-	if ( pos != std::string::npos )	
-	{
-		strModelName = pFile.substr(pos+1, pFile.size() - pos - 1);
-	}
-	else
-	{
-		strModelName = pFile;
-	}
-
-	// process all '\'
-	std::vector<char> ::iterator iter = m_Buffer.begin();
-	while (iter != m_Buffer.end())
-	{
-		if (*iter == '\\')
-		{
-			// remove '\'
-			iter = m_Buffer.erase(iter);
-			// remove next character
-			while (*iter == '\r' || *iter == '\n')
-				iter = m_Buffer.erase(iter);
-		}
-		else
-			++iter;
-	}
-
-	// parse the file into a temporary representation
-	ObjFileParser parser(m_Buffer, strModelName, pIOHandler);
-
-	// And create the proper return structures out of it
-	CreateDataFromImport(parser.GetModel(), pScene);
-
-	// Clean up allocated storage for the next import 
-	m_Buffer.clear();
+    // Clean up allocated storage for the next import 
+    m_Buffer.clear();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -170,98 +170,98 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
     if( 0L == pModel ) {
         return;
     }
-		
-	// Create the root node of the scene
-	pScene->mRootNode = new aiNode;
-	if ( !pModel->m_ModelName.empty() )
-	{
-		// Set the name of the scene
-		pScene->mRootNode->mName.Set(pModel->m_ModelName);
-	}
-	else
-	{
-		// This is a fatal error, so break down the application
-		ai_assert(false);
-	} 
-
-	// Create nodes for the whole scene	
-	std::vector<aiMesh*> MeshArray;
-	for (size_t index = 0; index < pModel->m_Objects.size(); index++)
-	{
-		createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray);
-	}
-
-	// Create mesh pointer buffer for this scene
-	if (pScene->mNumMeshes > 0)
-	{
-		pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
-		for (size_t index =0; index < MeshArray.size(); index++)
-		{
-			pScene->mMeshes [ index ] = MeshArray[ index ];
-		}
-	}
-
-	// Create all materials
-	createMaterials( pModel, pScene );
+        
+    // Create the root node of the scene
+    pScene->mRootNode = new aiNode;
+    if ( !pModel->m_ModelName.empty() )
+    {
+        // Set the name of the scene
+        pScene->mRootNode->mName.Set(pModel->m_ModelName);
+    }
+    else
+    {
+        // This is a fatal error, so break down the application
+        ai_assert(false);
+    } 
+
+    // Create nodes for the whole scene	
+    std::vector<aiMesh*> MeshArray;
+    for (size_t index = 0; index < pModel->m_Objects.size(); index++)
+    {
+        createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray);
+    }
+
+    // Create mesh pointer buffer for this scene
+    if (pScene->mNumMeshes > 0)
+    {
+        pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
+        for (size_t index =0; index < MeshArray.size(); index++)
+        {
+            pScene->mMeshes [ index ] = MeshArray[ index ];
+        }
+    }
+
+    // Create all materials
+    createMaterials( pModel, pScene );
 }
 
 // ------------------------------------------------------------------------------------------------
 //	Creates all nodes of the model
 aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject, 
-									 aiNode *pParent, aiScene* pScene, 
-									 std::vector<aiMesh*> &MeshArray )
+                                     aiNode *pParent, aiScene* pScene, 
+                                     std::vector<aiMesh*> &MeshArray )
 {
-	ai_assert( NULL != pModel );
+    ai_assert( NULL != pModel );
     if( NULL == pObject ) {
         return NULL;
     }
-	
-	// Store older mesh size to be able to computes mesh offsets for new mesh instances
-	const size_t oldMeshSize = MeshArray.size();
-	aiNode *pNode = new aiNode;
-
-	pNode->mName = pObject->m_strObjName;
-	
-	// If we have a parent node, store it
+    
+    // Store older mesh size to be able to computes mesh offsets for new mesh instances
+    const size_t oldMeshSize = MeshArray.size();
+    aiNode *pNode = new aiNode;
+
+    pNode->mName = pObject->m_strObjName;
+    
+    // If we have a parent node, store it
     if( pParent != NULL ) {
         appendChildToParentNode( pParent, pNode );
     }
 
-	for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ )
-	{
-		unsigned int meshId = pObject->m_Meshes[ i ];
-		aiMesh *pMesh = createTopology( pModel, pObject, meshId );	
+    for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ )
+    {
+        unsigned int meshId = pObject->m_Meshes[ i ];
+        aiMesh *pMesh = createTopology( pModel, pObject, meshId );	
         if( pMesh && pMesh->mNumFaces > 0 ) {
-			MeshArray.push_back( pMesh );
-		}
-	}
-
-	// Create all nodes from the sub-objects stored in the current object
-	if ( !pObject->m_SubObjects.empty() )
-	{
-		size_t numChilds = pObject->m_SubObjects.size();
-		pNode->mNumChildren = static_cast<unsigned int>( numChilds );
-		pNode->mChildren = new aiNode*[ numChilds ];
-		pNode->mNumMeshes = 1;
-		pNode->mMeshes = new unsigned int[ 1 ];
-	}
-
-	// Set mesh instances into scene- and node-instances
-	const size_t meshSizeDiff = MeshArray.size()- oldMeshSize;
-	if ( meshSizeDiff > 0 )
-	{
-		pNode->mMeshes = new unsigned int[ meshSizeDiff ];
-		pNode->mNumMeshes = static_cast<unsigned int>( meshSizeDiff );
-		size_t index = 0;
-		for (size_t i = oldMeshSize; i < MeshArray.size(); i++)
-		{
-			pNode->mMeshes[ index ] = pScene->mNumMeshes;
-			pScene->mNumMeshes++;
-			index++;
-		}
-	}
-	
-	return pNode;
+            MeshArray.push_back( pMesh );
+        }
+    }
+
+    // Create all nodes from the sub-objects stored in the current object
+    if ( !pObject->m_SubObjects.empty() )
+    {
+        size_t numChilds = pObject->m_SubObjects.size();
+        pNode->mNumChildren = static_cast<unsigned int>( numChilds );
+        pNode->mChildren = new aiNode*[ numChilds ];
+        pNode->mNumMeshes = 1;
+        pNode->mMeshes = new unsigned int[ 1 ];
+    }
+
+    // Set mesh instances into scene- and node-instances
+    const size_t meshSizeDiff = MeshArray.size()- oldMeshSize;
+    if ( meshSizeDiff > 0 )
+    {
+        pNode->mMeshes = new unsigned int[ meshSizeDiff ];
+        pNode->mNumMeshes = static_cast<unsigned int>( meshSizeDiff );
+        size_t index = 0;
+        for (size_t i = oldMeshSize; i < MeshArray.size(); i++)
+        {
+            pNode->mMeshes[ index ] = pScene->mNumMeshes;
+            pScene->mNumMeshes++;
+            index++;
+        }
+    }
+    
+    return pNode;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -269,83 +269,83 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
 aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData, 
                                          unsigned int uiMeshIndex )
 {
-	// Checking preconditions
-	ai_assert( NULL != pModel );
+    // Checking preconditions
+    ai_assert( NULL != pModel );
     if( NULL == pData ) {
         return NULL;
     }
 
-	// Create faces
-	ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
+    // Create faces
+    ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
     if( !pObjMesh ) {
         return NULL;
     }
     ai_assert( NULL != pObjMesh );
     aiMesh* pMesh = new aiMesh;
-	for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
-	{
-		ObjFile::Face *const inp = pObjMesh->m_Faces[ index ];
+    for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
+    {
+        ObjFile::Face *const inp = pObjMesh->m_Faces[ index ];
         ai_assert( NULL != inp  );
 
-		if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
-			pMesh->mNumFaces += inp->m_pVertices->size() - 1;
-			pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
-		} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
-			pMesh->mNumFaces += inp->m_pVertices->size();
-			pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
-		} else {
-			++pMesh->mNumFaces;
-			if (inp->m_pVertices->size() > 3) {
-				pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
-			} else {
-				pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
-			}
-		}
-	}
-
-	unsigned int uiIdxCount( 0u );
-	if ( pMesh->mNumFaces > 0 )
-	{
-		pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
-		if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial )
-		{
-			pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
-		}
-
-		unsigned int outIndex( 0 );
-
-		// Copy all data from all stored meshes
-		for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
-		{
-			ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
-			if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
-				for(size_t i = 0; i < inp->m_pVertices->size() - 1; ++i) {
-					aiFace& f = pMesh->mFaces[ outIndex++ ];
-					uiIdxCount += f.mNumIndices = 2;
-					f.mIndices = new unsigned int[2];
-				}
-				continue;
-			}
-			else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
-				for(size_t i = 0; i < inp->m_pVertices->size(); ++i) {
-					aiFace& f = pMesh->mFaces[ outIndex++ ];
-					uiIdxCount += f.mNumIndices = 1;
-					f.mIndices = new unsigned int[1];
-				}
-				continue;
-			}
-
-			aiFace *pFace = &pMesh->mFaces[ outIndex++ ];
-			const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size();
-			uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices;
-			if (pFace->mNumIndices > 0) {
-				pFace->mIndices = new unsigned int[ uiNumIndices ];			
-			}
-		}
-	}
-
-	// Create mesh vertices
-	createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount);
+        if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
+            pMesh->mNumFaces += inp->m_pVertices->size() - 1;
+            pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
+        } else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
+            pMesh->mNumFaces += inp->m_pVertices->size();
+            pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
+        } else {
+            ++pMesh->mNumFaces;
+            if (inp->m_pVertices->size() > 3) {
+                pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
+            } else {
+                pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
+            }
+        }
+    }
+
+    unsigned int uiIdxCount( 0u );
+    if ( pMesh->mNumFaces > 0 )
+    {
+        pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
+        if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial )
+        {
+            pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
+        }
+
+        unsigned int outIndex( 0 );
+
+        // Copy all data from all stored meshes
+        for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
+        {
+            ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
+            if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
+                for(size_t i = 0; i < inp->m_pVertices->size() - 1; ++i) {
+                    aiFace& f = pMesh->mFaces[ outIndex++ ];
+                    uiIdxCount += f.mNumIndices = 2;
+                    f.mIndices = new unsigned int[2];
+                }
+                continue;
+            }
+            else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
+                for(size_t i = 0; i < inp->m_pVertices->size(); ++i) {
+                    aiFace& f = pMesh->mFaces[ outIndex++ ];
+                    uiIdxCount += f.mNumIndices = 1;
+                    f.mIndices = new unsigned int[1];
+                }
+                continue;
+            }
+
+            aiFace *pFace = &pMesh->mFaces[ outIndex++ ];
+            const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size();
+            uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices;
+            if (pFace->mNumIndices > 0) {
+                pFace->mIndices = new unsigned int[ uiNumIndices ];			
+            }
+        }
+    }
+
+    // Create mesh vertices
+    createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount);
 
     return pMesh;
 }
@@ -353,335 +353,335 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
 // ------------------------------------------------------------------------------------------------
 //	Creates a vertex array
 void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, 
-										const ObjFile::Object* pCurrentObject, 
-										unsigned int uiMeshIndex,
-										aiMesh* pMesh,
-										unsigned int uiIdxCount)
+                                        const ObjFile::Object* pCurrentObject, 
+                                        unsigned int uiMeshIndex,
+                                        aiMesh* pMesh,
+                                        unsigned int uiIdxCount)
 {
-	// Checking preconditions
-	ai_assert( NULL != pCurrentObject );
-	
-	// Break, if no faces are stored in object
-	if ( pCurrentObject->m_Meshes.empty() )
-		return;
-
-	// Get current mesh
-	ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
-	if ( NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1)
-		return;
-
-	// Copy vertices of this mesh instance
-	pMesh->mNumVertices = uiIdxCount;
-	pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
-	
-	// Allocate buffer for normal vectors
-	if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals )
-		pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ];
-	
-	// Allocate buffer for texture coordinates
-	if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
-	{
-		pMesh->mNumUVComponents[ 0 ] = 2;
-		pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
-	}
-	
-	// Copy vertices, normals and textures into aiMesh instance
-	unsigned int newIndex = 0, outIndex = 0;
-	for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ )
-	{
-		// Get source face
-		ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ]; 
-
-		// Copy all index arrays
-		for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ )
-		{
-			const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex );
-			if ( vertex >= pModel->m_Vertices.size() ) 
-				throw DeadlyImportError( "OBJ: vertex index out of range" );
-			
-			pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
-			
-			// Copy all normals 
-			if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size())
-			{
-				const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex );
-				if ( normal >= pModel->m_Normals.size() )
-					throw DeadlyImportError("OBJ: vertex normal index out of range");
-
-				pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
-			}
-			
-			// Copy all texture coordinates
-			if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size())
-			{
-				const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
-				ai_assert( tex < pModel->m_TextureCoord.size() );
-					
-				if ( tex >= pModel->m_TextureCoord.size() )
-					throw DeadlyImportError("OBJ: texture coordinate index out of range");
-
-				const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ];
+    // Checking preconditions
+    ai_assert( NULL != pCurrentObject );
+    
+    // Break, if no faces are stored in object
+    if ( pCurrentObject->m_Meshes.empty() )
+        return;
+
+    // Get current mesh
+    ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
+    if ( NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1)
+        return;
+
+    // Copy vertices of this mesh instance
+    pMesh->mNumVertices = uiIdxCount;
+    pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
+    
+    // Allocate buffer for normal vectors
+    if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals )
+        pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ];
+    
+    // Allocate buffer for texture coordinates
+    if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
+    {
+        pMesh->mNumUVComponents[ 0 ] = 2;
+        pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
+    }
+    
+    // Copy vertices, normals and textures into aiMesh instance
+    unsigned int newIndex = 0, outIndex = 0;
+    for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ )
+    {
+        // Get source face
+        ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ]; 
+
+        // Copy all index arrays
+        for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ )
+        {
+            const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex );
+            if ( vertex >= pModel->m_Vertices.size() ) 
+                throw DeadlyImportError( "OBJ: vertex index out of range" );
+            
+            pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
+            
+            // Copy all normals 
+            if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size())
+            {
+                const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex );
+                if ( normal >= pModel->m_Normals.size() )
+                    throw DeadlyImportError("OBJ: vertex normal index out of range");
+
+                pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
+            }
+            
+            // Copy all texture coordinates
+            if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size())
+            {
+                const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
+                ai_assert( tex < pModel->m_TextureCoord.size() );
+                    
+                if ( tex >= pModel->m_TextureCoord.size() )
+                    throw DeadlyImportError("OBJ: texture coordinate index out of range");
+
+                const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ];
                 pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord3d.x, coord3d.y, coord3d.z );
-			}
-
-			ai_assert( pMesh->mNumVertices > newIndex );
-
-			// Get destination face
-			aiFace *pDestFace = &pMesh->mFaces[ outIndex ];
-
-			const bool last = ( vertexIndex == pSourceFace->m_pVertices->size() - 1 ); 
-			if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) 
-			{
-				pDestFace->mIndices[ outVertexIndex ] = newIndex;
-				outVertexIndex++;
-			}
-
-			if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) 
-			{
-				outIndex++;
-				outVertexIndex = 0;
-			}
-			else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) 
-			{
-				outVertexIndex = 0;
-
-				if(!last) 
-					outIndex++;
-
-				if (vertexIndex) {
-					if(!last) {
-						pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ];
-						if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) {
-							pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ];
-						}
-						if ( !pModel->m_TextureCoord.empty() ) {
-							for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) {
-								pMesh->mTextureCoords[ i ][ newIndex+1 ] = pMesh->mTextureCoords[ i ][ newIndex ];
-							}
-						}
-						++newIndex;
-					}
-
-					pDestFace[-1].mIndices[1] = newIndex;
-				}
-			}
-			else if (last) {
-				outIndex++;
-			}
-			++newIndex;
-		}
-	}	
+            }
+
+            ai_assert( pMesh->mNumVertices > newIndex );
+
+            // Get destination face
+            aiFace *pDestFace = &pMesh->mFaces[ outIndex ];
+
+            const bool last = ( vertexIndex == pSourceFace->m_pVertices->size() - 1 ); 
+            if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) 
+            {
+                pDestFace->mIndices[ outVertexIndex ] = newIndex;
+                outVertexIndex++;
+            }
+
+            if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) 
+            {
+                outIndex++;
+                outVertexIndex = 0;
+            }
+            else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) 
+            {
+                outVertexIndex = 0;
+
+                if(!last) 
+                    outIndex++;
+
+                if (vertexIndex) {
+                    if(!last) {
+                        pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ];
+                        if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) {
+                            pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ];
+                        }
+                        if ( !pModel->m_TextureCoord.empty() ) {
+                            for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) {
+                                pMesh->mTextureCoords[ i ][ newIndex+1 ] = pMesh->mTextureCoords[ i ][ newIndex ];
+                            }
+                        }
+                        ++newIndex;
+                    }
+
+                    pDestFace[-1].mIndices[1] = newIndex;
+                }
+            }
+            else if (last) {
+                outIndex++;
+            }
+            ++newIndex;
+        }
+    }	
 }
 
 // ------------------------------------------------------------------------------------------------
 //	Counts all stored meshes 
 void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes)
 {
-	iNumMeshes = 0;
-	if ( rObjects.empty() )	
-		return;
-
-	iNumMeshes += static_cast<unsigned int>( rObjects.size() );
-	for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin();
-		it != rObjects.end(); 
-		++it)
-	{
-		if (!(*it)->m_SubObjects.empty())
-		{
-			countObjects((*it)->m_SubObjects, iNumMeshes);
-		}
-	}
+    iNumMeshes = 0;
+    if ( rObjects.empty() )	
+        return;
+
+    iNumMeshes += static_cast<unsigned int>( rObjects.size() );
+    for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin();
+        it != rObjects.end(); 
+        ++it)
+    {
+        if (!(*it)->m_SubObjects.empty())
+        {
+            countObjects((*it)->m_SubObjects, iNumMeshes);
+        }
+    }
 }
 
 // ------------------------------------------------------------------------------------------------
 //	 Add clamp mode property to material if necessary 
 void ObjFileImporter::addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode)
 {
-	ai_assert( NULL != mat);
-	mat->AddProperty<int>(&clampMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0));
-	mat->AddProperty<int>(&clampMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0));
+    ai_assert( NULL != mat);
+    mat->AddProperty<int>(&clampMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0));
+    mat->AddProperty<int>(&clampMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0));
 }
 
 // ------------------------------------------------------------------------------------------------
 //	Creates the material 
 void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pScene )
 {
-	ai_assert( NULL != pScene );
-	if ( NULL == pScene )
-		return;
-
-	const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size();
-	pScene->mNumMaterials = 0;
-	if ( pModel->m_MaterialLib.empty() ) {
-		DefaultLogger::get()->debug("OBJ: no materials specified");
-		return;
-	}
-	
-	pScene->mMaterials = new aiMaterial*[ numMaterials ];
-	for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ )
-	{		
-		// Store material name
-		std::map<std::string, ObjFile::Material*>::const_iterator it;
-		it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] );
-		
-		// No material found, use the default material
-		if ( pModel->m_MaterialMap.end() == it )
-			continue;
-
-		aiMaterial* mat = new aiMaterial;
-		ObjFile::Material *pCurrentMaterial = (*it).second;
-		mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME );
-
-		// convert illumination model
-		int sm = 0;
-		switch (pCurrentMaterial->illumination_model) 
-		{
-		case 0:
-			sm = aiShadingMode_NoShading;
-			break;
-		case 1:
-			sm = aiShadingMode_Gouraud;
-			break;
-		case 2:
-			sm = aiShadingMode_Phong;
-			break;
-		default:
-			sm = aiShadingMode_Gouraud;
-			DefaultLogger::get()->error("OBJ: unexpected illumination model (0-2 recognized)");
-		}
-	
-		mat->AddProperty<int>( &sm, 1, AI_MATKEY_SHADING_MODEL);
-
-		// multiplying the specular exponent with 2 seems to yield better results
-		pCurrentMaterial->shineness *= 4.f;
-
-		// Adding material colors
-		mat->AddProperty( &pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT );
-		mat->AddProperty( &pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE );
-		mat->AddProperty( &pCurrentMaterial->specular, 1, AI_MATKEY_COLOR_SPECULAR );
-		mat->AddProperty( &pCurrentMaterial->emissive, 1, AI_MATKEY_COLOR_EMISSIVE );
-		mat->AddProperty( &pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS );
-		mat->AddProperty( &pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY );
-
-		// Adding refraction index
-		mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI );
-
-		// Adding textures
-		if ( 0 != pCurrentMaterial->texture.length ) 
-		{
-			mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0));
-			if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType])
-			{
-				addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE);
-			}
-		}
-
-		if ( 0 != pCurrentMaterial->textureAmbient.length )
-		{
-			mat->AddProperty( &pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0));
-			if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType])
-			{
-				addTextureMappingModeProperty(mat, aiTextureType_AMBIENT);
-			}
-		}
-
-		if ( 0 != pCurrentMaterial->textureEmissive.length )
-			mat->AddProperty( &pCurrentMaterial->textureEmissive, AI_MATKEY_TEXTURE_EMISSIVE(0));
-
-		if ( 0 != pCurrentMaterial->textureSpecular.length )
-		{
-			mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));
-			if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType])
-			{
-				addTextureMappingModeProperty(mat, aiTextureType_SPECULAR);
-			}
-		}
-
-		if ( 0 != pCurrentMaterial->textureBump.length )
-		{
-			mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0));
-			if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType])
-			{
-				addTextureMappingModeProperty(mat, aiTextureType_HEIGHT);
-			}
-		}
-
-		if ( 0 != pCurrentMaterial->textureNormal.length )
-		{
-			mat->AddProperty( &pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0));
-			if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType])
-			{
-				addTextureMappingModeProperty(mat, aiTextureType_NORMALS);
-			}
-		}
-
-		if ( 0 != pCurrentMaterial->textureDisp.length )
-		{
-			mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) );
-			if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType])
-			{
-				addTextureMappingModeProperty(mat, aiTextureType_DISPLACEMENT);
-			}
-		}
-
-		if ( 0 != pCurrentMaterial->textureOpacity.length )
-		{
-			mat->AddProperty( &pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0));
-			if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType])
-			{
-				addTextureMappingModeProperty(mat, aiTextureType_OPACITY);
-			}
-		}
-
-		if ( 0 != pCurrentMaterial->textureSpecularity.length )
-		{
-			mat->AddProperty( &pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0));
-			if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType])
-			{
-				addTextureMappingModeProperty(mat, aiTextureType_SHININESS);
-			}
-		}
-		
-		// Store material property info in material array in scene
-		pScene->mMaterials[ pScene->mNumMaterials ] = mat;
-		pScene->mNumMaterials++;
-	}
-	
-	// Test number of created materials.
-	ai_assert( pScene->mNumMaterials == numMaterials );
+    ai_assert( NULL != pScene );
+    if ( NULL == pScene )
+        return;
+
+    const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size();
+    pScene->mNumMaterials = 0;
+    if ( pModel->m_MaterialLib.empty() ) {
+        DefaultLogger::get()->debug("OBJ: no materials specified");
+        return;
+    }
+    
+    pScene->mMaterials = new aiMaterial*[ numMaterials ];
+    for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ )
+    {		
+        // Store material name
+        std::map<std::string, ObjFile::Material*>::const_iterator it;
+        it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] );
+        
+        // No material found, use the default material
+        if ( pModel->m_MaterialMap.end() == it )
+            continue;
+
+        aiMaterial* mat = new aiMaterial;
+        ObjFile::Material *pCurrentMaterial = (*it).second;
+        mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME );
+
+        // convert illumination model
+        int sm = 0;
+        switch (pCurrentMaterial->illumination_model) 
+        {
+        case 0:
+            sm = aiShadingMode_NoShading;
+            break;
+        case 1:
+            sm = aiShadingMode_Gouraud;
+            break;
+        case 2:
+            sm = aiShadingMode_Phong;
+            break;
+        default:
+            sm = aiShadingMode_Gouraud;
+            DefaultLogger::get()->error("OBJ: unexpected illumination model (0-2 recognized)");
+        }
+    
+        mat->AddProperty<int>( &sm, 1, AI_MATKEY_SHADING_MODEL);
+
+        // multiplying the specular exponent with 2 seems to yield better results
+        pCurrentMaterial->shineness *= 4.f;
+
+        // Adding material colors
+        mat->AddProperty( &pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT );
+        mat->AddProperty( &pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE );
+        mat->AddProperty( &pCurrentMaterial->specular, 1, AI_MATKEY_COLOR_SPECULAR );
+        mat->AddProperty( &pCurrentMaterial->emissive, 1, AI_MATKEY_COLOR_EMISSIVE );
+        mat->AddProperty( &pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS );
+        mat->AddProperty( &pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY );
+
+        // Adding refraction index
+        mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI );
+
+        // Adding textures
+        if ( 0 != pCurrentMaterial->texture.length ) 
+        {
+            mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0));
+            if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType])
+            {
+                addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE);
+            }
+        }
+
+        if ( 0 != pCurrentMaterial->textureAmbient.length )
+        {
+            mat->AddProperty( &pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0));
+            if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType])
+            {
+                addTextureMappingModeProperty(mat, aiTextureType_AMBIENT);
+            }
+        }
+
+        if ( 0 != pCurrentMaterial->textureEmissive.length )
+            mat->AddProperty( &pCurrentMaterial->textureEmissive, AI_MATKEY_TEXTURE_EMISSIVE(0));
+
+        if ( 0 != pCurrentMaterial->textureSpecular.length )
+        {
+            mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));
+            if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType])
+            {
+                addTextureMappingModeProperty(mat, aiTextureType_SPECULAR);
+            }
+        }
+
+        if ( 0 != pCurrentMaterial->textureBump.length )
+        {
+            mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0));
+            if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType])
+            {
+                addTextureMappingModeProperty(mat, aiTextureType_HEIGHT);
+            }
+        }
+
+        if ( 0 != pCurrentMaterial->textureNormal.length )
+        {
+            mat->AddProperty( &pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0));
+            if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType])
+            {
+                addTextureMappingModeProperty(mat, aiTextureType_NORMALS);
+            }
+        }
+
+        if ( 0 != pCurrentMaterial->textureDisp.length )
+        {
+            mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) );
+            if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType])
+            {
+                addTextureMappingModeProperty(mat, aiTextureType_DISPLACEMENT);
+            }
+        }
+
+        if ( 0 != pCurrentMaterial->textureOpacity.length )
+        {
+            mat->AddProperty( &pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0));
+            if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType])
+            {
+                addTextureMappingModeProperty(mat, aiTextureType_OPACITY);
+            }
+        }
+
+        if ( 0 != pCurrentMaterial->textureSpecularity.length )
+        {
+            mat->AddProperty( &pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0));
+            if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType])
+            {
+                addTextureMappingModeProperty(mat, aiTextureType_SHININESS);
+            }
+        }
+        
+        // Store material property info in material array in scene
+        pScene->mMaterials[ pScene->mNumMaterials ] = mat;
+        pScene->mNumMaterials++;
+    }
+    
+    // Test number of created materials.
+    ai_assert( pScene->mNumMaterials == numMaterials );
 }
 
 // ------------------------------------------------------------------------------------------------
 //	Appends this node to the parent node
 void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
 {
-	// Checking preconditions
-	ai_assert( NULL != pParent );
-	ai_assert( NULL != pChild );
-
-	// Assign parent to child
-	pChild->mParent = pParent;
-	
-	// If already children was assigned to the parent node, store them in a 
-	std::vector<aiNode*> temp;
-	if (pParent->mChildren != NULL)
-	{
-		ai_assert( 0 != pParent->mNumChildren );
-		for (size_t index = 0; index < pParent->mNumChildren; index++)
-		{
-			temp.push_back(pParent->mChildren [ index ] );
-		}
-		delete [] pParent->mChildren;
-	}
-	
-	// Copy node instances into parent node
-	pParent->mNumChildren++;
-	pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
-	for (size_t index = 0; index < pParent->mNumChildren-1; index++)
-	{
-		pParent->mChildren[ index ] = temp [ index ];
-	}
-	pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
+    // Checking preconditions
+    ai_assert( NULL != pParent );
+    ai_assert( NULL != pChild );
+
+    // Assign parent to child
+    pChild->mParent = pParent;
+    
+    // If already children was assigned to the parent node, store them in a 
+    std::vector<aiNode*> temp;
+    if (pParent->mChildren != NULL)
+    {
+        ai_assert( 0 != pParent->mNumChildren );
+        for (size_t index = 0; index < pParent->mNumChildren; index++)
+        {
+            temp.push_back(pParent->mChildren [ index ] );
+        }
+        delete [] pParent->mChildren;
+    }
+    
+    // Copy node instances into parent node
+    pParent->mNumChildren++;
+    pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
+    for (size_t index = 0; index < pParent->mNumChildren-1; index++)
+    {
+        pParent->mChildren[ index ] = temp [ index ];
+    }
+    pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 37 - 37
code/ObjFileImporter.h

@@ -64,57 +64,57 @@ struct Model;
 class ObjFileImporter : public BaseImporter
 {	
 public:
-	///	\brief	Default constructor
-	ObjFileImporter();
+    ///	\brief	Default constructor
+    ObjFileImporter();
 
-	///	\brief	Destructor
-	~ObjFileImporter();
+    ///	\brief	Destructor
+    ~ObjFileImporter();
 
 public:
-	/// \brief	Returns whether the class can handle the format of the given file. 
-	/// \remark	See BaseImporter::CanRead() for details.
-	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
+    /// \brief	Returns whether the class can handle the format of the given file. 
+    /// \remark	See BaseImporter::CanRead() for details.
+    bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
 
 private:
 
-	//! \brief	Appends the supported extension.
-	const aiImporterDesc* GetInfo () const;
+    //! \brief	Appends the supported extension.
+    const aiImporterDesc* GetInfo () const;
 
-	//!	\brief	File import implementation.
-	void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-	
-	//!	\brief	Create the data from imported content.
-	void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
-	
-	//!	\brief	Creates all nodes stored in imported content.
-	aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData,
-		aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
+    //!	\brief	File import implementation.
+    void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
+    
+    //!	\brief	Create the data from imported content.
+    void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
+    
+    //!	\brief	Creates all nodes stored in imported content.
+    aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData,
+        aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
 
-	//!	\brief	Creates topology data like faces and meshes for the geometry.
+    //!	\brief	Creates topology data like faces and meshes for the geometry.
     aiMesh *createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
-		unsigned int uiMeshIndex );	
-	
-	//!	\brief	Creates vertices from model.
-	void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
-		unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount);
+        unsigned int uiMeshIndex );	
+    
+    //!	\brief	Creates vertices from model.
+    void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
+        unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount);
 
-	//!	\brief	Object counter helper method.
-	void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
+    //!	\brief	Object counter helper method.
+    void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
 
-	//!	\brief	Material creation.
-	void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
-	void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1);
+    //!	\brief	Material creation.
+    void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
+    void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1);
 
-	//!	\brief	Appends a child node to a parent node and updates the data structures.
-	void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
+    //!	\brief	Appends a child node to a parent node and updates the data structures.
+    void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
 
 private:
-	//!	Data buffer
-	std::vector<char> m_Buffer;
-	//!	Pointer to root object instance
-	ObjFile::Object *m_pRootObject;
-	//!	Absolute pathname of model in file system
-	std::string m_strAbsPath;
+    //!	Data buffer
+    std::vector<char> m_Buffer;
+    //!	Pointer to root object instance
+    ObjFile::Object *m_pRootObject;
+    //!	Absolute pathname of model in file system
+    std::string m_strAbsPath;
 };
 
 // ------------------------------------------------------------------------------------------------

+ 59 - 59
code/ObjFileParser.h

@@ -63,76 +63,76 @@ class IOSystem;
 class ObjFileParser
 {
 public:
-	static const size_t BUFFERSIZE = 4096;
-	typedef std::vector<char> DataArray;
-	typedef std::vector<char>::iterator DataArrayIt;
-	typedef std::vector<char>::const_iterator ConstDataArrayIt;
+    static const size_t BUFFERSIZE = 4096;
+    typedef std::vector<char> DataArray;
+    typedef std::vector<char>::iterator DataArrayIt;
+    typedef std::vector<char>::const_iterator ConstDataArrayIt;
 
 public:
-	///	\brief	Constructor with data array.
-	ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem* io);
-	///	\brief	Destructor
-	~ObjFileParser();
-	///	\brief	Model getter.
-	ObjFile::Model *GetModel() const;
+    ///	\brief	Constructor with data array.
+    ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem* io);
+    ///	\brief	Destructor
+    ~ObjFileParser();
+    ///	\brief	Model getter.
+    ObjFile::Model *GetModel() const;
 
 private:
-	///	Parse the loaded file
-	void parseFile();
-	///	Method to copy the new delimited word in the current line.
-	void copyNextWord(char *pBuffer, size_t length);
-	///	Method to copy the new line.
-	void copyNextLine(char *pBuffer, size_t length);
+    ///	Parse the loaded file
+    void parseFile();
+    ///	Method to copy the new delimited word in the current line.
+    void copyNextWord(char *pBuffer, size_t length);
+    ///	Method to copy the new line.
+    void copyNextLine(char *pBuffer, size_t length);
     /// Stores the vector 
     void getVector( std::vector<aiVector3D> &point3d_array );
     ///	Stores the following 3d vector.
-	void getVector3( std::vector<aiVector3D> &point3d_array );
-	///	Stores the following 3d vector.
-	void getVector2(std::vector<aiVector2D> &point2d_array);
+    void getVector3( std::vector<aiVector3D> &point3d_array );
+    ///	Stores the following 3d vector.
+    void getVector2(std::vector<aiVector2D> &point2d_array);
     ///	Stores the following face.
-	void getFace(aiPrimitiveType type);
-	/// Reads the material description.
+    void getFace(aiPrimitiveType type);
+    /// Reads the material description.
     void getMaterialDesc();
-	///	Gets a comment.
-	void getComment();
-	/// Gets a a material library.
-	void getMaterialLib();
-	/// Creates a new material.
-	void getNewMaterial();
-	/// Gets the group name from file.
-	void getGroupName();
-	/// Gets the group number from file.
-	void getGroupNumber();
-	/// Gets the group number and resolution from file.
-	void getGroupNumberAndResolution();
-	/// Returns the index of the material. Is -1 if not material was found.
-	int getMaterialIndex( const std::string &strMaterialName );
-	/// Parse object name
-	void getObjectName();
-	/// Creates a new object.
-	void createObject(const std::string &strObjectName);
-	///	Creates a new mesh.
-	void createMesh(); 
-	///	Returns true, if a new mesh instance must be created.
-	bool needsNewMesh( const std::string &rMaterialName );
-	///	Error report in token
-	void reportErrorTokenInFace();
+    ///	Gets a comment.
+    void getComment();
+    /// Gets a a material library.
+    void getMaterialLib();
+    /// Creates a new material.
+    void getNewMaterial();
+    /// Gets the group name from file.
+    void getGroupName();
+    /// Gets the group number from file.
+    void getGroupNumber();
+    /// Gets the group number and resolution from file.
+    void getGroupNumberAndResolution();
+    /// Returns the index of the material. Is -1 if not material was found.
+    int getMaterialIndex( const std::string &strMaterialName );
+    /// Parse object name
+    void getObjectName();
+    /// Creates a new object.
+    void createObject(const std::string &strObjectName);
+    ///	Creates a new mesh.
+    void createMesh(); 
+    ///	Returns true, if a new mesh instance must be created.
+    bool needsNewMesh( const std::string &rMaterialName );
+    ///	Error report in token
+    void reportErrorTokenInFace();
 
 private:
-	///	Default material name
-	static const std::string DEFAULT_MATERIAL;
-	//!	Iterator to current position in buffer
-	DataArrayIt m_DataIt;
-	//!	Iterator to end position of buffer
-	DataArrayIt m_DataItEnd;
-	//!	Pointer to model instance
-	ObjFile::Model *m_pModel;
-	//!	Current line (for debugging)
-	unsigned int m_uiLine;
-	//!	Helper buffer
-	char m_buffer[BUFFERSIZE];
-	///	Pointer to IO system instance.
-	IOSystem *m_pIO;
+    ///	Default material name
+    static const std::string DEFAULT_MATERIAL;
+    //!	Iterator to current position in buffer
+    DataArrayIt m_DataIt;
+    //!	Iterator to end position of buffer
+    DataArrayIt m_DataItEnd;
+    //!	Pointer to model instance
+    ObjFile::Model *m_pModel;
+    //!	Current line (for debugging)
+    unsigned int m_uiLine;
+    //!	Helper buffer
+    char m_buffer[BUFFERSIZE];
+    ///	Pointer to IO system instance.
+    IOSystem *m_pIO;
 };
 
 }	// Namespace Assimp

+ 13 - 11
contrib/openddlparser/code/OpenDDLParser.cpp

@@ -244,15 +244,6 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
             in++;
         }
 
-        // set the properties
-        if( ddl_nullptr != first ) {
-            std::cout << id->m_buffer << std::endl;
-            DDLNode *current( top() );
-            if( current ) {
-                current->setProperties( first );
-            }
-        }
-
         // store the node
         DDLNode *node( createDDLNode( id, this ) );
         if( nullptr != node ) {
@@ -261,6 +252,11 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
             std::cerr << "nullptr returned by creating DDLNode." << std::endl;
         }
 
+        // set the properties
+        if( ddl_nullptr != first ) {
+            node->setProperties( first );
+        }
+
         Name *name( ddl_nullptr );
         in = OpenDDLParser::parseName( in, end, &name );
         if( ddl_nullptr != name ) {
@@ -277,6 +273,7 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
         return in;
     }
 
+    bool error( false );
     in = getNextToken( in, end );
     if( *in == '{' ) {
         in++;
@@ -307,6 +304,7 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
                     }
                 } else {
                     std::cerr << "0 for array is invalid." << std::endl;
+                    error = true;
                 }
             }
 
@@ -324,12 +322,16 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
     } else {
         in++;
         logInvalidTokenError( in, "{", m_logCallback );
+        error = true;
         return in;
 
     }
     in = getNextToken( in, end );
-
-    in++;
+    
+    // pop node from stack after successful parsing
+    if( !error ) {
+        popNode();
+    }
 
     return in;
 }