Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Halfedge_data_structure_decorator.h
Go to the documentation of this file.
1 // ======================================================================
2 //
3 // Copyright (c) 1997 The CGAL Consortium
4 
5 // This software and related documentation is part of the Computational
6 // Geometry Algorithms Library (CGAL).
7 // This software and documentation is provided "as-is" and without warranty
8 // of any kind. In no event shall the CGAL Consortium be liable for any
9 // damage of any kind.
10 //
11 // Every use of CGAL requires a license.
12 //
13 // Academic research and teaching license
14 // - For academic research and teaching purposes, permission to use and copy
15 // the software and its documentation is hereby granted free of charge,
16 // provided that it is not a component of a commercial product, and this
17 // notice appears in all copies of the software and related documentation.
18 //
19 // Commercial licenses
20 // - A commercial license is available through Algorithmic Solutions, who also
21 // markets LEDA (http://www.algorithmic-solutions.de).
22 // - Commercial users may apply for an evaluation license by writing to
23 // Algorithmic Solutions (contact@algorithmic-solutions.com).
24 //
25 // The CGAL Consortium consists of Utrecht University (The Netherlands),
26 // ETH Zurich (Switzerland), Free University of Berlin (Germany),
27 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
28 // (Germany), Max-Planck-Institute Saarbrucken (Germany), RISC Linz (Austria),
29 // and Tel-Aviv University (Israel).
30 //
31 // ----------------------------------------------------------------------
32 //
33 // release : CGAL-2.2
34 // release_date : 2000, September 30
35 //
36 // file : include/CGAL/Halfedge_data_structure_decorator.h
37 // package : Halfedge_DS (2.8)
38 // chapter : $CGAL_Chapter: Halfedge Data Structures $
39 // source : hds_decorator.fw
40 // revision : $Revision: 1.1.1.1 $
41 // revision_date : $Date: 2001/07/05 22:17:47 $
42 // author(s) : Lutz Kettner
43 //
44 // coordinator : MPI Saarbruecken (Stefan Schirra)
45 //
46 // Halfedge Data Structure Decorator.
47 // email : contact@cgal.org
48 // www : http://www.cgal.org
49 //
50 // ======================================================================
51 
52 #ifndef CGAL_HALFEDGE_DATA_STRUCTURE_DECORATOR_H
53 #define CGAL_HALFEDGE_DATA_STRUCTURE_DECORATOR_H 1
54 
55 #ifndef CGAL_BASIC_H
56 #include <CGAL/basic.h>
57 #endif
58 #ifndef CGAL_PROTECT_VECTOR
59 #include <vector>
60 #define CGAL_PROTECT_VECTOR
61 #endif
62 #ifndef CGAL_IO_VERBOSE_OSTREAM_H
64 #endif // CGAL_IO_VERBOSE_OSTREAM_H
65 
67 
68 template < class _HDS >
70 public:
71 
72 // The class Halfedge_data_structure_decorator<HDS> provides
73 // auxiliary functions to examine and modify a halfedge data structure
74 // with respect to the different capabilities supported by the different
75 // representations. The functions evaluate the support type tags of
76 // the halfedge data structure to decide on the actions. If the
77 // feature is not supported nothing is done. Note that for example
78 // the creation of new halfedges is mandatory for all halfedge data
79 // structure and will not be repeated here.
80 
81 // TYPES
82 // ----------------------------------
83  typedef _HDS HDS;
85  typedef typename _HDS::Vertex Vertex;
86  typedef typename _HDS::Halfedge Halfedge;
87  typedef typename _HDS::Facet Facet;
88 
89  // Point needed for Vertex constructor for efficiency reasons.
90  typedef typename _HDS::Point Point;
91 
92 // The following types are equal to either `Tag_true' or `Tag_false',
93 // dependant whether the named feature is supported or not.
94 
95  typedef typename _HDS::Supports_vertex_point
97  typedef typename _HDS::Supports_vertex_halfedge
99  typedef typename _HDS::Supports_halfedge_prev
101  typedef typename _HDS::Supports_halfedge_vertex
103  typedef typename _HDS::Supports_halfedge_facet
105  typedef typename _HDS::Supports_facet_halfedge
107 
108  typedef typename _HDS::Supports_removal Supports_removal;
109 
110 
111 // CREATION
112 // ----------------------------------
113 
114  // Halfedge_data_structure_decorator() {}
115 
116 // Access Functions
117 // ----------------------------------
118 
120  // returns the incident halfedge of v if supported, `NULL'
121  // otherwise.
123  }
124 
125  Vertex* get_vertex( Halfedge* h) const {
126  // returns the incident vertex of h if supported, `NULL'
127  // otherwise.
128  return get_vertex( h, Supports_halfedge_vertex());
129  }
130 
131  Halfedge* get_prev( Halfedge* h) const {
132  // returns the previous halfedge of h if supported, `NULL'
133  // otherwise.
134  return get_prev( h, Supports_halfedge_prev());
135  }
136 
138  // returns the previous halfedge of h. Uses the `prev()' method if
139  // supported or performs a search around the facet using `next()'.
140  return find_prev( h, Supports_halfedge_prev());
141  }
142 
144  // returns the previous halfedge of h. Uses the `prev()' method if
145  // supported or performs a search around the vertex using `next()'.
147  }
148 
149  Facet* get_facet( Halfedge* h) const {
150  // returns the incident facet of h if supported, `NULL' otherwise.
151  return get_facet( h, Supports_halfedge_facet());
152  }
153 
155  // returns the incident halfedge of f if supported, `NULL'
156  // otherwise.
158  }
159 
160 // Const Access Functions
161 // ----------------------------------
162 
163  const Halfedge* get_vertex_halfedge( const Vertex* v) const {
164  // returns the incident halfedge of v if supported, `NULL'
165  // otherwise.
167  }
168 
169  const Vertex* get_vertex( const Halfedge* h) const {
170  // returns the incident vertex of h if supported, `NULL'
171  // otherwise.
172  return get_vertex( h, Supports_halfedge_vertex());
173  }
174 
175  const Halfedge* get_prev( const Halfedge* h) const {
176  // returns the previous halfedge of h if supported, `NULL'
177  // otherwise.
178  return get_prev( h, Supports_halfedge_prev());
179  }
180 
181  const Halfedge* find_prev( const Halfedge* h) const {
182  // returns the previous halfedge of h. Uses the `prev()' method if
183  // supported or performs a search around the facet using `next()'.
184  return find_prev( h, Supports_halfedge_prev());
185  }
186 
187  const Halfedge* find_prev_around_vertex( const Halfedge* h) const {
188  // returns the previous halfedge of h. Uses the `prev()' method if
189  // supported or performs a search around the vertex using `next()'.
191  }
192 
193  const Facet* get_facet( const Halfedge* h) const {
194  // returns the incident facet of h if supported, `NULL' otherwise.
195  return get_facet( h, Supports_halfedge_facet());
196  }
197 
198  const Halfedge* get_facet_halfedge( const Facet* f) const {
199  // returns the incident halfedge of f if supported, `NULL'
200  // otherwise.
202  }
203 
204 // Creation of New Elements
205 // ----------------------------------
206 
207  Vertex* new_vertex( HDS& hds) const {
208  // returns a new vertex from `hds' if vertices are supported,
209  // `NULL' otherwise.
210  return new_vertex( hds, Supports_halfedge_vertex());
211  }
212 
213  Vertex* new_vertex( HDS& hds, const Point& p) const {
214  // returns a new vertex from `hds' initialized to p if vertices
215  // are supported, `NULL' otherwise.
216  return new_vertex( hds, p, Supports_halfedge_vertex());
217  }
218 
219  Vertex* new_vertex( HDS& hds, const Vertex* v) const {
220  // returns a copy of v from `hds' if vertices
221  // are supported, `NULL' otherwise.
222  return new_vertex( hds, v, Supports_halfedge_vertex());
223  }
224 
225  Facet* new_facet( HDS& hds) const {
226  // returns a new facet from `hds' if facets are supported, `NULL'
227  // otherwise.
228  return new_facet( hds, Supports_halfedge_facet());
229  }
230 
231  Facet* new_facet( HDS& hds, const Facet* f) const {
232  // returns a copy of f from `hds' if facets
233  // are supported, `NULL' otherwise.
234  return new_facet( hds, f, Supports_halfedge_facet());
235  }
236 
237 // Creation of New Composed Items
238 
240  // returns a halfedge from a newly created loop in `hds'
241  // consisting of a single closed edge, one vertex and two facets
242  // (if supported respectively).
243  Halfedge* h = hds.new_edge();
244  h->set_next( h);
245  h->opposite()->set_next( h->opposite());
246  set_prev( h, h);
247  set_prev( h->opposite(), h->opposite());
248  set_vertex( h, new_vertex(hds));
249  set_vertex( h->opposite(), get_vertex(h));
250  set_facet( h, new_facet(hds));
251  set_facet( h->opposite(), new_facet(hds));
252  set_facet_halfedge( h);
255  return h;
256  }
257 
259  // returns a halfedge from a newly created segment in `hds'
260  // consisting of a single open edge, two vertices and one facet
261  // (if supported respectively).
262  Halfedge* h = hds.new_edge();
263  h->set_next( h->opposite());
264  h->opposite()->set_next( h);
265  set_prev( h, h->opposite());
266  set_prev( h->opposite(), h);
267  set_vertex( h, new_vertex(hds));
268  set_vertex( h->opposite(), new_vertex(hds));
269  set_facet( h, new_facet(hds));
270  set_facet( h->opposite(), get_facet(h));
271  set_facet_halfedge( h);
274  return h;
275  }
276 
277 // Removal of Elements
278 // ----------------------------------
279 
280  void delete_vertex(HDS& hds, Vertex* v) {
281  // removes the vertex v if vertices are supported.
283  }
284 
285  void delete_facet(HDS& hds, Facet* f) {
286  // removes the facet f if facets are supported.
288  }
289 
290 // Modifying Functions (Composed)
291 // ----------------------------------
292 
293  void close_tip( Halfedge* h) const {
294  // makes `h->opposite()' the successor of h.
295  h->set_next( h->opposite());
296  set_prev( h->opposite(), h);
297  }
298 
299  void close_tip( Halfedge* h, Vertex* v) const {
300  // makes `h->opposite()' the successor of h and sets the vertex to
301  // v.
302  h->set_next( h->opposite());
303  set_prev( h->opposite(), h);
304  set_vertex( h, v);
305  }
306 
307  void insert_tip( Halfedge* h, Halfedge* v) const {
308  // inserts the tip of the edge h into the halfedges around the
309  // vertex pointed to by v. `h->opposite()' is the new successor of
310  // v and `h->next()' will be set to `v->next()'. The vertex of h
311  // will be the one v points to if vertices are supported.
312  h->set_next( v->next());
313  v->set_next( h->opposite());
314  set_prev( h->next(), h);
315  set_prev( h->opposite(), v);
316  set_vertex( h, get_vertex( v));
317  }
318 
319  void remove_tip( Halfedge* h) const {
320  // removes `h->next()->opposite()' from the halfedge circle around
321  // the vertex pointed to by h. The new successor of h will be
322  // `h->next()->opposite()->next()'.
323  h->set_next( h->next()->opposite()->next());
324  set_prev( h->next(), h);
325  }
326 
327  void insert_halfedge( Halfedge* h, Halfedge* f) const {
328  // inserts the halfedge h between f and `f->next()'. The facet of
329  // h will be the one f points to if facets are supported.
330  h->set_next( f->next());
331  f->set_next( h);
332  set_prev( h->next(), h);
333  set_prev( h, f);
334  set_facet( h, get_facet( f));
335  }
336 
337  void remove_halfedge( Halfedge* h) const {
338  // removes `h->next()' from the halfedge circle around the facet
339  // pointed to by h. The new successor of h will be `h->next()
340  // ->next()'.
341  h->set_next( h->next()->next());
342  set_prev( h->next(), h);
343  }
344 
346  Tag_false) {}
348  Tag_true) {
349  CGAL_assertion_code( std::size_t termination_count = 0;)
350  Halfedge* end = h;
351  do {
352  CGAL_assertion( ++termination_count != 0);
353  h->set_vertex( v);
354  h = h->next()->opposite();
355  } while ( h != end);
356  }
357 
359  // Loops around the vertex incident to h and sets all vertex
360  // pointers to v. Precondition: `h != NULL'.
361  CGAL_precondition( h != 0);
363  }
364 
367  CGAL_assertion_code( std::size_t termination_count = 0;)
368  Halfedge* end = h;
369  do {
370  CGAL_assertion( ++termination_count != 0);
371  h->set_facet( f);
372  h = h->next();
373  } while ( h != end);
374  }
375 
377  // Loops around the facet incident to h and sets all facet
378  // pointers to f. Precondition: `h != NULL'.
379  CGAL_precondition( h != 0);
381  }
382 
383 // Modifying Functions (Euler Operators)
384 // ----------------------------------
385 
386 
388  // split the facet incident to `h' and `g' into two facets with a
389  // new diagonal between the two vertices denoted by `h' and `g'
390  // respectively. The second (new) facet is a copy of the first
391  // facet. It returns the new diagonal. The time is proportional to
392  // the distance from `h' to `g' around the facet.
393  Halfedge* hnew = hds.new_edge();
394  Facet* fnew = new_facet( hds, get_facet(h));
395  insert_tip( hnew, g);
396  insert_tip( hnew->opposite(), h);
397  set_facet( hnew, get_facet(h));
398  set_facet_in_facet_loop( hnew->opposite(), fnew);
399  set_facet_halfedge( hnew);
400  set_facet_halfedge( hnew->opposite());
401  return hnew;
402  }
403 
405  // join the two facets incident to h. The facet incident to
406  // `h->opposite()' gets removed. Both facets might be holes.
407  // Returns the predecessor of h. The invariant `join_facet(
408  // split_facet( h, g))' returns h and keeps `hds'
409  // unchanged. The time is proportional to the size of the facet
410  // removed and the time to compute `h.prev()'. Precondition:
411  // `HDS' supports removal of facets.
413  Halfedge* hprev = find_prev( h);
414  Halfedge* gprev = find_prev( h->opposite());
415  remove_tip( hprev);
416  remove_tip( gprev);
417  hds.delete_edge( h);
418  if ( get_facet( gprev) != 0)
419  delete_facet( hds, get_facet( gprev));
420  h = hprev;
421  // 'half' of the halfedges have their correct facets.
422  // Here we do the remaining halfedges.
423  CGAL_assertion_code( std::size_t termination_count = 0;)
424  while ( h != gprev) {
425  CGAL_assertion( ++termination_count != 0);
426  h = h->next();
427  set_facet( h, get_facet( hprev));
428  }
429  if ( get_facet( hprev) != 0)
430  set_facet_halfedge( hprev);
431  set_vertex_halfedge( hprev);
432  set_vertex_halfedge( gprev);
433  return hprev;
434  }
435 
437  // split the vertex incident to `h' and `g' into two vertices and
438  // connects them with a new edge. The second (new) vertex is a
439  // copy of the first vertex. It returns the new edge. The time is
440  // proportional to the distance from `h' to `g' around the vertex.
441  Halfedge* hnew = hds.new_edge();
442  Vertex* vnew = new_vertex( hds, get_vertex(h));
443  insert_halfedge( hnew, g);
444  insert_halfedge( hnew->opposite(), h);
445  set_vertex( hnew, get_vertex(h));
446  set_vertex_in_vertex_loop( hnew->opposite(), vnew);
447  set_vertex_halfedge( hnew);
448  set_vertex_halfedge( hnew->opposite());
449  return hnew;
450  }
451 
453  // join the two vertices incident to h. The vertex denoted by
454  // `h->opposite()' gets removed. Returns the predecessor of h. The
455  // invariant `join_vertex( split_vertex( h, g))' returns h and
456  // keeps `hds' unchanged. The time is proportional to the
457  // degree of the vertex removed and the time to compute `h.prev()'
458  // . Precondition: `HDS' supports removal of vertices.
460  Halfedge* hprev = find_prev( h->opposite());
461  Halfedge* gprev = find_prev( h);
462  remove_halfedge( hprev);
463  remove_halfedge( gprev);
464  hds.delete_edge( h);
465  delete_vertex( hds, get_vertex( gprev));
466  // 'half' of the halfedges have their correct vertex.
467  // Here we do the remaining halfedges.
468  h = hprev;
469  CGAL_assertion_code( std::size_t termination_count = 0;)
470  while ( h != gprev) {
471  CGAL_assertion( ++termination_count != 0);
472  h = h->next()->opposite();
473  set_vertex( h, get_vertex( hprev));
474  }
475  set_vertex_halfedge( hprev);
476  if ( ! hprev->is_border())
477  set_facet_halfedge( hprev);
478  if ( ! gprev->is_border())
479  set_facet_halfedge( gprev);
480  return hprev;
481  }
482 
484  // cuts `hds' into two parts along the cycle (h,i,j).
485  // Three copies of the vertices, three copies of the halfedges,
486  // and two new triangles will be created. h,i,j will be incident
487  // to the first new triangle. The returnvalue will be an halfedge
488  // iterator denoting the new halfedge of the second new triangle
489  // which was h beforehand. Precondition: h,i,j are distinct,
490  // consecutive vertices of `hds' and form a cycle: i.e.
491  // `h->vertex() == i->opposite()->vertex()', ..., `j->vertex() ==
492  // h->opposite()->vertex()'.
493  CGAL_precondition( h != i);
494  CGAL_precondition( h != j);
495  CGAL_precondition( i != j);
499  // Create a copy of the triangle.
500  Halfedge* hnew = hds.new_edge( h);
501  Halfedge* inew = hds.new_edge( i);
502  Halfedge* jnew = hds.new_edge( j);
503  close_tip( hnew, new_vertex( hds, get_vertex( h)));
504  close_tip( inew, new_vertex( hds, get_vertex( i)));
505  close_tip( jnew, new_vertex( hds, get_vertex( j)));
506  insert_tip( inew->opposite(), hnew);
507  insert_tip( jnew->opposite(), inew);
508  insert_tip( hnew->opposite(), jnew);
509  // Make the new incidences with the old stucture.
510  CGAL_assertion_code( std::size_t termination_count = 0;)
511  if ( h->next() != i) {
512  Halfedge* g = h->next();
513  h->set_next( i);
514  set_prev( i, h);
515  hnew->set_next( g);
516  set_prev( g, hnew);
517  g = g->opposite();
518  while ( g->next() != i) {
519  CGAL_assertion( ++termination_count != 0);
520  set_vertex( g, get_vertex( hnew));
521  g = g->next()->opposite();
522  }
523  set_vertex( g, get_vertex( hnew));
524  g->set_next( inew);
525  set_prev( inew, g);
526  }
527  if ( i->next() != j) {
528  Halfedge* g = i->next();
529  i->set_next( j);
530  set_prev( j, i);
531  inew->set_next( g);
532  set_prev( g, inew);
533  g = g->opposite();
534  while ( g->next() != j) {
535  CGAL_assertion( ++termination_count != 0);
536  set_vertex( g, get_vertex( inew));
537  g = g->next()->opposite();
538  }
539  set_vertex( g, get_vertex( inew));
540  g->set_next( jnew);
541  set_prev( jnew, g);
542  }
543  if ( j->next() != h) {
544  Halfedge* g = j->next();
545  j->set_next( h);
546  set_prev( h, j);
547  jnew->set_next( g);
548  set_prev( g, jnew);
549  g = g->opposite();
550  while ( g->next() != h) {
551  CGAL_assertion( ++termination_count != 0);
552  set_vertex( g, get_vertex( jnew));
553  g = g->next()->opposite();
554  }
555  set_vertex( g, get_vertex( jnew));
556  g->set_next( hnew);
557  set_prev( hnew, g);
558  }
559  // Fill the holes with two new facets.
560  Facet* f = new_facet(hds);
561  set_facet( h, f);
562  set_facet( i, f);
563  set_facet( j, f);
564  set_facet_halfedge( h);
565  f = new_facet(hds);
566  set_facet( hnew->opposite(), f);
567  set_facet( inew->opposite(), f);
568  set_facet( jnew->opposite(), f);
569  set_facet_halfedge( hnew->opposite());
570  // Take care of maybe changed halfedge pointers.
571  set_facet_halfedge( hnew);
572  set_facet_halfedge( inew);
573  set_facet_halfedge( jnew);
574  set_vertex_halfedge( hnew);
575  set_vertex_halfedge( inew);
576  set_vertex_halfedge( jnew);
577  return hnew->opposite();
578  }
579 
581  // glues the boundary of two facets together. Both facets and the
582  // vertices of the facet loop g gets removed. Returns h. The
583  // invariant `join_loop( h, split_loop( h, i, j))' returns h and
584  // keeps `hds' unchanged. Precondition: `HDS' supports
585  // removal of vertices and facets. The facets denoted by h and g
586  // are different and have have equal size.
589  || get_facet(h) != get_facet(g));
590  if ( get_facet(h) != 0)
591  delete_facet( hds, get_facet(h));
592  if ( get_facet(g) != 0)
593  delete_facet( hds, get_facet(g));
594  Halfedge* hi = h;
595  Halfedge* gi = g;
596  CGAL_assertion_code( std::size_t termination_count = 0;)
597  do {
598  CGAL_assertion( ++termination_count != 0);
599  Halfedge* hii = hi;
600  Halfedge* gii = gi;
601  hi = hi->next();
602  // gi = find_prev(gi); // Replaced by search around vertex.
603  set_facet( hii, get_facet( gii->opposite()));
604  set_facet_halfedge( hii);
605  delete_vertex( hds, get_vertex( gii->opposite()));
606  if ( gii->opposite()->next()->opposite()->next() == gii) {
607  gi = gii->opposite()->next()->opposite();
608  } else {
609  hii->set_next( gii->opposite()->next());
610  set_prev( hii->next(), hii);
611  gii = gii->opposite()->next()->opposite();
612  set_vertex( gii, get_vertex(hii));
613  while ( gii->next()->opposite()->next() != gi) {
614  CGAL_assertion( ++termination_count != 0);
615  gii = gii->next()->opposite();
616  set_vertex( gii, get_vertex(hii));
617  }
618  gi = gii->next()->opposite();
619  gii->set_next( hi);
620  set_prev( gii->next(), gii);
621  }
622  } while ( hi != h);
623  CGAL_assertion( gi == g);
624  do {
625  Halfedge* gii = gi;
626  gi = gi->next();
627  hds.delete_edge( gii);
628  } while ( gi != g);
629  return h;
630  }
631 
632  protected:
633  // supports facet or not.
636 
637  void make_hole( HDS& hds, Halfedge* h, Tag_true) {
639  CGAL_precondition( h != 0);
640  CGAL_precondition( ! h->is_border());
641  hds.delete_facet( h->facet());
643  }
644 
645  void fill_hole( HDS& hds, Halfedge* h, Tag_true) {
646  CGAL_precondition( h != 0);
648  Facet* f = new_facet(hds);
650  set_facet_halfedge( h);
651  }
652 
653  public:
654 
656  // removes incident facet and makes all halfedges incident to the
657  // facet to border edges. Returns h. Precondition: `HDS'
658  // supports removal of facets. `! h.is_border()'.
660  return h;
661  }
662 
664  // fill a hole with a new created facet. Makes all border
665  // halfedges of the hole denoted by h incident to the new facet.
666  // Returns h. Precondition: `h.is_border()'.
668  return h;
669  }
670 
672  // creates a new facet from `hds' within the hole incident to h
673  // and g by connecting the tip of g with the tip of h with a new
674  // halfedge from `hds' and filling this separated part of the hole
675  // with a new facet from `hds'. Returns the new halfedge incident
676  // to the new facet. Precondition: `h != NULL', `g != NULL',
677  // `h->is_border()', `g->is_border()' and g can be reached along
678  // the same hole starting with h.
679  CGAL_precondition( h != 0);
680  CGAL_precondition( g != 0);
683  Halfedge* hh = hds.new_edge();
684  insert_tip( hh, h);
685  insert_tip( hh->opposite(), g);
686  fill_hole( hds, g);
687  return hh;
688  }
689 
691  // Left rotate of edge.
692  // Precond: both incident facets are triangles.
693  CGAL_precondition( h == h->next()->next()->next());
694  CGAL_precondition( h->opposite() ==
695  h->opposite()->next()->next()->next());
696  Halfedge* hprev = h->next()->next();
697  Halfedge* gprev = h->opposite()->next()->next();
698  remove_tip( hprev);
699  remove_tip( gprev);
700  set_facet_halfedge( hprev);
701  set_facet_halfedge( gprev);
702  set_vertex_halfedge( hprev);
703  set_vertex_halfedge( gprev);
704  set_facet( hprev->next(), hprev->facet());
705  set_facet( gprev->next(), gprev->facet());
706  hprev = hprev->next();
707  gprev = gprev->next();
708  insert_tip( h, gprev);
709  insert_tip( h->opposite(), hprev);
710  CGAL_postcondition( h == h->next()->next()->next());
712  h->opposite()->next()->next()->next());
713  return h;
714  }
715 
716 // Erasing
717 // ----------------------------------
718  protected:
719  // supports facet or not.
721  void erase_facet( HDS& hds, Halfedge* h, Tag_true) {
723  CGAL_precondition( h != 0);
724  CGAL_precondition( ! h->is_border());
725  hds.delete_facet( h->facet());
726  CGAL_assertion_code( std::size_t termination_count = 0;)
727  Halfedge* end = h;
728  do {
729  CGAL_assertion( ++termination_count != 0);
730  set_facet( h, 0);
731  Halfedge* g = h->next();
732  bool h_tag = h->opposite()->is_border();
733  bool g_tag = g->opposite()->is_border();
734  if ( h_tag && g_tag && g->opposite()->next() == h->opposite()){
735  delete_vertex( hds, get_vertex(h));
736  if ( h != end)
737  hds.delete_edge(h);
738  } else {
739  if ( g_tag) {
741  remove_tip(h);
742  }
743  if ( h_tag) {
746  if ( h != end)
747  hds.delete_edge(h);
748  }
749  }
750  h = g;
751  } while ( h != end);
752  if ( h->opposite()->is_border())
753  hds.delete_edge(h);
754  }
755 
756  public:
757  void erase_facet( HDS& hds, Halfedge* h) {
758  // removes the facet incident to `h' from `hds' and changes all
759  // halfedges incident to the facet into border edges or removes
760  // them from the polyhedral surface if they were already border
761  // edges. See `make_hole(h)' for a more specialized variant.
762  // Precondition: `h != NULL'. If facets are supported,
763  // `Supports_removal' must be equivalent to `Tag_true'.
765  }
766 
767  protected: // Supports_halfedge_vertices
769  Tag_false) {}
771  Tag_true) {
772  // Erases the the vertex incident to h and sets all references
773  // from halfedges around this vertex to NULL,
774  // if the incident vertex handle is not already equal to
775  // NULL. It is used to erase vertices as soon
776  // as an vertex is encountered in the graph traversal. At this
777  // point of the graph traversal the halfedge cycle around the
778  // vertex is still closed. Lateron it will be broken.
779  if ( h->vertex() != NULL) {
780  hds.delete_vertex( h->vertex());
781  set_vertex_in_vertex_loop( h, NULL);
782  }
783  }
787  }
788 
789  typedef std::vector<Halfedge*> HVector;
791  HVector& stack) {
792  // Delete incident facet and set all incidences to 0.
793  if ( get_facet(h) != 0) {
794  delete_facet( hds, get_facet(h));
796  }
797  // Cycle around facet, delete incident vertices, push new
798  // edges on the stack and mark edges as visited.
800  Halfedge* g = h->next();
801  h->set_next(0);
802  while (g != h) {
804  if ( g->opposite()->next() != 0)
805  stack.push_back( g->opposite());
806  Halfedge* gg = g->next();
807  g->set_next(0);
808  g = gg;
809  }
810  }
811 
812  public:
815  HVector stack;
816  // Algorithm: The next() pointer is used as visited tag
817  // for a graph search. If the next pointer of an halfedge
818  // or its opposite halfedge is set to 0, this edge has already
819  // been visited and must not be put on the stack again.
820  // Initializing: Cycle through the face-cycle of h and put
821  // all opposite halfedges on the stack. Put h->opposite()
822  // on the stack. Note that even if the face cycle of h looks
823  // ugly ( e.g. h->opposite() is also in the cycle), neither
824  // h nor h->opposite() will be put on the stack. If
825  // h->opposite() is in the cycle, when h will be popped from
826  // the stack it will be immediately deleted.
827  // Loop invariant: For each edge h on the stack h->opposite()->
828  // next() == NULL.
829  // Looping: For each edge h on the stack, if h->next() is
830  // not already equal to NULL, cycle through the face-cycle
831  // of h and put all opposite halfedges on the stack.
832  // Delete h.
833  // Where: Cycle through a face means: If h->facet() != NULL
834  // delete h->facet() and set all facet handles to NULL.
835  // Loop through the halfedges g around the facet, call
836  // erase_connected_component_vertex for each g, push
837  // g->opposite() on the stack if g->opposite()->next()
838  // is not already NULL. This implies that h->opposite()
839  // is not put on the stack again.
840  erase_connected_component_face_cycle( hds, h, stack);
841  stack.push_back( h->opposite());
842  while ( ! stack.empty()) {
843  h = stack.back();
844  stack.pop_back();
845  CGAL_assertion( h->opposite()->next() == 0);
846  if ( h->next() != 0)
847  erase_connected_component_face_cycle( hds, h, stack);
848  hds.delete_edge( h);
849  }
850  }
851 
852 // Modifying Functions (Primitives)
853 // ----------------------------------
854 
855  void set_point( Vertex* v, const Point& p) const {
857  // sets the point of v to p.
858  }
859 
860  void set_point( Halfedge* h, const Point& p) const {
861  // sets the point of the vertex incident to h to p.
863  }
864 
865  void set_vertex_halfedge( Vertex* v, Halfedge* g) const {
866  // sets the incident halfedge of v to g.
868  }
869 
870  void set_vertex_halfedge( Halfedge* h) const {
871  // sets the incident halfedge of the vertex incident to h to h.
873  }
874 
875  void set_vertex( Halfedge* h, Vertex* v) const {
876  // sets the incident vertex of h to v.
878  }
879 
880  void set_prev( Halfedge* h, Halfedge* g) const {
881  // sets the previous link of h to g.
883  }
884 
885  void set_facet( Halfedge* h, Facet* f) const {
886  // sets the incident facet of h to f.
888  }
889 
890  void set_facet_halfedge( Facet* f, Halfedge* g) const {
891  // sets the incident halfedge of f to g.
893  }
894 
895  void set_facet_halfedge( Halfedge* h) const {
896  // sets the incident halfedge of the facet incident to h to h.
898  }
899 
900 // Implementing These Functions.
901 // ====================================================
902 // Access Functions
903 // ----------------------------------
904 
906  return NULL;
907  }
909  return v->halfedge();
910  }
911 
912  Vertex* get_vertex( Halfedge* , Tag_false) const { return NULL;}
914  return h->vertex();
915  }
916 
917  Halfedge* get_prev(Halfedge* , Tag_false) const {return NULL;}
918  Halfedge* get_prev(Halfedge* h, Tag_true) const {return h->prev();}
919 
920  Halfedge* find_prev(Halfedge* h, Tag_true) const { return h->prev(); }
922  Halfedge* g = h;
923  while ( g->next() != h)
924  g = g->next();
925  return g;
926  }
927 
929  return h->prev();
930  }
932  Halfedge* g = h->opposite();
933  while ( g->next() != h)
934  g = g->next()->opposite();
935  return g;
936  }
937 
938  Facet* get_facet(Halfedge* , Tag_false) const { return NULL;}
939  Facet* get_facet(Halfedge* h, Tag_true) const { return h->facet();}
940 
942  return NULL;
943  }
945  return f->halfedge();
946  }
947 
948 // Const Access Functions
949 // ----------------------------------
950 
951  const Halfedge*
952  get_vertex_halfedge( const Vertex* ,Tag_false) const { return NULL; }
953  const Halfedge*
955  return v->halfedge();
956  }
957 
958  const Vertex*
959  get_vertex( const Halfedge* , Tag_false) const { return NULL; }
960  const Vertex*
961  get_vertex( const Halfedge* h, Tag_true) const { return h->vertex(); }
962 
963  const Halfedge*
964  get_prev( const Halfedge* , Tag_false) const { return NULL; }
965  const Halfedge*
966  get_prev( const Halfedge* h, Tag_true) const { return h->prev(); }
967 
968  const Halfedge*
969  find_prev( const Halfedge* h, Tag_true) const { return h->prev(); }
970  const Halfedge*
971  find_prev( const Halfedge* h, Tag_false) const {
972  const Halfedge* g = h;
973  while ( g->next() != h)
974  g = g->next();
975  return g;
976  }
977 
979  Tag_true) const {
980  return h->prev();
981  }
983  Tag_false) const {
984  const Halfedge* g = h->opposite();
985  while ( g->next() != h)
986  g = g->next()->opposite();
987  return g;
988  }
989 
990  const Facet*
991  get_facet( const Halfedge* , Tag_false) const { return NULL;}
992  const Facet*
993  get_facet( const Halfedge* h, Tag_true) const { return h->facet();}
994 
995  const Halfedge*
996  get_facet_halfedge( const Facet* , Tag_false) const {
997  return NULL;
998  }
999  const Halfedge*
1000  get_facet_halfedge( const Facet* f, Tag_true) const {
1001  return f->halfedge();
1002  }
1003 
1004 // Creation of New Elements
1005 // ----------------------------------
1006 
1007  Vertex* new_vertex( HDS& , Tag_false) const { return NULL;}
1008  Vertex* new_vertex( HDS& hds, Tag_true) const {
1009  return hds.new_vertex();
1010  }
1011 
1012  Vertex* new_vertex( HDS& , const Point& , Tag_false) const {
1013  return NULL;
1014  }
1015  Vertex* new_vertex( HDS& hds, const Point& p, Tag_true) const {
1016  return hds.new_vertex(p);
1017  }
1018 
1019  Vertex* new_vertex( HDS& , const Vertex* ,Tag_false) const {
1020  return NULL;
1021  }
1022  Vertex* new_vertex( HDS& hds, const Vertex* v,Tag_true) const {
1023  return hds.new_vertex(v);
1024  }
1025 
1026  Facet* new_facet( HDS& , Tag_false) const { return NULL;}
1027  Facet* new_facet( HDS& hds, Tag_true) const {
1028  return hds.new_facet();
1029  }
1030 
1031  Facet* new_facet( HDS& , const Facet* , Tag_false) const {
1032  return NULL;
1033  }
1034  Facet* new_facet( HDS& hds, const Facet* f, Tag_true) const {
1035  return hds.new_facet(f);
1036  }
1037 
1038 
1039 // Removal of Elements
1040 // ----------------------------------
1041 
1044  hds.delete_vertex( v);
1045  }
1046 
1048  void delete_facet(HDS& hds, Facet* f, Tag_true) {
1049  hds.delete_facet( f);
1050  }
1051 // Modifying Function Primitives
1052 // ----------------------------------
1053 
1054  void set_point( Vertex* , const Point& , Tag_false) const {}
1055  void set_point( Vertex* v, const Point& p, Tag_true) const {
1056  v->point() = p;
1057  }
1058 
1059  void set_point( Halfedge* , const Point& , Tag_false) const {}
1060  void set_point( Halfedge* h, const Point& p, Tag_true) const {
1061  set_point( h->vertex(), p);
1062  }
1063 
1066  v->set_halfedge(g);
1067  }
1068 
1071  set_vertex_halfedge( h->vertex(), g);
1072  }
1073 
1074  void set_vertex( Halfedge*, Vertex* , Tag_false) const {}
1075  void set_vertex( Halfedge* h, Vertex* v, Tag_true) const {
1076  h->set_vertex(v);
1077  }
1078 
1079  void set_prev( Halfedge* , Halfedge* , Tag_false) const {}
1080  void set_prev( Halfedge* h, Halfedge* g, Tag_true) const {
1081  h->set_prev( g);
1082  }
1083 
1084  void set_facet( Halfedge*, Facet* , Tag_false) const {}
1085  void set_facet( Halfedge* h, Facet* f, Tag_true) const {
1086  h->set_facet(f);
1087  }
1088 
1091  f->set_halfedge(g);
1092  }
1093 
1096  set_facet_halfedge( h->facet(), g);
1097  }
1098 
1099  bool normalized_border_is_valid( const _HDS& hds, bool verb = false)
1100  const;
1101  // checks whether all non-border edges precedes the border edges.
1102 
1103  bool is_valid( const _HDS& hds, bool verb = false, int level = 0)
1104  const;
1105  // checks the combinatorial consistency.
1106 
1107  void reorient_facet( Halfedge* first);
1108  // Supports: halfedge pointer in facets.
1109  void inside_out( _HDS& hds, Tag_false);
1110  void inside_out( _HDS& hds, Tag_true);
1111 
1112  void inside_out(_HDS& hds ) {
1114  }
1115 };
1116 
1117 template < class _HDS >
1118 bool
1120 normalized_border_is_valid( const _HDS& hds, bool verb) const {
1121  // checks whether all non-border edges precedes the border edges.
1122  typedef typename _HDS::Halfedge_const_iterator Halfedge_const_iterator;
1123  typedef typename _HDS::Size Size;
1124  bool valid = true;
1125  Verbose_ostream verr(verb);
1126  verr << "begin Halfedge_data_structure_decorator<HDS>::"
1127  "normalized_border_is_valid( verb=true):" << std::endl;
1128 
1129  Halfedge_const_iterator e = hds.halfedges_begin();
1130  Size count = 0;
1131  while( e != hds.halfedges_end() && ! e->is_border() && !
1132  e->opposite()->is_border()) {
1133  ++e;
1134  ++e;
1135  ++count;
1136  }
1137  verr << " non-border edges: " << count << std::endl;
1138  if ( e != hds.border_halfedges_begin()) {
1139  verr << " first border edge does not start at "
1140  "border_halfedges_begin()" << std::endl;
1141  valid = false;
1142  } else {
1143  count = 0;
1144  while( valid && e != hds.halfedges_end() &&
1145  e->opposite()->is_border()) {
1146  ++e;
1147  ++e;
1148  ++count;
1149  }
1150  verr << " border edges: " << count << std::endl;
1151  verr << " total edges: " << hds.size_of_halfedges()/2
1152  << std::endl;
1153  if ( e != hds.halfedges_end()) {
1154  if ( e->is_border()) {
1155  verr << " border edge " << count
1156  << ": wrong orientation." << std::endl;
1157  }
1158  verr << " the sum of full + border equals not total edges."
1159  << std::endl;
1160  valid = false;
1161  }
1162  }
1163  verr << "end of Halfedge_data_structure_decorator<HDS>::"
1164  "normalized_border_is_valid(): structure is "
1165  << ( valid ? "valid." : "NOT VALID.") << std::endl;
1166  return valid;
1167 }
1168 
1169 template < class _HDS >
1170 bool
1172 is_valid( const _HDS& hds, bool verb, int level) const {
1173  // checks the combinatorial consistency.
1174  typedef typename _HDS::Halfedge_const_iterator Halfedge_const_iterator;
1175  typedef typename _HDS::Vertex_const_iterator Vertex_const_iterator;
1176  typedef typename _HDS::Facet_const_iterator Facet_const_iterator;
1177  typedef typename _HDS::Size Size;
1178  typedef typename _HDS::Supports_halfedge_prev Supports_halfedge_prev;
1179  typedef typename _HDS::Supports_halfedge_vertex
1181  typedef typename _HDS::Supports_vertex_halfedge
1183  typedef typename _HDS::Supports_halfedge_facet
1185  typedef typename _HDS::Supports_facet_halfedge
1187 
1188  Verbose_ostream verr(verb);
1189  verr << "begin Halfedge_data_structure_decorator<HDS>::is_valid("
1190  " verb=true, level = " << level << "):" << std::endl;
1191 
1192  bool valid = ( 1 != (hds.size_of_halfedges() & 1));
1193  if ( ! valid)
1194  verr << "number of halfedges is odd." << std::endl;
1195 
1196  // All halfedges.
1197  Halfedge_const_iterator begin = hds.halfedges_begin();
1198  Halfedge_const_iterator end = hds.halfedges_end();
1199  Size n = 0;
1200  Size nb = 0;
1201  for( ; valid && (begin != end); begin++) {
1202  verr << "halfedge " << n << std::endl;
1203  if ( begin->is_border())
1204  verr << " is border halfedge" << std::endl;
1205  // Pointer integrity.
1206  valid = valid && ( begin->next() != NULL);
1207  valid = valid && ( begin->opposite() != NULL);
1208  if ( ! valid) {
1209  verr << " pointer integrity corrupted (ptr==NULL)."
1210  << std::endl;
1211  break;
1212  }
1213  // opposite integrity.
1214  valid = valid && ( begin->opposite() != &*begin);
1215  valid = valid && ( begin->opposite()->opposite() == &*begin);
1216  if ( ! valid) {
1217  verr << " opposite pointer integrity corrupted."
1218  << std::endl;
1219  break;
1220  }
1221  // previous integrity.
1222  valid = valid && ( ! check_tag( Supports_halfedge_prev()) ||
1223  get_prev(begin->next()) == &*begin);
1224  if ( ! valid) {
1225  verr << " previous pointer integrity corrupted."
1226  << std::endl;
1227  break;
1228  }
1229  if ( level > 0) {
1230  // vertex integrity.
1231  valid = valid && ( ! check_tag( Supports_halfedge_vertex())
1232  || get_vertex( &*begin) != NULL);
1233  valid = valid && ( get_vertex( &*begin) ==
1234  get_vertex( begin->next()->opposite()));
1235  if ( ! valid) {
1236  verr << " vertex pointer integrity corrupted."
1237  << std::endl;
1238  break;
1239  }
1240  // facet integrity.
1241  valid = valid && ( ! check_tag( Supports_halfedge_facet())
1242  || begin->is_border() || get_facet( &*begin) != NULL);
1243  valid = valid && ( get_facet( &*begin) ==
1244  get_facet( begin->next()));
1245  if ( ! valid) {
1246  verr << " facet pointer integrity corrupted."
1247  << std::endl;
1248  break;
1249  }
1250  }
1251  ++n;
1252  if ( begin->is_border())
1253  ++nb;
1254  }
1255  verr << "summe border halfedges (2*nb) = " << 2 * nb << std::endl;
1256  if ( valid && n != hds.size_of_halfedges())
1257  verr << "counting halfedges failed." << std::endl;
1258  if ( valid && level >= 4 && (nb != hds.size_of_border_halfedges()))
1259  verr << "counting border halfedges failed." << std::endl;
1260  valid = valid && ( n == hds.size_of_halfedges());
1261  valid = valid && ( level < 4 ||
1262  (nb == hds.size_of_border_halfedges()));
1263 
1264  // All vertices.
1265  Vertex_const_iterator vbegin = hds.vertices_begin();
1266  Vertex_const_iterator vend = hds.vertices_end();
1267  Size v = 0;
1268  n = 0;
1269  for( ; valid && (vbegin != vend); ++vbegin) {
1270  verr << "vertex " << v << std::endl;
1271  // Pointer integrity.
1272  if ( get_vertex_halfedge( &*vbegin) != NULL)
1273  valid = valid && ( ! check_tag(
1274  Supports_halfedge_vertex()) ||
1275  get_vertex( get_vertex_halfedge( &*vbegin)) == &*vbegin);
1276  else
1277  valid = valid && (! check_tag(
1278  Supports_vertex_halfedge()));
1279  if ( ! valid) {
1280  verr << " halfedge pointer in vertex corrupted."
1281  << std::endl;
1282  break;
1283  }
1284  // cycle-around-vertex test.
1285  const Halfedge* h = get_vertex_halfedge( &*vbegin);
1286  if ( h) {
1287  const Halfedge* g = h;
1288  do {
1289  verr << " halfedge " << n << std::endl;
1290  ++n;
1291  h = h->next()->opposite();
1292  valid = valid && ( n <= hds.size_of_halfedges() && n != 0);
1293  } while ( valid && (h != g));
1294  }
1295  ++v;
1296  }
1297  if ( valid && v != hds.size_of_vertices())
1298  verr << "counting vertices failed." << std::endl;
1299  if ( valid && level >= 2 && ( check_tag( Supports_vertex_halfedge())
1300  && n != hds.size_of_halfedges()))
1301  verr << "counting halfedges via vertices failed." << std::endl;
1302  valid = valid && ( v == hds.size_of_vertices());
1303  valid = valid && ( level < 2 ||
1304  ! check_tag( Supports_vertex_halfedge()) ||
1305  n == hds.size_of_halfedges());
1306 
1307  // All facets.
1308  Facet_const_iterator fbegin = hds.facets_begin();
1309  Facet_const_iterator fend = hds.facets_end();
1310  Size f = 0;
1311  n = 0;
1312  for( ; valid && (fbegin != fend); ++fbegin) {
1313  verr << "facet " << f << std::endl;
1314  // Pointer integrity.
1315  if ( get_facet_halfedge( &*fbegin) != NULL)
1316  valid = valid && ( ! check_tag(
1317  Supports_halfedge_facet()) ||
1318  get_facet( get_facet_halfedge( &*fbegin)) == &*fbegin);
1319  else
1320  valid = valid && (! check_tag(
1321  Supports_facet_halfedge()) || begin->is_border());
1322  if ( ! valid) {
1323  verr << " halfedge pointer in facet corrupted."
1324  << std::endl;
1325  break;
1326  }
1327  // cycle-around-facet test.
1328  const Halfedge* h = get_facet_halfedge( &*fbegin);
1329  if ( h) {
1330  const Halfedge* g = h;
1331  do {
1332  verr << " halfedge " << n << std::endl;
1333  ++n;
1334  h = h->next();
1335  valid = valid && ( n <= hds.size_of_halfedges() && n != 0);
1336  } while ( valid && (h != g));
1337  }
1338  ++f;
1339  }
1340  if ( valid && f != hds.size_of_facets())
1341  verr << "counting facets failed." << std::endl;
1342  if ( valid && level >= 3 && check_tag( Supports_facet_halfedge()) &&
1343  n + nb != hds.size_of_halfedges())
1344  verr << "counting halfedges via facets failed." << std::endl;
1345  valid = valid && ( f == hds.size_of_facets());
1346  valid = valid && ( level < 3 ||
1347  ! check_tag( Supports_facet_halfedge()) ||
1348  n + nb == hds.size_of_halfedges());
1349 
1350  if ( level >= 4) {
1351  verr << "level 4: normalized_border_is_valid( verbose = true)"
1352  << std::endl;
1353  valid = valid && ( normalized_border_is_valid( hds, verb));
1354  }
1355  verr << "end of Halfedge_data_structure_decorator<HDS>::"
1356  "is_valid(): structure is " << ( valid ? "valid." :
1357  "NOT VALID.") << std::endl;
1358  return valid;
1359 }
1360 
1361 
1362 template < class _HDS > CGAL_MEDIUM_INLINE
1363 void
1366  if ( first == NULL)
1367  return;
1369  Halfedge* last = first;
1370  Halfedge* prev = first;
1371  Halfedge* start = first;
1372  first = first->next();
1373  Vertex* new_v = decorator.get_vertex( start);
1374  while (first != last) {
1375  Vertex* tmp_v = decorator.get_vertex( first);
1376  decorator.set_vertex( first, new_v);
1377  decorator.set_vertex_halfedge( first);
1378  new_v = tmp_v;
1379  Halfedge* next = first->next();
1380  first->set_next( prev);
1381  decorator.set_prev( first, next);
1382  prev = first;
1383  first = next;
1384  }
1385  decorator.set_vertex( start, new_v);
1386  decorator.set_vertex_halfedge( start);
1387  Halfedge* next = start->next();
1388  start->set_next( prev);
1389  decorator.set_prev( start, next);
1390 }
1391 
1392 template < class _HDS >
1393 void // Supports: halfedge pointer in facets.
1395 inside_out( _HDS& hds, Tag_false) {
1396  typedef typename _HDS::Halfedge_iterator Halfedge_iterator;
1397  Halfedge_iterator begin = hds.halfedges_begin();
1398  Halfedge_iterator end = hds.halfedges_end();
1399  for( ; begin != end; ++begin) {
1400  // Define the halfedge with the `smallest' pointer
1401  // value as the one that is used to reorient the facet.
1402  Halfedge* h = &*begin;
1403  bool is_min = true;
1404  Halfedge* c = h;
1405  Halfedge* d = c;
1406  do {
1407  CGAL_assertion( c != NULL);
1408  if ( h > c)
1409  is_min = false;
1410  c = c->next();
1411  } while ( c != d && is_min);
1412  if ( is_min)
1413  reorient_facet( h);
1414  }
1415 }
1416 
1417 template < class _HDS >
1418 void // Supports: halfedge pointer in facets.
1420 inside_out( _HDS& hds, Tag_true) {
1421  typedef typename _HDS::Halfedge_iterator Halfedge_iterator;
1422  typedef typename _HDS::Facet_iterator Facet_iterator;
1423  Facet_iterator begin = hds.facets_begin();
1424  Facet_iterator end = hds.facets_end();
1425  for( ; begin != end; ++begin)
1426  reorient_facet( begin->halfedge());
1427  // Note: A border edge is now parallel to its opposite edge.
1428  // We scan all border edges for this property. If it holds, we
1429  // reorient the associated hole and search again until no border
1430  // edge with that property exists any longer. Then, all holes are
1431  // reoriented.
1432  Halfedge_iterator first = hds.halfedges_begin();
1433  Halfedge_iterator last = hds.halfedges_end();
1434  for( ; first != last; ++first) {
1435  if ( first->is_border() &&
1436  first->vertex() == first->opposite()->vertex())
1437  reorient_facet( &*first);
1438  }
1439 }
1440 
1442 #endif // CGAL_HALFEDGE_DATA_STRUCTURE_DECORATOR_H //
1443 // EOF //
const Halfedge * get_prev(const Halfedge *h) const
const Facet * get_facet(const Halfedge *h, Tag_true) const
void erase_connected_component_vertex(HDS &hds, Halfedge *h, Tag_false)
void fill_hole(HDS &hds, Halfedge *h, Tag_true)
#define CGAL_assertion(EX)
Definition: assertions.h:87
void set_vertex_halfedge(Halfedge *h, Halfedge *g, Tag_true) const
Halfedge * find_prev_around_vertex(Halfedge *h, Tag_true) const
const Facet * get_facet(const Halfedge *, Tag_false) const
_HDS::Supports_halfedge_facet Supports_halfedge_facet
Halfedge * join_facet(HDS &hds, Halfedge *h)
void erase_connected_component_face_cycle(HDS &hds, Halfedge *h, HVector &stack)
Vertex * new_vertex(HDS &hds, const Vertex *v, Tag_true) const
const Halfedge * get_facet_halfedge(const Facet *f) const
_HDS::Supports_vertex_halfedge Supports_vertex_halfedge
const NT & d
Facet * new_facet(HDS &hds, const Facet *f) const
void set_vertex_halfedge(Halfedge *, Halfedge *, Tag_false) const
Halfedge * join_loop(HDS &hds, Halfedge *h, Halfedge *g)
void erase_connected_component_vertex(HDS &hds, Halfedge *h, Tag_true)
void set_facet_halfedge(Halfedge *, Halfedge *, Tag_false) const
void set_facet(Halfedge *h, Facet *f, Tag_true) const
Halfedge opposite() const
Get the ID of the opposite edge of a given edge.
Definition: Manifold_2.h:454
void set_point(Vertex *, const Point &, Tag_false) const
const Vertex * get_vertex(const Halfedge *h, Tag_true) const
const Halfedge * find_prev(const Halfedge *h) const
void delete_vertex(HDS &hds, Vertex *v, Tag_true)
Halfedge prev() const
Get the previous halfedge of its owner element.
Definition: Manifold_2.h:460
This class encapsulate a halfedge over a window manifold.
Definition: Manifold_2.h:446
Halfedge * split_vertex(HDS &hds, Halfedge *h, Halfedge *g)
void set_point(Halfedge *h, const Point &p, Tag_true) const
void set_facet_halfedge(Facet *f, Halfedge *g) const
Halfedge next() const
Get the next halfedge of its owner element.
Definition: Manifold_2.h:465
const Halfedge * get_facet_halfedge(const Facet *, Tag_false) const
void set_vertex(Halfedge *, Vertex *, Tag_false) const
void set_vertex_in_vertex_loop(Halfedge *, Vertex *, Tag_false)
bool is_valid(const _HDS &hds, bool verb=false, int level=0) const
void erase_facet(HDS &hds, Halfedge *h, Tag_true)
void make_hole(HDS &, Halfedge *, Tag_false)
Vertex * new_vertex(HDS &hds, Tag_true) const
#define CGAL_MEDIUM_INLINE
Halfedge * find_prev(Halfedge *h, Tag_false) const
void set_facet_in_facet_loop(Halfedge *, Facet *, Tag_false)
void set_point(Halfedge *, const Point &, Tag_false) const
#define CGAL_assertion_code(CODE)
Definition: assertions.h:91
Halfedge * find_prev_around_vertex(Halfedge *h, Tag_false) const
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
void set_point(Vertex *v, const Point &p) const
Facet * new_facet(HDS &hds, const Facet *f, Tag_true) const
Halfedge * get_vertex_halfedge(Vertex *, Tag_false) const
const Halfedge * find_prev_around_vertex(const Halfedge *h, Tag_false) const
void set_prev(Halfedge *h, Halfedge *g, Tag_true) const
Facet * get_facet(Halfedge *h, Tag_true) const
Halfedge * get_prev(Halfedge *h, Tag_true) const
void set_point(Halfedge *h, const Point &p) const
const Halfedge * find_prev_around_vertex(const Halfedge *h) const
bool check_tag(Tag_true)
const Halfedge * get_vertex_halfedge(const Vertex *v, Tag_true) const
#define CGAL_precondition(EX)
Definition: assertions.h:147
void set_vertex_halfedge(Vertex *, Halfedge *, Tag_false) const
const Vertex * get_vertex(const Halfedge *, Tag_false) const
_HDS::Supports_facet_halfedge Supports_facet_halfedge
void set_vertex_in_vertex_loop(Halfedge *h, Vertex *v, Tag_true)
void set_prev(Halfedge *, Halfedge *, Tag_false) const
const Halfedge * find_prev_around_vertex(const Halfedge *h, Tag_true) const
void erase_connected_component_vertex(HDS &hds, Halfedge *h)
blockLoc i
Definition: read.cpp:79
void set_facet_in_facet_loop(Halfedge *h, Facet *f, Tag_true)
Halfedge * get_facet_halfedge(Facet *, Tag_false) const
Halfedge * find_prev(Halfedge *h, Tag_true) const
void insert_tip(Halfedge *h, Halfedge *v) const
Vertex * new_vertex(HDS &, const Point &, Tag_false) const
Halfedge * get_prev(Halfedge *, Tag_false) const
const NT & n
const Halfedge * get_vertex_halfedge(const Vertex *v) const
Vertex * new_vertex(HDS &, const Vertex *, Tag_false) const
Facet * get_facet(Halfedge *, Tag_false) const
void set_vertex_halfedge(Vertex *v, Halfedge *g, Tag_true) const
void close_tip(Halfedge *h, Vertex *v) const
void set_facet_halfedge(Facet *f, Halfedge *g, Tag_true) const
Facet * new_facet(HDS &, const Facet *, Tag_false) const
void set_facet_halfedge(Facet *, Halfedge *, Tag_false) const
const Halfedge * find_prev(const Halfedge *h, Tag_false) const
Halfedge * get_vertex_halfedge(Vertex *v, Tag_true) const
Halfedge * add_facet_to_border(HDS &hds, Halfedge *h, Halfedge *g)
Halfedge * split_facet(HDS &hds, Halfedge *h, Halfedge *g)
void fill_hole(HDS &, Halfedge *, Tag_false)
bool is_border() const
Is the edge a border edge?
Definition: Manifold_2.h:476
void Assert_compile_time_tag(const Tag &, const Derived &b)
const Vertex * get_vertex(const Halfedge *h) const
j indices j
Definition: Indexing.h:6
void make_hole(HDS &hds, Halfedge *h, Tag_true)
Vertex * get_vertex(Halfedge *h, Tag_true) const
Vertex * new_vertex(HDS &hds, const Point &p, Tag_true) const
void set_facet(Halfedge *h, Facet *f) const
void set_facet_halfedge(Halfedge *h, Halfedge *g, Tag_true) const
void set_facet(Halfedge *, Facet *, Tag_false) const
Vertex * new_vertex(HDS &hds, const Vertex *v) const
const Halfedge * get_prev(const Halfedge *, Tag_false) const
void set_vertex_halfedge(Vertex *v, Halfedge *g) const
Vertex * get_vertex(Halfedge *, Tag_false) const
const Halfedge * find_prev(const Halfedge *h, Tag_true) const
_HDS::Supports_halfedge_vertex Supports_halfedge_vertex
#define CGAL_BEGIN_NAMESPACE
Definition: kdtree_d.h:86
void set_vertex(Halfedge *h, Vertex *v) const
#define CGAL_postcondition(EX)
Definition: assertions.h:207
const Halfedge * get_vertex_halfedge(const Vertex *, Tag_false) const
bool normalized_border_is_valid(const _HDS &hds, bool verb=false) const
void set_point(Vertex *v, const Point &p, Tag_true) const
Facet * new_facet(HDS &hds, Tag_true) const
Halfedge * split_loop(HDS &hds, Halfedge *h, Halfedge *i, Halfedge *j)
const Halfedge * get_facet_halfedge(const Facet *f, Tag_true) const
Vertex * new_vertex(HDS &hds, const Point &p) const
void set_prev(Halfedge *h, Halfedge *g) const
Halfedge * get_facet_halfedge(Facet *f, Tag_true) const
#define CGAL_END_NAMESPACE
Definition: kdtree_d.h:87
void erase_facet(HDS &, Halfedge *, Tag_false)
void insert_halfedge(Halfedge *h, Halfedge *f) const
const Facet * get_facet(const Halfedge *h) const
void delete_facet(HDS &hds, Facet *f, Tag_true)
const Halfedge * get_prev(const Halfedge *h, Tag_true) const
Halfedge * join_vertex(HDS &hds, Halfedge *h)
void set_vertex(Halfedge *h, Vertex *v, Tag_true) const
Halfedge * find_prev_around_vertex(Halfedge *h) const
void set_vertex_in_vertex_loop(Halfedge *h, Vertex *v)