Merge pull request #2350 from appsforlife/issue-2349

Obj: we can still import partially incorrect files
pull/2353/head^2
Kim Kulling 2019-02-27 18:50:42 +01:00 committed by GitHub
commit a23aa70575
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 9 deletions

View File

@ -447,6 +447,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
} }
// Copy vertices, normals and textures into aiMesh instance // Copy vertices, normals and textures into aiMesh instance
bool normalsok = true, uvok = true;
unsigned int newIndex = 0, outIndex = 0; unsigned int newIndex = 0, outIndex = 0;
for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) { for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) {
// Get source face // Get source face
@ -466,12 +467,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ]; pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
// Copy all normals // 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 ); const unsigned int normal = pSourceFace->m_normals.at( vertexIndex );
if ( normal >= pModel->m_Normals.size() ) { if ( normal >= pModel->m_Normals.size() )
throw DeadlyImportError( "OBJ: vertex normal index out of range" ); {
normalsok = false;
}
else
{
pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
} }
pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
} }
// Copy all vertex colors // Copy all vertex colors
@ -482,15 +487,19 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
} }
// Copy all texture coordinates // 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 ); const unsigned int tex = pSourceFace->m_texturCoords.at( vertexIndex );
if ( tex >= pModel->m_TextureCoord.size() ) if ( tex >= pModel->m_TextureCoord.size() )
throw DeadlyImportError("OBJ: texture coordinate index out of range"); {
uvok = false;
const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ]; }
pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord3d.x, coord3d.y, coord3d.z ); else
{
const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ];
pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord3d.x, coord3d.y, coord3d.z );
}
} }
// Get destination face // Get destination face
@ -534,6 +543,18 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
++newIndex; ++newIndex;
} }
} }
if (!normalsok)
{
delete [] pMesh->mNormals;
pMesh->mNormals = nullptr;
}
if (!uvok)
{
delete [] pMesh->mTextureCoords[0];
pMesh->mTextureCoords[0] = nullptr;
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -377,6 +377,20 @@ TEST_F(utObjImportExport, 0based_array_Test) {
EXPECT_EQ(nullptr, scene); 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 ) { TEST_F( utObjImportExport, mtllib_after_g ) {
::Assimp::Importer importer; ::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/cube_mtllib_after_g.obj", aiProcess_ValidateDataStructure ); const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OBJ/cube_mtllib_after_g.obj", aiProcess_ValidateDataStructure );