From b895fdcbe1155840412f8e6261e9740875801983 Mon Sep 17 00:00:00 2001 From: artem-ogre Date: Thu, 12 Oct 2023 15:22:44 +0200 Subject: [PATCH] #148 Fix bug: vertex with no adjacent triangle when resolving intersections Add regression test --- CDT/extras/VerifyTopology.h | 11 ++++ CDT/include/Triangulation.h | 3 +- CDT/include/Triangulation.hpp | 16 +++--- CDT/tests/cdt.test.cpp | 7 ++- ...e-148-crossing-edges__auto_resolve_all.txt | 38 ++++++++++++++ ...ing-edges__conforming_auto_resolve_all.txt | 50 +++++++++++++++++++ CDT/tests/inputs/issue-148-crossing-edges.txt | 9 ++++ 7 files changed, 123 insertions(+), 11 deletions(-) create mode 100644 CDT/tests/expected/issue-148-crossing-edges__auto_resolve_all.txt create mode 100644 CDT/tests/expected/issue-148-crossing-edges__conforming_auto_resolve_all.txt create mode 100644 CDT/tests/inputs/issue-148-crossing-edges.txt diff --git a/CDT/extras/VerifyTopology.h b/CDT/extras/VerifyTopology.h index 5a8f7fb2..3bcac637 100644 --- a/CDT/extras/VerifyTopology.h +++ b/CDT/extras/VerifyTopology.h @@ -74,6 +74,17 @@ inline bool verifyTopology(const CDT::Triangulation& cdt) return true; } +/// Check that each vertex has a neighbor triangle +template +inline bool eachVertexHasNeighborTriangle( + const CDT::Triangulation& cdt) +{ + for(const auto& vt : cdt.VertTrisInternal()) + if(vt == noNeighbor) + return false; + return true; +} + } // namespace CDT #endif diff --git a/CDT/include/Triangulation.h b/CDT/include/Triangulation.h index 4177d033..8b4c72f7 100644 --- a/CDT/include/Triangulation.h +++ b/CDT/include/Triangulation.h @@ -355,6 +355,8 @@ class CDT_EXPORT Triangulation /// Access internal vertex adjacent triangles TriIndVec& VertTrisInternal(); + /// Access internal vertex adjacent triangles + const TriIndVec& VertTrisInternal() const; /// @} private: @@ -586,7 +588,6 @@ class CDT_EXPORT Triangulation bool hasEdge(VertInd a, VertInd b) const; void setAdjacentTriangle(const VertInd v, const TriInd t); void pivotVertexTriangleCW(VertInd v); - void removeAdjacentTriangle(VertInd v); /// Add vertex to nearest-point locator if locator is initialized void tryAddVertexToLocator(const VertInd v); /// Perform lazy initialization of nearest-point locator after the Kd-tree diff --git a/CDT/include/Triangulation.hpp b/CDT/include/Triangulation.hpp index d65ca199..e6efdb57 100644 --- a/CDT/include/Triangulation.hpp +++ b/CDT/include/Triangulation.hpp @@ -208,12 +208,19 @@ void Triangulation::removeTriangles( } } } + template TriIndVec& Triangulation::VertTrisInternal() { return m_vertTris; } +template +const TriIndVec& Triangulation::VertTrisInternal() const +{ + return m_vertTris; +} + template void Triangulation::finalizeTriangulation( const TriIndUSet& removedTriangles) @@ -605,7 +612,6 @@ void Triangulation::insertEdgeIteration( outerTrisL.push_back(edgeNeighbor(tOpo, polyL.back(), iVopo)); } polyL.push_back(iVopo); - removeAdjacentTriangle(iVopo); iV = iVL; iVL = iVopo; } @@ -627,7 +633,6 @@ void Triangulation::insertEdgeIteration( outerTrisR.push_back(edgeNeighbor(tOpo, polyR.back(), iVopo)); } polyR.push_back(iVopo); - removeAdjacentTriangle(iVopo); iV = iVR; iVR = iVopo; } @@ -2005,13 +2010,6 @@ void Triangulation::pivotVertexTriangleCW(const VertInd v) triangles[m_vertTris[v]].vertices[2] == v); } -template -void Triangulation::removeAdjacentTriangle( - const VertInd v) -{ - m_vertTris[v] = noNeighbor; -} - template void Triangulation::tryAddVertexToLocator(const VertInd v) { diff --git a/CDT/tests/cdt.test.cpp b/CDT/tests/cdt.test.cpp index 94544c73..65b457b1 100644 --- a/CDT/tests/cdt.test.cpp +++ b/CDT/tests/cdt.test.cpp @@ -556,6 +556,7 @@ TEMPLATE_LIST_TEST_CASE( cdt.insertVertices(vv); cdt.insertEdges(ee); REQUIRE(CDT::verifyTopology(cdt)); + REQUIRE(CDT::eachVertexHasNeighborTriangle(cdt)); // make true to update expected files (development purposes only) const auto outputFileBase = "expected/" + @@ -671,7 +672,10 @@ TEMPLATE_LIST_TEST_CASE( TEMPLATE_LIST_TEST_CASE("Ground truth tests: crossing edges", "", CoordTypes) { - const auto inputFile = std::string("crossing-edges.txt"); + const auto inputFile = GENERATE( + as{}, + "crossing-edges.txt", + "issue-148-crossing-edges.txt"); const auto order = VertexInsertionOrder::Auto; const auto intersectingEdgesStrategy = IntersectingConstraintEdges::Resolve; @@ -689,6 +693,7 @@ TEMPLATE_LIST_TEST_CASE("Ground truth tests: crossing edges", "", CoordTypes) cdt.insertVertices(vv); triangulationType == "" ? cdt.insertEdges(ee) : cdt.conformToEdges(ee); REQUIRE(CDT::verifyTopology(cdt)); + REQUIRE(CDT::eachVertexHasNeighborTriangle(cdt)); // make true to update expected files (development purposes only) const auto outputFileBase = "expected/" + inputFile.substr(0, inputFile.size() - 4) + diff --git a/CDT/tests/expected/issue-148-crossing-edges__auto_resolve_all.txt b/CDT/tests/expected/issue-148-crossing-edges__auto_resolve_all.txt new file mode 100644 index 00000000..2defa1f3 --- /dev/null +++ b/CDT/tests/expected/issue-148-crossing-edges__auto_resolve_all.txt @@ -0,0 +1,38 @@ +15 +0 1 4 4294967295 5 2 +0 3 6 2 9 3 +0 4 3 0 7 1 +0 6 2 1 6 4294967295 +1 2 5 4294967295 6 5 +1 5 4 4 10 0 +2 6 5 3 13 4 +3 4 7 2 12 8 +3 7 9 7 12 9 +3 9 6 8 13 1 +4 5 8 5 14 11 +4 8 9 10 14 12 +4 9 7 11 8 7 +5 6 9 6 9 14 +5 9 8 13 11 10 + +4 +3 9 +4 9 +5 9 +6 9 + +0 + +4 +3 9 + 1 + 3 5 +4 9 + 1 + 4 6 +5 9 + 1 + 3 5 +6 9 + 1 + 4 6 diff --git a/CDT/tests/expected/issue-148-crossing-edges__conforming_auto_resolve_all.txt b/CDT/tests/expected/issue-148-crossing-edges__conforming_auto_resolve_all.txt new file mode 100644 index 00000000..d50040a4 --- /dev/null +++ b/CDT/tests/expected/issue-148-crossing-edges__conforming_auto_resolve_all.txt @@ -0,0 +1,50 @@ +19 +0 1 4 4294967295 5 2 +0 3 6 2 9 3 +0 4 3 0 7 1 +0 6 2 1 6 4294967295 +1 2 5 4294967295 6 5 +1 5 4 4 10 0 +2 6 5 3 13 4 +3 4 7 2 12 8 +3 7 10 7 16 9 +3 10 6 8 15 1 +4 5 8 5 14 11 +4 8 11 10 17 12 +4 11 7 11 16 7 +5 6 9 6 15 14 +5 9 8 13 17 10 +6 10 9 9 18 13 +7 11 10 12 18 8 +8 9 11 14 18 11 +9 10 11 15 16 17 + +6 +3 10 +4 11 +5 9 +6 10 +9 10 +10 11 + +0 + +6 +3 10 + 1 + 3 5 +4 11 + 1 + 4 6 +5 9 + 1 + 3 5 +6 10 + 1 + 4 6 +9 10 + 1 + 3 5 +10 11 + 1 + 4 6 diff --git a/CDT/tests/inputs/issue-148-crossing-edges.txt b/CDT/tests/inputs/issue-148-crossing-edges.txt new file mode 100644 index 00000000..2b5be150 --- /dev/null +++ b/CDT/tests/inputs/issue-148-crossing-edges.txt @@ -0,0 +1,9 @@ +6 2 +0 0.2 +1 0 +1 1 +0 1 +0.5 0.2 +0.8 0.5 +0 2 +1 3 \ No newline at end of file