Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Polyhedron_incremental_builder_3.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/Polyhedron_incremental_builder_3.h
37 // package : Polyhedron (2.9)
38 // chapter : $CGAL_Chapter: 3D-Polyhedral Surfaces $
39 // source : polyhedron_builder.fw
40 // revision : $Revision: 1.1.1.1 $
41 // revision_date : $Date: 2001/07/05 22:17:48 $
42 // author(s) : Lutz Kettner
43 //
44 // coordinator : MPI Saarbruecken (Stefan Schirra)
45 //
46 // Incremental Construction of Polyhedral Surfaces.
47 // email : contact@cgal.org
48 // www : http://www.cgal.org
49 //
50 // ======================================================================
51 
52 #ifndef CGAL_POLYHEDRON_INCREMENTAL_BUILDER_3_H
53 #define CGAL_POLYHEDRON_INCREMENTAL_BUILDER_3_H 1
54 #ifndef CGAL_RANDOM_ACCESS_VALUE_ADAPTOR_H
56 #endif // CGAL_RANDOM_ACCESS_VALUE_ADAPTOR_H
57 #ifndef CGAL_PROTECT_VECTOR
58 #include <vector>
59 #define CGAL_PROTECT_VECTOR
60 #endif // CGAL_PROTECT_VECTOR
61 #ifndef CGAL_HALFEDGE_DATA_STRUCTURE_DECORATOR_H
63 #endif // CGAL_HALFEDGE_DATA_STRUCTURE_DECORATOR_H
64 #ifndef CGAL_IO_VERBOSE_OSTREAM_H
66 #endif // CGAL_IO_VERBOSE_OSTREAM_H
67 
69 
70 template < class HDS>
72 public:
74  typedef typename HDS::Vertex Vertex;
75  typedef typename HDS::Halfedge Halfedge;
76  typedef typename HDS::Facet Facet;
77  typedef typename HDS::Point Point;
78  typedef typename HDS::Size Size;
79 
80 protected:
81  typedef typename HDS::Supports_vertex_halfedge
83  typedef typename HDS::Supports_removal Supports_removal;
84  typedef typename HDS::Vertex_iterator Vertex_iterator;
87 
88  bool m_error;
89  bool m_verbose;
90  HDS& hds;
99  std::vector<Halfedge*> vertex_to_edge_map;
100 
101  Halfedge* g1; // first halfedge, 0 denotes none.
103  Halfedge* h1; // current halfedge
104  Size w1; // first vertex.
105  Size w2; // second vertex.
106  Size v1; // current vertex
109 
110  CGAL_assertion_code( int check_protocoll;) // use to check protocoll.
111  // states for checking: 0 = created, 1 = constructing, 2 = make facet.
112 
113  // Implement the vertex_to_edge_map either with an array or
114  // the halfedge pointer in the vertices (if supported).
115  // ----------------------------------------------------
118  vertex_to_edge_map = std::vector<Halfedge*>();
119  vertex_to_edge_map.reserve(n);
120  }
123  }
126  vertex_to_edge_map.push_back(h);
127  }
130  }
132  // Use the halfedge pointer within the vertex.
133  return index_to_vertex_map[i].halfedge();
134  }
136  // Use the self-managed array vertex_to_edge_map.
137  return vertex_to_edge_map[i];
138  }
141  }
143  // Use the halfedge pointer within the vertex.
144  index_to_vertex_map[i].set_halfedge(h);
145  }
147  // Use the self-managed array vertex_to_edge_map.
148  vertex_to_edge_map[i] = h;
149  }
152  }
153 
154 // An Incremental Builder for Polyhedral Surfaces
155 // ----------------------------------------------
156 // DEFINITION
157 //
158 // Polyhedron_incremental_builder_3<HDS> is an auxiliary class that
159 // supports the incremental construction of polyhedral surfaces. This is
160 // for example convinient when constructing polyhedral surfaces from
161 // files. The incremental construction starts with a list of all point
162 // coordinates and concludes with a list of all facet polygons. Edges are
163 // not explicitly specified. They are derived from the incidence
164 // information provided from the facet polygons. These are given as a
165 // sequence of vertex indices. The correct protocol of method calls to
166 // build a polyhedral surface can be stated as regular expression:
167 //
168 // `begin_surface (add_vertex | (begin_facet add_vertex_to_facet*
169 // end_facet))* end_surface '
170 //
171 // PARAMETERS
172 //
173 // `HDS' is the halfedge data structure used to represent the
174 // polyhedral surface that is to be constructed.
175 //
176 // CREATION
177 public:
178  bool error() const { return m_error; }
179 
180  Polyhedron_incremental_builder_3(HDS& h, bool verbose = false)
181  // stores a reference to the halfedge data structure `h' in the
182  // internal state. The previous polyhedral surface in `h'
183  // remains unchanged. The incremental builder adds the new
184  // polyhedral surface to the old one.
185  : m_error( false), m_verbose( verbose), hds(h) {
186  CGAL_assertion_code(check_protocoll = 0;)
187  }
188 
190  CGAL_assertion( check_protocoll == 0);
191  }
192 
193 // OPERATIONS
194 
195  #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
196  void begin_surface( Size v, Size f, Size h = 0);
197  #else
198  void begin_surface( std::size_t v, std::size_t f, std::size_t h = 0);
199  #endif
200  // starts the construction. v is the number of
201  // vertices to expect, f the number of facets, and h the number of
202  // halfedges. If h is unspecified (`== 0') it is estimated using
203  // Euler equations (plus 5% for the so far unkown holes and genus
204  // of the object). These values are used to reserve space in the
205  // polyhedron representation `HDS'. If the representation
206  // supports insertion these
207  // values do not restrict the class of readable polyhedrons.
208  // If the representation does not support insertion the object
209  // must fit in the reserved sizes.
210 
211 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
212  void add_vertex( const Point& p);
213  // adds p to the vertex list.
214 #endif
215 
216  void begin_facet();
217  // starts a facet.
218 
219 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
220  void add_vertex_to_facet( Size i);
221 #else
222  void add_vertex_to_facet( std::size_t i);
223 #endif
224  // adds a vertex with index i to the current facet. The first
225  // point added with `add_vertex()' has the index 0.
226 
227  void end_facet();
228  // ends a facet.
229 
230  void end_surface();
231  // ends the construction.
232 
234  // returns `true' if unconnected vertices are detected. If `verb'
235  // is set to `true' debug information about the unconnected
236  // vertices is printed.
237 
240  return ! check_unconnected_vertices();
241  }
243  // returns `true' if all unconnected vertices could be removed
244  // succesfully.
246  }
247 
248  void rollback();
249 
250 protected:
253  return lookup_hole( get_vertex_to_edge_map( w));
254  }
255 
256 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
258  // Returns 0 if v == NULL.
259 
260  Size find_facet( Facet* f);
261  // Returns 0 if f == NULL.
262 
264  // Pre: 0 <= w,v < new_vertices
265  // Case a: It exists an halfedge g from w to v:
266  // g must be a border halfedge and the facet of g->opposite()
267  // must be set and different from the current facet.
268  // Set the facet of g to the current facet. Return the
269  // halfedge pointing to g.
270  // Case b: It exists no halfedge from w to v:
271  // Create a new pair of halfedges g and g->opposite().
272  // Set the facet of g to the current facet and g->opposite()
273  // to a border halfedge. Assign the vertex references.
274  // Set g->opposite()->next() to g. Return g->opposite().
275 
277  // Halfedge e points to a vertex w. Walk around w to find a hole
278  // in the facet structure. Report an error if none exist. Return
279  // the halfedge at this hole that points to the vertex w.
280 
281 #else // CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS //
282  #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
283  template < class HDS> CGAL_LARGE_INLINE
284  typename HDS::Size
286  #else
287  Size
288  #endif
289  find_vertex( Vertex* v) {
290  if ( ! v)
291  return 0;
292  Size n = 0;
293  typename HDS::Vertex_iterator it = hds.vertices_begin();
294  while ( &(*it) != v) {
295  CGAL_assertion( it != hds.vertices_end());
296  ++n;
297  ++it;
298  }
299  n = n - ( hds.size_of_vertices() - new_vertices);
300  return n;
301  }
302 
303  #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
304  template < class HDS> CGAL_LARGE_INLINE
305  typename HDS::Size
307  #else
308  Size
309  #endif
310  find_facet( Facet* f) {
311  if ( ! f)
312  return 0;
313  Size n = 0;
314  typename HDS::Facet_iterator it = hds.facets_begin();
315  while ( &(*it) != f) {
316  CGAL_assertion( it != hds.facets_end());
317  ++n;
318  ++it;
319  }
320  n = n - ( hds.size_of_facets() - new_facets);
321  return n;
322  }
323 
324  #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
325  template < class HDS> CGAL_LARGE_INLINE
326  typename HDS::Halfedge*
328  #else
329  Halfedge*
330  #endif
331  lookup_halfedge( Size w, Size v) {
332  typedef typename HDS::Supports_halfedge_vertex
333  Supports_halfedge_vertex;
334  Assert_compile_time_tag( Supports_halfedge_vertex(), Tag_true());
338  Verbose_ostream verr( m_verbose);
341  if ( e) {
342  CGAL_assertion( e->vertex() == &(index_to_vertex_map[w]));
343  // check that the facet has no self intersections
344  if ( current_facet && current_facet == decorator.get_facet(e)) {
345  verr << " " << std::endl;
346  verr << "Polyhedron_incremental_builder_3<HDS>::"
347  << std::endl;
348  verr << "lookup_halfedge(): input error: facet "
349  << new_facets << " has a self intersection at vertex "
350  << w << "." << std::endl;
351  m_error = true;
352  return 0;
353  }
354  Halfedge* start_edge = e;
355  do {
356  if ( e->next()->vertex() == &(index_to_vertex_map[v]) ) {
357  if ( ! e->next()->is_border()) {
358  verr << " " << std::endl;
359  verr << "Polyhedron_incremental_builder_3"
360  "<HDS>::" << std::endl;
361  verr << "lookup_halfedge(): input error: facet "
362  << new_facets << " shares a halfedge from "
363  "vertex " << w << " to vertex " << v
364  << " with";
365  if ( current_facet)
366  verr << " facet "
367  << find_facet( decorator.get_facet(e->next()))
368  << '.' << std::endl;
369  else
370  verr << " another facet." << std::endl;
371  m_error = true;
372  return 0;
373  }
374  CGAL_assertion( ! e->next()->opposite()->is_border());
375  if ( current_facet &&
376  current_facet ==
377  decorator.get_facet( e->next()->opposite())) {
378  verr << " " << std::endl;
379  verr << "Polyhedron_incremental_builder_3"
380  "<HDS>::" << std::endl;
381  verr << "lookup_halfedge(): input error: facet "
382  << new_facets << " has a self intersection "
383  "at the halfedge from vertex " << w
384  << " to vertex " << v << "." << std::endl;
385  m_error = true;
386  return 0;
387  }
388  decorator.set_facet( e->next(), current_facet);
389  return e;
390  }
391  e = e->next()->opposite();
392  } while ( e != start_edge);
393  }
394  // create a new halfedge
395  if ( hds.size_of_halfedges() >= hds.capacity_of_halfedges()) {
396  verr << " " << std::endl;
397  verr << "Polyhedron_incremental_builder_3<HDS>::" << std::endl;
398  verr << "lookup_halfedge(): capacity error: more than "
399  << new_halfedges << " halfedges added while creating facet"
400  << new_facets << '.' << std::endl;
401  m_error = true;
402  return 0;
403  }
404  e = hds.new_edge();
405  new_halfedges++;
406  new_halfedges++;
407  decorator.set_facet( e, current_facet);
408  e->set_vertex( &(index_to_vertex_map[v]));
409  e->set_next( 0);
410  decorator.set_prev( e, e->opposite());
411  e = e->opposite();
412  e->set_vertex( &(index_to_vertex_map[w]));
413  e->set_next( e->opposite());
414  return e;
415  }
416 
417  #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
418  template < class HDS> CGAL_LARGE_INLINE
419  typename HDS::Halfedge*
421  #else
422  Halfedge*
423  #endif
424  lookup_hole( Halfedge* e) {
425  CGAL_assertion( e != NULL);
427  Halfedge* start_edge = e;
428  do {
429  if ( e->next()->is_border()) {
430  return e;
431  }
432  e = e->next()->opposite();
433  } while ( e != start_edge);
434 
435  Verbose_ostream verr( m_verbose);
436  verr << " " << std::endl;
437  verr << "Polyhedron_incremental_builder_3<HDS>::" << std::endl;
438  verr << "lookup_hole(): input error: at vertex "
439  << find_vertex( e->vertex())
440  << " a closed surface already exists and facet "
441  << new_facets << " is nonetheless adjacent." << std::endl;
442  if ( current_facet) {
443  verr << " The closed cycle of facets is:";
444  do {
445  if ( ! e->is_border())
446  verr << " " << find_facet( decorator.get_facet(e));
447  e = e->next()->opposite();
448  } while ( e != start_edge);
449  verr << '.' << std::endl;
450  }
451  m_error = true;
452  return 0;
453  }
454 
455  #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
456  template < class HDS> CGAL_MEDIUM_INLINE
457  void
459  #else
460  public:
461  void
462  #endif
463  add_vertex( const Point& p) {
464  CGAL_assertion( check_protocoll == 1);
465  if ( hds.size_of_vertices() >= hds.capacity_of_vertices()) {
466  Verbose_ostream verr( m_verbose);
467  verr << " " << std::endl;
468  verr << "Polyhedron_incremental_builder_3<HDS>::" << std::endl;
469  verr << "add_vertex(): capacity error: more than " << new_vertices
470  << " vertices added." << std::endl;
471  m_error = true;
472  return;
473  }
475  Vertex* v = decorator.new_vertex( hds, p);
477  decorator.set_vertex_halfedge( v, 0);
479  ++new_vertices;
480  }
481 #endif // CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS //
482 };
483 
484 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
485 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
486 template < class HDS> CGAL_LARGE_INLINE
487 typename HDS::Size
489 #else
490 Size
491 #endif
493  if ( ! v)
494  return 0;
495  Size n = 0;
496  typename HDS::Vertex_iterator it = hds.vertices_begin();
497  while ( &(*it) != v) {
498  CGAL_assertion( it != hds.vertices_end());
499  ++n;
500  ++it;
501  }
502  n = n - ( hds.size_of_vertices() - new_vertices);
503  return n;
504 }
505 
506 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
507 template < class HDS> CGAL_LARGE_INLINE
508 typename HDS::Size
510 #else
511 Size
512 #endif
514  if ( ! f)
515  return 0;
516  Size n = 0;
517  typename HDS::Facet_iterator it = hds.facets_begin();
518  while ( &(*it) != f) {
519  CGAL_assertion( it != hds.facets_end());
520  ++n;
521  ++it;
522  }
523  n = n - ( hds.size_of_facets() - new_facets);
524  return n;
525 }
526 
527 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
528 template < class HDS> CGAL_LARGE_INLINE
529 typename HDS::Halfedge*
531 #else
532 Halfedge*
533 #endif
535  typedef typename HDS::Supports_halfedge_vertex
536  Supports_halfedge_vertex;
537  Assert_compile_time_tag( Supports_halfedge_vertex(), Tag_true());
541  Verbose_ostream verr( m_verbose);
544  if ( e) {
545  CGAL_assertion( e->vertex() == &(index_to_vertex_map[w]));
546  // check that the facet has no self intersections
547  if ( current_facet && current_facet == decorator.get_facet(e)) {
548  verr << " " << std::endl;
549  verr << "Polyhedron_incremental_builder_3<HDS>::"
550  << std::endl;
551  verr << "lookup_halfedge(): input error: facet "
552  << new_facets << " has a self intersection at vertex "
553  << w << "." << std::endl;
554  m_error = true;
555  return 0;
556  }
557  Halfedge* start_edge = e;
558  do {
559  if ( e->next()->vertex() == &(index_to_vertex_map[v]) ) {
560  if ( ! e->next()->is_border()) {
561  verr << " " << std::endl;
562  verr << "Polyhedron_incremental_builder_3"
563  "<HDS>::" << std::endl;
564  verr << "lookup_halfedge(): input error: facet "
565  << new_facets << " shares a halfedge from "
566  "vertex " << w << " to vertex " << v
567  << " with";
568  if ( current_facet)
569  verr << " facet "
570  << find_facet( decorator.get_facet(e->next()))
571  << '.' << std::endl;
572  else
573  verr << " another facet." << std::endl;
574  m_error = true;
575  return 0;
576  }
577  CGAL_assertion( ! e->next()->opposite()->is_border());
578  if ( current_facet &&
579  current_facet ==
580  decorator.get_facet( e->next()->opposite())) {
581  verr << " " << std::endl;
582  verr << "Polyhedron_incremental_builder_3"
583  "<HDS>::" << std::endl;
584  verr << "lookup_halfedge(): input error: facet "
585  << new_facets << " has a self intersection "
586  "at the halfedge from vertex " << w
587  << " to vertex " << v << "." << std::endl;
588  m_error = true;
589  return 0;
590  }
591  decorator.set_facet( e->next(), current_facet);
592  return e;
593  }
594  e = e->next()->opposite();
595  } while ( e != start_edge);
596  }
597  // create a new halfedge
598  if ( hds.size_of_halfedges() >= hds.capacity_of_halfedges()) {
599  verr << " " << std::endl;
600  verr << "Polyhedron_incremental_builder_3<HDS>::" << std::endl;
601  verr << "lookup_halfedge(): capacity error: more than "
602  << new_halfedges << " halfedges added while creating facet"
603  << new_facets << '.' << std::endl;
604  m_error = true;
605  return 0;
606  }
607  e = hds.new_edge();
608  new_halfedges++;
609  new_halfedges++;
610  decorator.set_facet( e, current_facet);
611  e->set_vertex( &(index_to_vertex_map[v]));
612  e->set_next( 0);
613  decorator.set_prev( e, e->opposite());
614  e = e->opposite();
615  e->set_vertex( &(index_to_vertex_map[w]));
616  e->set_next( e->opposite());
617  return e;
618 }
619 
620 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
621 template < class HDS> CGAL_LARGE_INLINE
622 typename HDS::Halfedge*
624 #else
625 Halfedge*
626 #endif
628  CGAL_assertion( e != NULL);
630  Halfedge* start_edge = e;
631  do {
632  if ( e->next()->is_border()) {
633  return e;
634  }
635  e = e->next()->opposite();
636  } while ( e != start_edge);
637 
638  Verbose_ostream verr( m_verbose);
639  verr << " " << std::endl;
640  verr << "Polyhedron_incremental_builder_3<HDS>::" << std::endl;
641  verr << "lookup_hole(): input error: at vertex "
642  << find_vertex( e->vertex())
643  << " a closed surface already exists and facet "
644  << new_facets << " is nonetheless adjacent." << std::endl;
645  if ( current_facet) {
646  verr << " The closed cycle of facets is:";
647  do {
648  if ( ! e->is_border())
649  verr << " " << find_facet( decorator.get_facet(e));
650  e = e->next()->opposite();
651  } while ( e != start_edge);
652  verr << '.' << std::endl;
653  }
654  m_error = true;
655  return 0;
656 }
657 
658 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
659 template < class HDS> CGAL_MEDIUM_INLINE
660 void
662 #else
663 public:
664 void
665 #endif
666 add_vertex( const Point& p) {
667  CGAL_assertion( check_protocoll == 1);
668  if ( hds.size_of_vertices() >= hds.capacity_of_vertices()) {
669  Verbose_ostream verr( m_verbose);
670  verr << " " << std::endl;
671  verr << "Polyhedron_incremental_builder_3<HDS>::" << std::endl;
672  verr << "add_vertex(): capacity error: more than " << new_vertices
673  << " vertices added." << std::endl;
674  m_error = true;
675  return;
676  }
678  Vertex* v = decorator.new_vertex( hds, p);
680  decorator.set_vertex_halfedge( v, 0);
682  ++new_vertices;
683 }
684 #endif // CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS //
685 template < class HDS>
686 void
689  CGAL_assertion( rollback_v <= hds.size_of_vertices());
690  CGAL_assertion( rollback_h <= hds.size_of_halfedges());
691  CGAL_assertion( rollback_f <= hds.size_of_facets());
692  while ( rollback_v != hds.size_of_vertices())
693  hds.vertex_pop_back();
694  CGAL_assertion((( hds.size_of_halfedges() - rollback_h) & 1) == 0);
695  while ( rollback_h != hds.size_of_halfedges())
696  hds.edge_pop_back();
697  while ( rollback_f != hds.size_of_facets())
698  hds.facet_pop_back();
699  m_error = false;
700  CGAL_assertion_code( check_protocoll = 0;)
701 }
702 
703 template < class HDS> CGAL_MEDIUM_INLINE
704 void
706 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
708 #else
709 begin_surface( std::size_t v, std::size_t f, std::size_t h) {
710 #endif
711  CGAL_assertion( check_protocoll == 0);
712  CGAL_assertion_code( check_protocoll = 1;)
714  new_vertices = 0;
715  new_facets = 0;
716  new_halfedges = 0;
717  rollback_v = hds.size_of_vertices();
718  rollback_f = hds.size_of_facets();
719  rollback_h = hds.size_of_halfedges();
720  if ( h == 0) {
721  // Use the Eulerian equation for connected planar graphs. We do
722  // not know the number of facets that are holes and we do not
723  // know the genus of the surface. So we add 12 and a factor of
724  // 5 percent.
725  h = int((v + f - 2 + 12) * 2.1);
726  }
727  hds.reserve( hds.size_of_vertices() + v,
728  hds.size_of_halfedges() + h,
729  hds.size_of_facets() + f);
730  index_to_vertex_map = Random_access_index( hds.vertices_end());
733 }
734 
735 template < class HDS> CGAL_MEDIUM_INLINE
736 void
739  if ( m_error)
740  return;
741  CGAL_assertion( check_protocoll == 1);
742  CGAL_assertion_code( check_protocoll = 2;)
743  if ( hds.size_of_facets() >= hds.capacity_of_facets()) {
744  Verbose_ostream verr( m_verbose);
745  verr << " " << std::endl;
746  verr << "Polyhedron_incremental_builder_3<HDS>::" << std::endl;
747  verr << "begin_facet(): capacity error: more than " << new_vertices
748  << " facets added." << std::endl;
749  m_error = true;
750  return;
751  }
752  // initialize all status variables.
753  first_vertex = true; // denotes 'no vertex yet'
754  g1 = 0; // denotes 'no halfedge yet'
755  last_vertex = false;
756 
758  current_facet = decorator.new_facet( hds);
759 }
760 
761 template < class HDS>
762 void
764 #ifndef CGAL_CFG_NO_SCOPE_MEMBER_FUNCTION_PARAMETERS
766 #else
767 add_vertex_to_facet( std::size_t v2) {
768 #endif
769  if ( m_error)
770  return;
771  Verbose_ostream verr( m_verbose);
772  CGAL_assertion( check_protocoll == 2);
773  if ( v2 >= new_vertices) {
774  verr << " " << std::endl;
775  verr << "Polyhedron_incremental_builder_3<HDS>::" << std::endl;
776  verr << "add_vertex_to_facet(): vertex index " << v2
777  << " is out-of-range [0," << new_vertices-1 << "]."
778  << std::endl;
779  m_error = true;
780  return;
781  }
783 
784  if ( first_vertex) {
786  w1 = v2;
787  first_vertex = false;
788  return;
789  }
790  if ( g1 == 0) {
792  gprime = lookup_halfedge( w1, v2);
793  if ( m_error)
794  return;
795  h1 = g1 = gprime->next();
796  v1 = w2 = v2;
797  return;
798  }
799  // g1, h1, v1, w1, w2 are set. Insert halfedge.
800  // Lookup v1-->v2
801  Halfedge* hprime;
802  if ( last_vertex)
803  hprime = gprime;
804  else {
805  hprime = lookup_halfedge( v1, v2);
806  if ( m_error)
807  return;
808  }
809  Halfedge* h2 = hprime->next();
810  CGAL_assertion( ! last_vertex || h2 == g1);
811  Halfedge* prev = h1->next();
812  h1->set_next( h2);
813  decorator.set_prev( h2, h1);
814 
815  if ( get_vertex_to_edge_map( v1) == 0) { // case 1:
816  h2->opposite()->set_next( h1->opposite());
817  decorator.set_prev( h1->opposite(), h2->opposite());
818  } else { // case 2:
819  bool b1 = h1->opposite()->is_border();
820  bool b2 = h2->opposite()->is_border();
821  if ( b1 && b2) {
822  Halfedge* hole = lookup_hole( v1);
823  if ( m_error)
824  return;
825  CGAL_assertion( hole != NULL);
826  h2->opposite()->set_next( hole->next());
827  decorator.set_prev( hole->next(), h2->opposite());
828  hole->set_next( h1->opposite());
829  decorator.set_prev( h1->opposite(), hole);
830  } else if ( b2) { // case 2.b:
831  CGAL_assertion( prev->is_border());
832  h2->opposite()->set_next( prev);
833  decorator.set_prev( prev, h2->opposite());
834  } else if ( b1) { // case 2.c:
835  CGAL_assertion( hprime->is_border());
836  hprime->set_next( h1->opposite());
837  decorator.set_prev( h1->opposite(), hprime);
838  } else if ( h2->opposite()->next() == h1->opposite()) {// case 2.d:
839  // f1 == f2
840  CGAL_assertion( decorator.get_facet( h1->opposite()) ==
841  decorator.get_facet( h2->opposite()));
842  } else { // case 2.e:
843  if ( prev == h2) { // case _i:
844  // nothing to be done, hole is closed.
845  } else { // case _ii:
846  CGAL_assertion( prev->is_border());
847  CGAL_assertion( hprime->is_border());
848  hprime->set_next( prev);
849  decorator.set_prev( prev, hprime);
850  // Check whether the halfedges around v1 are connected.
851  // It is sufficient to check it for h1 to prev.
852  // Assert loop termination.
853  CGAL_assertion_code( std::size_t k = 0;)
854  // Look for a hole in the facet complex starting at h1.
855  Halfedge* hole = 0;
856  Halfedge* e = h1;
857  do {
858  if ( e->is_border())
859  hole = e;
860  e = e->next()->opposite();
861  CGAL_assertion( k++ < hds.size_of_halfedges());
862  } while ( e->next() != prev && e != h1);
863  if ( e == h1) {
864  // disconnected facet complexes
865  if ( hole) {
866  // The complex can be connected with
867  // the hole at hprime.
868  hprime->set_next( hole->next());
869  decorator.set_prev( hole->next(), hprime);
870  hole->set_next( prev);
871  decorator.set_prev( prev, hole);
872  } else {
873  verr << " " << std::endl;
874  verr << "Polyhedron_incremental_builder_3<"
875  "HDS>::" << std::endl;
876  verr << "add_vertex_to_facet(): input error: "
877  "disconnected facet complexes at vertex "
878  << v1 << ":" << std::endl;
879 
880  if ( current_facet && m_verbose) {
881  verr << " involved facets are:";
882  do {
883  if ( ! e->is_border())
884  verr << " " << find_facet(
885  decorator.get_facet(e));
886  e = e->next()->opposite();
887  } while ( e != h1);
888  verr << " (closed cycle) and";
889  e = hprime;
890  do {
891  if ( ! e->is_border())
892  verr << " " << find_facet(
893  decorator.get_facet(e));
894  } while ( e != hprime);
895  verr << "." << std::endl;
896  }
897  m_error = true;
898  return;
899  }
900  }
901  }
902  }
903  }
904  if( h1->vertex() == &(index_to_vertex_map[v1]))
906  CGAL_assertion( h1->vertex() == &(index_to_vertex_map[v1]));
907  h1 = h2;
908  v1 = v2;
909 }
910 
911 template < class HDS>
912 void
915  if ( m_error)
916  return;
917  CGAL_assertion( check_protocoll == 2);
919  // cleanup all static status variables
921  last_vertex = true;
923  CGAL_assertion( check_protocoll == 2);
924  CGAL_assertion_code( check_protocoll = 1;)
928  ++new_facets;
929 }
930 
931 template < class HDS> CGAL_MEDIUM_INLINE
932 void
935  if ( m_error)
936  return;
937  CGAL_assertion( check_protocoll == 1);
938  CGAL_assertion_code( check_protocoll = 0;)
939 }
940 
941 template < class HDS>
942 bool
945  if ( m_error)
946  return false;
947  bool unconnected = false;
948  Verbose_ostream verr( m_verbose);
949  for( std::size_t i = 0; i < new_vertices; i++) {
950  if( get_vertex_to_edge_map( i) == NULL) {
951  verr << "Polyhedron_incremental_builder_3<HDS>::\n"
952  << "check_unconnected_vertices( verb = true): "
953  << "vertex " << i << " is unconnected." << std::endl;
954  unconnected = true;
955  }
956  }
957  return unconnected;
958 }
959 
960 template < class HDS>
961 bool
964  if ( m_error)
965  return true;
966  for( std::size_t i = 0; i < new_vertices; i++) {
967  if( get_vertex_to_edge_map( i) == NULL) {
968  hds.delete_vertex( &index_to_vertex_map[i]);
969  }
970  }
971  return true;
972 }
973 
975 #endif // CGAL_POLYHEDRON_INCREMENTAL_BUILDER_3_H //
976 // EOF //
#define CGAL_assertion(EX)
Definition: assertions.h:87
j indices k indices k
Definition: Indexing.h:6
#define CGAL_LARGE_INLINE
Halfedge opposite() const
Get the ID of the opposite edge of a given edge.
Definition: Manifold_2.h:454
void push_back_vertex_to_edge_map(Halfedge *, Tag_true)
void push_back_vertex_to_edge_map(Halfedge *h, Tag_false)
This class encapsulate a halfedge over a window manifold.
Definition: Manifold_2.h:446
void set_facet_halfedge(Facet *f, Halfedge *g) const
Tag_true void initialize_vertex_to_edge_map(Size n, Tag_false)
Halfedge next() const
Get the next halfedge of its owner element.
Definition: Manifold_2.h:465
HDS::Supports_vertex_halfedge Supports_vertex_halfedge
#define CGAL_MEDIUM_INLINE
*********************************************************************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
Random_access_value_adaptor< Vertex_iterator, Vertex > Random_access_index
void set_vertex_to_edge_map(int i, Halfedge *h, Tag_true)
blockLoc i
Definition: read.cpp:79
void set_vertex_to_edge_map(int i, Halfedge *h, Tag_false)
const NT & n
CGAL_assertion_code(int check_protocoll;) void initialize_vertex_to_edge_map(Size
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)
void reserve(size_type r, std::forward_iterator_tag)
void set_facet(Halfedge *h, Facet *f) const
void set_vertex_halfedge(Vertex *v, Halfedge *g) const
#define CGAL_BEGIN_NAMESPACE
Definition: kdtree_d.h:86
void set_prev(Halfedge *h, Halfedge *g) const
#define CGAL_END_NAMESPACE
Definition: kdtree_d.h:87
Halfedge * get_vertex_to_edge_map(int i, Tag_false)
void push_back(const IC &k, std::forward_iterator_tag)