BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Polyhedron_3.h
Go to the documentation of this file.
00001 // Copyright (c) 1997  ETH Zurich (Switzerland).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under
00005 // the terms of the Q Public License version 1.0.
00006 // See the file LICENSE.QPL distributed with CGAL.
00007 //
00008 // Licensees holding a valid commercial license may use this file in
00009 // accordance with the commercial license agreement provided with the software.
00010 //
00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 //
00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Polyhedron/include/CGAL/Polyhedron_3.h $
00015 // $Id: Polyhedron_3.h 49918 2009-06-15 13:09:47Z lsaboret $
00016 //
00017 //
00018 // Author(s)     : Lutz Kettner  <kettner@mpi-sb.mpg.de>)
00019 
00020 #ifndef CGAL_POLYHEDRON_3_H
00021 #define CGAL_POLYHEDRON_3_H 1
00022 
00023 #include <CGAL/basic.h>
00024 #include <algorithm>
00025 #include <cstddef>
00026 
00027 #include <CGAL/HalfedgeDS_iterator.h>
00028 #include <CGAL/Iterator_project.h>
00029 #include <CGAL/function_objects.h>
00030 #include <CGAL/N_step_adaptor_derived.h>
00031 #include <CGAL/Polyhedron_items_3.h>
00032 #include <CGAL/HalfedgeDS_default.h>
00033 #include <CGAL/HalfedgeDS_const_decorator.h>
00034 #include <CGAL/HalfedgeDS_decorator.h>
00035 #include <CGAL/Modifier_base.h>
00036 #include <CGAL/IO/Verbose_ostream.h>
00037 #include <CGAL/Polyhedron_traits_3.h>
00038 
00039 CGAL_BEGIN_NAMESPACE
00040 
00041 template <class VertexBase>
00042 class I_Polyhedron_vertex  : public VertexBase  {
00043 public:
00044     typedef VertexBase                            Base;
00045     //typedef typename Base::HalfedgeDS              HDS;
00046     typedef typename Base::Point                   Point;
00047     typedef Point                                  Point_3;
00048 
00049     // Handles have to explicitly repeated, although they are derived
00050     typedef typename Base::Vertex_handle           Vertex_handle;
00051     typedef typename Base::Halfedge_handle         Halfedge_handle;
00052     typedef typename Base::Face_handle             Face_handle;
00053     typedef typename Base::Face_handle             Facet_handle;
00054     typedef typename Base::Vertex_const_handle     Vertex_const_handle;
00055     typedef typename Base::Halfedge_const_handle   Halfedge_const_handle;
00056     typedef typename Base::Face_const_handle       Face_const_handle;
00057     typedef typename Base::Face_const_handle       Facet_const_handle;
00058     typedef typename Base::Halfedge                Halfedge;
00059     typedef typename Base::Face                    Face;
00060     typedef typename Base::Face                    Facet;
00061 
00062     // Supported options by HDS.
00063     typedef typename Base::Supports_vertex_halfedge
00064                                                   Supports_vertex_halfedge;
00065     typedef typename Base::Supports_vertex_point  Supports_vertex_point;
00066 
00067     // Circulator category.
00068     typedef typename Halfedge::Supports_halfedge_prev  Supports_prev;
00069 
00070 public:
00071     // Circulator category.
00072     typedef HalfedgeDS_circulator_traits<Supports_prev> Ctr;
00073     typedef typename Ctr::iterator_category circulator_category;
00074 
00075     // Circulators around a vertex and around a facet.
00076     typedef I_HalfedgeDS_facet_circ< Halfedge_handle, circulator_category>
00077                                          Halfedge_around_facet_circulator;
00078 
00079     typedef I_HalfedgeDS_vertex_circ< Halfedge_handle, circulator_category>
00080                                         Halfedge_around_vertex_circulator;
00081 
00082     typedef I_HalfedgeDS_facet_circ<
00083         Halfedge_const_handle,
00084         circulator_category>       Halfedge_around_facet_const_circulator;
00085 
00086     typedef I_HalfedgeDS_vertex_circ<
00087         Halfedge_const_handle,
00088         circulator_category>      Halfedge_around_vertex_const_circulator;
00089 
00090 
00091 
00092     typedef typename Halfedge_around_vertex_circulator::size_type
00093         size_type;
00094     typedef typename Halfedge_around_vertex_circulator::difference_type
00095         difference_type;
00096 
00097 public:
00098     // We need to repeat the constructors here.
00099     I_Polyhedron_vertex() {}
00100     I_Polyhedron_vertex( const VertexBase& b) : VertexBase(b) {}
00101     I_Polyhedron_vertex( const Point_3& p) : VertexBase(p) {}
00102 
00103 // New Access Functions (not provided in VertexBase).
00104 
00105     Halfedge_around_vertex_circulator vertex_begin() {
00106         // a circulator of halfedges around the vertex (clockwise).
00107         return Halfedge_around_vertex_circulator( this->halfedge());
00108     }
00109     Halfedge_around_vertex_const_circulator vertex_begin() const {
00110         // a circulator of halfedges around the vertex (clockwise).
00111         return Halfedge_around_vertex_const_circulator( this->halfedge());
00112     }
00113 
00114     // the degree of the vertex, i.e., edges emanating from this vertex
00115     std::size_t vertex_degree() const {
00116         return this->halfedge()->vertex_degree();
00117     }
00118     size_type degree() const { return vertex_degree(); } //backwards compatible
00119 
00120     // returns true if the vertex has exactly two incident edges
00121     bool is_bivalent() const { return  this->halfedge()->is_bivalent(); }
00122 
00123     // returns true if the vertex has exactly three incident edges
00124     bool is_trivalent() const { return  this->halfedge()->is_trivalent(); }
00125 
00126     // No longer hidden. Now the restricted version with precondition.
00127     // sets incident halfedge to h. Precondition: h is incident, i.e.,
00128     // h->vertex() == v.
00129     void  set_halfedge( Halfedge_handle hh) {
00130         CGAL_assertion( &*(hh->vertex()) == this);
00131         Base::set_halfedge(hh);
00132     }
00133 };
00134 
00135 // A halfedge is an oriented edge. Both orientations exist, i.e.
00136 // an edge is represented by two opposite halfedges. The geometric
00137 // relations are as follows:
00138 //
00139 //              _ _ _   .
00140 //             /        |\.
00141 //                      | \.
00142 //           /             \ next half
00143 //                          \ edge
00144 //         /                 \.
00145 //
00146 //        |                   O  incident vertex
00147 //                facet      ,
00148 //        |                 /| |
00149 //                         / | | opposite
00150 //         \                 | | half edge
00151 //                      half | |
00152 //           \          edge | | /
00153 //                           | |/
00154 //             \_ _ _ _ _ _    '
00155 //
00156 
00157 template <class HalfedgeBase>
00158 class I_Polyhedron_halfedge : public HalfedgeBase {
00159 public:
00160     typedef HalfedgeBase                          Base;
00161     typedef typename Base::HalfedgeDS              HDS;
00162 
00163     // Handles have to explicitly repeated, although they are derived
00164     typedef typename Base::Vertex_handle           Vertex_handle;
00165     typedef typename Base::Halfedge_handle         Halfedge_handle;
00166     typedef typename Base::Face_handle             Face_handle;
00167     typedef typename Base::Face_handle             Facet_handle;
00168     typedef typename Base::Vertex_const_handle     Vertex_const_handle;
00169     typedef typename Base::Halfedge_const_handle   Halfedge_const_handle;
00170     typedef typename Base::Face_const_handle       Face_const_handle;
00171     typedef typename Base::Face_const_handle       Facet_const_handle;
00172 
00173     typedef typename Base::Vertex                  Vertex;
00174     typedef typename Base::Face                    Face;
00175     typedef typename Base::Face                    Facet;
00176 
00177     // Supported options by HDS.
00178     typedef typename Base::Supports_halfedge_prev Supports_halfedge_prev;
00179     typedef typename Base::Supports_halfedge_vertex
00180                                                   Supports_halfedge_vertex;
00181     typedef typename Base::Supports_halfedge_face Supports_halfedge_face;
00182 
00183     // Circulator category.
00184     typedef typename Base::Supports_halfedge_prev Supports_prev;
00185 
00186 public:
00187     // Circulator category.
00188     typedef HalfedgeDS_circulator_traits<Supports_prev> Ctr;
00189     typedef typename Ctr::iterator_category circulator_category;
00190 
00191     // Circulators around a vertex and around a facet.
00192     typedef I_HalfedgeDS_facet_circ< Halfedge_handle, circulator_category>
00193                                          Halfedge_around_facet_circulator;
00194 
00195     typedef I_HalfedgeDS_vertex_circ< Halfedge_handle, circulator_category>
00196                                         Halfedge_around_vertex_circulator;
00197 
00198     typedef I_HalfedgeDS_facet_circ<
00199         Halfedge_const_handle,
00200         circulator_category>       Halfedge_around_facet_const_circulator;
00201 
00202     typedef I_HalfedgeDS_vertex_circ<
00203         Halfedge_const_handle,
00204         circulator_category>      Halfedge_around_vertex_const_circulator;
00205 
00206 
00207 
00208 public:
00209     I_Polyhedron_halfedge() {}
00210     I_Polyhedron_halfedge( const HalfedgeBase& b) : HalfedgeBase(b) {}
00211 
00212 // New Access Functions (not provided in HalfedgeBase).
00213 
00214     // Change semantic of prev: it is always available at this level.
00215     // If the HDS does not provide a prev-function, the previous
00216     // halfedge will be searched around the incident facet.
00217 private:
00218     Halfedge_handle       find_prev( Halfedge_handle,       Tag_true) {
00219         return Base::prev();
00220     }
00221     Halfedge_const_handle find_prev( Halfedge_const_handle, Tag_true) const {
00222         return Base::prev();
00223     }
00224     Halfedge_handle find_prev( Halfedge_handle h, Tag_false) const {
00225         CGAL_precondition( &*h != this); // we have at least 2-gons
00226         while ( &*(h->next()) != this)
00227             h = h->next();
00228         return h;
00229     }
00230     Halfedge_const_handle find_prev( Halfedge_const_handle h, Tag_false) const{
00231         CGAL_precondition( &*h != this); // we have at least 2-gons
00232         while ( &*(h->next()) != this)
00233             h = h->next();
00234         return h;
00235     }
00236 
00237 public:
00238     Halfedge_handle       prev() {
00239         return find_prev( this->next(), Supports_halfedge_prev());
00240     }
00241     Halfedge_const_handle prev() const {
00242         return find_prev( this->next(), Supports_halfedge_prev());
00243     }
00244 
00245     // Make face-functions also available as facet-functions.
00246     Face_handle           facet()       { return this->face();}
00247     Face_const_handle     facet() const { return this->face();}
00248 
00249 
00250     // the next halfedge around the vertex (clockwise). This is equal to
00251     // `h.next()->opposite()'.
00252     Halfedge_handle       next_on_vertex() { return this->next()->opposite(); }
00253     Halfedge_const_handle next_on_vertex() const {
00254         return this->next()->opposite();
00255     }
00256 
00257     // the previous halfedge around the vertex (counterclockwise). Is
00258     // equal to `h.opposite()->prev()'.
00259     Halfedge_handle       prev_on_vertex() { return this->opposite()->prev(); }
00260     Halfedge_const_handle prev_on_vertex() const {
00261         return this->opposite()->prev();
00262     }
00263 
00264     bool is_border_edge() const {
00265         // is true if `h' or `h.opposite()' is a border halfedge.
00266         return (this->opposite()->is_border() || this->is_border());
00267     }
00268 
00269     // a circulator of halfedges around the vertex (clockwise).
00270     Halfedge_around_vertex_circulator vertex_begin() {
00271         return Halfedge_around_vertex_circulator(
00272             HDS::halfedge_handle(this));
00273     }
00274     Halfedge_around_vertex_const_circulator vertex_begin() const {
00275         return Halfedge_around_vertex_const_circulator(
00276             HDS::halfedge_handle(this));
00277     }
00278 
00279     // a circulator of halfedges around the facet (counterclockwise).
00280     Halfedge_around_facet_circulator facet_begin() {
00281         return Halfedge_around_facet_circulator(
00282             HDS::halfedge_handle(this));
00283     }
00284     Halfedge_around_facet_const_circulator facet_begin() const {
00285         return Halfedge_around_facet_const_circulator(
00286             HDS::halfedge_handle(this));
00287     }
00288 
00289     // the degree of the incident vertex, i.e., edges emanating from this
00290     // vertex
00291     std::size_t vertex_degree() const {
00292         return circulator_size( vertex_begin());
00293     }
00294 
00295     // the degree of the incident facet, i.e., edges on the boundary of this
00296     // facet
00297     std::size_t facet_degree() const {
00298         return circulator_size( facet_begin());
00299     }
00300 
00301     // returns true if the incident vertex has exactly two incident edges
00302     bool is_bivalent() const {
00303         CGAL_precondition( this != &* (this->next()->opposite()));
00304         return  (this == &* (this->next()->opposite()->next()->opposite()));
00305     }
00306 
00307     // returns true if the incident vertex has exactly three incident edges
00308     bool is_trivalent() const {
00309         CGAL_precondition( this != &* (this->next()->opposite()));
00310         return  (   this != &* (this->next()->opposite()->next()->opposite())
00311                  && this == &* (this->next()->opposite()->next()->opposite()
00312                                 ->next()->opposite()));
00313     }
00314 
00315     // returns true if the incident facet is a triangle.
00316     bool is_triangle() const {
00317         CGAL_precondition( this != &* (this->next()));
00318         CGAL_precondition( this != &* (this->next()->next()));
00319         return  (this == &* (this->next()->next()->next()));
00320     }
00321 
00322     // returns true if the incident facet is a quadrilateral.
00323     bool is_quad()     const {
00324         CGAL_precondition( this != &* (this->next()));
00325         CGAL_precondition( this != &* (this->next()->next()));
00326         return  (this == &* (this->next()->next()->next()->next()));
00327     }
00328 
00329 
00330 private:
00331     // Hide some other functions of H.
00332     void  set_next( Halfedge_handle hh)  { Base::set_next(hh);}
00333     void  set_prev( Halfedge_handle hh)  { Base::set_prev(hh);}
00334     void  set_vertex( Vertex_handle vv)  { Base::set_vertex(vv);}
00335     void  set_face( Face_handle ff)      { Base::set_face(ff);}
00336     void  set_facet( Face_handle ff)     { set_face(ff);}
00337 };
00338 
00339 
00340 template <class FacetBase>
00341 class I_Polyhedron_facet  : public FacetBase  {
00342 public:
00343     typedef FacetBase                             Base;
00344     //typedef typename Base::HalfedgeDS              HDS;
00345     typedef typename Base::Plane                   Plane;
00346     typedef Plane                                  Plane_3;
00347 
00348     // Handles have to explicitly repeated, although they are derived
00349     typedef typename Base::Vertex_handle           Vertex_handle;
00350     typedef typename Base::Halfedge_handle         Halfedge_handle;
00351     typedef typename Base::Face_handle             Face_handle;
00352     typedef typename Base::Face_handle             Facet_handle;
00353     typedef typename Base::Vertex_const_handle     Vertex_const_handle;
00354     typedef typename Base::Halfedge_const_handle   Halfedge_const_handle;
00355     typedef typename Base::Face_const_handle       Face_const_handle;
00356     typedef typename Base::Face_const_handle       Facet_const_handle;
00357     typedef typename Base::Vertex                  Vertex;
00358     typedef typename Base::Halfedge                Halfedge;
00359 
00360     // Supported options by HDS.
00361     typedef typename Base::Supports_face_halfedge Supports_face_halfedge;
00362     typedef typename Base::Supports_face_plane    Supports_face_plane;
00363 
00364     // No longer required.
00365     typedef Tag_false                             Supports_face_normal;
00366 
00367     // Circulator category.
00368     typedef typename Halfedge::Supports_halfedge_prev  Supports_prev;
00369 
00370 public:
00371     // Circulator category.
00372     typedef HalfedgeDS_circulator_traits<Supports_prev> Ctr;
00373     typedef typename Ctr::iterator_category circulator_category;
00374 
00375     // Circulators around a vertex and around a facet.
00376     typedef I_HalfedgeDS_facet_circ< Halfedge_handle, circulator_category>
00377                                          Halfedge_around_facet_circulator;
00378 
00379     typedef I_HalfedgeDS_vertex_circ< Halfedge_handle, circulator_category>
00380                                         Halfedge_around_vertex_circulator;
00381 
00382     typedef I_HalfedgeDS_facet_circ<
00383         Halfedge_const_handle,
00384         circulator_category>       Halfedge_around_facet_const_circulator;
00385 
00386     typedef I_HalfedgeDS_vertex_circ<
00387         Halfedge_const_handle,
00388         circulator_category>      Halfedge_around_vertex_const_circulator;
00389 
00390 
00391 
00392     typedef typename Halfedge_around_vertex_circulator::size_type
00393         size_type;
00394     typedef typename Halfedge_around_vertex_circulator::difference_type
00395         difference_type;
00396 
00397 public:
00398     // We need to repeat the constructors here.
00399     I_Polyhedron_facet() {}
00400     I_Polyhedron_facet( const FacetBase& b) : FacetBase(b) {}
00401 
00402 // New Access Functions (not provided in FacetBase).
00403 
00404     Halfedge_around_facet_circulator facet_begin() {
00405         // a circulator of halfedges around the facet (counterclockwise).
00406         return Halfedge_around_facet_circulator( this->halfedge());
00407     }
00408     Halfedge_around_facet_const_circulator facet_begin() const {
00409         // a circulator of halfedges around the facet (counterclockwise).
00410         return Halfedge_around_facet_const_circulator( this->halfedge());
00411     }
00412 
00413     // the degree of the incident facet, i.e., edges on the boundary of this
00414     // facet
00415     std::size_t facet_degree() const {return this->halfedge()->facet_degree();}
00416     size_type size() const { return facet_degree(); } // backwards compatible
00417 
00418     // returns true if the facet is a triangle.
00419     bool is_triangle() const { return this->halfedge()->is_triangle(); }
00420 
00421     // returns true if the facet is a quadrilateral.
00422     bool is_quad()     const { return this->halfedge()->is_quad(); }
00423 
00424     // No longer hidden. Now the restricted version with precondition.
00425     // sets incident halfedge to h. Precondition: h is incident, i.e.,
00426     // h->face() == v.
00427     void  set_halfedge( Halfedge_handle hh) {
00428         CGAL_assertion( &*(hh->facet()) == this);
00429         Base::set_halfedge(hh);
00430     }
00431 };
00432 
00433 
00434 template < class Items>
00435 class I_Polyhedron_derived_items_3 {
00436 public:
00437     template < class Refs, class Traits>
00438     class Vertex_wrapper {
00439     public:
00440         typedef typename Items::template Vertex_wrapper<Refs,Traits> VWrap;
00441         typedef typename VWrap::Vertex Vertex_base;
00442         typedef I_Polyhedron_vertex< Vertex_base> Vertex;
00443     };
00444     template < class Refs, class Traits>
00445     class Halfedge_wrapper {
00446     public:
00447         typedef typename Items::template Halfedge_wrapper<Refs,Traits> HWrap;
00448         typedef typename HWrap::Halfedge Halfedge_base;
00449         typedef I_Polyhedron_halfedge< Halfedge_base> Halfedge;
00450     };
00451     template < class Refs, class Traits>
00452     class Face_wrapper {
00453     public:
00454         typedef typename Items::template Face_wrapper<Refs,Traits> FWrap;
00455         typedef typename FWrap::Face Face_base;
00456         typedef I_Polyhedron_facet< Face_base> Face;
00457     };
00458 };
00459 
00460 
00461 template < class PolyhedronTraits_3,
00462            class PolyhedronItems_3 = Polyhedron_items_3,
00463 #ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
00464            template < class T, class I, class A>
00465 #endif
00466            class T_HDS = HalfedgeDS_default,
00467            class Alloc = CGAL_ALLOCATOR(int)>
00468 class Polyhedron_3 {
00469     //
00470     // DEFINITION
00471     //
00472     // The boundary representation of a 3d-polyhedron P of the type
00473     // Polyhedron consists of vertices, edges and facets. The
00474     // vertices are points in space. The edges are straight line
00475     // segments. The facets are planar polygons. We restrict here
00476     // the facets to be simple planar polygons without holes and the
00477     // boundary of the polyhedron to be an oriented 2-manifold. Thus
00478     // facets are consistently oriented and an edge is incident to
00479     // exactly two facets. We restrict the representation further
00480     // that an edge has two distinct incident endpoints and
00481     // following duality that an edge has two distinct incident
00482     // facets. The class Polyhedron is able to guarantee
00483     // the combinatorial properties, but not all geometric
00484     // properties. Support functions are provided for testing
00485     // geometric properties, e.g. test for self intersections which
00486     // is  too expensive to be guaranteed as a class invariant.
00487 public:
00488     typedef Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>
00489                                                   Self;
00490     typedef PolyhedronTraits_3                    Traits;
00491     typedef PolyhedronItems_3                     Items;
00492     typedef I_Polyhedron_derived_items_3<Items>   Derived_items;
00493 #ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
00494     typedef T_HDS< Traits, Derived_items, Alloc>  HDS;
00495 #else
00496     typedef typename T_HDS::template HDS< Traits, Derived_items, Alloc>  HDS;
00497 #endif
00498     typedef HDS                                   HalfedgeDS;
00499 
00500     // portability with older CGAL release
00501     typedef HDS                                   Halfedge_data_structure;
00502 
00503     typedef Alloc                                 Allocator;
00504     typedef Alloc                                 allocator_type; // STL name
00505 
00506     // Container stuff.
00507     typedef typename HDS::size_type               size_type;
00508     typedef typename HDS::difference_type         difference_type;
00509     typedef typename HDS::iterator_category       iterator_category;
00510     typedef typename HDS::Supports_removal        Supports_removal;
00511 
00512     // Geometry
00513     typedef typename Traits::Point_3              Point_3;
00514     typedef typename Traits::Plane_3              Plane_3;
00515     // No longer required.
00516     //typedef typename Traits::Normal               Normal;
00517 
00518     // Items
00519     typedef typename HDS::Vertex                  Vertex;
00520     typedef typename HDS::Halfedge                Halfedge;
00521     typedef typename HDS::Face                    Face;
00522 
00523     typedef typename Vertex::Base                 VBase;
00524     typedef typename Halfedge::Base               HBase;
00525     typedef typename Face::Base                   FBase;
00526 
00527     // Handles and Iterators
00528     typedef typename HDS::Vertex_handle           Vertex_handle;
00529     typedef typename HDS::Halfedge_handle         Halfedge_handle;
00530     typedef typename HDS::Face_handle             Face_handle;
00531     typedef typename HDS::Vertex_iterator         Vertex_iterator;
00532     typedef typename HDS::Halfedge_iterator       Halfedge_iterator;
00533     typedef typename HDS::Face_iterator           Face_iterator;
00534 
00535     typedef typename HDS::Vertex_const_handle     Vertex_const_handle;
00536     typedef typename HDS::Halfedge_const_handle   Halfedge_const_handle;
00537     typedef typename HDS::Face_const_handle       Face_const_handle;
00538     typedef typename HDS::Vertex_const_iterator   Vertex_const_iterator;
00539     typedef typename HDS::Halfedge_const_iterator Halfedge_const_iterator;
00540     typedef typename HDS::Face_const_iterator     Face_const_iterator;
00541 
00542     // Auxiliary iterators for convenience
00543     typedef Project_point<Vertex>                 Proj_point;
00544     typedef Iterator_project<Vertex_iterator, Proj_point>
00545                                                   Point_iterator;
00546     typedef Iterator_project<Vertex_const_iterator, Proj_point,
00547         const Point_3&, const Point_3*>           Point_const_iterator;
00548 
00549     typedef Project_plane<Face>                   Proj_plane;
00550     typedef Iterator_project<Face_iterator, Proj_plane>
00551                                                   Plane_iterator;
00552     typedef Iterator_project<Face_const_iterator, Proj_plane,
00553         const Plane_3&, const Plane_3*>           Plane_const_iterator;
00554 
00555     typedef N_step_adaptor_derived<Halfedge_iterator, 2>
00556                                                   Edge_iterator;
00557     typedef N_step_adaptor_derived<Halfedge_const_iterator, 2>
00558                                                   Edge_const_iterator;
00559 
00560     // All face related types get a related facet type name.
00561     typedef Face                                  Facet;
00562     typedef Face_handle                           Facet_handle;
00563     typedef Face_iterator                         Facet_iterator;
00564     typedef Face_const_handle                     Facet_const_handle;
00565     typedef Face_const_iterator                   Facet_const_iterator;
00566 
00567     // Supported options by HDS.
00568     typedef typename VBase::Supports_vertex_halfedge
00569                                                   Supports_vertex_halfedge;
00570     typedef typename HBase::Supports_halfedge_prev  Supports_halfedge_prev;
00571     typedef typename HBase::Supports_halfedge_prev  Supports_prev;
00572     typedef typename HBase::Supports_halfedge_vertex
00573                                                   Supports_halfedge_vertex;
00574     typedef typename HBase::Supports_halfedge_face  Supports_halfedge_face;
00575     typedef typename FBase::Supports_face_halfedge  Supports_face_halfedge;
00576 
00577     // Supported options especially for Polyhedron_3.
00578     typedef typename VBase::Supports_vertex_point   Supports_vertex_point;
00579     typedef typename FBase::Supports_face_plane     Supports_face_plane;
00580 
00581     // No longer required.
00582     typedef Tag_false                               Supports_face_normal;
00583 
00584     // Renamed versions for facet
00585     typedef Supports_halfedge_face  Supports_halfedge_facet;
00586     typedef Supports_face_halfedge  Supports_facet_halfedge;
00587     typedef Supports_face_plane     Supports_facet_plane;
00588     // No longer required.
00589     typedef Supports_face_normal    Supports_facet_normal;
00590 
00591 public:
00592     // Circulator category.
00593     typedef HalfedgeDS_circulator_traits<Supports_prev> Ctr;
00594     typedef typename Ctr::iterator_category circulator_category;
00595 
00596     // Circulators around a vertex and around a facet.
00597     typedef I_HalfedgeDS_facet_circ< Halfedge_handle, circulator_category>
00598                                          Halfedge_around_facet_circulator;
00599 
00600     typedef I_HalfedgeDS_vertex_circ< Halfedge_handle, circulator_category>
00601                                         Halfedge_around_vertex_circulator;
00602 
00603     typedef I_HalfedgeDS_facet_circ<
00604         Halfedge_const_handle,
00605         circulator_category>       Halfedge_around_facet_const_circulator;
00606 
00607     typedef I_HalfedgeDS_vertex_circ<
00608         Halfedge_const_handle,
00609         circulator_category>      Halfedge_around_vertex_const_circulator;
00610 
00611 
00612 
00613 protected:
00614     HDS     hds;  // the boundary representation.
00615     Traits  m_traits;
00616 
00617 // CREATION
00618 public:
00619 
00620     Polyhedron_3( const Traits& trts = Traits()) : m_traits(trts) {}
00621         // the empty polyhedron `P'.
00622 
00623     Polyhedron_3( size_type v, size_type h, size_type f,
00624                   const Traits& traits = Traits())
00625     : hds(v,h,f), m_traits(traits) {}
00626         // a polyhedron `P' with storage reserved for v vertices, h
00627         // halfedges, and f facets. The reservation sizes are a hint for
00628         // optimizing storage allocation.
00629 
00630     void reserve( size_type v, size_type h, size_type f) {
00631         // reserve storage for v vertices, h halfedges, and f facets. The
00632         // reservation sizes are a hint for optimizing storage allocation.
00633         // If the `capacity' is already greater than the requested size
00634         // nothing happens. If the `capacity' changes all iterators and
00635         // circulators invalidates.
00636         hds.reserve(v,h,f);
00637     }
00638 
00639 protected:
00640     Halfedge_handle
00641     make_triangle( Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) {
00642         HalfedgeDS_decorator<HDS> decorator(hds);
00643         Halfedge_handle h  = hds.edges_push_back( Halfedge(), Halfedge());
00644         h->HBase::set_next( hds.edges_push_back( Halfedge(), Halfedge()));
00645         h->next()->HBase::set_next( hds.edges_push_back( Halfedge(),
00646                                                          Halfedge()));
00647         h->next()->next()->HBase::set_next( h);
00648         decorator.set_prev( h, h->next()->next());
00649         decorator.set_prev( h->next(), h);
00650         decorator.set_prev( h->next()->next(), h->next());
00651         h->opposite()->HBase::set_next( h->next()->next()->opposite());
00652         h->next()->opposite()->HBase::set_next( h->opposite());
00653         h->next()->next()->opposite()->HBase::set_next(
00654             h->next()->opposite());
00655         decorator.set_prev( h->opposite(), h->next()->opposite());
00656         decorator.set_prev( h->next()->opposite(),
00657                             h->next()->next()->opposite());
00658         decorator.set_prev( h->next()->next()->opposite(), h->opposite());
00659         // the vertices
00660         decorator.set_vertex( h, v1);
00661         decorator.set_vertex( h->next(), v2);
00662         decorator.set_vertex( h->next()->next(), v3);
00663         decorator.set_vertex( h->opposite(), v3);
00664         decorator.set_vertex( h->next()->opposite(), v1);
00665         decorator.set_vertex( h->next()->next()->opposite(), v2);
00666         decorator.set_vertex_halfedge( h);
00667         decorator.set_vertex_halfedge( h->next());
00668         decorator.set_vertex_halfedge( h->next()->next());
00669         // the facet
00670         Facet_handle f = decorator.faces_push_back( Facet());
00671         decorator.set_face( h, f);
00672         decorator.set_face( h->next(), f);
00673         decorator.set_face( h->next()->next(), f);
00674         decorator.set_face_halfedge( h);
00675         return h;
00676     }
00677 
00678     Halfedge_handle
00679     make_tetrahedron( Vertex_handle v1,
00680                       Vertex_handle v2,
00681                       Vertex_handle v3,
00682                       Vertex_handle v4) {
00683         HalfedgeDS_decorator<HDS> decorator(hds);
00684         Halfedge_handle h  = make_triangle(v1,v2,v3);
00685         // The remaining tip.
00686         Halfedge_handle g  = hds.edges_push_back( Halfedge(), Halfedge());
00687         decorator.insert_tip( g->opposite(), h->opposite());
00688         decorator.close_tip( g);
00689         decorator.set_vertex( g, v4);
00690         Halfedge_handle e  = hds.edges_push_back( Halfedge(), Halfedge());
00691         Halfedge_handle d  = hds.edges_push_back( Halfedge(), Halfedge());
00692         decorator.insert_tip( e->opposite(), h->next()->opposite());
00693         decorator.insert_tip( e, g);
00694         decorator.insert_tip( d->opposite(),h->next()->next()->opposite());
00695         decorator.insert_tip( d, e);
00696         decorator.set_vertex_halfedge( g);
00697         // facets
00698         Facet_handle f = decorator.faces_push_back( Facet());
00699         decorator.set_face( h->opposite(), f);
00700         decorator.set_face( g, f);
00701         decorator.set_face( e->opposite(), f);
00702         decorator.set_face_halfedge( g);
00703         f = decorator.faces_push_back( Facet());
00704         decorator.set_face( h->next()->opposite(), f);
00705         decorator.set_face( e, f);
00706         decorator.set_face( d->opposite(), f);
00707         decorator.set_face_halfedge( e);
00708         f = decorator.faces_push_back( Facet());
00709         decorator.set_face( h->next()->next()->opposite(), f);
00710         decorator.set_face( d, f);
00711         decorator.set_face( g->opposite(), f);
00712         decorator.set_face_halfedge( d);
00713         return h;
00714     }
00715 
00716 public:
00717     Halfedge_handle make_tetrahedron() {
00718         // the combinatorial structure of a tetrahedron is added to the
00719         // actual polyhedral surface. Returns an arbitrary halfedge of
00720         // this structure.
00721         reserve( 4 + size_of_vertices(),
00722                 12 + size_of_halfedges(),
00723                  4 + size_of_facets());
00724         HalfedgeDS_decorator<HDS> decorator(hds);
00725         return make_tetrahedron( decorator.vertices_push_back( Vertex()),
00726                                  decorator.vertices_push_back( Vertex()),
00727                                  decorator.vertices_push_back( Vertex()),
00728                                  decorator.vertices_push_back( Vertex()));
00729     }
00730 
00731     Halfedge_handle make_tetrahedron( const Point_3& p1,
00732                                       const Point_3& p2,
00733                                       const Point_3& p3,
00734                                       const Point_3& p4) {
00735         reserve( 4 + size_of_vertices(),
00736                 12 + size_of_halfedges(),
00737                  4 + size_of_facets());
00738         HalfedgeDS_decorator<HDS> decorator(hds);
00739         return make_tetrahedron( decorator.vertices_push_back( Vertex(p1)),
00740                                  decorator.vertices_push_back( Vertex(p2)),
00741                                  decorator.vertices_push_back( Vertex(p3)),
00742                                  decorator.vertices_push_back( Vertex(p4)));
00743 
00744     }
00745 
00746     Halfedge_handle make_triangle() {
00747         // the combinatorial structure of a single triangle with border
00748         // edges is added to the actual polyhedral surface. Returns an
00749         // arbitrary halfedge of this structure.
00750         reserve( 3 + size_of_vertices(),
00751                  6 + size_of_halfedges(),
00752                  1 + size_of_facets());
00753         HalfedgeDS_decorator<HDS> decorator(hds);
00754         return make_triangle( decorator.vertices_push_back( Vertex()),
00755                               decorator.vertices_push_back( Vertex()),
00756                               decorator.vertices_push_back( Vertex()));
00757     }
00758 
00759     Halfedge_handle make_triangle( const Point_3& p1,
00760                                    const Point_3& p2,
00761                                    const Point_3& p3) {
00762         // the single triangle p_1, p_2, p_3 with border edges is added to
00763         // the actual polyhedral surface. Returns an arbitrary halfedge of
00764         // this structure.
00765         reserve( 3 + size_of_vertices(),
00766                  6 + size_of_halfedges(),
00767                  1 + size_of_facets());
00768         HalfedgeDS_decorator<HDS> decorator(hds);
00769         return make_triangle( decorator.vertices_push_back( Vertex(p1)),
00770                               decorator.vertices_push_back( Vertex(p2)),
00771                               decorator.vertices_push_back( Vertex(p3)));
00772     }
00773 
00774 // Access Member Functions
00775 
00776     allocator_type get_allocator() const { return hds.get_allocator(); }
00777 
00778     size_type size_of_vertices() const { return hds.size_of_vertices();}
00779         // number of vertices.
00780 
00781     size_type size_of_halfedges() const { return hds.size_of_halfedges();}
00782         // number of all halfedges (including border halfedges).
00783 
00784     size_type size_of_facets() const { return hds.size_of_faces();}
00785         // number of facets.
00786 
00787     bool empty() const { return size_of_halfedges() == 0; }
00788 
00789     size_type capacity_of_vertices() const {
00790         // space reserved for vertices.
00791         return hds.capacity_of_vertices();
00792     }
00793 
00794     size_type capacity_of_halfedges() const {
00795         // space reserved for halfedges.
00796         return hds.capacity_of_halfedges();
00797     }
00798 
00799     size_type capacity_of_facets() const {
00800         // space reserved for facets.
00801         return hds.capacity_of_faces();
00802     }
00803 
00804     std::size_t bytes() const {
00805         // bytes used for the polyhedron.
00806         return sizeof(Self) - sizeof(HDS) + hds.bytes();
00807     }
00808 
00809     std::size_t bytes_reserved() const {
00810         // bytes reserved for the polyhedron.
00811         return sizeof(Self) - sizeof(HDS) + hds.bytes_reserved();
00812     }
00813 
00814     Vertex_iterator vertices_begin() { return hds.vertices_begin();}
00815         // iterator over all vertices.
00816 
00817     Vertex_iterator vertices_end() { return hds.vertices_end();}
00818 
00819     Halfedge_iterator halfedges_begin() { return hds.halfedges_begin();}
00820         // iterator over all halfedges
00821 
00822     Halfedge_iterator halfedges_end() { return hds.halfedges_end();}
00823 
00824     Facet_iterator facets_begin() { return hds.faces_begin();}
00825         // iterator over all facets
00826 
00827     Facet_iterator facets_end() { return hds.faces_end();}
00828 
00829     // The constant iterators and circulators.
00830 
00831     Vertex_const_iterator vertices_begin() const {
00832         return hds.vertices_begin();
00833     }
00834     Vertex_const_iterator vertices_end() const {
00835         return hds.vertices_end();
00836     }
00837 
00838     Halfedge_const_iterator halfedges_begin() const {
00839       return hds.halfedges_begin();
00840     }
00841     Halfedge_const_iterator halfedges_end() const {
00842         return hds.halfedges_end();
00843     }
00844     Facet_const_iterator facets_begin() const { return hds.faces_begin();}
00845     Facet_const_iterator facets_end()   const { return hds.faces_end();}
00846 
00847     // Auxiliary iterators for convinience
00848     Point_iterator       points_begin()       { return vertices_begin();}
00849     Point_iterator       points_end()         { return vertices_end();}
00850 
00851     Point_const_iterator points_begin() const { return vertices_begin();}
00852     Point_const_iterator points_end()   const { return vertices_end();}
00853 
00854     Plane_iterator       planes_begin()       { return facets_begin();}
00855     Plane_iterator       planes_end()         { return facets_end();}
00856 
00857     Plane_const_iterator planes_begin() const { return facets_begin();}
00858     Plane_const_iterator planes_end()   const { return facets_end();}
00859 
00860     Edge_iterator        edges_begin()        { return halfedges_begin();}
00861         // iterator over all edges. The iterator refers to halfedges, but
00862         // enumerates only one of the two corresponding opposite
00863         // halfedges.
00864     Edge_iterator        edges_end()          { return halfedges_end();}
00865         // end of the range over all edges.
00866 
00867     Edge_const_iterator  edges_begin()  const { return halfedges_begin();}
00868     Edge_const_iterator  edges_end()    const { return halfedges_end();}
00869 
00870     Traits&       traits()       { return m_traits; }
00871     const Traits& traits() const { return m_traits; }
00872 
00873 
00874 // Combinatorial Predicates
00875 
00876     bool is_closed() const {
00877         for ( Halfedge_const_iterator i = halfedges_begin();
00878               i != halfedges_end(); ++i) {
00879             if ( i->is_border())
00880                 return false;
00881         }
00882         return true;
00883     }
00884 
00885 private:
00886     bool is_pure_bivalent( Tag_true) const {
00887         for ( Vertex_const_iterator i = vertices_begin();
00888               i != vertices_end(); ++i)
00889             if ( ! i->is_bivalent())
00890                 return false;
00891         return true;
00892     }
00893     bool is_pure_bivalent( Tag_false) const {
00894         for ( Halfedge_const_iterator i = halfedges_begin();
00895               i != halfedges_end(); ++i)
00896             if ( ! i->is_bivalent())
00897                 return false;
00898         return true;
00899     }
00900 
00901 public:
00902     // returns true if all vertices have exactly two incident edges
00903     bool is_pure_bivalent() const {
00904         return is_pure_bivalent( Supports_vertex_halfedge());
00905     }
00906 
00907 private:
00908     bool is_pure_trivalent( Tag_true) const {
00909         for ( Vertex_const_iterator i = vertices_begin();
00910               i != vertices_end(); ++i)
00911             if ( ! i->is_trivalent())
00912                 return false;
00913         return true;
00914     }
00915     bool is_pure_trivalent( Tag_false) const {
00916         for ( Halfedge_const_iterator i = halfedges_begin();
00917               i != halfedges_end(); ++i)
00918             if ( ! i->is_trivalent())
00919                 return false;
00920         return true;
00921     }
00922 
00923 public:
00924     // returns true if all vertices have exactly three incident edges
00925     bool is_pure_trivalent() const {
00926         return is_pure_trivalent( Supports_vertex_halfedge());
00927     }
00928 
00929 private:
00930     bool is_pure_triangle( Tag_true) const {
00931         for ( Facet_const_iterator i = facets_begin();
00932               i != facets_end(); ++i)
00933             if ( ! i->is_triangle())
00934                 return false;
00935         return true;
00936     }
00937     bool is_pure_triangle( Tag_false) const {
00938         for ( Halfedge_const_iterator i = halfedges_begin();
00939               i != halfedges_end(); ++i)
00940             if ( ! i->is_border() && ! i->is_triangle())
00941                 return false;
00942         return true;
00943     }
00944 
00945 public:
00946     // returns true if all facets are triangles
00947     bool is_pure_triangle() const {
00948         return is_pure_triangle( Supports_facet_halfedge());
00949     }
00950 
00951 private:
00952     bool is_pure_quad( Tag_true) const {
00953         for ( Facet_const_iterator i = facets_begin();
00954               i != facets_end(); ++i)
00955             if ( ! i->is_quad())
00956                 return false;
00957         return true;
00958     }
00959     bool is_pure_quad( Tag_false) const {
00960         for ( Halfedge_const_iterator i = halfedges_begin();
00961               i != halfedges_end(); ++i)
00962             if ( ! i->is_border() && ! i->is_quad())
00963                 return false;
00964         return true;
00965     }
00966 
00967 public:
00968     // returns true if all facets are quadrilaterals
00969     bool is_pure_quad() const {
00970         return is_pure_quad( Supports_facet_halfedge());
00971     }
00972 
00973 
00974 // Geometric Predicates
00975 
00976     bool
00977     is_triangle( Halfedge_const_handle h1) const {
00978         Halfedge_const_handle h2 = h1->next();
00979         Halfedge_const_handle h3 = h1->next()->next();
00980         // check halfedge combinatorics.
00981         // exact two edges at vertices 1, 2, 3.
00982         if ( h1->opposite()->next() != h3->opposite())    return false;
00983         if ( h2->opposite()->next() != h1->opposite())    return false;
00984         if ( h3->opposite()->next() != h2->opposite())    return false;
00985         // The facet is a triangle.
00986         if ( h1->next()->next()->next() != h1) return false;
00987 
00988         if ( check_tag( Supports_halfedge_face())
00989              &&  ! h1->is_border_edge())
00990             return false;  // implies h2 and h3
00991         CGAL_assertion( ! h1->is_border() || ! h1->opposite()->is_border());
00992 
00993         // Assert consistency.
00994         CGAL_assertion( h1 != h2);
00995         CGAL_assertion( h1 != h3);
00996         CGAL_assertion( h3 != h2);
00997 
00998         // check prev pointer.
00999         CGAL_assertion_code( HalfedgeDS_items_decorator<HDS> D;)
01000         CGAL_assertion(D.get_prev(h1) == Halfedge_handle() ||
01001                        D.get_prev(h1) == h3);
01002         CGAL_assertion(D.get_prev(h2) == Halfedge_handle() ||
01003                        D.get_prev(h2) == h1);
01004         CGAL_assertion(D.get_prev(h3) == Halfedge_handle() ||
01005                        D.get_prev(h3) == h2);
01006 
01007         // check vertices.
01008         CGAL_assertion( D.get_vertex(h1) == D.get_vertex( h2->opposite()));
01009         CGAL_assertion( D.get_vertex(h2) == D.get_vertex( h3->opposite()));
01010         CGAL_assertion( D.get_vertex(h3) == D.get_vertex( h1->opposite()));
01011 
01012         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01013                    D.get_vertex(h1) != D.get_vertex(h2));
01014         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01015                    D.get_vertex(h1) != D.get_vertex(h3));
01016         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01017                    D.get_vertex(h2) != D.get_vertex(h3));
01018 
01019         // check facets.
01020         CGAL_assertion( D.get_face(h1) == D.get_face(h2));
01021         CGAL_assertion( D.get_face(h1) == D.get_face(h3));
01022 
01023         return true;
01024     }
01025 
01026     bool
01027     is_tetrahedron( Halfedge_const_handle h1) const {
01028         Halfedge_const_handle h2 = h1->next();
01029         Halfedge_const_handle h3 = h1->next()->next();
01030         Halfedge_const_handle h4 = h1->opposite()->next();
01031         Halfedge_const_handle h5 = h2->opposite()->next();
01032         Halfedge_const_handle h6 = h3->opposite()->next();
01033         // check halfedge combinatorics.
01034         // at least three edges at vertices 1, 2, 3.
01035         if ( h4 == h3->opposite())    return false;
01036         if ( h5 == h1->opposite())    return false;
01037         if ( h6 == h2->opposite())    return false;
01038         // exact three edges at vertices 1, 2, 3.
01039         if ( h4->opposite()->next() != h3->opposite())    return false;
01040         if ( h5->opposite()->next() != h1->opposite())    return false;
01041         if ( h6->opposite()->next() != h2->opposite())    return false;
01042         // three edges at v4.
01043         if ( h4->next()->opposite() != h5) return false;
01044         if ( h5->next()->opposite() != h6) return false;
01045         if ( h6->next()->opposite() != h4) return false;
01046         // All facets are triangles.
01047         if ( h1->next()->next()->next() != h1) return false;
01048         if ( h4->next()->next()->next() != h4) return false;
01049         if ( h5->next()->next()->next() != h5) return false;
01050         if ( h6->next()->next()->next() != h6) return false;
01051         // all edges are non-border edges.
01052         if ( h1->is_border()) return false;  // implies h2 and h3
01053         CGAL_assertion( ! h2->is_border());
01054         CGAL_assertion( ! h3->is_border());
01055         if ( h4->is_border()) return false;
01056         if ( h5->is_border()) return false;
01057         if ( h6->is_border()) return false;
01058 
01059         // Assert consistency.
01060         CGAL_assertion( h1 != h2);
01061         CGAL_assertion( h1 != h3);
01062         CGAL_assertion( h3 != h2);
01063         CGAL_assertion( h4 != h5);
01064         CGAL_assertion( h5 != h6);
01065         CGAL_assertion( h6 != h4);
01066 
01067         // check prev pointer.
01068         CGAL_assertion_code( HalfedgeDS_items_decorator<HDS> D;)
01069         CGAL_assertion(D.get_prev(h1) == Halfedge_handle() ||
01070                        D.get_prev(h1) == h3);
01071         CGAL_assertion(D.get_prev(h2) == Halfedge_handle() ||
01072                        D.get_prev(h2) == h1);
01073         CGAL_assertion(D.get_prev(h3) == Halfedge_handle() ||
01074                        D.get_prev(h3) == h2);
01075         CGAL_assertion(D.get_prev(h4) == Halfedge_handle() ||
01076                   D.get_prev(h4) == h1->opposite());
01077         CGAL_assertion(D.get_prev(h5) == Halfedge_handle() ||
01078                   D.get_prev(h5) == h2->opposite());
01079         CGAL_assertion(D.get_prev(h6) == Halfedge_handle() ||
01080                   D.get_prev(h6) == h3->opposite());
01081 
01082         // check vertices.
01083         CGAL_assertion( D.get_vertex(h1) == D.get_vertex( h2->opposite()));
01084         CGAL_assertion( D.get_vertex(h1) == D.get_vertex( h5->opposite()));
01085         CGAL_assertion( D.get_vertex(h2) == D.get_vertex( h3->opposite()));
01086         CGAL_assertion( D.get_vertex(h2) == D.get_vertex( h6->opposite()));
01087         CGAL_assertion( D.get_vertex(h3) == D.get_vertex( h1->opposite()));
01088         CGAL_assertion( D.get_vertex(h3) == D.get_vertex( h4->opposite()));
01089         CGAL_assertion( D.get_vertex(h4) == D.get_vertex( h5));
01090         CGAL_assertion( D.get_vertex(h4) == D.get_vertex( h6));
01091 
01092         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01093                    D.get_vertex(h1) != D.get_vertex(h2));
01094         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01095                    D.get_vertex(h1) != D.get_vertex(h3));
01096         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01097                    D.get_vertex(h1) != D.get_vertex(h4));
01098         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01099                    D.get_vertex(h2) != D.get_vertex(h3));
01100         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01101                    D.get_vertex(h2) != D.get_vertex(h4));
01102         CGAL_assertion( ! check_tag( Supports_halfedge_vertex()) ||
01103                    D.get_vertex(h3) != D.get_vertex(h4));
01104 
01105         // check facets.
01106         CGAL_assertion( D.get_face(h1) == D.get_face(h2));
01107         CGAL_assertion( D.get_face(h1) == D.get_face(h3));
01108         CGAL_assertion( D.get_face(h4) == D.get_face(h4->next()));
01109         CGAL_assertion( D.get_face(h4) == D.get_face(h1->opposite()));
01110         CGAL_assertion( D.get_face(h5) == D.get_face(h5->next()));
01111         CGAL_assertion( D.get_face(h5) == D.get_face(h2->opposite()));
01112         CGAL_assertion( D.get_face(h6) == D.get_face(h6->next()));
01113         CGAL_assertion( D.get_face(h6) == D.get_face(h3->opposite()));
01114 
01115         CGAL_assertion( ! check_tag( Supports_halfedge_face()) ||
01116                    D.get_face(h1) != D.get_face(h4));
01117         CGAL_assertion( ! check_tag( Supports_halfedge_face()) ||
01118                    D.get_face(h1) != D.get_face(h5));
01119         CGAL_assertion( ! check_tag( Supports_halfedge_face()) ||
01120                    D.get_face(h1) != D.get_face(h6));
01121         CGAL_assertion( ! check_tag( Supports_halfedge_face()) ||
01122                    D.get_face(h4) != D.get_face(h5));
01123         CGAL_assertion( ! check_tag( Supports_halfedge_face()) ||
01124                    D.get_face(h4) != D.get_face(h6));
01125         CGAL_assertion( ! check_tag( Supports_halfedge_face()) ||
01126                    D.get_face(h5) != D.get_face(h6));
01127 
01128         return true;
01129     }
01130 
01131 // Euler Operators (Combinatorial Modifications)
01132 //
01133 // The following Euler operations modify consistently the combinatorial
01134 // structure of the polyhedral surface. The geometry remains unchanged.
01135 
01136     Halfedge_handle split_facet( Halfedge_handle h, Halfedge_handle g) {
01137         // split the facet incident to `h' and `g' into two facets with
01138         // new diagonal between the two vertices denoted by `h' and `g'
01139         // respectively. The second (new) facet is a copy of the first
01140         // facet. It returns the new diagonal. The time is proportional to
01141         // the distance from `h' to `g' around the facet. Precondition:
01142         // `h' and `g' are incident to the same facet. `h != g' (no
01143         // loops). `h->next() != g' and `g->next() != h' (no multi-edges).
01144         reserve( size_of_vertices(),
01145                  2 + size_of_halfedges(),
01146                  1 + size_of_facets());
01147         HalfedgeDS_decorator<HDS> D(hds);
01148         CGAL_precondition( D.get_face(h) == D.get_face(g));
01149         CGAL_precondition( h != g);
01150         CGAL_precondition( h != g->next());
01151         CGAL_precondition( h->next() != g);
01152         return D.split_face( h, g);
01153     }
01154 
01155     Halfedge_handle join_facet( Halfedge_handle h) {
01156         // join the two facets incident to h. The facet incident to
01157         // `h->opposite()' gets removed. Both facets might be holes.
01158         // Returns the predecessor of h. The invariant `join_facet(
01159         // split_facet( h, g))' returns h and keeps the polyhedron
01160         // unchanged. The time is proportional to the size of the facet
01161         // removed and the time to compute `h.prev()'. Precondition:
01162         // `HDS' supports removal of facets. The degree of both
01163         // vertices incident to h is at least three (no antennas).
01164         HalfedgeDS_decorator<HDS> D(hds);
01165         CGAL_precondition( circulator_size(h->vertex_begin())
01166                            >= size_type(3));
01167         CGAL_precondition( circulator_size(h->opposite()->vertex_begin())
01168                            >= size_type(3));
01169         return D.join_face(h);
01170     }
01171 
01172     Halfedge_handle split_vertex( Halfedge_handle h, Halfedge_handle g) {
01173         // split the vertex incident to `h' and `g' into two vertices and
01174         // connects them with a new edge. The second (new) vertex is a
01175         // copy of the first vertex. It returns the new edge. The time is
01176         // proportional to the distance from `h' to `g' around the vertex.
01177         // Precondition: `h' and `g' are incident to the same vertex. `h
01178         // != g' (no antennas). `h->next() != g' and `g->next() != h'.
01179         reserve( 1 + size_of_vertices(),
01180                  2 + size_of_halfedges(),
01181                  size_of_facets());
01182         HalfedgeDS_decorator<HDS> D(hds);
01183         CGAL_precondition( D.get_vertex(h) == D.get_vertex(g));
01184         CGAL_precondition( h != g);
01185         return D.split_vertex( h, g);
01186     }
01187 
01188     Halfedge_handle join_vertex( Halfedge_handle h) {
01189         // join the two vertices incident to h. The vertex denoted by
01190         // `h->opposite()' gets removed. Returns the predecessor of h. The
01191         // invariant `join_vertex( split_vertex( h, g))' returns h and
01192         // keeps the polyhedron unchanged. The time is proportional to
01193         // the degree of the vertex removed and the time to compute
01194         // `h.prev()'.
01195         // Precondition: `HDS' supports removal of vertices. The size of
01196         // both facets incident to h is at least four (no multi-edges)
01197         HalfedgeDS_decorator<HDS> D(hds);
01198         CGAL_precondition( circulator_size( h->facet_begin())
01199                            >= size_type(4));
01200         CGAL_precondition( circulator_size( h->opposite()->facet_begin())
01201                            >= size_type(4));
01202         return D.join_vertex(h);
01203     }
01204 
01205     Halfedge_handle split_edge( Halfedge_handle h) {
01206         return split_vertex( h->prev(), h->opposite())->opposite();
01207     }
01208 
01209     Halfedge_handle flip_edge( Halfedge_handle h) {
01210         HalfedgeDS_items_decorator<HDS> D;
01211         return D.flip_edge(h);
01212     }
01213 
01214     Halfedge_handle create_center_vertex( Halfedge_handle h) {
01215         HalfedgeDS_decorator<HDS> D(hds);
01216         CGAL_assertion( circulator_size( h->facet_begin())
01217                         >= size_type(3));
01218         return D.create_center_vertex(h);
01219     }
01220 
01221     Halfedge_handle erase_center_vertex( Halfedge_handle h) {
01222         HalfedgeDS_decorator<HDS> D(hds);
01223         return D.erase_center_vertex(h);
01224     }
01225 
01226 // Euler Operators Modifying Genus
01227 
01228     Halfedge_handle split_loop( Halfedge_handle h,
01229                                 Halfedge_handle i,
01230                                 Halfedge_handle j) {
01231         // cut the polyhedron into two parts along the cycle (h,i,j).
01232         // Three copies of the vertices and two new triangles will be
01233         // created. h,i,j will be incident to the first new triangle. The
01234         // returnvalue will be an halfedge iterator denoting the new
01235         // halfegdes of the second new triangle which was h beforehand.
01236         // Precondition: h,i,j are distinct, consecutive vertices of the
01237         // polyhedron and form a cycle: i.e. `h->vertex() == i->opposite()
01238         // ->vertex()', ..., `j->vertex() == h->opposite()->vertex()'. The
01239         // six facets incident to h,i,j are all distinct.
01240         reserve( 3 + size_of_vertices(),
01241                  6 + size_of_halfedges(),
01242                  2 + size_of_facets());
01243         HalfedgeDS_decorator<HDS> D(hds);
01244         CGAL_precondition( h != i);
01245         CGAL_precondition( h != j);
01246         CGAL_precondition( i != j);
01247         CGAL_precondition( D.get_vertex(h) == D.get_vertex(i->opposite()));
01248         CGAL_precondition( D.get_vertex(i) == D.get_vertex(j->opposite()));
01249         CGAL_precondition( D.get_vertex(j) == D.get_vertex(h->opposite()));
01250         CGAL_precondition( D.get_face(h) == Facet_handle() ||
01251                            D.get_face(h) != D.get_face(i));
01252         CGAL_precondition( D.get_face(h) == Facet_handle() ||
01253                            D.get_face(h) != D.get_face(j));
01254         CGAL_precondition( D.get_face(i) == Facet_handle() ||
01255                            D.get_face(i) != D.get_face(j));
01256         CGAL_precondition( D.get_face(h) == Facet_handle() ||
01257                            D.get_face(h) != D.get_face(h->opposite()));
01258         CGAL_precondition( D.get_face(h) == Facet_handle() ||
01259                            D.get_face(h) != D.get_face(i->opposite()));
01260         CGAL_precondition( D.get_face(h) == Facet_handle() ||
01261                            D.get_face(h) != D.get_face(j->opposite()));
01262         CGAL_precondition( D.get_face(i) == Facet_handle() ||
01263                            D.get_face(i) != D.get_face(h->opposite()));
01264         CGAL_precondition( D.get_face(i) == Facet_handle() ||
01265                            D.get_face(i) != D.get_face(i->opposite()));
01266         CGAL_precondition( D.get_face(i) == Facet_handle() ||
01267                            D.get_face(i) != D.get_face(j->opposite()));
01268         CGAL_precondition( D.get_face(j) == Facet_handle() ||
01269                            D.get_face(j) != D.get_face(h->opposite()));
01270         CGAL_precondition( D.get_face(j) == Facet_handle() ||
01271                            D.get_face(j) != D.get_face(i->opposite()));
01272         CGAL_precondition( D.get_face(j) == Facet_handle() ||
01273                            D.get_face(j) != D.get_face(j->opposite()));
01274         CGAL_precondition( D.get_face(h->opposite()) == Facet_handle() ||
01275             D.get_face(h->opposite()) != D.get_face(i->opposite()));
01276         CGAL_precondition( D.get_face(h->opposite()) == Facet_handle() ||
01277             D.get_face(h->opposite()) != D.get_face(j->opposite()));
01278         CGAL_precondition( D.get_face(i->opposite()) == Facet_handle() ||
01279             D.get_face(i->opposite()) != D.get_face(j->opposite()));
01280         return D.split_loop( h, i, j);
01281     }
01282 
01283     Halfedge_handle join_loop( Halfedge_handle h, Halfedge_handle g) {
01284         // glues the boundary of two facets together. Both facets and the
01285         // vertices of g gets removed. Returns an halfedge iterator for h.
01286         // The invariant `join_loop( h, split_loop( h, i, j))' returns h
01287         // and keeps the polyhedron unchanged. Precondition: `HDS'
01288         // supports removal of vertices and facets. The facets denoted by
01289         // h and g have equal size.
01290         HalfedgeDS_decorator<HDS> D(hds);
01291         CGAL_precondition( D.get_face(h) == Facet_handle() ||
01292                            D.get_face(h) != D.get_face(g));
01293         CGAL_precondition( circulator_size( h->facet_begin())
01294                            >= size_type(3));
01295         CGAL_precondition( circulator_size( h->facet_begin())
01296                            == circulator_size( g->facet_begin()));
01297         return D.join_loop( h, g);
01298     }
01299 
01300 // Modifying Facets and Holes
01301 
01302     Halfedge_handle make_hole( Halfedge_handle h) {
01303         // removes incident facet and makes all halfedges incident to the
01304         // facet to border edges. Returns h. Precondition: `HDS'
01305         // supports removal of facets. `! h.is_border()'.
01306         HalfedgeDS_decorator<HDS> D(hds);
01307         return D.make_hole(h);
01308     }
01309 
01310     Halfedge_handle fill_hole( Halfedge_handle h) {
01311         // fill a hole with a new created facet. Makes all border
01312         // halfedges of the hole denoted by h incident to the new facet.
01313         // Returns h. Precondition: `h.is_border()'.
01314         reserve( size_of_vertices(),
01315                  size_of_halfedges(),
01316                  1 + size_of_facets());
01317         HalfedgeDS_decorator<HDS> D(hds);
01318         return D.fill_hole(h);
01319     }
01320 
01321     Halfedge_handle add_vertex_and_facet_to_border( Halfedge_handle h,
01322                                                     Halfedge_handle g) {
01323         // creates a new facet within the hole incident to h and g by
01324         // connecting the tip of g with the tip of h with two new
01325         // halfedges and a new vertex and filling this separated part of
01326         // the hole with a new facet. Returns the new halfedge incident to
01327         // the new facet and the new vertex. Precondition: `h->is_border(
01328         // )', `g->is_border()', `h != g', and g can be reached along the
01329         // same hole starting with h.
01330         CGAL_precondition( h != g);
01331         reserve( 1 + size_of_vertices(),
01332                  4 + size_of_halfedges(),
01333                  1 + size_of_facets());
01334         HalfedgeDS_decorator<HDS> D(hds);
01335         Halfedge_handle hh = D.add_face_to_border( h, g);
01336         CGAL_assertion( hh == g->next());
01337         D.split_vertex( g, hh->opposite());
01338         return g->next();
01339     }
01340 
01341     Halfedge_handle add_facet_to_border( Halfedge_handle h,
01342                                          Halfedge_handle g) {
01343         // creates a new facet within the hole incident to h and g by
01344         // connecting the tip of g with the tip of h with a new halfedge
01345         // and filling this separated part of the hole with a new facet.
01346         // Returns the new halfedge incident to the new facet.
01347         // Precondition: `h->is_border()', `g->is_border()', `h != g',
01348         // `h->next() != g', and g can be reached along the same hole
01349         // starting with h.
01350         CGAL_precondition( h != g);
01351         CGAL_precondition( h->next() != g);
01352         reserve( size_of_vertices(),
01353                  2 + size_of_halfedges(),
01354                  1 + size_of_facets());
01355         HalfedgeDS_decorator<HDS> D(hds);
01356         return D.add_face_to_border( h, g);
01357     }
01358 
01359 // Erasing
01360 
01361     void erase_facet( Halfedge_handle h) {
01362         // removes the incident facet of h and changes all halfedges
01363         // incident to the facet into border edges or removes them from
01364         // the polyhedral surface if they were already border edges. See
01365         // `make_hole(h)' for a more specialized variant. Precondition:
01366         // `Traits' supports removal.
01367         HalfedgeDS_decorator<HDS> D(hds);
01368         D.erase_face(h);
01369     }
01370 
01371     void erase_connected_component( Halfedge_handle h) {
01372         // removes the vertices, halfedges, and facets that belong to the
01373         // connected component of h. Precondition: `Traits' supports
01374         // removal.
01375         HalfedgeDS_decorator<HDS> D(hds);
01376         D.erase_connected_component(h);
01377     }
01378 
01388     unsigned int keep_largest_connected_components(unsigned int nb_components_to_keep)
01389     {
01390         HalfedgeDS_decorator<HDS> D(hds);
01391         return D.keep_largest_connected_components(nb_components_to_keep);
01392     }
01393 
01394     void clear() { hds.clear(); }
01395         // removes all vertices, halfedges, and facets.
01396 
01397     void erase_all() { clear(); }
01398         // equivalent to `clear()'. Depricated.
01399 
01400 // Special Operations on Polyhedral Surfaces
01401 
01402     void delegate( Modifier_base<HDS>& modifier) {
01403         // calls the `operator()' of the `modifier'. Precondition: The
01404         // `modifier' returns a consistent representation.
01405         modifier( hds);
01406         CGAL_expensive_postcondition( is_valid());
01407     }
01408 
01409 // Operations with Border Halfedges
01410 
01411     size_type size_of_border_halfedges() const {
01412         // number of border halfedges. An edge with no incident facet
01413         // counts as two border halfedges. Precondition: `normalize_border
01414         // ()' has been called and no halfedge insertion or removal and no
01415         // change in border status of the halfedges have occured since
01416         // then.
01417         return hds.size_of_border_halfedges();
01418     }
01419 
01420     size_type size_of_border_edges() const {
01421         // number of border edges. If `size_of_border_edges() ==
01422         // size_of_border_halfedges()' all border edges are incident to a
01423         // facet on one side and to a hole on the other side.
01424         // Precondition: `normalize_border()' has been called and no
01425         // halfedge insertion or removal and no change in border status of
01426         // the halfedges have occured since then.
01427         return hds.size_of_border_edges();
01428     }
01429 
01430     Halfedge_iterator border_halfedges_begin() {
01431         // halfedge iterator starting with the border edges. The range [
01432         // `halfedges_begin(), border_halfedges_begin()') denotes all
01433         // non-border edges. The range [`border_halfedges_begin(),
01434         // halfedges_end()') denotes all border edges. Precondition:
01435         // `normalize_border()' has been called and no halfedge insertion
01436         // or removal and no change in border status of the halfedges have
01437         // occured since then.
01438         return hds.border_halfedges_begin();
01439     }
01440     Halfedge_const_iterator border_halfedges_begin() const {
01441         return hds.border_halfedges_begin();
01442     }
01443 
01444     // Convenient edge iterator
01445     Edge_iterator border_edges_begin() { return border_halfedges_begin(); }
01446     Edge_const_iterator border_edges_begin() const {
01447         return border_halfedges_begin();
01448     }
01449 
01450     bool normalized_border_is_valid( bool verbose = false) const {
01451         // checks whether all non-border edges precedes the border edges.
01452         HalfedgeDS_const_decorator<HDS> decorator(hds);
01453         bool valid = decorator.normalized_border_is_valid( verbose);
01454         for ( Halfedge_const_iterator i = border_halfedges_begin();
01455               valid && (i != halfedges_end()); (++i, ++i)) {
01456             if ( i->is_border()) {
01457                 Verbose_ostream verr(verbose);
01458                 verr << "    both halfedges of an edge are border "
01459                         "halfedges." << std::endl;
01460                 valid = false;
01461             }
01462         }
01463         return valid;
01464     }
01465 
01466     void normalize_border() {
01467         // sorts halfedges such that the non-border edges precedes the
01468         // border edges.
01469         hds.normalize_border();
01470         CGAL_postcondition( normalized_border_is_valid());
01471     }
01472 
01473 protected:            // Supports_face_plane
01474     void inside_out_geometry( Tag_false) {}
01475     void inside_out_geometry( Tag_true) {
01476         typename Traits::Construct_opposite_plane_3 opp
01477             = traits().construct_opposite_plane_3_object();
01478         std::transform( planes_begin(), planes_end(), planes_begin(), opp);
01479     }
01480 
01481 public:
01482     void inside_out() {
01483         // reverse facet orientation.
01484         HalfedgeDS_decorator<HDS> decorator(hds);
01485         decorator.inside_out();
01486         inside_out_geometry( Supports_face_plane());
01487     }
01488 
01489     bool is_valid( bool verb = false, int level = 0) const {
01490         // checks the combinatorial consistency.
01491         Verbose_ostream verr(verb);
01492         verr << "begin CGAL::Polyhedron_3<...>::is_valid( verb=true, "
01493                           "level = " << level << "):" << std::endl;
01494         HalfedgeDS_const_decorator<HDS> D(hds);
01495         bool valid = D.is_valid( verb, level + 3);
01496         // All halfedges.
01497         Halfedge_const_iterator i   = halfedges_begin();
01498         Halfedge_const_iterator end = halfedges_end();
01499         size_type  n = 0;
01500         for( ; valid && (i != end); ++i) {
01501             verr << "halfedge " << n << std::endl;
01502             // At least triangular facets and distinct geometry.
01503             valid = valid && ( i->next() != i);
01504             valid = valid && ( i->next()->next() != i);
01505             valid = valid && ( ! check_tag( Supports_halfedge_vertex()) ||
01506                                D.get_vertex(i) != D.get_vertex(i->opposite()));
01507             valid = valid && ( ! check_tag( Supports_halfedge_vertex()) ||
01508                                D.get_vertex(i) != D.get_vertex(i->next()));
01509             valid = valid && ( ! check_tag( Supports_halfedge_vertex()) ||
01510                         D.get_vertex(i) != D.get_vertex(i->next()->next()));
01511             if ( ! valid) {
01512                 verr << "    incident facet is not at least a triangle."
01513                      << std::endl;
01514                 break;
01515             }
01516             // Distinct facets on each side of an halfegde.
01517             valid = valid && ( ! check_tag( Supports_halfedge_face()) ||
01518                                D.get_face(i) != D.get_face(i->opposite()));
01519             if ( ! valid) {
01520                 verr << "    both incident facets are equal." << std::endl;
01521                 break;
01522             }
01523             ++n;
01524         }
01525         valid = valid && (n == size_of_halfedges());
01526         if ( n != size_of_halfedges())
01527             verr << "counting halfedges failed." << std::endl;
01528 
01529         verr << "end of CGAL::Polyhedron_3<...>::is_valid(): structure is "
01530              << ( valid ? "valid." : "NOT VALID.") << std::endl;
01531         return valid;
01532     }
01533 };
01534 
01535 CGAL_END_NAMESPACE
01536 
01537 #endif // CGAL_POLYHEDRON_3_H //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines