1 // Copyright (c) 1997-2000  Max-Planck-Institute Saarbruecken (Germany).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Nef_2/include/CGAL/Nef_2/PM_decorator.h $
7 // $Id: PM_decorator.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
12 
13 #ifndef CGAL_PM_DECORATOR_H
14 #define CGAL_PM_DECORATOR_H
15 
16 #include <CGAL/license/Nef_2.h>
17 
18 #include <CGAL/Nef_2/PM_const_decorator.h>
19 #ifdef CGAL_I_DO_WANT_TO_USE_GENINFO
20 #include <CGAL/Nef_2/geninfo.h>
21 #else
22 #include <boost/any.hpp>
23 #endif
24 #include <CGAL/Unique_hash_map.h>
25 #include <vector>
26 
27 namespace CGAL {
28 
29 /*{\Moptions outfile=PMDecorator.man }*/
30 /*{\Msubst
31 PM_decorator#PMDecorator
32 PM_const_decorator#PMConstDecorator
33 }*/
34 /*{\Manpage {PMDecorator}{}{Plane map manipulation}{D}}*/
35 
36 template <typename HDS>
37 class PM_decorator : public PM_const_decorator<HDS>
38 {
39 /*{\Mdefinition An instance |\Mvar| of the data type |\Mname| is a
40 decorator to examine and modify a plane map. |\Mvar| inherits from
41 |PM_const_decorator| but provides additional manipulation operations.}*/
42 
43 /*{\Mgeneralization PM_const_decorator}*/
44 
45 public:
46 /*{\Mtypes 3}*/
47   typedef PM_decorator<HDS>        Self;
48   typedef PM_const_decorator<HDS>  Base;
49   typedef HDS                       Plane_map;
50   typedef typename HDS::Vertex_base Vertex_base;
51   typedef typename HDS::Halfedge_base Halfedge_base;
52   typedef typename HDS::Face_base Face_base;
53   typedef typename HDS::Vertex Vertex;
54   typedef typename HDS::Halfedge Halfedge;
55   typedef typename HDS::Face Face;
56   typedef typename HDS::Vertex_handle Vertex_handle;
57   typedef typename HDS::Vertex_iterator Vertex_iterator;
58   typedef typename HDS::Halfedge_handle Halfedge_handle;
59   typedef typename HDS::Halfedge_iterator Halfedge_iterator;
60   typedef typename HDS::Face_handle Face_handle;
61   typedef typename HDS::Face_iterator Face_iterator;
62   typedef typename HDS::Vertex_const_handle Vertex_const_handle;
63   typedef typename HDS::Halfedge_const_handle Halfedge_const_handle;
64   typedef typename HDS::Face_const_handle Face_const_handle;
65   typedef typename HDS::Vertex_const_iterator Vertex_const_iterator;
66   typedef typename HDS::Halfedge_const_iterator Halfedge_const_iterator;
67   typedef typename HDS::Face_const_iterator Face_const_iterator;
68   typedef typename Base::Hole_const_iterator Hole_const_iterator ;
69   typedef typename Base::Isolated_vertex_const_iterator Isolated_vertex_const_iterator;
70   typedef typename Base::Point_const_iterator Point_const_iterator;
71   typedef typename Base::Mark Mark;
72 typedef typename Base::Point Point;
73 typedef typename Base::GenPtr GenPtr;
74 
75 /*{\Mtext Local types are handles, iterators and circulators of the following
76 kind: |Vertex_handle|, |Vertex_iterator|, |Halfedge_handle|,
77 |Halfedge_iterator|, |Face_handle|, |Face_iterator|.  Additionally the
78 following circulators are defined. The |circulators| can be constructed from
79 the corresponding halfedge handles or iterators.}*/
80 
81 typedef CircFromIt<
82         Halfedge_iterator,
83         move_halfedge_around_vertex<Halfedge_iterator> >
84         Halfedge_around_vertex_circulator;
85 /*{\Mtypemember circulating the outgoing halfedges in $A(v)$.}*/
86 
87 typedef CircFromIt<
88         Halfedge_iterator,
89         move_halfedge_around_face<Halfedge_iterator> >
90         Halfedge_around_face_circulator;
91 /*{\Mtypemember circulating the halfedges in the face cycle of a
92 face |f|.}*/
93 
94 typedef typename Face::Hole_iterator Hole_iterator;
95 /*{\Mtypemember iterating all holes of a face |f|. The type is
96 convertible to |Halfedge_handle|.}*/
97 
98 typedef typename Face::Isolated_vertex_iterator Isolated_vertex_iterator;
99 /*{\Mtypemember iterating all isolated vertices of a face |f|.
100 The type generalizes |Vertex_handle|.}*/
101 
102 
103 /* note: originally I had the mhavs, mhafs hardwired to Halfedge
104    in this class scope. egcs 290.60 reacted with an internal compiler
105    error; this recursive instatiation scheme works however!
106    what a shitty world */
107 
108 enum { BEFORE = -1, AFTER = 1 };
109 /*{\Menum insertion order labels.}*/
110 
111 
112 
113 
114   using Base::phds;
115 
116 /*{\Mcreation 3}*/
117 
PM_decorator()118 PM_decorator() : Base() {}
PM_decorator(const PM_decorator & D)119 PM_decorator(const PM_decorator& D) :
120   Base((PM_const_decorator<HDS>)D) {}
121 PM_decorator& operator=(const PM_decorator& D)
122 { Base::phds = ((PM_const_decorator<HDS>)D).phds; return *this; }
123 
PM_decorator(Plane_map & p)124 PM_decorator(Plane_map& p) : Base(p) {}
125 /*{\Mcreate constructs a decorator working on |P|.}*/
126 
127 #define BASE(t) { return Base::t; }
holes_begin(Face_const_handle f)128 Hole_const_iterator  holes_begin(Face_const_handle f) const
129 BASE(holes_begin(f))
130 Hole_const_iterator  holes_end(Face_const_handle f) const
131 BASE(holes_end(f))
132 Isolated_vertex_const_iterator
133 isolated_vertices_begin(Face_const_handle f) const
134 BASE(isolated_vertices_begin(f))
135 Isolated_vertex_const_iterator
136 isolated_vertices_end(Face_const_handle f) const
137 BASE(isolated_vertices_end(f))
138 Vertex_const_handle source(Halfedge_const_handle e) const
139 BASE(source(e))
140 Vertex_const_handle target(Halfedge_const_handle e) const
141 BASE(target(e))
142 Halfedge_const_handle twin(Halfedge_const_handle e) const
143 BASE(twin(e))
144 bool is_isolated(Vertex_const_handle v) const
145 BASE(is_isolated(v))
146 Halfedge_const_handle first_out_edge(Vertex_const_handle v) const
147 BASE(first_out_edge(v))
148 Halfedge_const_handle last_out_edge(Vertex_const_handle v) const
149 BASE(last_out_edge(v))
150 Halfedge_const_handle cyclic_adj_succ(
151   Halfedge_const_handle e) const
152 BASE(cyclic_adj_succ(e))
153 Halfedge_const_handle cyclic_adj_pred(
154   Halfedge_const_handle e) const
155 BASE(cyclic_adj_pred(e))
156 Halfedge_const_handle next(Halfedge_const_handle e) const
157 BASE(next(e))
158 Halfedge_const_handle previous(Halfedge_const_handle e) const
159 BASE(previous(e))
160 Face_const_handle face(Halfedge_const_handle e) const
161 BASE(face(e))
162 Face_const_handle face(Vertex_const_handle v) const
163 BASE(face(v))
164 const Mark& mark(Vertex_const_handle v) const
165 BASE(mark(v))
166 const Mark& mark(Halfedge_const_handle e) const
167 BASE(mark(e))
168 const Mark& mark(Face_const_handle f) const
169 BASE(mark(f))
170 const Point& point(Vertex_const_handle v) const
171 BASE(point(v))
172 const GenPtr& info(Vertex_const_handle v) const
173 BASE(info(v))
174 const GenPtr& info(Halfedge_const_handle e) const
175 BASE(info(e))
176 const GenPtr& info(Face_const_handle f) const
177 BASE(info(f))
178 #undef BASE
179 
180 /*{\Moperations 3 3}*/
181 
182 Plane_map& plane_map() const
183 /*{\Mop returns the plane map decorated.}*/
184 { return *Base::phds; }
185 
clear()186 void clear() const
187 /*{\Mop reinitializes |P| to the empty map.}*/
188 { this->phds->clear(); }
189 
source(Halfedge_handle e)190 Vertex_handle source(Halfedge_handle e) const
191 /*{\Mop returns the source of |e|.}*/
192 { return e->opposite()->vertex(); }
193 
target(Halfedge_handle e)194 Vertex_handle target(Halfedge_handle e) const
195 /*{\Mop returns the target of |e|.}*/
196 { return e->vertex(); }
197 
twin(Halfedge_handle e)198 Halfedge_handle twin(Halfedge_handle e) const
199 /*{\Mop returns the twin of |e|.}*/
200 { return e->opposite(); }
201 
is_isolated(Vertex_handle v)202 bool is_isolated(Vertex_handle v) const
203 /*{\Mop returns |true| iff |v| is linked to the interior of a face.
204 This is equivalent to the condition that $A(v) = \emptyset$.}*/
205 { return v->is_isolated(); }
206 
is_closed_at_source(Halfedge_handle e)207 bool is_closed_at_source(Halfedge_handle e) const
208 /*{\Mop returns |true| when |prev(e) == twin(e)|.}*/
209 { return e->prev() == e->opposite(); }
210 
first_out_edge(Vertex_handle v)211 Halfedge_handle first_out_edge(Vertex_handle v) const
212 /*{\Mop returns a halfedge with source |v|. It's the starting point for
213   the circular iteration over the halfedges with source |v|.
214   \precond |!is_isolated(v)|.}*/
215 { return v->halfedge()->opposite(); }
216 
last_out_edge(Vertex_handle v)217 Halfedge_handle last_out_edge(Vertex_handle v) const
218 /*{\Mop returns a the halfedge with source |v| that is the last
219   in the circular iteration before encountering |first_out_edge(v)|
220   again. \precond |!is_isolated(v)|.}*/
221 { return v->halfedge()->next(); }
222 
cas(Halfedge_handle e)223 Halfedge_handle cas(Halfedge_handle e) const
224 { return e->prev()->opposite(); }
225 
cap(Halfedge_handle e)226 Halfedge_handle cap(Halfedge_handle e) const
227 { return e->opposite()->next(); }
228 
cyclic_adj_succ(Halfedge_handle e)229 Halfedge_handle cyclic_adj_succ(Halfedge_handle e) const
230 { return cas(e); }
231 /*{\Mop returns the edge after |e| in the cyclic ordered adjacency list of
232   |source(e)|.}*/
233 
cyclic_adj_pred(Halfedge_handle e)234 Halfedge_handle cyclic_adj_pred(Halfedge_handle e) const
235 { return cap(e); }
236 /*{\Mop returns the edge before |e| in the cyclic ordered adjacency list of
237   |source(e)|.}*/
238 
adj_succ_at_source(Halfedge_handle e)239 Halfedge_handle adj_succ_at_source(Halfedge_handle e) const
240 { if (e==last_out_edge(source(e))) return Halfedge_handle();
241   return cas(e); }
242 // the edge of source(e) is the first in the adj list
243 
adj_pred_at_source(Halfedge_handle e)244 Halfedge_handle adj_pred_at_source(Halfedge_handle e) const
245 { if (e==first_out_edge(source(e))) return Halfedge_handle();
246   return cap(e); }
247 // the edge of source(e) is the first in the adj list
248 
next(Halfedge_handle e)249 Halfedge_handle next(Halfedge_handle e) const
250 /*{\Mop returns the next edge in the face cycle containing |e|.}*/
251 { return e->next(); }
252 
previous(Halfedge_handle e)253 Halfedge_handle previous(Halfedge_handle e) const
254 /*{\Mop returns the previous edge in the face cycle containing |e|.}*/
255 { return e->prev(); }
256 
face(Halfedge_handle e)257 Face_handle face(Halfedge_handle e) const
258 /*{\Mop returns the face incident to |e|.}*/
259 { return e->face(); }
260 
face(Vertex_handle v)261 Face_handle face(Vertex_handle v) const
262 /*{\Mop returns the face incident to |v|.
263    \precond |is_isolated(v)|.}*/
264 { return v->face(); }
265 
halfedge(Face_handle f)266 Halfedge_handle halfedge(Face_handle f) const
267 /*{\Mop returns a halfedge in the bounding face cycle of |f|
268 (|Halfedge_handle()| if there is no bounding face cycle).}*/
269 { return f->halfedge(); }
270 
vertices_begin()271 Vertex_iterator   vertices_begin() const
272 { return this->phds->vertices_begin(); }
halfedges_begin()273 Halfedge_iterator halfedges_begin() const
274 { return this->phds->halfedges_begin(); }
faces_begin()275 Face_iterator     faces_begin() const
276 { return this->phds->faces_begin(); }
vertices_end()277 Vertex_iterator   vertices_end() const
278 { return this->phds->vertices_end(); }
halfedges_end()279 Halfedge_iterator halfedges_end() const
280 { return this->phds->halfedges_end(); }
faces_end()281 Face_iterator     faces_end() const
282 { return this->phds->faces_end(); }
283 
284 /*{\Mtext \headerline{Iteration} \setopdims{6.5cm}{0cm}}*/
285 
286 Halfedge_around_vertex_circulator
out_edges(Vertex_handle v)287   out_edges(Vertex_handle v) const
288 /*{\Mop returns a circulator for the cyclic adjacency list of |v|.}*/
289 { return Halfedge_around_vertex_circulator(first_out_edge(v)); }
290 
291 Halfedge_around_face_circulator
face_cycle(Face_handle f)292   face_cycle(Face_handle f) const
293 /*{\Mop returns a circulator for the outer face cycle of |f|.}*/
294 { return Halfedge_around_face_circulator(f->halfedge()); }
295 
holes_begin(Face_handle f)296 Hole_iterator  holes_begin(Face_handle f) const
297 /*{\Mop returns an iterator for all holes in the interior of |f|.
298    A |Hole_iterator| can be assigned to a
299    |Halfedge_around_face_circulator|.}*/
300 { return f->fc_begin(); }
301 
holes_end(Face_handle f)302 Hole_iterator  holes_end(Face_handle f) const
303 /*{\Mop returns the past-the-end iterator of |f|.}*/
304 { return f->fc_end(); }
305 
isolated_vertices_begin(Face_handle f)306 Isolated_vertex_iterator isolated_vertices_begin(Face_handle f) const
307 /*{\Mop returns an iterator for all isolated vertices in the interior
308 of |f|.}*/
309 { return f->iv_begin(); }
310 
isolated_vertices_end(Face_handle f)311 Isolated_vertex_iterator isolated_vertices_end(Face_handle f) const
312 /*{\Mop returns the past the end iterator of |f|.}*/
313 { return f->iv_end(); }
314 
315 /*{\Mtext \headerline{Update Operations} \restoreopdims}*/
316 
317 Vertex_handle new_vertex(const Vertex_base& vb = Vertex_base()) const
318 /*{\Mop creates a new vertex.}*/
319 { Vertex_handle v = this->phds->vertices_push_back(vb);
320   v->set_halfedge(Halfedge_handle());
321   return v;
322 }
323 
324 Face_handle new_face(const Face_base& fb = Face_base()) const
325 /*{\Mop creates a new face.}*/
326 { Face_handle f = this->phds->faces_push_back(fb);
327   return f;
328 }
329 
330 
link_as_outer_face_cycle(Face_handle f,Halfedge_handle e)331 void link_as_outer_face_cycle(Face_handle f, Halfedge_handle e) const
332 /*{\Mop makes |e| the entry point of the outer face cycle of |f| and
333 makes |f| the face of all halfedges in the face cycle of |e|.}*/
334 {
335   Halfedge_around_face_circulator hfc(e), hend(hfc);
336   CGAL_For_all(hfc,hend) hfc->set_face(f);
337   f->set_halfedge(e);
338 }
339 
link_as_hole(Face_handle f,Halfedge_handle e)340 void link_as_hole(Face_handle f, Halfedge_handle e) const
341 /*{\Mop makes |e| the entry point of a hole face cycle of |f| and
342     makes |f| the face of all halfedges in the face cycle of |e|.}*/
343 {
344   Halfedge_around_face_circulator hfc(e), hend(hfc);
345   CGAL_For_all(hfc,hend) hfc->set_face(f);
346   f->store_fc(e);
347 }
348 
link_as_isolated_vertex(Face_handle f,Vertex_handle v)349 void link_as_isolated_vertex(Face_handle f, Vertex_handle v) const
350 /*{\Mop makes |v| an isolated vertex within |f|.}*/
351 {  f->store_iv(v); v->set_face(f); }
352 
clear_face_cycle_entries(Face_handle f)353 void clear_face_cycle_entries(Face_handle f) const
354 /*{\Mop removes all isolated vertices and halfedges that
355 are entrie points into face cycles from the lists of |f|.}*/
356 { f->clear_all_entries(); }
357 
358 
359 Halfedge_handle new_halfedge_pair(Vertex_handle v1, Vertex_handle v2,
360                                   Halfedge_base hb = Halfedge_base()) const
361 /*{\Mop creates a new pair of edges |(e1,e2)| representing |(v1,v2)|
362   by appending the |ei| to |A(vi)| $(i=1,2)$.}*/
363 { Halfedge_handle e1 = this->phds->edges_push_back(hb,hb);
364   Halfedge_handle e2 = e1->opposite();
365   e1->set_face(Face_handle()); e2->set_face(Face_handle());
366   if ( ! is_isolated(v1) )
367     set_adjacency_at_source_between(cap(first_out_edge(v1)),e1,
368                                     first_out_edge(v1));
369   else
370     close_tip_at_source(e1,v1);
371   if ( ! is_isolated(v2) )
372     set_adjacency_at_source_between(cap(first_out_edge(v2)),e2,
373                                     first_out_edge(v2));
374   else
375     close_tip_at_source(e2,v2);
376   return e1;
377 }
378 
379 
380 Halfedge_handle new_halfedge_pair(Halfedge_handle e1,
381                                   Halfedge_handle e2,
382                                   Halfedge_base hb = Halfedge_base(),
383                                   int pos1 = AFTER, int pos2 = AFTER) const
384 /*{\Mop creates a new pair of edges |(h1,h2)| representing
385   |(source(e1),source(e2))| by inserting the |hi| before or after |ei|
386   into the cyclic adjacency list of |source(ei)| depending on
387   |posi| $(i=1,2)$ from |\Mname::BEFORE, \Mname::AFTER|.}*/
388 {
389   Halfedge_handle er = this->phds->edges_push_back(hb,hb);
390   Halfedge_handle ero = er->opposite();
391   er->set_face(Face_handle()); ero->set_face(Face_handle());
392   if (pos1 < 0) { // before e1
393     set_adjacency_at_source_between(cap(e1),er,e1);
394     if ( e1 == first_out_edge(source(e1)) )
395       make_first_out_edge(er); // added 22/8/00
396   } else { // after e1
397     set_adjacency_at_source_between(e1,er,cas(e1));
398   }
399   if (pos2 < 0) { // before e2
400     set_adjacency_at_source_between(cap(e2),ero,e2);
401     if ( e2 == first_out_edge(source(e2)) )
402       make_first_out_edge(ero);
403   } else { // after e2
404     set_adjacency_at_source_between(e2,ero,cas(e2));
405   }
406   return er;
407 }
408 
409 Halfedge_handle new_halfedge_pair(Halfedge_handle e, Vertex_handle v,
410                                   Halfedge_base hb = Halfedge_base(),
411                                   int pos = AFTER) const
412 /*{\Mop creates a new pair of edges  |(e1,e2)| representing |(source(e),v)|
413   by inserting |e1| before or after |e| into the cyclic adjacency list of
414   |source(e)| depending on |pos| from |\Mname::BEFORE, \Mname::AFTER|
415   and appending |e2| to |A(v)|.}*/
416 {
417   Halfedge_handle e_new = this->phds->edges_push_back(hb,hb);
418   Halfedge_handle e_opp = e_new->opposite();
419   e_new->set_face(Face_handle()); e_opp->set_face(Face_handle());
420 
421   if (pos < 0) { // before e
422     set_adjacency_at_source_between(cap(e),e_new,e);
423     if ( e == first_out_edge(source(e)) )
424       make_first_out_edge(e_new);
425   } else  // after e
426     set_adjacency_at_source_between(e,e_new,cas(e));
427 
428   if ( ! is_isolated(v) ) {
429     Halfedge_handle e_first = first_out_edge(v);
430     set_adjacency_at_source_between(cap(e_first),e_opp,e_first);
431   } else
432     close_tip_at_source(e_opp,v);
433 
434   return e_new;
435 }
436 
437 
438 Halfedge_handle new_halfedge_pair(Vertex_handle v, Halfedge_handle e,
439                                   Halfedge_base hb = Halfedge_base(),
440                                   int pos = AFTER) const
441 /*{\Mop symmetric to the previous one.}*/
442 { return new_halfedge_pair(e,v,hb,pos)->opposite(); }
443 
444 
445 
446 
delete_halfedge_pair(Halfedge_handle e)447 void delete_halfedge_pair(Halfedge_handle e) const
448 /*{\Mop deletes |e| and its twin and updates the adjacency at its source
449         and its target.}*/
450 { remove_from_adj_list_at_source(e);
451   remove_from_adj_list_at_source(e->opposite());
452   this->phds->edges_erase(e);
453 }
454 
delete_vertex(Vertex_handle v)455 void delete_vertex(Vertex_handle v) const
456 /*{\Mop deletes |v| and all outgoing edges |A(v)| as well as their twins.
457         Updates the adjacency at the targets of the edges in |A(v)|.}*/
458 {
459   if ( ! is_isolated(v) ) {
460     Halfedge_handle e = first_out_edge(v);
461     while ( e != cap(e) )
462       delete_halfedge_pair(cap(e));
463     delete_halfedge_pair(e);
464   }
465   this->phds->vertices_erase(v);
466 }
467 
delete_face(Face_handle f)468 void delete_face(Face_handle f) const
469 /*{\Mop deletes the face |f| without consideration of topological linkage.}*/
470 { this->phds->faces_erase(f); }
471 
472 
has_outdeg_two(Vertex_handle v)473 bool has_outdeg_two(Vertex_handle v) const
474 /*{\Mop return true when |v| has outdegree two.}*/
475 { if (v->is_isolated()) return false;
476   Halfedge_handle e1 = v->halfedge();
477   Halfedge_handle e2 = e1->next()->opposite();
478   return (e1!=e2 && e2->next()->opposite()==e1);
479 }
480 
merge_halfedge_pairs_at_target(Halfedge_handle e)481 void merge_halfedge_pairs_at_target(Halfedge_handle e) const
482 /*{\Mop merges the halfedge pairs at |v = target(e)|. |e| and
483   |twin(e)| are preserved, |next(e)|, |twin(next(e))| and |v| are deleted
484   in the merger. \precond |v| has outdegree two. The adjacency at |source(e)|
485   and |target(next(e))| is kept consistent.}*/
486 {
487   CGAL_NEF_TRACEN("merge_halfedge_pairs_at_target "<<PE(e));
488   Halfedge_handle eo = e->opposite(),
489                   en = e->next(), eno = en->opposite(),
490                   enn = en->next(), enno = eno->prev();
491   Vertex_handle v = e->vertex(), vn = en->vertex();
492   CGAL_assertion(has_outdeg_two(v));
493   Face_handle f1 = en->face(), f2 = eno->face();
494   // transfer the opposite face cycles e-en-enn to e-enn
495   if ( enn != eno ) {
496     e->set_next(enn); enn->set_prev(e);
497     eo->set_prev(enno); enno->set_next(eo);
498   } else {
499     e->set_next(eo); eo->set_prev(e);
500   }
501   // set vertex of e and deal with vertex-halfedge incidence
502   e->set_vertex(vn);
503   if (vn->halfedge()==en) vn->set_halfedge(e);
504   if (en->is_hole_entry())
505   { f1->remove_fc(en); f1->store_fc(e); }
506   if (eno->is_hole_entry())
507   { f2->remove_fc(eno); f2->store_fc(eo); }
508   if (f1->halfedge() == en) f1->set_halfedge(e);
509   if (f2->halfedge() == eno) f2->set_halfedge(eo);
510   this->phds->vertices_erase(v);
511   this->phds->edges_erase(en);
512 }
513 
flip_diagonal(Halfedge_handle e)514 void flip_diagonal(Halfedge_handle e) const
515 { Halfedge_handle r = twin(e);
516   Halfedge_handle en = e->next(), enn= en->next();
517   Halfedge_handle rn = r->next(), rnn= rn->next();
518   CGAL_assertion( enn->next()==e && rnn->next()==r );
519   remove_from_adj_list_at_source(e);
520   remove_from_adj_list_at_source(r);
521   set_adjacency_at_source_between(enn,e,twin(en));
522   set_adjacency_at_source_between(rnn,r,twin(rn));
523 }
524 
525 
526 /*{\Mtext \headerline{Incomplete topological update primitives}}*/
527 
528 Halfedge_handle new_halfedge_pair_at_source
529   (Halfedge_handle e, int pos = AFTER, Halfedge_base hb =
530    Halfedge_base()) const
531 /*{\Xop creates a new pair of edges  |(e1,e2)| representing |(source(e),())|
532   by inserting |e1| before or after |e| into cyclic adjacency list of
533   |source(e)| depending on |pos| from |\Mname::BEFORE, \Mname::AFTER|.}*/
534 {
535   Halfedge_handle e_new = this->phds->edges_push_back(hb,hb);
536   if (pos < 0) // before e
537     set_adjacency_at_source_between(cap(e),e_new,e);
538   else  // after e
539     set_adjacency_at_source_between(e,e_new,cas(e));
540   return e_new;
541 }
542 
543 Halfedge_handle new_halfedge_pair_at_source
544   (Vertex_handle v, int pos = AFTER, Halfedge_base hb = Halfedge_base()) const
545 /*{\Mop creates a new pair of edges  |(e1,e2)| representing |(v,())|
546   by inserting |e1| at the beginning (BEFORE) or end (AFTER)
547   of adjacency list of |v|.}*/
548 { Halfedge_handle e1 = this->phds->edges_push_back(hb,hb);
549   Halfedge_handle e2 = e1->opposite();
550   e1->set_face(Face_handle()); e2->set_face(Face_handle());
551   if ( ! is_isolated(v) ) {
552     Halfedge_handle ef = first_out_edge(v);
553     set_adjacency_at_source_between(cap(ef),e1,ef);
554     if ( pos == BEFORE ) v->set_halfedge(e2);
555   } else
556     close_tip_at_source(e1,v);
557   return e1;
558 }
559 
delete_halfedge_pair_at_source(Halfedge_handle e)560 void delete_halfedge_pair_at_source(Halfedge_handle e) const
561 /*{\Mop deletes |e| and its twin and updates the adjacency at its
562   source.}*/
563 { remove_from_adj_list_at_source(e);
564   this->phds->edges_erase(e);
565 }
566 
link_as_target_and_append(Vertex_handle v,Halfedge_handle e)567 void link_as_target_and_append(Vertex_handle v, Halfedge_handle e) const
568 /*{\Mop makes |v| the target of |e| and appends |twin(e)| to $A(v)$.}*/
569 { if ( ! is_isolated(v) )
570     set_adjacency_at_source_between(cap(first_out_edge(v)),twin(e),
571       first_out_edge(v));
572   else
573     close_tip_at_target(e,v);
574 }
575 
new_halfedge_pair_without_vertices()576 Halfedge_handle new_halfedge_pair_without_vertices() const
577 /*{\Mop inserts an open edge pair, and inits all link slots to their default
578     handles.}*/
579 {
580   Halfedge_handle e_new = this->phds->edges_push_back(Halfedge(),Halfedge());
581   return e_new;
582 }
583 
delete_vertex_only(Vertex_handle v)584 void delete_vertex_only(Vertex_handle v) const
585 /*{\Mop deletes |v| without consideration of adjacency.}*/
586 { this->phds->vertices_erase(v); }
587 
delete_halfedge_pair_only(Halfedge_handle e)588 void delete_halfedge_pair_only(Halfedge_handle e) const
589 /*{\Mop deletes |e| and its twin without consideration of adjacency.}*/
590 { this->phds->edges_erase(e); }
591 
link_as_target_of(Halfedge_handle e,Vertex_handle v)592 void link_as_target_of(Halfedge_handle e, Vertex_handle v) const
593 /*{\Mop makes |target(e) = v| and sets |e| as the first
594         in-edge if |v| was isolated before.}*/
595 { e->set_vertex(v);
596   if (v->halfedge() == Halfedge_handle()) v->set_halfedge(e); }
597 
link_as_source_of(Halfedge_handle e,Vertex_handle v)598 void link_as_source_of(Halfedge_handle e, Vertex_handle v) const
599 /*{\Mop makes |source(e) = v| and sets |e| as the first
600         out-edge if |v| was isolated before.}*/
601 { link_as_target_of(e->opposite(),v); }
602 
make_first_out_edge(Halfedge_handle e)603 void make_first_out_edge(Halfedge_handle e) const
604 /*{\Mop makes |e| the first outgoing halfedge in the cyclic adjacency
605     list of |source(e)|.}*/
606 { source(e)->set_halfedge(e->opposite()); }
607 
608 
set_adjacency_at_source_between(Halfedge_handle e,Halfedge_handle en)609 void set_adjacency_at_source_between(Halfedge_handle e, Halfedge_handle en)
610   const
611 /*{\Mop makes |e| and |en| neigbors in the cyclic ordered adjacency list
612   around |v=source(e)|. \precond |source(e)==source(en)|.}*/
613 { CGAL_assertion(source(e)==source(en));
614   link_as_prev_next_pair(en->opposite(),e);
615 }
616 
set_adjacency_at_source_between(Halfedge_handle e1,Halfedge_handle e_between,Halfedge_handle e2)617 void set_adjacency_at_source_between(Halfedge_handle e1,
618                                      Halfedge_handle e_between,
619                                      Halfedge_handle e2) const
620 /*{\Mop inserts |e_between| into the adjacency list around |source(e1)|
621   between |e1| and |e2| and makes |source(e1)| the source of |e_between|.
622   \precond |source(e1)==source(e2)|.}*/
623 { e_between->opposite()->set_vertex(source(e1));
624   set_adjacency_at_source_between(e1,e_between);
625   set_adjacency_at_source_between(e_between,e2);
626 }
627 
close_tip_at_target(Halfedge_handle e,Vertex_handle v)628 void close_tip_at_target(Halfedge_handle e, Vertex_handle v) const
629 /*{\Mop sets |v| as target of |e| and closes the tip by setting the
630   corresponding pointers such that |prev(twin(e)) == e| and
631   |next(e) == twin(e)|.}*/
632 { link_as_target_of(e,v);
633   link_as_prev_next_pair(e,e->opposite()); }
634 
close_tip_at_source(Halfedge_handle e,Vertex_handle v)635 void close_tip_at_source(Halfedge_handle e, Vertex_handle v) const
636 /*{\Mop sets |v| as source of |e| and closes the tip by setting the
637   corresponding pointers such that |prev(e) == twin(e)| and
638   |next(twin(e)) == e|.}*/
639 { close_tip_at_target(e->opposite(),v); }
640 
641 
remove_from_adj_list_at_source(Halfedge_handle e)642 void remove_from_adj_list_at_source(Halfedge_handle e) const
643 /*{\Mop removes a halfedge pair |(e,twin(e)| from the adjacency list
644         of |source(e)|. Afterwards |next(prev(e))==next(twin(e))|
645         and |first_out_edge(source(e))| is valid if
646         |degree(source(v))>1| before the operation.}*/
647 {
648   Vertex_handle vs = source(e);
649   if ( is_closed_at_source(e) ) { // last outgoing
650     vs->set_halfedge(Halfedge_handle());
651   } else {
652     if (e == first_out_edge(vs))
653       vs->set_halfedge(e->prev());
654     set_adjacency_at_source_between(cap(e),cas(e));
655   }
656 }
657 
658 
unlink_as_hole(Halfedge_handle e)659 void unlink_as_hole(Halfedge_handle e) const
660 /*{\Mop removes |e|'s existence as an face cycle entry point of |face(e)|.
661     Does not update the face links of the corresponding face cycle
662     halfedges.}*/
663 { e->face()->remove_fc(e); }
664 
unlink_as_isolated_vertex(Vertex_handle v)665 void unlink_as_isolated_vertex(Vertex_handle v) const
666 /*{\Mop removes |v|'s existence as an isolated vertex in |face(v)|.
667     Does not update |v|'s face link.}*/
668 { v->face()->remove_iv(v); }
669 
link_as_prev_next_pair(Halfedge_handle e1,Halfedge_handle e2)670 void link_as_prev_next_pair(Halfedge_handle e1, Halfedge_handle e2) const
671 /*{\Mop makes |e1| and |e2| adjacent in the face cycle $\ldots-|e1-e2|-\ldots$.
672     Afterwards |e1 = previous(e2)| and |e2 = next(e1)|.}*/
673 { e1->set_next(e2); e2->set_prev(e1); }
674 
set_face(Halfedge_handle e,Face_handle f)675 void set_face(Halfedge_handle e, Face_handle f) const
676 /*{\Mop makes |f| the face of |e|.}*/
677 { e->set_face(f); }
678 
set_face(Vertex_handle v,Face_handle f)679 void set_face(Vertex_handle v, Face_handle f) const
680 /*{\Mop makes |f| the face of |v|.}*/
681 { v->set_face(f); }
682 
set_halfedge(Face_handle f,Halfedge_handle e)683 void set_halfedge(Face_handle f, Halfedge_handle e) const
684 /*{\Mop makes |e| entry edge in the outer face cycle of |f|.}*/
685 { f->set_halfedge(e); }
686 
set_hole(Face_handle f,Halfedge_handle e)687 void set_hole(Face_handle f, Halfedge_handle e) const
688 /*{\Mop makes |e| entry edge in a hole face cycle of |f|.}*/
689 { f->store_fc(e); }
690 
set_isolated_vertex(Face_handle f,Vertex_handle v)691 void set_isolated_vertex(Face_handle f, Vertex_handle v) const
692 /*{\Mop makes |v| an isolated vertex of |f|.}*/
693 { f->store_iv(v); }
694 
695 
696 /*{\Mtext \headerline{Cloning}\setopdims{2cm}{1cm}}*/
697 
698 void clone(const Plane_map& H) const;
699 /*{\Mop clones |H| into |P|. Afterwards |P| is a copy of |H|.\\
700   \precond |H.check_integrity_and_topological_planarity()| and
701   |P| is empty.}*/
702 
703 template <typename LINKDA>
704 void clone_skeleton(const Plane_map& H, const LINKDA& L) const;
705 /*{\Mop clones the skeleton of |H| into |P|. Afterwards |P| is a copy
706 of |H|. The link data accessor allows to transfer information from
707 the old to the new objects. It needs the function call operators:\\
708 |void operator()(Vertex_handle vn, Ver\-tex_\-const_\-handle vo) const|\\
709 |void operator()(Halfedge_handle hn, Half\-edge_\-const_\-handle ho) const|\\
710 where |vn,hn| are the cloned objects and |vo,ho| are the original
711 objects.\\
712 \precond |H.check_integrity_and_topological_planarity()| and
713 |P| is empty.}*/
714 
715 
reflecting_inversion()716 void reflecting_inversion()
717 /*{\Xop inverts the topological links corresponding to a reflecting
718 inversion. Assume that the plane map is embedded into the x-y plane
719 and one looks at it from the tip of the positive z-axis in space. Now
720 change your view point to a point on the negative z-axis. As a
721 consequence faces are right of edges and adjacency list are clockwise
722 order-preserving. This operation recreates our embedding invariant
723 (faces are left of edges and adjacency lists are counterclockwise
724 order-preserving).}*/
725 {
726   // swap faces:
727   Halfedge_iterator e;
728   for (e = halfedges_begin(); e != halfedges_end(); ++(++e)) {
729     Face_handle f1 = face(e), f2 = face(twin(e));
730     e->set_face(f2); twin(e)->set_face(f1);
731   }
732   // reverse adjacency lists:
733   std::vector<Halfedge_handle> A;
734   Vertex_iterator v;
735   for (v = vertices_begin(); v != vertices_end(); ++v) {
736     if ( is_isolted(v) ) continue;
737     Halfedge_around_vertex_circulator h = out_edges(v), hend(h);
738     CGAL_For_all(h,hend) A.push_back(h);
739     int n = A.size();
740     for (int i=0; i<n; ++i)
741       set_adjacency_at_source_between(A[(i+1)%n],A[i],A[(i-1)%n]);
742   }
743   CGAL_error_msg("test this");
744 }
745 
746 /*{\Mtext \headerline{Associated Information}\restoreopdims}*/
747 
point(Vertex_handle v)748 Point& point(Vertex_handle v) const
749 /*{\Mop returns the embedding of |v|.}*/
750 { return v->point(); }
751 
752 
mark(Vertex_handle v)753 Mark& mark(Vertex_handle v) const
754 /*{\Mop returns the mark of |v|.}*/
755 { return v->mark(); }
756 
mark(Halfedge_handle e)757 Mark& mark(Halfedge_handle e) const
758 /*{\Mop returns the mark of |e|.}*/
759 { if (&*e < &*(e->opposite())) return e->mark();
760   else return e->opposite()->mark();
761 } // we store the mark in the container with smaller memory address !
762 
mark(Face_handle f)763 Mark& mark(Face_handle f) const
764 /*{\Mop returns the mark of |f|.}*/
765 { return f->mark(); }
766 
set_marks_in_face_cycle(Halfedge_handle e,Mark m)767 void set_marks_in_face_cycle(Halfedge_handle e, Mark m) const
768 {
769   Halfedge_around_face_circulator hfc(e), hend(hfc);
770   CGAL_For_all(hfc,hend) {
771     mark(hfc) = mark(target(hfc)) = m;
772   }
773 }
774 
info(Vertex_handle v)775 GenPtr& info(Vertex_handle v) const
776 /*{\Mop returns a generic information slot.}*/
777 { return v->info(); }
778 
info(Halfedge_handle e)779 GenPtr& info(Halfedge_handle e) const
780 /*{\Mop returns a generic information slot.}*/
781 { return e->info(); }
782 
info(Face_handle f)783 GenPtr& info(Face_handle f) const
784 /*{\Mop returns a generic information slot.}*/
785 { return f->info(); }
786 
787 
788 }; // PM_decorator<HDS>
789 
790 template <typename  HDS>
clone(const HDS & H)791 void PM_decorator<HDS>::clone(const HDS& H) const
792 {
793   CGAL_assertion(this->number_of_vertices()==0&&
794                  this->number_of_halfedges()==0&&
795                  this->number_of_faces()==0);
796 
797   PM_const_decorator<HDS> DC(H);
798   CGAL_assertion((DC.check_integrity_and_topological_planarity(),1));
799   CGAL::Unique_hash_map<Vertex_const_iterator,Vertex_handle>     Vnew;
800   CGAL::Unique_hash_map<Halfedge_const_iterator,Halfedge_handle> Hnew;
801   CGAL::Unique_hash_map<Face_const_iterator,Face_handle>         Fnew;
802 
803   /* First clone all objects and store correspondance in three maps.*/
804   Vertex_const_iterator vit, vend = H.vertices_end();
805   for (vit = H.vertices_begin(); vit!=vend; ++vit)
806     Vnew[vit] = this->phds->vertices_push_back(Vertex_base());
807   Halfedge_const_iterator eit, eend = H.halfedges_end();
808   for (eit = H.halfedges_begin(); eit!=eend; ++(++eit)) {
809     Hnew[eit] = this->phds->edges_push_back(Halfedge_base(),Halfedge_base());
810     Hnew[eit->opposite()] = Hnew[eit]->opposite();
811   }
812   Face_const_iterator fit, fend = H.faces_end();
813   for (fit = H.faces_begin(); fit!=fend; ++fit) {
814     Fnew[fit] = this->phds->faces_push_back(Face_base());
815   }
816 
817   /* Now copy topology.*/
818   Vertex_iterator vit2, vend2 = this->phds->vertices_end();
819   for (vit = H.vertices_begin(), vit2 = vertices_begin();
820        vit2!=vend2; ++vit, ++vit2) {
821     mark(vit2) = DC.mark(vit);
822     point(vit2) = DC.point(vit);
823     if ( DC.is_isolated(vit) ) vit2->set_face(Fnew[vit->face()]);
824     else vit2->set_halfedge(Hnew[vit->halfedge()]);
825   }
826   Halfedge_iterator eit2, eend2 = this->phds->halfedges_end();
827   for (eit = H.halfedges_begin(), eit2 = halfedges_begin();
828        eit2!=eend2; ++eit, ++eit2) {
829     eit2->set_prev(Hnew[eit->prev()]);
830     eit2->set_next(Hnew[eit->next()]);
831     eit2->set_vertex(Vnew[eit->vertex()]);
832     eit2->set_face(Fnew[eit->face()]);
833     mark(eit2) = DC.mark(eit);
834   }
835 
836   Face_iterator fit2, fend2 = faces_end();
837   for (fit = H.faces_begin(), fit2 = faces_begin();
838        fit2!=fend2; ++fit, ++fit2) {
839     fit2->set_halfedge(Hnew[fit->halfedge()]);
840       // outer face cycle
841     Hole_const_iterator fcit, fcend = holes_end(fit);
842     for (fcit = holes_begin(fit); fcit!=fcend; ++fcit) {
843       fit2->store_fc(Hnew[fcit]);
844     } // hole face cycles
845     Isolated_vertex_const_iterator ivit;
846     for (ivit = isolated_vertices_begin(fit);
847          ivit != isolated_vertices_end(fit); ++ivit)
848       fit2->store_iv(Vnew[ivit]);
849       // isolated vertices in the interior
850     mark(fit2) = DC.mark(fit);
851   }
852   CGAL_assertion((this->check_integrity_and_topological_planarity(),1));
853 }
854 
855 
856 template <typename HDS>
857 template <typename LINKDA>
858 void PM_decorator<HDS>::
clone_skeleton(const HDS & H,const LINKDA & L)859 clone_skeleton(const HDS& H, const LINKDA& L) const
860 {
861   CGAL_assertion(this->number_of_vertices()==0&&
862                  this->number_of_halfedges()==0&&
863                  this->number_of_faces()==0);
864 
865   PM_const_decorator<HDS> DC(H);
866   CGAL_assertion((DC.check_integrity_and_topological_planarity(),1));
867   CGAL::Unique_hash_map<Vertex_const_iterator,Vertex_handle>     Vnew;
868   CGAL::Unique_hash_map<Halfedge_const_iterator,Halfedge_handle> Hnew;
869 
870   /* First clone all objects and store correspondance in the two maps.*/
871   Vertex_const_iterator vit, vend = H.vertices_end();
872   for (vit = H.vertices_begin(); vit!=vend; ++vit) {
873     Vertex_handle v = this->phds->vertices_push_back(Vertex_base());
874     Vnew[vit] = v;
875   }
876   Halfedge_const_iterator eit, eend = H.halfedges_end();
877   for (eit = H.halfedges_begin(); eit!=eend; ++(++eit)) {
878     Halfedge_handle e = this->phds->edges_push_back(Halfedge_base(),Halfedge_base());
879     Hnew[eit] = e; Hnew[eit->opposite()] = e->opposite();
880   }
881 
882   /* Now copy topology.*/
883   Vertex_iterator vit2, vend2 = vertices_end();
884   for (vit = H.vertices_begin(), vit2 = vertices_begin();
885        vit2!=vend2; ++vit, ++vit2) {
886     mark(vit2) = DC.mark(vit);
887     point(vit2) = DC.point(vit);
888     if ( !DC.is_isolated(vit) )
889       vit2->set_halfedge(Hnew[vit->halfedge()]);
890     L(vit2,vit);
891   }
892   Halfedge_iterator eit2, eend2 = this->phds->halfedges_end();
893   for (eit = H.halfedges_begin(), eit2 = halfedges_begin();
894        eit2!=eend2; ++eit, ++eit2) {
895     eit2->set_prev(Hnew[eit->prev()]);
896     eit2->set_next(Hnew[eit->next()]);
897     eit2->set_vertex(Vnew[eit->vertex()]);
898     mark(eit2) = DC.mark(eit);
899     // eit2->set_face(Face_handle((Face*)&*(eit->face())));
900     L(eit2,eit);
901     // link to face of original
902   }
903 }
904 
905 } //namespace CGAL
906 
907 #endif //CGAL_PM_DECORATOR_H
908