From d1c7d905e83e3e0ff929cb53459921803c922980 Mon Sep 17 00:00:00 2001 From: rmitton Date: Sun, 19 Mar 2017 13:46:23 -0700 Subject: [PATCH] Fixed infinite loop on non-manifold geometry Geometry that had strange non-manifold faces could cause the normal calculation to enter an infinite loop. Instead we now correctly detect which faces to scan over. --- code/SIBImporter.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/code/SIBImporter.cpp b/code/SIBImporter.cpp index 2da683bed..0a4df61a3 100644 --- a/code/SIBImporter.cpp +++ b/code/SIBImporter.cpp @@ -391,7 +391,7 @@ static void ConnectFaces(SIBMesh* mesh) // with non-2-manifold surfaces, but then so does Silo to begin with. if (edge.faceA == 0xffffffff) edge.faceA = static_cast(faceIdx); - else + else if (edge.faceB == 0xffffffff) edge.faceB = static_cast(faceIdx); prev = next; @@ -435,12 +435,17 @@ static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_ { SIBEdge& edge = GetEdge(mesh, posA, posB); - // Move to whichever side we didn't just come from. - if (!edge.creased) { - if (edge.faceA != prevFaceIdx && edge.faceA != faceIdx && edge.faceA != 0xffffffff) - nextFaceIdx = edge.faceA; - else if (edge.faceB != prevFaceIdx && edge.faceB != faceIdx && edge.faceB != 0xffffffff) - nextFaceIdx = edge.faceB; + // Non-manifold meshes can produce faces which share + // positions but have no edge entry, so check it. + if (edge.faceA == faceIdx || edge.faceB == faceIdx) + { + // Move to whichever side we didn't just come from. + if (!edge.creased) { + if (edge.faceA != prevFaceIdx && edge.faceA != faceIdx && edge.faceA != 0xffffffff) + nextFaceIdx = edge.faceA; + else if (edge.faceB != prevFaceIdx && edge.faceB != faceIdx && edge.faceB != 0xffffffff) + nextFaceIdx = edge.faceB; + } } }