33 #ifdef OGDF_INCLUDE_CGAL
49 template<
typename Kernel,
bool parallel = false>
50 class BloatedDualGraph {
52 using Segment = geometry::LineSegment_t<Kernel>;
53 using Point = geometry::Point_t<Kernel>;
55 unsigned int m_number_of_nodes = 0;
57 std::vector<omp_lock_t> locks;
61 struct LocalIntersection {
62 unsigned int left_intersection_ids[2] = {(
unsigned int)-1, (
unsigned int)-1};
63 unsigned int right_intersection_ids[2] = {(
unsigned int)-1, (
unsigned int)-1};
64 bool is_end_point =
false;
66 inline bool left_is_valid()
const {
return left_intersection_ids[0] != (
unsigned int)-1; }
68 inline bool right_is_valid()
const {
return right_intersection_ids[0] != (
unsigned int)-1; }
70 unsigned int intersection_id()
const {
71 if (left_is_valid()) {
72 return left_intersection_ids[0];
74 return right_intersection_ids[0];
79 using Node =
unsigned int;
80 using Edge =
unsigned int;
82 std::vector<Segment> segments;
83 std::vector<geometry::Intersection> intersecting_segments;
84 std::vector<Point> intersections;
86 std::vector<unsigned int> segm_to_node_range;
87 std::vector<Node> edges;
88 std::vector<unsigned int> node_to_segment;
89 std::vector<std::vector<LocalIntersection>> segment_to_intersections;
92 m_number_of_nodes = 0;
94 intersecting_segments.clear();
95 intersections.clear();
96 segm_to_node_range.clear();
98 node_to_segment.clear();
99 segment_to_intersections.clear();
103 BloatedDualGraph() { }
105 unsigned int number_of_nodes()
const {
return m_number_of_nodes; }
107 unsigned int degree(
const Node v)
const {
108 if (edges[3 * v + 2] != v) {
110 }
else if (edges[3 * v + 1] != v) {
112 }
else if (edges[3 * v] != v) {
119 Node add_node(
unsigned int segment_id) {
120 edges.push_back(m_number_of_nodes);
121 edges.push_back(m_number_of_nodes);
122 edges.push_back(m_number_of_nodes);
124 node_to_segment.push_back(segment_id);
127 locks.push_back(omp_lock_t());
130 return m_number_of_nodes++;
133 void add_edge(
const Node u,
const Node v,
bool face_edge) {
137 auto add_edge = [&](
Node _u,
Node _v) {
139 omp_set_lock(&locks[_u]);
142 unsigned int i = _u * 3;
144 if (edges[i] != _v && edges[i + 1] != _v && edges[i + 2] != _v) {
147 unsigned int off = 0;
150 if (edges[i + 1] != _u) {
158 omp_unset_lock(&locks[_u]);
166 bool is_left(
const Node v)
const {
171 bool is_right(
const Node v)
const {
176 Point get_intersection_point(
const LocalIntersection& li)
const {
177 unsigned int intersection_id = -1;
178 if (li.left_is_valid()) {
179 intersection_id = li.left_intersection_ids[0];
181 intersection_id = li.right_intersection_ids[1];
183 return intersections[intersection_id];
186 unsigned int get_first_id(
const unsigned int segment,
const unsigned int intersection_id)
const {
187 OGDF_ASSERT(intersection_id < intersecting_segments.size());
189 const geometry::Intersection& is = intersecting_segments[intersection_id];
191 unsigned int pos = 2 * (is.pos(segment) - 1);
192 OGDF_ASSERT(segment < segment_to_intersections.size());
193 OGDF_ASSERT(segm_to_node_range[segment] + pos < segm_to_node_range[segment + 1]);
194 return segm_to_node_range[segment] + pos;
197 unsigned int get_second_id(
const unsigned int segment,
const unsigned int intersection_id)
const {
198 OGDF_ASSERT(intersection_id < intersecting_segments.size());
200 const geometry::Intersection& is = intersecting_segments[intersection_id];
203 unsigned int pos = 2 * is.pos(segment);
205 OGDF_ASSERT(segment < segment_to_intersections.size());
206 OGDF_ASSERT(segm_to_node_range[segment] + pos < segm_to_node_range[segment + 1]);
208 return segm_to_node_range[segment] + pos;
211 unsigned int get_first_id(
const unsigned int segment,
const LocalIntersection& li)
const {
212 if (li.left_is_valid()) {
213 return get_first_id(segment, li.left_intersection_ids[0]);
215 return get_first_id(segment, li.right_intersection_ids[0]);
219 unsigned int get_second_id(
const unsigned int segment,
const LocalIntersection& li)
const {
220 if (li.left_is_valid()) {
221 return get_second_id(segment, li.left_intersection_ids[0]);
223 return get_second_id(segment, li.right_intersection_ids[0]);
227 Node first_left(
const unsigned int segment,
const unsigned int intersection_id)
const {
228 OGDF_ASSERT(get_first_id(segment, intersection_id) < number_of_nodes());
229 return get_first_id(segment, intersection_id);
232 Node first_right(
const unsigned int segment,
const unsigned int intersection_id)
const {
233 OGDF_ASSERT(get_first_id(segment, intersection_id) + 1 < number_of_nodes());
234 return get_first_id(segment, intersection_id) + 1;
237 Node second_left(
const unsigned int segment,
const unsigned int intersection_id)
const {
238 OGDF_ASSERT(get_second_id(segment, intersection_id) < number_of_nodes());
239 return get_second_id(segment, intersection_id);
242 Node second_right(
const unsigned int segment,
const unsigned int intersection_id)
const {
243 OGDF_ASSERT(get_second_id(segment, intersection_id) + 1 < number_of_nodes());
244 return get_second_id(segment, intersection_id) + 1;
247 Node first_left(
const unsigned int segment,
const LocalIntersection& li)
const {
248 OGDF_ASSERT(get_first_id(segment, li) < number_of_nodes());
249 return get_first_id(segment, li);
252 Node first_right(
const unsigned int segment,
const LocalIntersection& li)
const {
253 OGDF_ASSERT(get_first_id(segment, li) + 1 < number_of_nodes());
254 return get_first_id(segment, li) + 1;
257 Node second_left(
const unsigned int segment,
const LocalIntersection& li)
const {
258 OGDF_ASSERT(get_second_id(segment, li) < number_of_nodes());
259 return get_second_id(segment, li);
262 Node second_right(
const unsigned int segment,
const LocalIntersection& li)
const {
263 OGDF_ASSERT(get_second_id(segment, li) + 1 < number_of_nodes());
264 return get_second_id(segment, li) + 1;
267 bool is_face_edge(
const Edge e)
const {