فهرست منبع

Merge pull request #2350 from appsforlife/issue-2349

Obj: we can still import partially incorrect files
Kim Kulling 6 سال پیش
والد
کامیت
a23aa70575
2فایلهای تغییر یافته به همراه44 افزوده شده و 9 حذف شده
  1. 30 9
      code/ObjFileImporter.cpp
  2. 14 0
      test/unit/utObjImportExport.cpp

+ 30 - 9
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;
+    }
 }
 
 // ------------------------------------------------------------------------------------------------

+ 14 - 0
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 );