diff --git a/CDT/include/Triangulation.h b/CDT/include/Triangulation.h index 173038c..e0f446e 100644 --- a/CDT/include/Triangulation.h +++ b/CDT/include/Triangulation.h @@ -126,13 +126,8 @@ class CDT_EXPORT Triangulation { public: typedef std::vector > V2dVec; ///< Vertices vector - typedef std::vector boolVec; ///< Steiner Vertices flag V2dVec vertices; ///< triangulation's vertices - boolVec isSteinerVertex; ///< triangulation's vertices Steiner point flag - IndexSizeType - maxSteinerPoints; ///< triangulation's maximum number of Steiner - IndexSizeType numOfSteinerPoints; ///< triangulation's maximum number of - ///< Steiner points to be added + std::vector isSteinerVertex; ///< triangulation's vertices Steiner point flag TriangleVec triangles; ///< triangulation's triangles EdgeUSet fixedEdges; ///< triangulation's constraints (fixed edges) @@ -302,12 +297,13 @@ class CDT_EXPORT Triangulation * @note bad triangles don't fulfill constraints defined by the user * @param refinement_constrain refinement strategy that is used to identify * bad triangles - * @param threshold threshold value for refinement + * @param refinementThreshold threshold value for refinement */ void refineTriangles( - RefinementCriterion::Enum refinementConstrain = + VertInd maxVerticesToInsert, + RefinementCriterion::Enum refinementCriterion = RefinementCriterion::SmallestAngle, - T threshold = 20 / 180.0 * M_PI); + T refinementThreshold = 20 / 180.0 * M_PI); /** * Erase triangles adjacent to super triangle * @@ -527,14 +523,14 @@ class CDT_EXPORT Triangulation /// Returns queue of encroached edges EdgeQue detectEncroachedEdges(const V2d& v); /// Recursively split encroached edges - /// returns vector of badly shaped triangles and number of splits - std::pair resolveEncroachedEdges( + /// @return vector of badly shaped triangles + TriIndVec resolveEncroachedEdges( EdgeQue encroachedEdges, - const V2d& v = {}, - bool validV = false, - bool fillBadTriangles = false, - RefinementCriterion::Enum refinementConstrain = {}, - T badTriangleThreshold = {}); + VertInd& newVertBudget, + const V2d* const circumcenterOrNull = NULL, + RefinementCriterion::Enum refinementCriterion = + RefinementCriterion::SmallestAngle, + T badTriangleThreshold = T(0)); VertInd splitEncroachedEdge(Edge e, TriInd iT, TriInd iTopo); void changeNeighbor(TriInd iT, TriInd oldNeighbor, TriInd newNeighbor); void changeNeighbor( diff --git a/CDT/include/Triangulation.hpp b/CDT/include/Triangulation.hpp index 2f87acb..0e98e75 100644 --- a/CDT/include/Triangulation.hpp +++ b/CDT/include/Triangulation.hpp @@ -1253,7 +1253,7 @@ TriInd Triangulation::edgeTriangle(const Edge edge) const template bool Triangulation::isRefinementNeeded( const Triangle& tri, - RefinementCriterion::Enum refinementCriterion, + const RefinementCriterion::Enum refinementCriterion, const T refinementThreshold) const { const V2d& a = vertices[tri.vertices[0]]; @@ -1321,19 +1321,17 @@ Triangulation::detectEncroachedEdges(const V2d& v) } template -std::pair -Triangulation::resolveEncroachedEdges( +TriIndVec Triangulation::resolveEncroachedEdges( EdgeQue encroachedEdges, - const V2d& v, - const bool validV, - const bool fillBadTriangles, - const RefinementCriterion::Enum refinementConstrain, + VertInd& newVertBudget, + const V2d* const circumcenterOrNull, + const RefinementCriterion::Enum refinementCriterion, const T badTriangleThreshold) { IndexSizeType numOfSplits = 0; std::vector badTriangles; - while(!encroachedEdges.empty() && numOfSteinerPoints < maxSteinerPoints) + while(!encroachedEdges.empty() && newVertBudget > 0) { Edge edge = encroachedEdges.front(); encroachedEdges.pop(); @@ -1345,15 +1343,15 @@ Triangulation::resolveEncroachedEdges( const Triangle& t = triangles[iT]; VertInd i = splitEncroachedEdge( edge, iT, edgeNeighbor(triangles[iT], edge.v1(), edge.v2())); - ++numOfSplits; + --newVertBudget; TriInd start = m_vertTris[i]; TriInd currTri = start; do { const Triangle& t = triangles[currTri]; - if(fillBadTriangles && - isRefinementNeeded(t, refinementConstrain, badTriangleThreshold)) + if(circumcenterOrNull && + isRefinementNeeded(t, refinementCriterion, badTriangleThreshold)) { badTriangles.push_back(currTri); } @@ -1372,7 +1370,9 @@ Triangulation::resolveEncroachedEdges( const V2d& edgeEnd = vertices[edge.v2()]; if(isEncroachingOnEdge(vertices[v1], edgeStart, edgeEnd) || isEncroachingOnEdge(vertices[v2], edgeStart, edgeEnd) || - (validV && isEncroachingOnEdge(v, edgeStart, edgeEnd))) + (circumcenterOrNull && + isEncroachingOnEdge( + *circumcenterOrNull, edgeStart, edgeEnd))) { encroachedEdges.push(edge); } @@ -1380,7 +1380,7 @@ Triangulation::resolveEncroachedEdges( currTri = t.next(i).first; } while(currTri != start); } - return std::make_pair(badTriangles, numOfSplits); + return badTriangles; } template @@ -1446,7 +1446,6 @@ VertInd Triangulation::splitEncroachedEdge( std::stack triStack = insertVertexOnEdge(iMid, iT, iTopo); tryAddVertexToLocator(iMid); ensureDelaunayByEdgeFlips(mid, iMid, triStack); - ++numOfSteinerPoints; return iMid; } @@ -2251,8 +2250,9 @@ void Triangulation::tryInitNearestPointLocator() template void Triangulation::refineTriangles( - RefinementCriterion::Enum refinementConstrain, - T threshold) + const VertInd maxVerticesToInsert, + const RefinementCriterion::Enum refinementCriterion, + const T refinementThreshold) { if(isFinalized()) { @@ -2260,7 +2260,9 @@ void Triangulation::refineTriangles( "method. Refinement is not possible"); } tryInitNearestPointLocator(); - resolveEncroachedEdges(detectEncroachedEdges()); + + VertInd newVertBudget = maxVerticesToInsert; + resolveEncroachedEdges(detectEncroachedEdges(), newVertBudget); std::queue badTriangles; for(TriInd iT(0), n = triangles.size(); iT < n; ++iT) @@ -2269,7 +2271,7 @@ void Triangulation::refineTriangles( if(t.vertices[0] < 3 || t.vertices[1] < 3 || t.vertices[2] < 3) continue; - if(isRefinementNeeded(t, refinementConstrain, threshold)) + if(isRefinementNeeded(t, refinementCriterion, refinementThreshold)) { const V2d vert = circumcenter( vertices[t.vertices[0]], @@ -2289,8 +2291,8 @@ void Triangulation::refineTriangles( TriInd iT = badTriangles.front(); const Triangle& t = triangles[iT]; badTriangles.pop(); - if(!isRefinementNeeded(t, refinementConstrain, threshold) || - numOfSteinerPoints >= maxSteinerPoints) + if(!isRefinementNeeded(t, refinementCriterion, refinementThreshold) || + newVertBudget == 0) { continue; } @@ -2304,20 +2306,18 @@ void Triangulation::refineTriangles( continue; } TriIndVec badTris = resolveEncroachedEdges( - detectEncroachedEdges(vert), - vert, - true, - true, - refinementConstrain, - threshold) - .first; + detectEncroachedEdges(vert), + newVertBudget, + &vert, + refinementCriterion, + refinementThreshold); for(IndexSizeType i(0); i < TriInd(badTris.size()); ++i) { badTriangles.push(badTris[i]); } - if(badTris.empty() && numOfSteinerPoints < maxSteinerPoints) + if(badTris.empty() && newVertBudget > 0) { const VertInd iVert = static_cast(vertices.size()); addNewVertex(vert, noNeighbor, true); @@ -2327,7 +2327,8 @@ void Triangulation::refineTriangles( do { const Triangle& t = triangles[currTri]; - if(isRefinementNeeded(t, refinementConstrain, threshold)) + if(isRefinementNeeded( + t, refinementCriterion, refinementThreshold)) { badTriangles.push(currTri); } diff --git a/visualizer/main.cpp b/visualizer/main.cpp index 2bcfb0f..317c21a 100644 --- a/visualizer/main.cpp +++ b/visualizer/main.cpp @@ -192,7 +192,6 @@ public slots: CDT::VertexInsertionOrder::Auto, CDT::IntersectingConstraintEdges::Resolve, 1e-3); - m_cdt.maxSteinerPoints = 1000U; if(!m_points.empty()) { std::vector pts = @@ -224,7 +223,9 @@ public slots: if(m_isRemoveOuterAndHoles) { m_cdt.refineTriangles( - CDT::RefinementCriterion::SmallestAngle, 20 / 180.0 * M_PI); + 1000, + CDT::RefinementCriterion::SmallestAngle, + 20 / 180.0 * M_PI); m_cdt.eraseOuterTrianglesAndHoles(); } else if(m_isRemoveOuter) @@ -232,7 +233,9 @@ public slots: else if(m_isHideSuperTri) { m_cdt.refineTriangles( - CDT::RefinementCriterion::SmallestAngle, 20 / 180.0 * M_PI); + 1000, + CDT::RefinementCriterion::SmallestAngle, + 20 / 180.0 * M_PI); m_cdt.eraseSuperTriangle(); } const CDT::unordered_map tmp =