33 #ifdef OGDF_INCLUDE_CGAL
41 # include <boost/graph/breadth_first_search.hpp>
42 # include <boost/graph/visitors.hpp>
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>
61 template<
typename kernel>
62 class CGALPlanarSubdivision {
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>;
72 using LinearTraits = CGAL::Arr_linear_traits_2<kernel>;
74 using Dcel = CGAL::Arr_extended_dcel<Traits, unsigned int, unsigned int, unsigned int>;
75 using ArrWH = CGAL::Arrangement_with_history_2<Traits, Dcel>;
77 using Arr = CGAL::Arrangement_2<Traits>;
78 using LinearArr = CGAL::Arrangement_2<LinearTraits>;
80 using DualArr = CGAL::Dual<Arr>;
81 using Face_index_map = CGAL::Arr_face_index_map<Arr>;
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);
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;
91 const Vertex_const_handle* v;
92 const Halfedge_const_handle* e;
93 const Face_const_handle* f;
96 if ((f = boost::get<Face_const_handle>(&obj))) {
98 auto c = (*f)->outer_ccb();
100 poly.push_back(c->source()->point());
101 }
while (++c != (*f)->outer_ccb());
102 }
else if ((e = boost::get<Halfedge_const_handle>(&obj))) {
104 poly.push_back((*e)->source()->point());
105 poly.push_back((*e)->target()->point());
106 }
else if ((v = boost::get<Vertex_const_handle>(&obj))) {
107 poly.push_back((*v)->point());
117 using LCGEdge = std::tuple<unsigned int, unsigned int, unsigned int>;
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);
126 Polygon extract_face(
const std::vector<LineSegment>& segments,
const Point& q) {
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);
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) {
144 separator = segments.size();
146 CGAL::insert(arr, segments.begin(), segments.begin() + separator);
147 CGAL::insert(arr, lines.begin(), lines.end());
149 CGAL::insert(arr, segments.begin() + separator, segments.end());
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());
157 auto f_make_edge = [&](decltype(arr.induced_edges_begin(arr.curves_begin()))& e_itr,
158 const Direction& ref,
unsigned int flag) {
160 LineSegment t(e->source()->point(), e->target()->point());
162 if (t.direction() == ref) {
163 return LCGEdge(e->source()->data() - 1, e->target()->data() - 1, flag);
165 return LCGEdge(e->target()->data() - 1, e->source()->data() - 1, flag);
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);
173 edge_list.push_back(f_make_edge(e_itr, s.direction(), i));
177 for (
unsigned int i = 0; i < lines.size(); ++i, ++itr) {
179 for (
auto e_itr = arr.induced_edges_begin(itr); e_itr != arr.induced_edges_end(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));
196 void process(std::vector<LineSegment>& segments, std::vector<Point>& node_to_point,
197 std::vector<LCGEdge>& edge_list,
unsigned int separator = 0) {
199 process(segments,
r, node_to_point, edge_list, separator);