CDT  2.0.0
C++ library for constrained Delaunay triangulation
Loading...
Searching...
No Matches
CDT.h
Go to the documentation of this file.
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
9
10#ifndef CDT_lNrmUayWQaIR5fxnsg9B
11#define CDT_lNrmUayWQaIR5fxnsg9B
12
13#include "CDTUtils.h"
14#include "Triangulation.h"
15
16#include "remove_at.hpp"
17
18#include <algorithm>
19#include <cassert>
20#include <cstdlib>
21#include <iterator>
22#include <memory>
23#include <vector>
24
26namespace CDT
27{
28
33
39typedef unsigned short LayerDepth;
40typedef LayerDepth BoundaryOverlapCount;
41
43typedef std::vector<TriIndVec> VerticesTriangles;
44
49
56CDT_EXPORT VerticesTriangles
57calculateTrianglesByVertex(const TriangleVec& triangles, VertInd verticesSize);
58
66struct CDT_EXPORT DuplicatesInfo
67{
68 std::vector<std::size_t> mapping;
69 std::vector<std::size_t> duplicates;
70};
71
86template <
87 typename T,
88 typename TVertexIter,
89 typename TGetVertexCoordX,
90 typename TGetVertexCoordY>
92 TVertexIter first,
93 TVertexIter last,
94 TGetVertexCoordX getX,
95 TGetVertexCoordY getY);
96
104template <typename TVertex, typename TAllocator>
106 std::vector<TVertex, TAllocator>& vertices,
107 const std::vector<std::size_t>& duplicates);
108
116template <typename T>
117CDT_EXPORT DuplicatesInfo RemoveDuplicates(std::vector<V2d<T> >& vertices);
118
136template <
137 typename TEdgeIter,
138 typename TGetEdgeVertexStart,
139 typename TGetEdgeVertexEnd,
140 typename TMakeEdgeFromStartAndEnd>
141void RemapEdges(
142 TEdgeIter first,
143 TEdgeIter last,
144 const std::vector<std::size_t>& mapping,
145 TGetEdgeVertexStart getStart,
146 TGetEdgeVertexEnd getEnd,
147 TMakeEdgeFromStartAndEnd makeEdge);
148
156CDT_EXPORT void
157RemapEdges(std::vector<Edge>& edges, const std::vector<std::size_t>& mapping);
158
189template <
190 typename T,
191 typename TVertex,
192 typename TGetVertexCoordX,
193 typename TGetVertexCoordY,
194 typename TVertexAllocator,
195 typename TEdgeIter,
196 typename TGetEdgeVertexStart,
197 typename TGetEdgeVertexEnd,
198 typename TMakeEdgeFromStartAndEnd>
200 std::vector<TVertex, TVertexAllocator>& vertices,
201 TGetVertexCoordX getX,
202 TGetVertexCoordY getY,
203 TEdgeIter edgesFirst,
204 TEdgeIter edgesLast,
205 TGetEdgeVertexStart getStart,
206 TGetEdgeVertexEnd getEnd,
207 TMakeEdgeFromStartAndEnd makeEdge);
208
216template <typename T>
218 std::vector<V2d<T> >& vertices,
219 std::vector<Edge>& edges);
220
227CDT_EXPORT EdgeUSet extractEdgesFromTriangles(const TriangleVec& triangles);
228
234CDT_EXPORT unordered_map<Edge, EdgeVec>
235EdgeToPiecesMapping(const unordered_map<Edge, EdgeVec>& pieceToOriginals);
236
245template <typename T>
246unordered_map<Edge, std::vector<VertInd> > EdgeToSplitVertices(
247 const unordered_map<Edge, EdgeVec>& edgeToPieces,
248 const std::vector<V2d<T> >& vertices);
249
251
253
254} // namespace CDT
255
256//*****************************************************************************
257// Implementations of template functionlity
258//*****************************************************************************
259// hash for CDT::V2d<T>
260#ifdef CDT_CXX11_IS_SUPPORTED
261namespace std
262#else
263namespace boost
264#endif
265{
266template <typename T>
267struct hash<CDT::V2d<T> >
268{
269 size_t operator()(const CDT::V2d<T>& xy) const
270 {
271#ifdef CDT_CXX11_IS_SUPPORTED
272 typedef std::hash<T> Hasher;
273#else
274 typedef boost::hash<T> Hasher;
275#endif
276 return Hasher()(xy.x) ^ Hasher()(xy.y);
277 }
278};
279} // namespace std
280
281namespace CDT
282{
283
284//-----
285// API
286//-----
287template <
288 typename T,
289 typename TVertexIter,
290 typename TGetVertexCoordX,
291 typename TGetVertexCoordY>
293 TVertexIter first,
294 TVertexIter last,
295 TGetVertexCoordX getX,
296 TGetVertexCoordY getY)
297{
298 typedef unordered_map<V2d<T>, std::size_t> PosToIndex;
299 PosToIndex uniqueVerts;
300 const std::size_t verticesSize = std::distance(first, last);
301 DuplicatesInfo di = {
302 std::vector<std::size_t>(verticesSize), std::vector<std::size_t>()};
303 for(std::size_t iIn = 0, iOut = iIn; iIn < verticesSize; ++iIn, ++first)
304 {
305 typename PosToIndex::const_iterator it;
306 bool isUnique;
307 tie(it, isUnique) = uniqueVerts.insert(
308 std::make_pair(V2d<T>(getX(*first), getY(*first)), iOut));
309 if(isUnique)
310 {
311 di.mapping[iIn] = iOut++;
312 continue;
313 }
314 di.mapping[iIn] = it->second; // found a duplicate
315 di.duplicates.push_back(iIn);
316 }
317 return di;
318}
319
320template <typename TVertex, typename TAllocator>
322 std::vector<TVertex, TAllocator>& vertices,
323 const std::vector<std::size_t>& duplicates)
324{
325 vertices.erase(
326 remove_at(
327 vertices.begin(),
328 vertices.end(),
329 duplicates.begin(),
330 duplicates.end()),
331 vertices.end());
332}
333
334template <
335 typename TEdgeIter,
336 typename TGetEdgeVertexStart,
337 typename TGetEdgeVertexEnd,
338 typename TMakeEdgeFromStartAndEnd>
340 TEdgeIter first,
341 const TEdgeIter last,
342 const std::vector<std::size_t>& mapping,
343 TGetEdgeVertexStart getStart,
344 TGetEdgeVertexEnd getEnd,
345 TMakeEdgeFromStartAndEnd makeEdge)
346{
347 for(; first != last; ++first)
348 {
349 *first = makeEdge(
350 static_cast<VertInd>(mapping[getStart(*first)]),
351 static_cast<VertInd>(mapping[getEnd(*first)]));
352 }
353}
354
355template <
356 typename T,
357 typename TVertex,
358 typename TGetVertexCoordX,
359 typename TGetVertexCoordY,
360 typename TVertexAllocator,
361 typename TEdgeIter,
362 typename TGetEdgeVertexStart,
363 typename TGetEdgeVertexEnd,
364 typename TMakeEdgeFromStartAndEnd>
366 std::vector<TVertex, TVertexAllocator>& vertices,
367 TGetVertexCoordX getX,
368 TGetVertexCoordY getY,
369 const TEdgeIter edgesFirst,
370 const TEdgeIter edgesLast,
371 TGetEdgeVertexStart getStart,
372 TGetEdgeVertexEnd getEnd,
373 TMakeEdgeFromStartAndEnd makeEdge)
374{
375 const DuplicatesInfo di =
376 FindDuplicates<T>(vertices.begin(), vertices.end(), getX, getY);
377 RemoveDuplicates(vertices, di.duplicates);
378 RemapEdges(edgesFirst, edgesLast, di.mapping, getStart, getEnd, makeEdge);
379 return di;
380}
381
382template <typename T>
383unordered_map<Edge, std::vector<VertInd> > EdgeToSplitVertices(
384 const unordered_map<Edge, EdgeVec>& edgeToPieces,
385 const std::vector<V2d<T> >& vertices)
386{
387 typedef std::pair<VertInd, T> VertCoordPair;
388 struct ComparePred
389 {
390 bool operator()(const VertCoordPair& a, const VertCoordPair& b) const
391 {
392 return a.second < b.second;
393 }
394 } comparePred;
395
396 unordered_map<Edge, std::vector<VertInd> > edgeToSplitVerts;
397 typedef unordered_map<Edge, EdgeVec>::const_iterator It;
398 for(It e2pIt = edgeToPieces.begin(); e2pIt != edgeToPieces.end(); ++e2pIt)
399 {
400 const Edge& e = e2pIt->first;
401 const T dX = vertices[e.v2()].x - vertices[e.v1()].x;
402 const T dY = vertices[e.v2()].y - vertices[e.v1()].y;
403 const bool isX = std::abs(dX) >= std::abs(dY); // X-coord longer
404 const bool isAscending =
405 isX ? dX >= 0 : dY >= 0; // Longer coordinate ascends
406 const EdgeVec& pieces = e2pIt->second;
407 std::vector<VertCoordPair> splitVerts;
408 // size is: 2[ends] + (pieces - 1)[split vertices] = pieces + 1
409 splitVerts.reserve(pieces.size() + 1);
410 typedef EdgeVec::const_iterator EIt;
411 for(EIt pieceIt = pieces.begin(); pieceIt != pieces.end(); ++pieceIt)
412 {
413 const array<VertInd, 2> vv = {pieceIt->v1(), pieceIt->v2()};
414 typedef array<VertInd, 2>::const_iterator VIt;
415 for(VIt v = vv.begin(); v != vv.end(); ++v)
416 {
417 const T c = isX ? vertices[*v].x : vertices[*v].y;
418 splitVerts.push_back(std::make_pair(*v, isAscending ? c : -c));
419 }
420 }
421 // sort by longest coordinate
422 std::sort(splitVerts.begin(), splitVerts.end(), comparePred);
423 // remove duplicates
424 splitVerts.erase(
425 std::unique(splitVerts.begin(), splitVerts.end()),
426 splitVerts.end());
427 assert(splitVerts.size() > 2); // 2 end points with split vertices
428 std::pair<Edge, std::vector<VertInd> > val =
429 std::make_pair(e, std::vector<VertInd>());
430 val.second.reserve(splitVerts.size());
431 typedef typename std::vector<VertCoordPair>::const_iterator SEIt;
432 for(SEIt it = splitVerts.begin() + 1; it != splitVerts.end() - 1; ++it)
433 {
434 val.second.push_back(it->first);
435 }
436 edgeToSplitVerts.insert(val);
437 }
438 return edgeToSplitVerts;
439}
440
441} // namespace CDT
442
443#ifndef CDT_USE_AS_COMPILED_LIBRARY
444#include "CDT.hpp"
445#endif
446
447#endif // header-guard
Utilities and helpers.
Public API - implementation.
Triangulation class.
unsigned short LayerDepth
Type used for storing layer depths for triangles.
Definition CDT.h:39
std::vector< TriIndVec > VerticesTriangles
Triangles by vertex index.
Definition CDT.h:43
CDT_EXPORT VerticesTriangles calculateTrianglesByVertex(const TriangleVec &triangles, VertInd verticesSize)
Calculate triangles adjacent to vertices (triangles by vertex index)
Definition CDT.hpp:24
void RemoveDuplicates(std::vector< TVertex, TAllocator > &vertices, const std::vector< std::size_t > &duplicates)
Remove duplicates in-place from vector of custom points.
Definition CDT.h:321
void RemapEdges(TEdgeIter first, TEdgeIter last, const std::vector< std::size_t > &mapping, TGetEdgeVertexStart getStart, TGetEdgeVertexEnd getEnd, TMakeEdgeFromStartAndEnd makeEdge)
Remap vertex indices in edges (in-place) using given vertex-index mapping.
Definition CDT.h:339
DuplicatesInfo RemoveDuplicatesAndRemapEdges(std::vector< TVertex, TVertexAllocator > &vertices, TGetVertexCoordX getX, TGetVertexCoordY getY, TEdgeIter edgesFirst, TEdgeIter edgesLast, TGetEdgeVertexStart getStart, TGetEdgeVertexEnd getEnd, TMakeEdgeFromStartAndEnd makeEdge)
Find point duplicates, remove them from vector (in-place) and remap edges (in-place)
Definition CDT.h:365
unordered_map< Edge, std::vector< VertInd > > EdgeToSplitVertices(const unordered_map< Edge, EdgeVec > &edgeToPieces, const std::vector< V2d< T > > &vertices)
Definition CDT.h:383
CDT_EXPORT EdgeUSet extractEdgesFromTriangles(const TriangleVec &triangles)
Extract all edges of triangles.
Definition CDT.hpp:78
CDT_EXPORT unordered_map< Edge, EdgeVec > EdgeToPiecesMapping(const unordered_map< Edge, EdgeVec > &pieceToOriginals)
Definition CDT.hpp:92
DuplicatesInfo FindDuplicates(TVertexIter first, TVertexIter last, TGetVertexCoordX getX, TGetVertexCoordY getY)
Find duplicates in given custom point-type range.
Definition CDT.h:292
Namespace containing triangulation functionality.
std::vector< Edge > EdgeVec
Vector of edges.
Definition CDTUtils.h:400
unordered_set< Edge > EdgeUSet
Hash table of edges.
Definition CDTUtils.h:403
IndexSizeType VertInd
Vertex index.
Definition CDTUtils.h:254
std::vector< Triangle > TriangleVec
Vector of triangles.
Definition CDTUtils.h:467
Information about removed duplicated vertices.
Definition CDT.h:67
std::vector< std::size_t > mapping
vertex index mapping
Definition CDT.h:68
std::vector< std::size_t > duplicates
duplicates' indices
Definition CDT.h:69
Edge connecting two vertices: vertex with smaller index is always first.
Definition CDTUtils.h:334
VertInd v1() const
V1 getter.
Definition CDTUtils.h:361
VertInd v2() const
V2 getter.
Definition CDTUtils.h:367
2D vector
Definition CDTUtils.h:192
T y
Y-coordinate.
Definition CDTUtils.h:194
T x
X-coordinate.
Definition CDTUtils.h:193