Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
CGALPlanarSubdivision.h
Go to the documentation of this file.
1
31#pragma once
32
33#ifdef OGDF_INCLUDE_CGAL
34
40
41# include <boost/graph/breadth_first_search.hpp>
42# include <boost/graph/visitors.hpp>
43# include <tuple>
44
45# include <CGAL/Arr_extended_dcel.h>
46# include <CGAL/Arr_face_index_map.h>
47# include <CGAL/Arr_linear_traits_2.h>
48# include <CGAL/Arr_segment_traits_2.h>
49# include <CGAL/Arr_walk_along_line_point_location.h>
50# include <CGAL/Arrangement_2.h>
51# include <CGAL/Arrangement_with_history_2.h>
52# include <CGAL/graph_traits_dual_arrangement_2.h>
53
54namespace ogdf {
55namespace internal {
56namespace gcm {
57namespace geometry {
58
61template<typename kernel>
63private:
64 using LineSegment = geometry::LineSegment_t<kernel>;
65 using Point = geometry::Point_t<kernel>;
66 using Polygon = geometry::Polygon_t<kernel>;
67 using Line = geometry::Line_t<kernel>;
68 using Ray = geometry::Ray_t<kernel>;
69 using Direction = geometry::Direction_t<kernel>;
70 using Traits = CGAL::Arr_segment_traits_2<kernel>;
71
72 using LinearTraits = CGAL::Arr_linear_traits_2<kernel>;
73
74 using Dcel = CGAL::Arr_extended_dcel<Traits, unsigned int, unsigned int, unsigned int>;
75 using ArrWH = CGAL::Arrangement_with_history_2<Traits, Dcel>;
76
77 using Arr = CGAL::Arrangement_2<Traits>;
78 using LinearArr = CGAL::Arrangement_2<LinearTraits>;
79
80 using DualArr = CGAL::Dual<Arr>;
81 using Face_index_map = CGAL::Arr_face_index_map<Arr>;
82
83 template<typename _Arr>
84 Polygon get_face(CGAL::Arr_walk_along_line_point_location<_Arr>& pl, const Point& q) {
85 auto obj = pl.locate(q);
86
87 using Vertex_const_handle = typename _Arr::Vertex_const_handle;
88 using Halfedge_const_handle = typename _Arr::Halfedge_const_handle;
89 using Face_const_handle = typename _Arr::Face_const_handle;
90
91 const Vertex_const_handle* v;
92 const Halfedge_const_handle* e;
93 const Face_const_handle* f;
94
96 if ((f = boost::get<Face_const_handle>(&obj))) { // located inside a face
97 OGDF_ASSERT(!(*f)->is_unbounded());
98 auto c = (*f)->outer_ccb();
99 do {
100 poly.push_back(c->source()->point());
101 } while (++c != (*f)->outer_ccb());
102 } else if ((e = boost::get<Halfedge_const_handle>(&obj))) { // located on an edge
103
104 poly.push_back((*e)->source()->point());
105 poly.push_back((*e)->target()->point());
106 } else if ((v = boost::get<Vertex_const_handle>(&obj))) { // located on a vertex
107 poly.push_back((*v)->point());
108 } else {
109 // undefined behaviour
110 OGDF_ASSERT(false);
111 }
112
113 return poly;
114 }
115
116public:
117 using LCGEdge = std::tuple<unsigned int, unsigned int, unsigned int>;
118
119 Polygon extract_face(const std::vector<Line>& lines, const Point& q) {
121 CGAL::Arr_walk_along_line_point_location<LinearArr> pl(arr);
122 CGAL::insert(arr, lines.begin(), lines.end());
123 return get_face(pl, q);
124 }
125
126 Polygon extract_face(const std::vector<LineSegment>& segments, const Point& q) {
127 Arr arr;
128 CGAL::Arr_walk_along_line_point_location<Arr> pl(arr);
129 CGAL::insert(arr, segments.begin(), segments.end());
130 return get_face(pl, q);
131 }
132
140 void process(std::vector<LineSegment>& segments, std::vector<Line>& lines,
141 std::vector<Point>& node_to_point, std::vector<LCGEdge>& edge_list, int separator = -1) {
142 ArrWH arr;
143 if (separator < 0) {
144 separator = segments.size();
145 }
146 CGAL::insert(arr, segments.begin(), segments.begin() + separator);
147 CGAL::insert(arr, lines.begin(), lines.end());
148 //polygon edges
149 CGAL::insert(arr, segments.begin() + separator, segments.end());
150
151 unsigned int node = 1;
152 for (auto v_it = arr.vertices_begin(); v_it != arr.vertices_end(); ++v_it) {
153 v_it->set_data(node++);
154 node_to_point.push_back(v_it->point());
155 }
156
157 auto f_make_edge = [&](decltype(arr.induced_edges_begin(arr.curves_begin()))& e_itr,
158 const Direction& ref, unsigned int flag) {
159 auto e = *e_itr;
160 LineSegment t(e->source()->point(), e->target()->point());
161
162 if (t.direction() == ref) {
163 return LCGEdge(e->source()->data() - 1, e->target()->data() - 1, flag);
164 } else {
165 return LCGEdge(e->target()->data() - 1, e->source()->data() - 1, flag);
166 }
167 };
168 auto itr = arr.curves_begin();
169 for (unsigned int i = 0; i < segments.size(); ++i, ++itr) {
170 LineSegment s(itr->source(), itr->target());
171 for (auto e_itr = arr.induced_edges_begin(itr); e_itr != arr.induced_edges_end(itr);
172 ++e_itr) {
173 edge_list.push_back(f_make_edge(e_itr, s.direction(), i));
174 }
175 }
176
177 for (unsigned int i = 0; i < lines.size(); ++i, ++itr) {
178 OGDF_ASSERT(itr != arr.curves_end());
179 for (auto e_itr = arr.induced_edges_begin(itr); e_itr != arr.induced_edges_end(itr);
180 ++e_itr) {
181 auto e = *e_itr;
182 if (e->source()->data() > 0 && e->target()->data() > 0) {
183 edge_list.push_back(LCGEdge(e->source()->data() - 1, e->target()->data() - 1, i));
184 }
185 }
186 }
187 }
188
196 void process(std::vector<LineSegment>& segments, std::vector<Point>& node_to_point,
197 std::vector<LCGEdge>& edge_list, unsigned int separator = 0) {
198 std::vector<Line> r;
200 }
201};
202
203}
204}
205}
206}
207
208#endif
NodeElement * node
The type of nodes.
Definition Graph_d.h:64
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
int r[]
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
Direction
Definition basic.h:134