diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 782b62a73..814180c81 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -447,6 +447,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, } // Copy vertices, normals and textures into aiMesh instance + bool normalsok = true, uvok = true; unsigned int newIndex = 0, outIndex = 0; for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) { // Get source face @@ -466,12 +467,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ]; // Copy all normals - if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) { + if ( normalsok && !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) { const unsigned int normal = pSourceFace->m_normals.at( vertexIndex ); - if ( normal >= pModel->m_Normals.size() ) { - throw DeadlyImportError( "OBJ: vertex normal index out of range" ); + if ( normal >= pModel->m_Normals.size() ) + { + normalsok = false; + } + else + { + pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ]; } - pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ]; } // Copy all vertex colors @@ -482,15 +487,19 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, } // Copy all texture coordinates - if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_texturCoords.size()) + if ( uvok && !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_texturCoords.size()) { const unsigned int tex = pSourceFace->m_texturCoords.at( vertexIndex ); 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 ); + { + uvok = false; + } + else + { + const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ]; + pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord3d.x, coord3d.y, coord3d.z ); + } } // Get destination face @@ -534,6 +543,18 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, ++newIndex; } } + + if (!normalsok) + { + delete [] pMesh->mNormals; + pMesh->mNormals = nullptr; + } + + if (!uvok) + { + delete [] pMesh->mTextureCoords[0]; + pMesh->mTextureCoords[0] = nullptr; + } } // ------------------------------------------------------------------------------------------------ diff --git a/test/unit/utObjImportExport.cpp b/test/unit/utObjImportExport.cpp index 0f715af14..2d1933094 100644 --- a/test/unit/utObjImportExport.cpp +++ b/test/unit/utObjImportExport.cpp @@ -377,6 +377,20 @@ TEST_F(utObjImportExport, 0based_array_Test) { EXPECT_EQ(nullptr, scene); } +TEST_F(utObjImportExport, invalid_normals_uvs) { + static const char *ObjModel = + "v -0.500000 0.000000 0.400000\n" + "v -0.500000 0.000000 -0.800000\n" + "v -0.500000 1.000000 -0.800000\n" + "vt 0 0\n" + "vn 0 1 0\n" + "f 1/1/1 1/1/1 2/2/2\nB"; + + Assimp::Importer myImporter; + const aiScene *scene = myImporter.ReadFileFromMemory(ObjModel, strlen(ObjModel), 0); + EXPECT_NE(nullptr, scene); +} + TEST_F( utObjImportExport, mtllib_after_g ) { ::Assimp::Importer importer; const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/cube_mtllib_after_g.obj", aiProcess_ValidateDataStructure );