CDT  1.4.2
C++ library for constrained Delaunay triangulation
 
Loading...
Searching...
No Matches

CDT Logo

CI Builds

What is CDT

CDT is a C++ library for generating constraint or conforming Delaunay triangulations.

  • open-source: permissively-licensed under Mozilla Public License (MPL) 2.0
  • cross-platform: tested on Windows, Linux (Ubuntu), and macOS; tested architectures: x64 and arm64
  • portable: backwards-compatible with C++98
  • bloat-free: no external dependencies by default
  • flexible: can be consumed as a header-only or as a compiled library
  • performant: continuously profiled, measured, and optimized
  • numerically robust: triangulation algorithms rely on robust geometric predicates

If CDT helped you please consider adding a star on GitHub. This means a lot to the authors 🤩

Table of Contents

What can CDT do?

CDT show-case: constrained and conforming triangulations, convex hulls, automatically removing holes

  • Constrained Delaunay Triangulations: force edges into Delaunay triangulation
  • Conforming Delaunay Triangulations: add new points into Delaunay triangulation until the edge is present in triangulation
  • Convex-hulls
  • Automatically finding and removing holes

Properly Handling the Corner-Cases

CDT supported corner cases: points on edges, overlapping edges, resolving edge intersections

Online Documentation

Latest online documentation (automatically generated with Doxygen).

Algorithm

  • Implementation closely follows incremental construction algorithm by Anglada [1].
  • During the legalization, the cases when at least one vertex belongs to super-triangle are resolved using an approach as described in Žalik et al. [2].
  • For finding a triangle that contains inserted point remembering randomized triangle walk is used [3]. To find the starting triangle for the walk the nearest point is found using a kd-tree with mid-split nodes.
  • Order in which vertices are inserted is controlled by CDT::VertexInsertionOrder:

Pre-conditions:

  • No duplicated points (use provided functions for removing duplicate points and re-mapping edges)
  • No two constraint edges intersect each other (overlapping boundaries are allowed)

Post-conditions:

  • Triangles have counter-clockwise (CCW) winding in a 2D coordinate system where X-axis points right and Y-axis points up.

Implementation Details

Adding CDT to your C++ project Using a Package Manager

vcpkg

CDT port is available in Microsoft's vcpkg.

Conan

CDT is not in the conan-center but there's a conanfile.py recipe provided (in this repo). Note that it might need small adjustments like changing boost version to fit your needs.

spack

A recipe for CDT is available in spack.

Installation/Building

CDT uses modern CMake and should just work out of the box without any surprises. The are many ways to consume CDT:

  • copy headers and use as a header-only library
  • add to CMake project directly with add_subdirectory
  • pre-build and add to CMake project as a dependency with find_package
  • consume as a Conan package

CMake options

Option Default value Description
CDT_USE_64_BIT_INDEX_TYPE OFF Use 64bits to store vertex/triangle index types. Otherwise 32bits are used (up to 4.2bn items)
CDT_USE_AS_COMPILED_LIBRARY OFF Instantiate templates for float and double and compiled into a library
CDT_DISABLE_EXCEPTIONS OFF Disables exceptions: instead of throwing the library will call std::terminate
CDT_ENABLE_CALLBACK_HANDLER OFF If enabled it is possible to provide a callback handler to the triangulation

Adding to CMake project directly

Can be done with add_subdirectory command (e.g., see CDT visualizer's CMakeLists.txt).

# add CDT as subdirectory to CMake project
add_subdirectory(../CDT CDT)

Adding to non-CMake project directly

To use as header-only copy headers from CDT/include

To use as a compiled library define CDT_USE_AS_COMPILED_LIBRARY and compile CDT.cpp

Consume pre-build CDT in CMake project with find_package

CDT provides package config files that can be included by other projects to find and use it.

# from CDT folder
mkdir build && cd build
# configure with desired CMake flags
cmake -DCDT_USE_AS_COMPILED_LIBRARY=ON ..
# build and install
cmake --build . && cmake --install .
# In consuming CMakeLists.txt
find_package(CDT REQUIRED CONFIG)

Where to find CDT API

Public API is provided in two places:

  • CDT::Triangulation class is used for performing constrained Delaunay triangulations.
  • Free functions in CDT.h provide some additional functionality for removing duplicates, re-mapping edges and triangle depth-peeling

Code Examples

ℹ️ For more up-to-date code examples please see CDT tests in cdt.test.cpp.

Delaunay triangulation without constraints (triangulated convex-hull)

Example of a triangulated convex hull

#include "CDT.h"
cdt.insertVertices(/* points */);
/* access triangles */ = cdt.triangles;
/* access vertices */ = cdt.vertices;
/* access boundary (fixed) edges */ = cdt.fixedEdges;
/* calculate all edges (on demand) */ = CDT::extractEdgesFromTriangles(cdt.triangles);
Public API.
Data structure representing a 2D constrained Delaunay triangulation.
EdgeUSet fixedEdges
triangulation's constraints (fixed edges)
V2dVec vertices
triangulation's vertices
void insertVertices(TVertexIter first, TVertexIter last, TGetVertexCoordX getX, TGetVertexCoordY getY)
Insert custom point-types specified by iterator range and X/Y-getters.
void eraseSuperTriangle()
Erase triangles adjacent to super triangle.
TriangleVec triangles
triangulation's triangles
CDT_EXPORT EdgeUSet extractEdgesFromTriangles(const TriangleVec &triangles)
Extract all edges of triangles.
Definition CDT.hpp:74

Constrained Delaunay triangulation (auto-detected boundaries and holes)

Example of a triangulation with constrained boundaries and auto-detected holes

// ... same as above
cdt.insertVertices(/* points */);
cdt.insertEdges(/* boundary edges */);
/* access triangles */ = cdt.triangles;
/* access vertices */ = cdt.vertices;
/* access boundary (fixed) edges */ = cdt.fixedEdges;
/* calculate all edges (on demand) */ = CDT::extractEdgesFromTriangles(cdt.triangles);
void eraseOuterTrianglesAndHoles()
Erase triangles outside of constrained boundary and auto-detected holes.
void insertEdges(TEdgeIter first, TEdgeIter last, TGetEdgeVertexStart getStart, TGetEdgeVertexEnd getEnd)
Insert constraint edges into triangulation for Constrained Delaunay Triangulation (for example see fi...

Conforming Delaunay triangulation

Use CDT::Triangulation::conformToEdges instead of CDT::Triangulation::insertEdges

Resolve edge intersections by adding new points and splitting edges

Pass CDT::IntersectingConstraintEdges::TryResolve to CDT::Triangulation constructor.

Custom point/edge type

struct CustomPoint2D
{
double data[2];
};
struct CustomEdge
{
std::pair<std::size_t, std::size_t> vertices;
};
// containers other than std::vector will work too
std::vector<CustomPoint2D> points = /*...*/;
std::vector<CustomEdge> edges = /*...*/;
points.begin(),
points.end(),
[](const CustomPoint2D& p){ return p.data[0]; },
[](const CustomPoint2D& p){ return p.data[1]; }
);
edges.begin(),
edges.end(),
[](const CustomEdge& e){ return e.vertices.first; },
[](const CustomEdge& e){ return e.vertices.second; }
);

Callbacks

For advanced usage and deep integration with custom algorithms CDT allows to register user callbacks for important events. For example it is possible to do progress reporting or abort triangulation.

⚠️ Callbacks need to be enabled with CDT_ENABLE_CALLBACK_HANDLER.

User needs to implement callback handler by deriving from CDT::ICallbackHandler and register it with CDT::Triangulation::setCallbackHandler. See cdt.test.cpp for usage examples.

Python bindings?

For Python bindings check-out PythonCDT

Contributors

Contributing

Any feedback and contributions are welcome.

License

Mozilla Public License, v. 2.0

For attribution you can use the following template:

This software is based part on CDT (C++ library for constrained Delaunay triangulation):
Copyright © 2019 Leica Geosystems Technology AB
Copyright © The CDT Contributors
Licensed under the MPL-2.0 license.
https://github.com/artem-ogre/CDT
${INSERT_FULL_MPL_2.0_TEXT}

Example Gallery

A Bean Guitar Guitar with holes Lake Superior Sweden Overlapping boundaries

Bibliography

[1] Marc Vigo Anglada, An improved incremental algorithm for constructing restricted Delaunay triangulations, Computers & Graphics, Volume 21, Issue 2, 1997, Pages 215-223, ISSN 0097-8493.

[2] Borut Žalik and Ivana Kolingerová, An incremental construction algorithm for Delaunay triangulation using the nearest-point paradigm, International Journal of Geographical Information Science, Volume 17, Issue 2, Pages 119-138, 2003, DOI 10.1080/713811749.

[3] Olivier Devillers, Sylvvain Pion, Monique Tellaud, Walking in a triangulation, International Journal of Foundations of Computer Science, Volume 13, Issue 2, Pages 181-199, 2002

[4] Liu, Jianfei & Yan, Jinhui & Lo, S.. A new insertion sequence for incremental Delaunay triangulation. Acta Mechanica Sinica, Volume 29, 2013