From 1bff38e5e7daa3f300ad65acc2b2042f231c2d08 Mon Sep 17 00:00:00 2001 From: artem-ogre Date: Sat, 30 Sep 2023 01:14:42 +0200 Subject: [PATCH] Refactoring and fixes after rebasing on master --- CDT/include/CDTUtils.h | 3 +- CDT/include/CDTUtils.hpp | 5 -- CDT/include/Triangulation.h | 2 +- CDT/include/Triangulation.hpp | 142 +++++++++++++++++----------------- 4 files changed, 75 insertions(+), 77 deletions(-) diff --git a/CDT/include/CDTUtils.h b/CDT/include/CDTUtils.h index 0d11224..d3457a1 100644 --- a/CDT/include/CDTUtils.h +++ b/CDT/include/CDTUtils.h @@ -244,7 +244,8 @@ inline Edge edge_make(VertInd iV1, VertInd iV2) } typedef std::vector EdgeVec; ///< Vector of edges -typedef std::queue EdgeQueue; ///< Queue of edges +typedef std::queue EdgeQueue; ///< Queue of edges +typedef std::queue TriIndQueue; ///< Queue of triangles typedef unordered_set EdgeUSet; ///< Hash table of edges typedef unordered_set TriIndUSet; ///< Hash table of triangles typedef unordered_map TriIndUMap; ///< Triangle hash map diff --git a/CDT/include/CDTUtils.hpp b/CDT/include/CDTUtils.hpp index d6daa96..739c99f 100644 --- a/CDT/include/CDTUtils.hpp +++ b/CDT/include/CDTUtils.hpp @@ -368,9 +368,4 @@ T smallestAngle(const V2d& a, const V2d& b, const V2d& c) return std::asin(angleSine); } -bool touchesSuperTriangle(const Triangle& t) -{ - return t.vertices[0] < 3 || t.vertices[1] < 3 || t.vertices[2] < 3; -} - } // namespace CDT diff --git a/CDT/include/Triangulation.h b/CDT/include/Triangulation.h index f95b362..dddd38f 100644 --- a/CDT/include/Triangulation.h +++ b/CDT/include/Triangulation.h @@ -516,7 +516,7 @@ class CDT_EXPORT Triangulation bool isEdgeEncroached(const Edge& edge) const; bool isEdgeEncroachedBy(const Edge& edge, const V2d& v) const; /// Find all fixed edges encroached by its opposed vertices - EdgeQueue allEncroachedEdges() const; + EdgeQueue findEncroachedFixedEdges() const; /// Find all fixed edges encroached by a given vertex EdgeQueue edgesEncroachedBy(const V2d& v) const; /// Recursively split encroached edges diff --git a/CDT/include/Triangulation.hpp b/CDT/include/Triangulation.hpp index 72099e6..90e16da 100644 --- a/CDT/include/Triangulation.hpp +++ b/CDT/include/Triangulation.hpp @@ -1273,7 +1273,7 @@ bool Triangulation::isEdgeEncroachedBy( } template -EdgeQueue Triangulation::allEncroachedEdges() const +EdgeQueue Triangulation::findEncroachedFixedEdges() const { // Search in all fixed edges to find encroached edges // Returns queue of encroached edges @@ -1317,7 +1317,6 @@ TriIndVec Triangulation::resolveEncroachedEdges( const RefinementCriterion::Enum refinementCriterion, const T badTriangleThreshold) { - IndexSizeType numOfSplits = 0; std::vector badTriangles; while(!encroachedEdges.empty() && remainingVertexBudget > 0) @@ -1366,10 +1365,6 @@ VertInd Triangulation::splitEncroachedEdge( const Edge edge, const VertInd steinerVerticesOffset) { - TriInd iT, iTopo; - std::tie(iT, iTopo) = edgeTriangles(edge.v1(), edge.v2()); - assert(iT != invalidIndex && iTopo != invalidIndex); - const VertInd iMid = static_cast(vertices.size()); const V2d& start = vertices[edge.v1()]; const V2d& end = vertices[edge.v2()]; T split = T(0.5); @@ -1377,7 +1372,7 @@ VertInd Triangulation::splitEncroachedEdge( if(edge.v1() >= steinerVerticesOffset || edge.v2() >= steinerVerticesOffset) { // In Ruppert's paper, he used D(0.01) factor to divide edge length, but - // that introduces FP rounding erros, so it's avoided. + // that introduces FP rounding errors, so it's avoided. const T len = distance(start, end); const T d = len / T(2); // Find the splitting distance @@ -1395,38 +1390,19 @@ VertInd Triangulation::splitEncroachedEdge( if(edge.v1() >= steinerVerticesOffset) split = T(1) - split; } + const V2d mid = V2d::make( detail::lerp(start.x, end.x, split), detail::lerp(start.y, end.y, split)); + TriInd iT, iTopo; + std::tie(iT, iTopo) = edgeTriangles(edge.v1(), edge.v2()); + assert(iT != invalidIndex && iTopo != invalidIndex); - // split constraint edge that already exists in triangulation + const VertInd iMid = addSplitEdgeVertex(mid, iT, iTopo); if(fixedEdges.find(edge) != fixedEdges.end()) { - const Edge half1(edge.v1(), iMid); - const Edge half2(iMid, edge.v2()); - const BoundaryOverlapCount overlaps = overlapCount[edge]; - // remove the edge that will be split - fixedEdges.erase(edge); - overlapCount.erase(edge); - // add split edge's halves - fixEdge(half1, overlaps); - fixEdge(half2, overlaps); - // maintain piece-to-original mapping - EdgeVec newOriginals(1, edge); - const unordered_map::const_iterator originalsIt = - pieceToOriginals.find(edge); - if(originalsIt != pieceToOriginals.end()) - { // edge being split was split before: pass-through originals - newOriginals = originalsIt->second; - pieceToOriginals.erase(originalsIt); - } - detail::insert_unique(pieceToOriginals[half1], newOriginals); - detail::insert_unique(pieceToOriginals[half2], newOriginals); + splitFixedEdge(edge, iMid); } - addNewVertex(mid, noNeighbor); - std::stack triStack = insertVertexOnEdge(iMid, iT, iTopo); - tryAddVertexToLocator(iMid); - ensureDelaunayByEdgeFlips(mid, iMid, triStack); return iMid; } @@ -2244,10 +2220,34 @@ void Triangulation::refineTriangles( VertInd remainingVertexBudget = maxVerticesToInsert; const VertInd steinerVerticesOffset = vertices.size(); - resolveEncroachedEdges( - allEncroachedEdges(), remainingVertexBudget, steinerVerticesOffset); - std::queue badTriangles; + // split all the encroached constrained (fixed) edges + EdgeQueue encroachedEdges = findEncroachedFixedEdges(); + for(; !encroachedEdges.empty() && remainingVertexBudget > 0; + --remainingVertexBudget) + { + const Edge edge = encroachedEdges.front(); + encroachedEdges.pop(); + const VertInd iSplitVert = + splitEncroachedEdge(edge, steinerVerticesOffset); + // if resulting halves are encroached, add them to the queue + const Edge half1(edge.v1(), iSplitVert); + if(isEdgeEncroached(half1)) + { + encroachedEdges.push(half1); + } + const Edge half2(iSplitVert, edge.v2()); + if(isEdgeEncroached(half2)) + { + encroachedEdges.push(half2); + } + } + + if(!remainingVertexBudget) + return; + + // refine triangulation by inserting bad-quality triangles' circumcenters + TriIndQueue badTriangles; for(TriInd iT(0), n = triangles.size(); iT < n; ++iT) { const Triangle& t = triangles[iT]; @@ -2258,61 +2258,63 @@ void Triangulation::refineTriangles( } } - while(!badTriangles.empty()) + while(!badTriangles.empty() && remainingVertexBudget > 0) { - TriInd iT = badTriangles.front(); - const Triangle& t = triangles[iT]; + const TriInd iT = badTriangles.front(); badTriangles.pop(); - if(!isRefinementNeeded(t, refinementCriterion, refinementThreshold) || - remainingVertexBudget == 0) + const Triangle& badT = triangles[iT]; + if(!isRefinementNeeded(badT, refinementCriterion, refinementThreshold)) { continue; } - const V2d vert = circumcenter( - vertices[t.vertices[0]], - vertices[t.vertices[1]], - vertices[t.vertices[2]]); - if(locatePointTriangle(vert, vertices[0], vertices[1], vertices[2]) == + const V2d triCircumenter = circumcenter( + vertices[badT.vertices[0]], + vertices[badT.vertices[1]], + vertices[badT.vertices[2]]); + if(locatePointTriangle( + triCircumenter, vertices[0], vertices[1], vertices[2]) == PtTriLocation::Outside) { continue; } const TriIndVec badTris = resolveEncroachedEdges( - edgesEncroachedBy(vert), + edgesEncroachedBy(triCircumenter), remainingVertexBudget, steinerVerticesOffset, - &vert, + &triCircumenter, refinementCriterion, refinementThreshold); - for(IndexSizeType i(0); i < TriInd(badTris.size()); ++i) + if(!remainingVertexBudget) + break; + if(!badTris.empty()) { - badTriangles.push(badTris[i]); + typedef TriIndVec::const_iterator It; + for(It it = badTris.begin(); it != badTris.end(); ++it) + { + badTriangles.push(*it); + } + badTriangles.push(iT); + continue; } - if(badTris.empty() && remainingVertexBudget > 0) + --remainingVertexBudget; + const VertInd iVert = static_cast(vertices.size()); + addNewVertex(triCircumenter, noNeighbor); + insertVertex(iVert); + + TriInd start = m_vertTris[iVert]; + TriInd currTri = start; + do { - --remainingVertexBudget; - const VertInd iVert = static_cast(vertices.size()); - addNewVertex(vert, noNeighbor); - insertVertex(iVert); - TriInd start = m_vertTris[iVert]; - TriInd currTri = start; - do + const Triangle& t = triangles[currTri]; + if(isRefinementNeeded(t, refinementCriterion, refinementThreshold)) { - const Triangle& t = triangles[currTri]; - if(isRefinementNeeded( - t, refinementCriterion, refinementThreshold)) - { - badTriangles.push(currTri); - } - currTri = t.next(iVert).first; - } while(currTri != start); - } - else - { - badTriangles.push(iT); - } + badTriangles.push(currTri); + } + currTri = t.next(iVert).first; + } while(currTri != start); } } + } // namespace CDT