10#ifndef CDT_vW1vZ0lO8rS4gY4uI4fB
11#define CDT_vW1vZ0lO8rS4gY4uI4fB
113 const std::string&
file()
const
118 const std::string&
func()
const
135#define CDT_SOURCE_LOCATION \
136 SourceLocation(std::string(__FILE__), std::string(__func__), __LINE__)
142class CDT_EXPORT
Error :
public std::runtime_error
147 : std::runtime_error(
148 description +
"\nin '" + srcLoc.func() +
"' at " + srcLoc.file() +
149 ":" +
CDT::to_string(srcLoc.line()))
159 return m_description;
168 std::string m_description;
182 "Triangulation was finalized with 'erase...' method. Further "
183 "modification is not possible.",
200 "Duplicate vertex detected: #" +
CDT::to_string(
v1) +
201 " is a duplicate of #" +
CDT::to_string(
v2),
234 "Intersecting constraint edges detected: (" +
235 CDT::to_string(
e1.v1()) +
", " +
CDT::to_string(
e1.v2()) +
236 ") intersects (" +
CDT::to_string(
e2.v1()) +
", " +
237 CDT::to_string(
e2.v2()) +
")",
271 "Intersection of constraint edges (" +
CDT::to_string(
e1.v1()) +
272 ", " +
CDT::to_string(
e1.v2()) +
") and (" +
273 CDT::to_string(
e2.v1()) +
", " +
CDT::to_string(
e2.v2()) +
274 ") can not be resolved: computed split vertex is invalid",
294#ifdef CDT_ENABLE_CALLBACK_HANDLER
334#pragma GCC diagnostic push
335#pragma GCC diagnostic ignored "-Wunused-parameter"
366 const TriInd iRepurposedTri,
383 const TriInd iRepurposedTri1,
384 const TriInd iRepurposedTri2,
434#pragma GCC diagnostic pop
452template <
typename T,
typename TNearPo
intLocator = LocatorKDTree<T> >
497 T minDistToConstraintEdge);
511 const TNearPointLocator& nearPtLocator,
513 T minDistToConstraintEdge);
529 typename TVertexIter,
530 typename TGetVertexCoordX,
531 typename TGetVertexCoordY>
535 TGetVertexCoordX getX,
536 TGetVertexCoordY getY);
580 typename TGetEdgeVertexStart,
581 typename TGetEdgeVertexEnd>
585 TGetEdgeVertexStart getStart,
586 TGetEdgeVertexEnd getEnd);
649 typename TGetEdgeVertexStart,
650 typename TGetEdgeVertexEnd>
654 TGetEdgeVertexStart getStart,
655 TGetEdgeVertexEnd getEnd);
725#ifdef CDT_ENABLE_CALLBACK_HANDLER
782 void addSuperTriangle(
const Box2d<T>& box);
784 void insertVertex(
VertInd iVert);
786 void ensureDelaunayByEdgeFlips(
VertInd iV1, std::stack<TriInd>& triStack);
788 std::vector<Edge> insertVertex_FlipFixedEdges(
VertInd iV1);
791 typedef tuple<IndexSizeType, IndexSizeType, TriInd, TriInd, Index>
792 TriangulatePseudoPolygonTask;
810 std::vector<TriangulatePseudoPolygonTask>& tppIterations);
824 void insertEdgeIteration(
828 std::vector<TriangulatePseudoPolygonTask>& tppIterations);
831 typedef tuple<Edge, EdgeVec, BoundaryOverlapCount> ConformToEdgeTask;
848 BoundaryOverlapCount overlaps,
849 std::vector<ConformToEdgeTask>& remaining);
862 void conformToEdgeIteration(
865 BoundaryOverlapCount overlaps,
866 std::vector<ConformToEdgeTask>& remaining);
868 tuple<TriInd, VertInd, VertInd> intersectedTriangle(
872 T orientationTolerance = T(0))
const;
874 std::stack<TriInd> insertVertexInsideTriangle(
VertInd v,
TriInd iT);
876 std::stack<TriInd> insertVertexOnEdge(
880 const bool doHandleFixedSplitEdge =
false);
881 array<TriInd, 2> trianglesAt(
const V2d<T>& pos)
const;
905 void triangulatePseudoPolygon(
906 const std::vector<VertInd>& poly,
907 unordered_map<Edge, TriInd>& outerTris,
910 std::vector<TriInd>& trianglesToReuse,
911 std::vector<TriangulatePseudoPolygonTask>& iterations);
912 void triangulatePseudoPolygonIteration(
913 const std::vector<VertInd>& poly,
914 unordered_map<Edge, TriInd>& outerTris,
915 std::vector<TriInd>& trianglesToReuse,
916 std::vector<TriangulatePseudoPolygonTask>& iterations);
917 IndexSizeType findDelaunayPoint(
918 const std::vector<VertInd>& poly,
920 IndexSizeType iB)
const;
928 void finalizeTriangulation(
const TriIndUSet& removedTriangles);
929 TriIndUSet growToBoundary(std::stack<TriInd> seeds)
const;
930 void fixEdge(
const Edge& edge);
931 void fixEdge(
const Edge& edge,
const Edge& originalEdge);
937 void splitFixedEdge(
const Edge& edge,
const VertInd iSplitVert);
982 bool isEdgeSplitVertexValid(
995 Edge originalInputEdge(
const Edge& e)
const;
1019 unordered_map<TriInd, LayerDepth> peelLayer(
1020 std::stack<TriInd> seeds,
1022 std::vector<LayerDepth>& triDepths)
const;
1024 void insertVertices_AsProvided(
VertInd superGeomVertCount);
1025 void insertVertices_Randomized(
VertInd superGeomVertCount);
1026 void insertVertices_KDTreeBFS(
VertInd superGeomVertCount,
Box2d<T> box);
1027 std::pair<TriInd, TriInd> edgeTriangles(
VertInd a,
VertInd b)
const;
1030 void pivotVertexTriangleCW(
VertInd v);
1032 void tryAddVertexToLocator(
const VertInd v);
1035 void tryInitNearestPointLocator();
1037 TNearPointLocator m_nearPtLocator;
1042 T m_minDistToConstraintEdge;
1044#ifdef CDT_ENABLE_CALLBACK_HANDLER
1072 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
1073 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
1074 return z ^ (z >> 31);
1079template <
class RandomIt>
1083 typename std::iterator_traits<RandomIt>::difference_type i, n;
1085 for(i = n - 1; i > 0; --i)
1087 std::swap(first[i], first[prng() % (i + 1)]);
1092template <
class ForwardIt,
class T>
1093void iota(ForwardIt first, ForwardIt last, T value)
1095 while(first != last)
1107template <
typename T,
typename TNearPo
intLocator>
1109 typename TVertexIter,
1110 typename TGetVertexCoordX,
1111 typename TGetVertexCoordY>
1113 const TVertexIter first,
1114 const TVertexIter last,
1115 TGetVertexCoordX getX,
1116 TGetVertexCoordY getY)
1121 const bool isFirstTime =
vertices.empty();
1126 const std::size_t nNewVertices = std::distance(first, last);
1127 std::size_t exactCapacityTriangles =
triangles.size() + 2 * nNewVertices;
1128 std::size_t exactCapacityVertices =
vertices.size() + nNewVertices;
1131 exactCapacityTriangles += 1;
1132 exactCapacityVertices += nSuperTriangleVertices;
1134 std::size_t capacityTriangles = exactCapacityTriangles;
1135 std::size_t capacityVertices = exactCapacityVertices;
1141 const VertInd overAllocationVerticesThreshold(1000);
1142 const T overAllocationFactor(1.1);
1143 const bool isOverPreAllocated =
1144 m_intersectingEdgesStrategy ==
1146 VertInd(nNewVertices) >= overAllocationVerticesThreshold;
1147 if(isOverPreAllocated)
1149 capacityTriangles *= overAllocationFactor;
1150 capacityVertices *= overAllocationFactor;
1153 vertices.reserve(capacityVertices);
1154 m_vertTris.reserve(capacityVertices);
1160 addSuperTriangle(box);
1162 tryInitNearestPointLocator();
1165 for(TVertexIter it = first; it != last; ++it)
1166 addNewVertex(
V2d<T>(getX(*it), getY(*it)), noNeighbor);
1168 switch(m_vertexInsertionOrder)
1171 insertVertices_AsProvided(nExistingVerts);
1174 isFirstTime ? insertVertices_KDTreeBFS(nExistingVerts, box)
1175 : insertVertices_Randomized(nExistingVerts);
1180#ifdef CDT_ENABLE_CALLBACK_HANDLER
1182 !m_callbackHandler || m_callbackHandler->isAbortCalculation() ||
1183 (
vertices.size() == exactCapacityVertices));
1185 !m_callbackHandler || m_callbackHandler->isAbortCalculation() ||
1186 (
triangles.size() == exactCapacityTriangles));
1188 assert(
vertices.size() == exactCapacityVertices);
1189 assert(
triangles.size() == exactCapacityTriangles);
1193template <
typename T,
typename TNearPo
intLocator>
1196 typename TGetEdgeVertexStart,
1197 typename TGetEdgeVertexEnd>
1200 const TEdgeIter last,
1201 TGetEdgeVertexStart getStart,
1202 TGetEdgeVertexEnd getEnd)
1207 std::vector<TriangulatePseudoPolygonTask> tppIterations;
1209 for(; first != last; ++first)
1211#ifdef CDT_ENABLE_CALLBACK_HANDLER
1212 if(m_callbackHandler && m_callbackHandler->isAbortCalculation())
1219 VertInd(getStart(*first) + m_nTargetVerts),
1220 VertInd(getEnd(*first) + m_nTargetVerts));
1221 insertEdge(edge, edge, remaining, tppIterations);
1225template <
typename T,
typename TNearPo
intLocator>
1228 typename TGetEdgeVertexStart,
1229 typename TGetEdgeVertexEnd>
1232 const TEdgeIter last,
1233 TGetEdgeVertexStart getStart,
1234 TGetEdgeVertexEnd getEnd)
1239 tryInitNearestPointLocator();
1241 std::vector<ConformToEdgeTask> remaining;
1242 for(; first != last; ++first)
1244#ifdef CDT_ENABLE_CALLBACK_HANDLER
1245 if(m_callbackHandler && m_callbackHandler->isAbortCalculation())
1252 VertInd(getStart(*first) + m_nTargetVerts),
1253 VertInd(getEnd(*first) + m_nTargetVerts));
1254 conformToEdge(e,
EdgeVec(1, e), 0, remaining);
1260#ifndef CDT_USE_AS_COMPILED_LIBRARY
Adapter between for KDTree and CDT.
void random_shuffle(RandomIt first, RandomIt last)
backport from c++11
void iota(ForwardIt first, ForwardIt last, T value)
backport from c++11
Triangulation class - implementation.
VertInd v2() const
second duplicate
VertInd v1() const
first duplicate
DuplicateVertexError(const VertInd v1, const VertInd v2, const SourceLocation &srcLoc)
Constructor.
virtual ~Error() CDT_NOEXCEPT
Destructor.
const SourceLocation & sourceLocation() const
Get source location from where the error was thrown.
Error(const std::string &description, const SourceLocation &srcLoc)
Constructor.
const std::string & description() const
Get error description.
Error thrown when triangulation modification is attempted after it was finalized.
FinalizedError(const SourceLocation &srcLoc)
Constructor.
Interface for the callback handler that user can derive from and inject into the triangulation to mon...
virtual void onAddSuperTriangle()
Called when super-triangle is added.
virtual void onInsertVertexOnEdge(const TriInd iRepurposedTri1, const TriInd iRepurposedTri2, const TriInd iNewTri1, const TriInd iNewTri2)
Called when inserted vertex is on an edge.
virtual bool isAbortCalculation() const
Tells whether the user wants to abort the triangulation at the earliest opportunity.
virtual ~ICallbackHandler()
Virtual destructor.
virtual void onReTriangulatePolygon(const std::vector< TriInd > &tris)
Called when inserting a constraint edge causes polygon containing triangles to be re-triangulated @tr...
virtual void onFlipEdge(const TriInd iT, const TriInd iTopo)
Called just before an edge between tro triangles is flipped.
virtual void onInsertVertexInsideTriangle(const TriInd iRepurposedTri, const TriInd iNewTri1, const TriInd iNewTri2)
Called when inserted vertex is inside a triangle.
virtual void onAddEdgeStart(const Edge &edge)
Called at the start of adding a constraint edge to the triangulation.
virtual void onAddVertexStart(const VertInd iV, const AddVertexType::Enum vertexType)
Called at the start of adding new vertex to the triangulation.
const Edge & e1() const
first intersecting constraint
const Edge & e2() const
second intersecting constraint
IntersectingConstraintsError(const Edge &e1, const Edge &e2, const SourceLocation &srcLoc)
Constructor.
const Edge & e2() const
second intersecting constraint
const Edge & e1() const
first intersecting constraint
InvalidEdgeSplitVertex(const Edge &e1, const Edge &e2, const SourceLocation &srcLoc)
Constructor.
Contains source location info: file, function, line.
SourceLocation(const std::string &file, const std::string &func, int line)
Constructor.
const std::string & func() const
source function
int line() const
source line
const std::string & file() const
source file
EdgeUSet fixedEdges
triangulation's constraints (fixed edges)
void eraseOuterTriangles()
Erase triangles outside of constrained boundary using growing.
void conformToEdges(TEdgeIter first, TEdgeIter last, TGetEdgeVertexStart getStart, TGetEdgeVertexEnd getEnd)
Insert constraint edges into triangulation for Conforming Delaunay Triangulation (for example see fig...
std::vector< V2d< T > > V2dVec
Vertices vector.
std::vector< LayerDepth > calculateTriangleDepths() const
Calculate depth of each triangle in constraint triangulation.
bool isFinalized() const
Check if the triangulation was finalized with erase... method and super-triangle was removed.
Triangulation(VertexInsertionOrder::Enum vertexInsertionOrder)
Constructor.
void eraseOuterTrianglesAndHoles()
Erase triangles outside of constrained boundary and auto-detected holes.
V2dVec vertices
triangulation's vertices
void insertEdges(TEdgeIter first, TEdgeIter last, TGetEdgeVertexStart getStart, TGetEdgeVertexEnd getEnd)
Insert constraint edges into triangulation for Constrained Delaunay Triangulation (for example see fi...
void insertVertices(TVertexIter first, TVertexIter last, TGetVertexCoordX getX, TGetVertexCoordY getY)
Insert custom point-types specified by iterator range and X/Y-getters.
Triangulation(VertexInsertionOrder::Enum vertexInsertionOrder, IntersectingConstraintEdges::Enum intersectingEdgesStrategy, T minDistToConstraintEdge)
Constructor.
void eraseSuperTriangle()
Erase triangles adjacent to super triangle.
unordered_map< Edge, EdgeVec > pieceToOriginals
Stores list of original edges represented by a given fixed edge.
Triangulation(VertexInsertionOrder::Enum vertexInsertionOrder, const TNearPointLocator &nearPtLocator, IntersectingConstraintEdges::Enum intersectingEdgesStrategy, T minDistToConstraintEdge)
Constructor.
unordered_map< Edge, BoundaryOverlapCount > overlapCount
Stores count of overlapping boundaries for a fixed edge.
TriangleVec triangles
triangulation's triangles
Triangulation()
Default constructor.
void setCallbackHandler(ICallbackHandler *callbackHandler)
Set user-provided callback handler.
void initializedWithCustomSuperGeometry()
Call this method after directly setting custom super-geometry via vertices and triangles members.
unsigned short LayerDepth
Type used for storing layer depths for triangles.
void flipEdge(TriInd iT, TriInd iTopo)
Flip an edge between two triangle.
TriIndVec & VertTrisInternal()
Access internal vertex adjacent triangles.
void removeTriangles(const TriIndUSet &removedTriangles)
Remove triangles with specified indices.
Namespace containing triangulation functionality.
std::vector< Edge > EdgeVec
Vector of edges.
unordered_set< Edge > EdgeUSet
Hash table of edges.
std::vector< TriInd > TriIndVec
Vector of triangle indices.
IndexSizeType VertInd
Vertex index.
unordered_set< TriInd > TriIndUSet
Hash table of triangles.
IndexSizeType TriInd
Triangle index.
std::vector< Triangle > TriangleVec
Vector of triangles.
What type of vertex is added to the triangulation.
@ UserInput
Original vertex from user input.
@ FixedEdgeMidpoint
During conforming triangulation edge mid-point is added.
@ FixedEdgesIntersection
Resolving fixed/constraint edges' intersection.
Box2d< T > & envelopPoints(TVertexIter first, TVertexIter last, TGetVertexCoordX getX, TGetVertexCoordY getY)
Envelop box around a collection of custom points.
Edge connecting two vertices: vertex with smaller index is always first.
Enum of strategies for treating intersecting constraint edges.
@ TryResolve
attempt to resolve constraint edge intersections
@ NotAllowed
constraint edge intersections are not allowed
@ DontCheck
No checks: slightly faster but less safe.
Enum of what type of geometry used to embed triangulation into.
@ SuperTriangle
conventional super-triangle
@ Custom
user-specified custom geometry (e.g., grid)
What type of triangle change happened.
@ AddedNew
new triangle added to the triangulation
@ ModifiedExisting
existing triangle was modified
Triangulation triangle (counter-clockwise winding)
Enum of strategies specifying order in which a range of vertices is inserted.
@ AsProvided
insert vertices in same order they are provided
@ Auto
Automatic insertion order optimized for better performance.
SplitMix64 pseudo-random number generator.
uint64 m_state
PRNG's state.
SplitMix64RandGen()
default constructor
uint64 operator()()
functor's operator
unsigned long long uint64
uint64 type
SplitMix64RandGen(uint64 state)
constructor