Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
RestrictedTriangulation.h
Go to the documentation of this file.
1
31#pragma once
32
33#ifdef OGDF_INCLUDE_CGAL
34
35//CGAL example
37
38# include <iostream>
39
40# include <CGAL/Constrained_Delaunay_triangulation_2.h>
41# include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
42# include <CGAL/Point_2.h>
43# include <CGAL/Polygon_2.h>
44# include <CGAL/Triangulation_face_base_with_info_2.h>
45
46namespace ogdf {
47namespace internal {
48namespace gcm {
49namespace geometry {
52template<typename Kernel>
54private:
55 struct FaceInfo2 {
56 FaceInfo2() { }
57
58 int nesting_level;
59
60 bool in_domain() { return nesting_level % 2 == 1; }
61 };
62
63 using K = Kernel;
64 using Vb = CGAL::Triangulation_vertex_base_2<K>;
65 using Fbb = CGAL::Triangulation_face_base_with_info_2<FaceInfo2, K>;
66 using Fb = CGAL::Constrained_triangulation_face_base_2<K, Fbb>;
67 using TDS = CGAL::Triangulation_data_structure_2<Vb, Fb>;
68 using Itag = CGAL::Exact_predicates_tag;
69 using CDT = CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag>;
70 using Point = CGAL::Point_2<K>;
71 using Polygon_2 = CGAL::Polygon_2<K>;
72
73 void mark_domains(CDT& ct, typename CDT::Face_handle start, int index,
74 std::list<typename CDT::Edge>& border) {
75 if (start->info().nesting_level != -1) {
76 return;
77 }
78 std::list<typename CDT::Face_handle> queue;
79 queue.push_back(start);
80 while (!queue.empty()) {
81 typename CDT::Face_handle fh = queue.front();
82 queue.pop_front();
83 if (fh->info().nesting_level == -1) {
84 fh->info().nesting_level = index;
85 for (int i = 0; i < 3; i++) {
86 typename CDT::Edge e(fh, i);
87 typename CDT::Face_handle n = fh->neighbor(i);
88 if (n->info().nesting_level == -1) {
89 if (ct.is_constrained(e)) {
90 border.push_back(e);
91 } else {
92 queue.push_back(n);
93 }
94 }
95 }
96 }
97 }
98 }
99
100 //explore set of facets connected with non constrained edges,
101 //and attribute to each such set a nesting level.
102 //We start from facets incident to the infinite vertex, with a nesting
103 //level of 0. Then we recursively consider the non-explored facets incident
104 //to constrained edges bounding the former set and increase the nesting level by 1.
105 //Facets in the domain are those with an odd nesting level.
106 void mark_domains(CDT& cdt) {
107 for (typename CDT::All_faces_iterator it = cdt.all_faces_begin(); it != cdt.all_faces_end();
108 ++it) {
109 it->info().nesting_level = -1;
110 }
111 std::list<typename CDT::Edge> border;
112 mark_domains(cdt, cdt.infinite_face(), 0, border);
113 while (!border.empty()) {
114 typename CDT::Edge e = border.front();
115 border.pop_front();
116 typename CDT::Face_handle n = e.first->neighbor(e.second);
117 if (n->info().nesting_level == -1) {
118 mark_domains(cdt, n, e.first->info().nesting_level + 1, border);
119 }
120 }
121 }
122
123 void insert_polygon(CDT& cdt, const Polygon_2& polygon) {
124 if (polygon.is_empty()) {
125 return;
126 }
127 typename CDT::Vertex_handle v_prev = cdt.insert(*CGAL::cpp11::prev(polygon.vertices_end()));
128 for (typename Polygon_2::Vertex_iterator vit = polygon.vertices_begin();
129 vit != polygon.vertices_end(); ++vit) {
130 typename CDT::Vertex_handle vh = cdt.insert(*vit);
131 cdt.insert_constraint(vh, v_prev);
132 v_prev = vh;
133 }
134 }
135
136public:
137 CDT run(const Polygon_t<Kernel>& polygon) {
138 CDT cdt;
139 insert_polygon(cdt, polygon);
141 return std::move(cdt);
142 }
143};
144}
145}
146}
147}
148
149#endif
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.