Skip to content

Commit

Permalink
#84 #86 Performance and API improvments
Browse files Browse the repository at this point in the history
- Don't re-calculate triangles by vertex when finalizing triangulation
  (don't pay for what you don't use)
- If needed calculating triangles by vertex can be done with new `calculateTrianglesByVertex` helper
- Detect if triangulation was finalized and throw exceptions if it was when adding new vertices or edges
  • Loading branch information
artem-ogre committed Jul 11, 2022
1 parent 6dbadcf commit d4488e8
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 12 deletions.
8 changes: 6 additions & 2 deletions CDT/extras/VerifyTopology.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ template <typename T, typename TNearPointLocator = LocatorKDTree<T> >
inline bool verifyTopology(const CDT::Triangulation<T, TNearPointLocator>& cdt)
{
// Check if vertices' adjacent triangles contain vertex
const VerticesTriangles vertTris =
cdt.isFinalized()
? calculateTrianglesByVertex(cdt.triangles, cdt.vertices.size())
: cdt.vertTris;
for(VertInd iV(0); iV < VertInd(cdt.vertices.size()); ++iV)
{
const TriIndVec& vTris = cdt.vertTris[iV];
const TriIndVec& vTris = vertTris[iV];
typedef TriIndVec::const_iterator TriIndCit;
for(TriIndCit it = vTris.begin(); it != vTris.end(); ++it)
{
Expand Down Expand Up @@ -64,7 +68,7 @@ inline bool verifyTopology(const CDT::Triangulation<T, TNearPointLocator>& cdt)
typedef VerticesArr3::const_iterator VCit;
for(VCit it = t.vertices.begin(); it != t.vertices.end(); ++it)
{
const TriIndVec& tt = cdt.vertTris[*it];
const TriIndVec& tt = vertTris[*it];
if(std::find(tt.begin(), tt.end(), iT) == tt.end())
return false;
}
Expand Down
54 changes: 48 additions & 6 deletions CDT/include/CDT.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ const static VertInd noVertex(std::numeric_limits<VertInd>::max());
typedef unsigned short LayerDepth;
typedef LayerDepth BoundaryOverlapCount;

/// Triangles by vertex index
typedef std::vector<TriIndVec> VerticesTriangles;

/**
* Data structure representing a 2D constrained Delaunay triangulation
*
Expand All @@ -101,12 +104,17 @@ template <typename T, typename TNearPointLocator = LocatorKDTree<T> >
class CDT_EXPORT Triangulation
{
public:
typedef std::vector<V2d<T> > V2dVec; ///< Vertices vector
typedef std::vector<TriIndVec> VerticesTriangles; ///< Triangles by vertex
V2dVec vertices; ///< triangulation's vertices
TriangleVec triangles; ///< triangulation's triangles
EdgeUSet fixedEdges; ///< triangulation's constraints (fixed edges)
VerticesTriangles vertTris; ///< triangles adjacent to each vertex
typedef std::vector<V2d<T> > V2dVec; ///< Vertices vector
V2dVec vertices; ///< triangulation's vertices
TriangleVec triangles; ///< triangulation's triangles
EdgeUSet fixedEdges; ///< triangulation's constraints (fixed edges)
/**
* triangles adjacent to each vertex
* @note will be reset to empty when super-triangle is removed and
* triangulation is finalized. To re-calculate adjacent triangles use
* @ref CDT::calculateTrianglesByVertex helper
*/
VerticesTriangles vertTris;

/** Stores count of overlapping boundaries for a fixed edge. If no entry is
* present for an edge: no boundaries overlap.
Expand Down Expand Up @@ -276,6 +284,13 @@ class CDT_EXPORT Triangulation
*/
void initializedWithCustomSuperGeometry();

/**
* Check if the triangulation was finalized with `erase...` method and
* super-triangle was removed.
* @return true if triangulation is finalized, false otherwise
*/
bool isFinalized() const;

/**
* @defgroup Advanced
* Advanced methods for manually modifying the triangulation from
Expand Down Expand Up @@ -419,6 +434,15 @@ class CDT_EXPORT Triangulation
T m_minDistToConstraintEdge;
};

/**
* Calculate triangles adjacent to vertices (triangles by vertex index)
* @param triangles triangulation
* @param verticesSize total number of vertices to pre-allocate the output
* @return triangles by vertex index
*/
CDT_EXPORT VerticesTriangles
calculateTrianglesByVertex(const TriangleVec& triangles, VertInd verticesSize);

/**
* Information about removed duplicated vertices.
*
Expand Down Expand Up @@ -721,6 +745,12 @@ void Triangulation<T, TNearPointLocator>::insertVertices(
TGetVertexCoordX getX,
TGetVertexCoordY getY)
{
if(isFinalized())
{
throw std::runtime_error(
"Triangulation was finalized with 'erase...' method. Inserting new "
"vertices is not possible");
}
detail::randGenerator.seed(9001); // ensure deterministic behavior
if(vertices.empty())
{
Expand Down Expand Up @@ -763,6 +793,12 @@ void Triangulation<T, TNearPointLocator>::insertEdges(
TGetEdgeVertexStart getStart,
TGetEdgeVertexEnd getEnd)
{
if(isFinalized())
{
throw std::runtime_error(
"Triangulation was finalized with 'erase...' method. Inserting new "
"edges is not possible");
}
for(; first != last; ++first)
{
// +3 to account for super-triangle vertices
Expand All @@ -785,6 +821,12 @@ void Triangulation<T, TNearPointLocator>::conformToEdges(
TGetEdgeVertexStart getStart,
TGetEdgeVertexEnd getEnd)
{
if(isFinalized())
{
throw std::runtime_error(
"Triangulation was finalized with 'erase...' method. Conforming to "
"new edges is not possible");
}
for(; first != last; ++first)
{
// +3 to account for super-triangle vertices
Expand Down
28 changes: 24 additions & 4 deletions CDT/include/CDT.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ void Triangulation<T, TNearPointLocator>::finalizeTriangulation(
triangles.erase(triangles.end() - removedTriangles.size(), triangles.end());
// adjust triangles
// vertices' adjacent triangles will be re-calculated
vertTris = VerticesTriangles(vertices.size());
vertTris = VerticesTriangles();
for(TriInd iT = 0; iT < triangles.size(); ++iT)
{
Triangle& t = triangles[iT];
Expand All @@ -270,13 +270,11 @@ void Triangulation<T, TNearPointLocator>::finalizeTriangulation(
}
if(m_superGeomType == SuperGeometryType::SuperTriangle)
{
// account for removed super-triangle
VerticesArr3& vv = t.vertices;
for(VerticesArr3::iterator v = vv.begin(); v != vv.end(); ++v)
{
// account for removed super-triangle
*v -= 3;
// re-calculate vertices' adjacent triangles
vertTris[*v].push_back(iT);
}
}
}
Expand Down Expand Up @@ -1473,6 +1471,28 @@ void Triangulation<T, TNearPointLocator>::insertVertices(
newVertices.begin(), newVertices.end(), getX_V2d<T>, getY_V2d<T>);
}

template <typename T, typename TNearPointLocator>
bool Triangulation<T, TNearPointLocator>::isFinalized() const
{
return !vertices.empty() && vertTris.empty();
}

CDT_INLINE_IF_HEADER_ONLY VerticesTriangles calculateTrianglesByVertex(
const TriangleVec& triangles,
const VertInd verticesSize)
{
VerticesTriangles vertTris(verticesSize);
for(TriInd iT = 0; iT < triangles.size(); ++iT)
{
const VerticesArr3& vv = triangles[iT].vertices;
for(VerticesArr3::const_iterator v = vv.begin(); v != vv.end(); ++v)
{
vertTris[*v].push_back(iT);
}
}
return vertTris;
}

template <typename T>
DuplicatesInfo RemoveDuplicates(std::vector<V2d<T> >& vertices)
{
Expand Down

0 comments on commit d4488e8

Please sign in to comment.