-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Gps_agg_op_visitor.h
242 lines (201 loc) · 8.59 KB
/
Gps_agg_op_visitor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// Copyright (c) 2005 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Baruch Zukerman <baruchzu@post.tau.ac.il>
// Ron Wein <wein@post.tau.ac.il>
#ifndef CGAL_BSO_2_GSP_AGG_OP_VISITOR_H
#define CGAL_BSO_2_GSP_AGG_OP_VISITOR_H
#include <CGAL/license/Boolean_set_operations_2.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h>
#include <CGAL/Arr_tags.h>
#include <CGAL/Arr_topology_traits/Arr_bounded_planar_construction_helper.h>
#include <CGAL/Arr_topology_traits/Arr_unb_planar_construction_helper.h>
#include <CGAL/Default.h>
namespace CGAL {
template <typename Helper_, typename Arrangement_, typename Visitor_ = Default>
class Gps_agg_op_base_visitor :
public Arr_construction_ss_visitor<
Helper_,
typename Default::Get<Visitor_, Gps_agg_op_base_visitor<Helper_,
Arrangement_,
Visitor_> >::type>
{
public:
typedef Helper_ Helper;
typedef Arrangement_ Arrangement_2;
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
typedef typename Helper::Event Event;
typedef typename Helper::Subcurve Subcurve;
private:
typedef Geometry_traits_2 Gt2;
typedef Arrangement_2 Arr;
typedef Gps_agg_op_base_visitor<Helper, Arr, Visitor_>
Self;
typedef typename Default::Get<Visitor_, Self>::type Visitor;
typedef Arr_construction_ss_visitor<Helper, Visitor> Base;
public:
typedef typename Arr::Halfedge_handle Halfedge_handle;
typedef typename Arr::Vertex_handle Vertex_handle;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Gt2::Point_2 Point_2;
typedef Unique_hash_map<Halfedge_handle, unsigned int>
Edges_hash;
protected:
Edges_hash* m_edges_hash; // maps halfedges to their BC (coundary counter)
public:
Gps_agg_op_base_visitor(Arr* arr, Edges_hash* hash) :
Base(arr),
m_edges_hash(hash)
{}
// TODO (IMPORTANT): unbounded helper might be not fully supported
// TODO add mpl-warning
virtual Halfedge_handle insert_in_face_interior(const X_monotone_curve_2& cv,
Subcurve* sc)
{
Halfedge_handle he = Base::insert_in_face_interior(cv, sc);
insert_edge_to_hash(he, cv);
return he;
}
virtual Halfedge_handle insert_at_vertices(const X_monotone_curve_2& cv,
Halfedge_handle hhandle,
Halfedge_handle prev,
Subcurve* sc,
bool& new_face_created)
{
Halfedge_handle res_he =
Base::insert_at_vertices(cv, hhandle, prev, sc, new_face_created);
insert_edge_to_hash(res_he, cv);
return res_he;
}
virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv,
Halfedge_handle he,
Subcurve* sc)
{
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc);
insert_edge_to_hash(res_he, cv);
return res_he;
}
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
Halfedge_handle he,
Subcurve* sc)
{
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
insert_edge_to_hash(res_he, cv);
return res_he;
}
private:
void insert_edge_to_hash(Halfedge_handle he, const X_monotone_curve_2& cv)
{
const Comparison_result he_dir =
((Arr_halfedge_direction)he->direction() == ARR_LEFT_TO_RIGHT) ?
SMALLER : LARGER;
const Comparison_result cv_dir =
this->m_arr_access.arrangement().geometry_traits()->
compare_endpoints_xy_2_object()(cv);
if (he_dir == cv_dir) {
(*m_edges_hash)[he] = cv.data().bc();
(*m_edges_hash)[he->twin()] = cv.data().twin_bc();
}
else {
(*m_edges_hash)[he] = cv.data().twin_bc();
(*m_edges_hash)[he->twin()] = cv.data().bc();
}
}
};
template <typename Helper_, typename Arrangement_, typename Visitor_ = Default>
class Gps_agg_op_visitor :
public Gps_agg_op_base_visitor<Helper_, Arrangement_,
Gps_agg_op_visitor<Helper_, Arrangement_,
Visitor_> >
{
public:
typedef Helper_ Helper;
typedef Arrangement_ Arrangement_2;
typedef typename Helper::Geometry_traits_2 Geometry_traits_2;
typedef typename Helper::Event Event;
typedef typename Helper::Subcurve Subcurve;
private:
typedef Geometry_traits_2 Gt2;
typedef Arrangement_2 Arr;
typedef Gps_agg_op_visitor<Helper, Arr, Visitor_> Self;
typedef typename Default::Get<Visitor_, Self>::type Visitor;
typedef Gps_agg_op_base_visitor<Helper, Arr, Visitor> Base;
public:
typedef typename Base::Halfedge_handle Halfedge_handle;
typedef typename Base::Vertex_handle Vertex_handle;
typedef typename Gt2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Gt2::Point_2 Point_2;
protected:
unsigned int m_event_count; // The number of events so far.
std::vector<Vertex_handle>* m_vertices_vec; // The vertices, sorted in
// ascending order.
public:
Gps_agg_op_visitor(Arr* arr, typename Base::Edges_hash* hash,
std::vector<Vertex_handle>* vertices_vec) :
Base(arr, hash),
m_event_count(0),
m_vertices_vec(vertices_vec)
{}
void before_handle_event(Event* event)
{
event->set_index(m_event_count);
m_event_count++;
}
virtual Halfedge_handle
insert_in_face_interior(const X_monotone_curve_2& cv, Subcurve* sc)
{
Halfedge_handle res_he = Base::insert_in_face_interior(cv, sc);
// We now have a halfedge whose source vertex is associated with the
// last event and whose target vertex is associated with the current event:
Event* curr_event = this->current_event();
Event* last_event = (sc)->last_event();
CGAL_assertion((Arr_halfedge_direction)res_he->direction() ==
ARR_LEFT_TO_RIGHT);
_insert_vertex(curr_event, res_he->target());
_insert_vertex(last_event, res_he->source());
return res_he;
}
virtual Halfedge_handle insert_from_right_vertex(const X_monotone_curve_2& cv,
Halfedge_handle he,
Subcurve* sc)
{
Halfedge_handle res_he = Base::insert_from_right_vertex(cv, he, sc);
// We now have a halfedge whose target vertex is associated with the
// last event (we have already dealt with its source vertex).
Event* last_event = (sc)->last_event();
CGAL_assertion((Arr_halfedge_direction)res_he->direction() ==
ARR_RIGHT_TO_LEFT);
_insert_vertex(last_event, res_he->target());
return res_he;
}
virtual Halfedge_handle insert_from_left_vertex(const X_monotone_curve_2& cv,
Halfedge_handle he,
Subcurve* sc)
{
Halfedge_handle res_he = Base::insert_from_left_vertex(cv, he, sc);
// We now have a halfedge whose target vertex is associated with the
// current event(we have already dealt with its source vertex).
Event* curr_event = this->current_event();
CGAL_assertion((Arr_halfedge_direction)res_he->direction() ==
ARR_LEFT_TO_RIGHT);
_insert_vertex (curr_event, res_he->target());
return res_he;
}
private:
void _insert_vertex(const Event* event, Vertex_handle v)
{
const unsigned int index = event->index();
if (index >= m_vertices_vec->size()) m_vertices_vec->resize(2 * (index + 1));
(*m_vertices_vec)[index] = v;
}
};
} // namespace CGAL
#endif