BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/HalfedgeDS_list.h
Go to the documentation of this file.
00001 // Copyright (c) 1997  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/HalfedgeDS/include/CGAL/HalfedgeDS_list.h $
00019 // $Id: HalfedgeDS_list.h 28567 2006-02-16 14:30:13Z lsaboret $
00020 // 
00021 //
00022 // Author(s)     : Lutz Kettner  <kettner@mpi-sb.mpg.de>
00023 
00024 #ifndef CGAL_HALFEDGEDS_LIST_H
00025 #define CGAL_HALFEDGEDS_LIST_H 1
00026 
00027 #include <CGAL/In_place_list.h>
00028 #include <CGAL/HalfedgeDS_items_decorator.h>
00029 #include <CGAL/memory.h>
00030 #include <CGAL/Unique_hash_map.h>
00031 #include <cstddef>
00032 
00033 CGAL_BEGIN_NAMESPACE
00034 
00035 template < class VertexBase>
00036 class HalfedgeDS_in_place_list_vertex
00037     : public VertexBase, public In_place_list_base<
00038                       HalfedgeDS_in_place_list_vertex< VertexBase> > {
00039 public:
00040     typedef HalfedgeDS_in_place_list_vertex< VertexBase> Self;
00041     typedef typename VertexBase::Vertex_handle       Vertex_handle;
00042     typedef typename VertexBase::Vertex_const_handle Vertex_const_handle;
00043     HalfedgeDS_in_place_list_vertex() {}
00044     HalfedgeDS_in_place_list_vertex( const VertexBase& v)   // down cast
00045         : VertexBase(v) {}
00046     Self& operator=( const Self& v) {
00047         // This self written assignment avoids that assigning vertices will
00048         // overwrite the list linking of the target vertex.
00049         *((VertexBase*)this) = ((const VertexBase&)v);
00050         return *this;
00051     }
00052 };
00053 
00054 template < class HalfedgeBase>
00055 class HalfedgeDS_in_place_list_halfedge
00056     : public HalfedgeBase, public In_place_list_base<
00057                   HalfedgeDS_in_place_list_halfedge< HalfedgeBase> > {
00058 public:
00059     typedef HalfedgeDS_in_place_list_halfedge< HalfedgeBase> Self;
00060     typedef typename HalfedgeBase::Halfedge_handle       Halfedge_handle;
00061     typedef typename HalfedgeBase::Halfedge_const_handle
00062                                                     Halfedge_const_handle;
00063     HalfedgeDS_in_place_list_halfedge() {}                   // down cast
00064     HalfedgeDS_in_place_list_halfedge( const HalfedgeBase& h)
00065         : HalfedgeBase(h) {}
00066     Self& operator=( const Self& h) {
00067         // This self written assignment avoids that assigning halfedges will
00068         // overwrite the list linking of the target halfedge.
00069         *((HalfedgeBase*)this) = ((const HalfedgeBase&)h);
00070         return *this;
00071     }
00072 };
00073 
00074 template < class FaceBase>
00075 class HalfedgeDS_in_place_list_face
00076     : public FaceBase, public In_place_list_base<
00077                             HalfedgeDS_in_place_list_face< FaceBase> > {
00078 public:
00079     typedef HalfedgeDS_in_place_list_face< FaceBase>  Self;
00080     typedef typename FaceBase::Face_handle       Face_handle;
00081     typedef typename FaceBase::Face_const_handle Face_const_handle;
00082     HalfedgeDS_in_place_list_face() {}                   // down cast
00083     HalfedgeDS_in_place_list_face( const FaceBase& f) : FaceBase(f) {}
00084     Self& operator=( const Self& f) {
00085         // This self written assignment avoids that assigning faces will
00086         // overwrite the list linking of the target face.
00087         *((FaceBase*)this) = ((const FaceBase&)f);
00088         // this->FaceBase::operator=(f); // does not compile on SGI
00089         return *this;
00090     }
00091 };
00092 
00093 template < class Traits_, class HalfedgeDSItems, class Alloc>
00094 class HalfedgeDS_list_types {
00095 public:
00096     typedef HalfedgeDS_list_types<Traits_, HalfedgeDSItems, Alloc> Self;
00097     typedef Traits_                                    Traits;
00098     typedef HalfedgeDSItems                            Items;
00099     typedef Alloc                                      Allocator;
00100     typedef Alloc                                      allocator_type;
00101 
00102     typedef typename Items::template Vertex_wrapper<Self,Traits>
00103                                                        Vertex_wrapper;
00104     typedef typename Items::template Halfedge_wrapper<Self,Traits> 
00105                                                        Halfedge_wrapper;
00106     typedef typename Items::template Face_wrapper<Self,Traits>
00107                                                        Face_wrapper;
00108 
00109     typedef typename Vertex_wrapper::Vertex            Vertex_base;
00110     typedef HalfedgeDS_in_place_list_vertex< Vertex_base> Vertex;
00111     typedef typename Halfedge_wrapper::Halfedge        Halfedge_base;
00112     typedef HalfedgeDS_in_place_list_halfedge< Halfedge_base> Halfedge;
00113     typedef typename Face_wrapper::Face                Face_base;
00114     typedef HalfedgeDS_in_place_list_face< Face_base>  Face;
00115 
00116     typedef typename Allocator::template rebind< Vertex> Vertex_alloc_rebind;
00117     typedef typename Vertex_alloc_rebind::other        Vertex_allocator;
00118     typedef typename Allocator::template rebind< Halfedge>
00119                                                        Halfedge_alloc_rebind;
00120     typedef typename Halfedge_alloc_rebind::other      Halfedge_allocator;
00121     typedef typename Allocator::template rebind< Face> Face_alloc_rebind;
00122     typedef typename Face_alloc_rebind::other          Face_allocator;
00123 
00124     typedef In_place_list<Vertex,false,Vertex_allocator>  Vertex_list;
00125     typedef typename Vertex_list::iterator             Vertex_handle;
00126     typedef typename Vertex_list::const_iterator       Vertex_const_handle;
00127     typedef typename Vertex_list::iterator             Vertex_iterator;
00128     typedef typename Vertex_list::const_iterator       Vertex_const_iterator;
00129 
00130     typedef In_place_list<Halfedge,false,Halfedge_allocator>  Halfedge_list;
00131     typedef typename Halfedge_list::iterator           Halfedge_handle;
00132     typedef typename Halfedge_list::const_iterator     Halfedge_const_handle;
00133     typedef typename Halfedge_list::iterator           Halfedge_iterator;
00134     typedef typename Halfedge_list::const_iterator     Halfedge_const_iterator;
00135 
00136     typedef In_place_list<Face,false,Face_allocator>   Face_list;
00137     typedef typename Face_list::iterator               Face_handle;
00138     typedef typename Face_list::const_iterator         Face_const_handle;
00139     typedef typename Face_list::iterator               Face_iterator;
00140     typedef typename Face_list::const_iterator         Face_const_iterator;
00141 
00142     typedef typename Halfedge_list::size_type          size_type;
00143     typedef typename Halfedge_list::difference_type    difference_type;
00144     typedef std::bidirectional_iterator_tag            iterator_category;
00145     static inline Vertex_handle vertex_handle( Vertex_base* v) {
00146         Vertex* vv = 0;
00147         vv = (Vertex*)((char*) v - (std::ptrdiff_t)((Vertex_base*)vv));
00148         return vv;
00149     }
00150     static inline Vertex_const_handle vertex_handle( const Vertex_base* v) {
00151         const Vertex* vv = 0;
00152         vv = (const Vertex*)((const char*) v -
00153                  (std::ptrdiff_t)((const Vertex_base*)vv));
00154         return vv;
00155     }
00156 
00157     static inline Halfedge_handle halfedge_handle( Halfedge_base* h) {
00158         Halfedge* hh = 0;
00159         hh = (Halfedge*)((char*) h - (std::ptrdiff_t)((Halfedge_base*)hh));
00160         return hh;
00161     }
00162     static inline
00163     Halfedge_const_handle halfedge_handle( const Halfedge_base* h) {
00164         const Halfedge* hh = 0;
00165         hh = (const Halfedge*)((const char*) h -
00166                  (std::ptrdiff_t)((const Halfedge_base*)hh));
00167         return hh;
00168     }
00169 
00170     static inline Face_handle face_handle( Face_base* f) {
00171         Face* ff = 0;
00172         ff = (Face*)((char*) f - (std::ptrdiff_t)((Face_base*)ff));
00173         return ff;
00174     }
00175     static inline Face_const_handle face_handle( const Face_base* f) {
00176         const Face* ff = 0;
00177         ff = (const Face*)((const char*)f -
00178                  (std::ptrdiff_t)((const Face_base*)ff));
00179         return ff;
00180     }
00181 };
00182 
00183 #ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
00184 template < class Traits_, class HalfedgeDSItems, 
00185            class Alloc = CGAL_ALLOCATOR(int)>
00186 class HalfedgeDS_list
00187     : public HalfedgeDS_list_types<Traits_, HalfedgeDSItems, Alloc> {
00188 public:
00189     typedef HalfedgeDS_list<Traits_, HalfedgeDSItems, Alloc> Self;
00190 #else
00191 struct HalfedgeDS_list {
00192 template < class Traits_, class HalfedgeDSItems, 
00193            class Alloc = CGAL_ALLOCATOR(int)>
00194 class HDS : public HalfedgeDS_list_types<Traits_, HalfedgeDSItems, Alloc> {
00195 public:
00196     typedef HDS<Traits_, HalfedgeDSItems, Alloc> Self;
00197 #endif
00198 public:
00199     typedef HalfedgeDS_list_types<Traits_, HalfedgeDSItems, Alloc> Types;
00200     typedef typename Types::Traits                     Traits;
00201     typedef typename Types::Items                      Items;
00202     typedef typename Types::Allocator                  Allocator;
00203     typedef typename Types::allocator_type             allocator_type;
00204 
00205     typedef typename Types::Vertex                     Vertex;
00206     typedef typename Types::Halfedge                   Halfedge;
00207     typedef typename Types::Face                       Face;
00208 
00209     typedef typename Types::Vertex_allocator           Vertex_allocator;
00210     typedef typename Types::Vertex_list                Vertex_list;
00211     typedef typename Types::Vertex_handle              Vertex_handle;
00212     typedef typename Types::Vertex_const_handle        Vertex_const_handle;
00213     typedef typename Types::Vertex_iterator            Vertex_iterator;
00214     typedef typename Types::Vertex_const_iterator      Vertex_const_iterator;
00215 
00216     typedef typename Types::Halfedge_allocator         Halfedge_allocator;
00217     typedef typename Types::Halfedge_list              Halfedge_list;
00218     typedef typename Types::Halfedge_handle            Halfedge_handle;
00219     typedef typename Types::Halfedge_const_handle      Halfedge_const_handle;
00220     typedef typename Types::Halfedge_iterator          Halfedge_iterator;
00221     typedef typename Types::Halfedge_const_iterator    Halfedge_const_iterator;
00222 
00223     typedef typename Types::Face_allocator             Face_allocator;
00224     typedef typename Types::Face_list                  Face_list;
00225     typedef typename Types::Face_handle                Face_handle;
00226     typedef typename Types::Face_const_handle          Face_const_handle;
00227     typedef typename Types::Face_iterator              Face_iterator;
00228     typedef typename Types::Face_const_iterator        Face_const_iterator;
00229 
00230     typedef typename Types::size_type                  size_type;
00231     typedef typename Types::difference_type            difference_type;
00232     typedef typename Types::iterator_category          iterator_category;
00233 
00234     typedef Tag_true                                   Supports_removal;
00235 
00236     typedef typename Vertex::Supports_vertex_halfedge Supports_vertex_halfedge;
00237     typedef typename Halfedge::Supports_halfedge_prev Supports_halfedge_prev;
00238     typedef typename Halfedge::Supports_halfedge_vertex
00239                                                       Supports_halfedge_vertex;
00240     typedef typename Halfedge::Supports_halfedge_face
00241                                                       Supports_halfedge_face;
00242     typedef typename Face::Supports_face_halfedge     Supports_face_halfedge;
00243 
00244     // Halfedges are allocated in pairs. Here is the type for that.
00245     typedef std::pair<Halfedge,Halfedge>              Halfedge_pair;
00246 
00247     typedef typename Allocator::template rebind< Halfedge_pair>
00248                                                        Edge_alloc_rebind;
00249     typedef typename Edge_alloc_rebind::other          Edge_allocator;
00250 
00251 protected:
00252     // Changed from static to local variable
00253     Vertex_allocator vertex_allocator;
00254     Edge_allocator   edge_allocator;  // allocates pairs of halfedges
00255     Face_allocator   face_allocator;
00256     
00257     Vertex* get_vertex_node( const Vertex& t) {
00258         Vertex* p = vertex_allocator.allocate(1);
00259         vertex_allocator.construct(p, t);
00260         return p;
00261     }
00262     void put_vertex_node( Vertex* p) {
00263         vertex_allocator.destroy( p);
00264         vertex_allocator.deallocate( p, 1);
00265     }
00266 
00267     Halfedge* get_edge_node( const Halfedge& h, const Halfedge& g) {
00268         // creates a new pair of opposite border halfedges.
00269         Halfedge_pair* hpair = edge_allocator.allocate(1);
00270         edge_allocator.construct(hpair, Halfedge_pair( h, g));
00271         Halfedge* h2 = &(hpair->first);
00272         Halfedge* g2 = &(hpair->second);
00273         CGAL_assertion( h2 == (Halfedge*)hpair);
00274         CGAL_assertion( g2 == h2 + 1);
00275         h2->HBase_base::set_opposite(g2);
00276         g2->HBase_base::set_opposite(h2);
00277         return h2;
00278     }
00279     void put_edge_node( Halfedge* h) {
00280         // deletes the pair of opposite halfedges h and h->opposite().
00281         Halfedge_handle g = h->opposite();
00282         Halfedge_pair* hpair = (Halfedge_pair*)(&*h);
00283         if ( &*h > &*g)
00284             hpair = (Halfedge_pair*)(&*g);
00285         CGAL_assertion( &(hpair->first) == (Halfedge*)hpair);
00286         edge_allocator.destroy( hpair);
00287         edge_allocator.deallocate( hpair, 1);
00288     }
00289 
00290     Face* get_face_node( const Face& t) {
00291         Face* p = face_allocator.allocate(1);
00292         face_allocator.construct(p, t);
00293         return p;
00294     }
00295     void put_face_node( Face* p) {
00296         face_allocator.destroy( p);
00297         face_allocator.deallocate( p, 1);
00298     }
00299 
00300     typedef typename Vertex::Base                      VBase;
00301     typedef typename Halfedge::Base                    HBase;
00302     typedef typename Halfedge::Base_base               HBase_base;
00303     typedef typename Face::Base                        FBase;
00304 
00305     Vertex_list        vertices;
00306     Halfedge_list      halfedges;
00307     Face_list          faces;
00308 
00309     size_type          nb_border_halfedges;
00310     size_type          nb_border_edges;
00311     Halfedge_iterator  border_halfedges;
00312 
00313 // CREATION
00314 
00315 private:
00316     void pointer_update( const Self& hds) {
00317         // Update own pointers assuming that they lived previously
00318         // in a halfedge data structure `hds' with lists.
00319         // Update own pointers assuming that they lived previously
00320         // in a halfedge data structure `hds' with lists.
00321         typedef Unique_hash_map< Vertex_const_iterator, Vertex_iterator> V_map;
00322         typedef Unique_hash_map< Halfedge_const_iterator, Halfedge_iterator>
00323                                                                          H_map;
00324         typedef Unique_hash_map< Face_const_iterator, Face_iterator>     F_map;
00325         // initialize maps.
00326         H_map h_map( hds.halfedges_begin(), hds.halfedges_end(),
00327                      halfedges_begin(), Halfedge_iterator(), 
00328                      3 * hds.size_of_halfedges() / 2);
00329         Vertex_iterator vii;
00330         V_map v_map( vii, 3 * hds.size_of_vertices() / 2);
00331         Face_iterator fii;
00332         F_map f_map( fii, 3 * hds.size_of_faces() / 2);
00333         // some special values
00334         h_map[Halfedge_const_iterator()] = Halfedge_iterator();
00335         h_map[hds.halfedges_end()]       = halfedges_end();
00336         v_map[Vertex_const_iterator()]   = Vertex_iterator();
00337         v_map[hds.vertices_end()]        = vertices_end();
00338         f_map[Face_const_iterator()]     = Face_iterator();
00339         f_map[hds.faces_end()]           = faces_end();
00340         // vertices and faces are optional
00341         if ( check_tag( Supports_halfedge_vertex())) {
00342             v_map.insert( hds.vertices_begin(),
00343                           hds.vertices_end(),
00344                           vertices_begin());
00345         }
00346         if ( check_tag( Supports_halfedge_face())) {
00347             f_map.insert( hds.faces_begin(), hds.faces_end(), faces_begin());
00348         }
00349         HalfedgeDS_items_decorator<Self> D;
00350         for (Halfedge_iterator h = halfedges_begin(); h!=halfedges_end(); ++h){
00351             h->HBase::set_next( h_map[ h->next()]);
00352             // Superfluous and false: opposite pointer get set upon creation
00353             // h->HBase_base::set_opposite( h_map[ h->opposite()]);
00354             if ( check_tag( Supports_halfedge_prev()))
00355                 D.set_prev( h, h_map[ D.get_prev(h)]);
00356             if ( check_tag( Supports_halfedge_vertex()))
00357                 D.set_vertex( h, v_map[ D.get_vertex(h)]);
00358             if ( check_tag( Supports_halfedge_face()))
00359                 D.set_face( h, f_map[ D.get_face(h)]);
00360         }
00361         border_halfedges = h_map[ border_halfedges];
00362         if (check_tag( Supports_vertex_halfedge())) {
00363             for (Vertex_iterator v = vertices_begin(); v != vertices_end();++v)
00364                 D.set_vertex_halfedge(v, h_map[ D.get_vertex_halfedge(v)]);
00365         }
00366         if (check_tag( Supports_face_halfedge())) {
00367             for ( Face_iterator f = faces_begin(); f != faces_end(); ++f)
00368                 D.set_face_halfedge(f, h_map[ D.get_face_halfedge(f)]);
00369         }
00370         //h_map.statistics();
00371         //v_map.statistics();
00372         //f_map.statistics();
00373     }
00374 
00375 public:
00376 #ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
00377     HalfedgeDS_list()
00378         : nb_border_halfedges(0), nb_border_edges(0) {}
00379         // the empty polyhedron `P'.
00380 
00381     HalfedgeDS_list( size_type, size_type, size_type)
00382         : nb_border_halfedges(0), nb_border_edges(0) {}
00383         // Parameter order is v,h,f.
00384         // a polyhedron `P' with storage reserved for v vertices, h
00385         // halfedges, and f faces. The reservation sizes are a hint for
00386         // optimizing storage allocation. They are not used here.
00387 
00388     ~HalfedgeDS_list() { clear(); }
00389 
00390     HalfedgeDS_list( const Self& hds)
00391 #else
00392     HDS() : nb_border_halfedges(0), nb_border_edges(0) {}
00393     HDS( size_type, size_type, size_type)
00394           : nb_border_halfedges(0), nb_border_edges(0) {}
00395     ~HDS() { clear(); }
00396     HDS( const Self& hds)
00397 #endif // CGAL_CFG_NO_TMPL_IN_TMPL_PARAM //
00398     :  vertices( hds.vertices),
00399        //halfedges( hds.halfedges),
00400        faces( hds.faces),
00401        nb_border_halfedges( hds.nb_border_halfedges),
00402        nb_border_edges( hds.nb_border_edges),
00403        border_halfedges( hds.border_halfedges)
00404     {
00405         // goal is halfedges = hds.halfedges, but we have pairs here
00406         Halfedge_const_iterator i = hds.halfedges_begin();
00407         for ( ; i != hds.halfedges_end(); ++ ++ i) {
00408             edges_push_back( *i);
00409         }
00410         pointer_update( hds);
00411     }
00412 
00413     Self& operator=( const Self& hds)  {
00414         if ( this != &hds) {
00415             clear();
00416             vertices            = hds.vertices;
00417             // goal is halfedges = hds.halfedges, but we have pairs here
00418             halfedges = Halfedge_list();
00419             Halfedge_const_iterator i = hds.halfedges_begin();
00420             for ( ; i != hds.halfedges_end(); ++ ++ i) {
00421                 edges_push_back( *i);
00422             }
00423             faces               = hds.faces;
00424             nb_border_halfedges = hds.nb_border_halfedges;
00425             nb_border_edges     = hds.nb_border_edges;
00426             border_halfedges    = hds.border_halfedges;
00427             pointer_update( hds);
00428         }
00429         return *this;
00430     }
00431 
00432     void reserve( size_type, size_type, size_type) {}
00433         // Parameter order is v,h,f.
00434         // reserve storage for v vertices, h halfedges, and f faces. The
00435         // reservation sizes are a hint for optimizing storage allocation.
00436         // If the `capacity' is already greater than the requested size
00437         // nothing happens. If the `capacity' changes all iterators and
00438         // circulators invalidates. The function is void here.
00439 
00440 // Access Member Functions
00441 
00442     allocator_type  get_allocator() const { return allocator_type(); }
00443 
00444     size_type size_of_vertices() const  { return vertices.size();}
00445     size_type size_of_halfedges() const { return halfedges.size();}
00446         // number of all halfedges (including border halfedges).
00447     size_type size_of_faces() const     { return faces.size();}
00448 
00449     size_type capacity_of_vertices() const    { return vertices.max_size();}
00450     size_type capacity_of_halfedges() const   { return halfedges.max_size();}
00451     size_type capacity_of_faces() const       { return faces.max_size();}
00452 
00453     std::size_t bytes() const {
00454         return sizeof(Self)
00455                + vertices.size()  * sizeof( Vertex)
00456                + halfedges.size() * sizeof( Halfedge)
00457                + faces.size()     * sizeof( Face);
00458     }
00459     std::size_t bytes_reserved() const { return bytes();}
00460 
00461     Vertex_iterator   vertices_begin()   { return vertices.begin();}
00462     Vertex_iterator   vertices_end()     { return vertices.end();}
00463     Halfedge_iterator halfedges_begin()  { return halfedges.begin();}
00464     Halfedge_iterator halfedges_end()    { return halfedges.end();}
00465     Face_iterator     faces_begin()      { return faces.begin();}
00466     Face_iterator     faces_end()        { return faces.end();}
00467 
00468     // The constant iterators and circulators.
00469 
00470     Vertex_const_iterator   vertices_begin()  const{ return vertices.begin();}
00471     Vertex_const_iterator   vertices_end()    const{ return vertices.end();}
00472     Halfedge_const_iterator halfedges_begin() const{ return halfedges.begin();}
00473     Halfedge_const_iterator halfedges_end()   const{ return halfedges.end();}
00474     Face_const_iterator     faces_begin()     const{ return faces.begin();}
00475     Face_const_iterator     faces_end()       const{ return faces.end();}
00476 
00477 // Insertion
00478 //
00479 // The following operations simply allocate a new element of that type.
00480 // Halfedges are always allocated in pairs of opposite halfedges. The
00481 // opposite pointers are automatically set.
00482 
00483     Vertex_handle vertices_push_back( const Vertex& v) {
00484         vertices.push_back( * get_vertex_node(v));
00485         Vertex_handle vh = vertices.end();
00486         return --vh;
00487     }
00488 
00489     Halfedge_handle edges_push_back( const Halfedge& h, const Halfedge& g) {
00490         // creates a new pair of opposite border halfedges.
00491         Halfedge* ptr = get_edge_node( h, g);
00492         halfedges.push_back( *ptr);
00493         Halfedge_handle hh = halfedges.end();
00494         --hh;
00495         halfedges.push_back( *(ptr->opposite()));
00496         return hh;
00497     }
00498 
00499     Halfedge_handle edges_push_back( const Halfedge& h) {
00500         CGAL_precondition( h.opposite() != Halfedge_const_handle());
00501         return edges_push_back( h, *(h.opposite()));
00502     }
00503 
00504     Face_handle faces_push_back( const Face& f) {
00505         faces.push_back( * get_face_node(f));
00506         Face_handle fh = faces.end();
00507         return --fh;
00508     }
00509 
00510 
00511 // Removal
00512 //
00513 // The following operations erase an element referenced by a handle.
00514 // Halfedges are always deallocated in pairs of opposite halfedges. Erase
00515 // of single elements is optional. The deletion of all is mandatory.
00516 
00517     void vertices_pop_front() {
00518         Vertex* v = &(vertices.front());
00519         vertices.pop_front();
00520         put_vertex_node( v);
00521     }
00522     void vertices_pop_back() {
00523         Vertex* v = &(vertices.back());
00524         vertices.pop_back();
00525         put_vertex_node( v);
00526     }
00527     void vertices_erase( Vertex_handle v) {
00528         Vertex* ptr = &*v;
00529         vertices.erase(v);
00530         put_vertex_node( ptr);
00531     }
00532     void vertices_erase( Vertex_iterator first, Vertex_iterator last) {
00533         while (first != last)
00534             vertices_erase(first++);
00535     }
00536 
00537     void edges_erase( Halfedge_handle h) {
00538         // deletes the pair of opposite halfedges h and h->opposite().
00539         Halfedge_handle g = h->opposite();
00540         halfedges.erase(h);
00541         halfedges.erase(g);
00542         put_edge_node(&*h);
00543     }
00544     void edges_pop_front() { edges_erase( halfedges.begin()); }
00545     void edges_pop_back()  {
00546         Halfedge_iterator h = halfedges.end();
00547         edges_erase( --h);
00548     }
00549     void edges_erase( Halfedge_iterator first, Halfedge_iterator last) {
00550         while (first != last) {
00551             Halfedge_iterator nxt = first;
00552             ++nxt;
00553             CGAL_assertion( nxt != last);
00554             ++nxt;
00555             edges_erase(first);
00556             first = nxt;
00557         }
00558     }
00559 
00560     void faces_pop_front() {
00561         Face* f = &(faces.front());
00562         faces.pop_front();
00563         put_face_node( f);
00564     }
00565     void faces_pop_back() {
00566         Face* f = &(faces.back());
00567         faces.pop_back();
00568         put_face_node( f);
00569     }
00570     void faces_erase( Face_handle f) {
00571         Face* ptr = &*f;
00572         faces.erase(f);
00573         put_face_node( ptr);
00574     }
00575     void faces_erase( Face_iterator first, Face_iterator last) {
00576         while (first != last)
00577             faces_erase(first++);
00578     }
00579 
00580     void vertices_clear() { vertices.destroy(); }
00581     void edges_clear() {
00582         edges_erase( halfedges.begin(), halfedges.end());
00583         nb_border_halfedges = 0;
00584         nb_border_edges = 0;
00585         border_halfedges = Halfedge_handle();
00586     }
00587     void faces_clear() { faces.destroy(); }
00588     void clear() {
00589         vertices_clear();
00590         edges_clear();
00591         faces_clear();
00592     }
00593 
00594     void vertices_splice( Vertex_iterator target, Self &source,
00595                           Vertex_iterator begin, Vertex_iterator end) {
00596         vertices.splice( target, source.vertices, begin, end);
00597     }
00598 
00599     void halfedges_splice( Halfedge_iterator target, Self &source,
00600                            Halfedge_iterator begin, Halfedge_iterator end) {
00601         halfedges.splice( target, source.halfedges, begin, end);
00602     }
00603 
00604     void faces_splice( Face_iterator target, Self &source,
00605                        Face_iterator begin, Face_iterator end) {
00606         faces.splice( target, source.faces, begin, end);
00607     }
00608 
00609 // Operations with Border Halfedges
00610 
00611     size_type size_of_border_halfedges() const { return nb_border_halfedges;}
00612         // number of border halfedges. An edge with no incident face
00613         // counts as two border halfedges. Precondition: `normalize_border()'
00614         // has been called and no halfedge insertion or removal and no
00615         // change in border status of the halfedges have occured since
00616         // then.
00617 
00618     size_type size_of_border_edges() const { return nb_border_edges;}
00619         // number of border edges. If `size_of_border_edges() ==
00620         // size_of_border_halfedges()' all border edges are incident to a
00621         // face on one side and to a hole on the other side.
00622         // Precondition: `normalize_border()' has been called and no
00623         // halfedge insertion or removal and no change in border status of
00624         // the halfedges have occured since then.
00625 
00626     Halfedge_iterator border_halfedges_begin() {
00627         // halfedge iterator starting with the border edges. The range [
00628         // `halfedges_begin(), border_halfedges_begin()') denotes all
00629         // non-border edges. The range [`border_halfedges_begin(),
00630         // halfedges_end()') denotes all border edges. Precondition:
00631         // `normalize_border()' has been called and no halfedge insertion
00632         // or removal and no change in border status of the halfedges have
00633         // occured since then.
00634         return border_halfedges;
00635     }
00636 
00637     Halfedge_const_iterator border_halfedges_begin() const {
00638         return border_halfedges;
00639     }
00640 
00641     void normalize_border() {
00642         // sorts halfedges such that the non-border edges precedes the
00643         // border edges. For each border edge that is incident to a face
00644         // the halfedge iterator will reference the halfedge incident to
00645         // the face right before the halfedge incident to the hole.
00646         CGAL_assertion_code( size_type count = halfedges.size();)
00647         nb_border_halfedges = 0;
00648         nb_border_edges = 0;
00649         Halfedge_list  border;
00650         Halfedge_iterator i = halfedges_begin();
00651         while ( i != halfedges_end()) {
00652             Halfedge_iterator j = i;
00653             ++i;
00654             ++i;
00655             Halfedge_iterator k = j;
00656             ++k;
00657             if ( j->is_border()) {
00658                 nb_border_halfedges++;
00659                 nb_border_edges++;
00660                 if (k->is_border())
00661                     nb_border_halfedges++;
00662                 border.splice( border.end(), halfedges, k);
00663                 border.splice( border.end(), halfedges, j);
00664             } else if ( k->is_border()) {
00665                 nb_border_halfedges++;
00666                 nb_border_edges++;
00667                 border.splice( border.end(), halfedges, j);
00668                 border.splice( border.end(), halfedges, k);
00669             } else {
00670                 CGAL_assertion_code( count -= 2;)
00671             }
00672         }
00673         CGAL_assertion( count == 2 * nb_border_edges );
00674         CGAL_assertion( count == border.size());
00675         if ( i == halfedges_begin()) {
00676             halfedges.splice( halfedges.end(), border);
00677             i = halfedges_begin();
00678         } else {
00679             --i;
00680             --i;
00681             CGAL_assertion( ! i->is_border() && ! i->opposite()->is_border());
00682             halfedges.splice( halfedges.end(), border);
00683             ++i;
00684             ++i;
00685         }
00686         CGAL_assertion( i == halfedges_end() || i->opposite()->is_border());
00687         border_halfedges = i;
00688     }
00689 };
00690 #ifdef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
00691 };
00692 #endif
00693 
00694 
00695 //  #ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
00696 //  #define CGAL__HDS_IP_List HalfedgeDS_list
00697 //  #else
00698 //  #define CGAL__HDS_IP_List HalfedgeDS_list::HDS
00699 //  #endif
00700 
00701 // init static member allocator objects (no longer static)
00702 //template < class Traits_, class HalfedgeDSItems, class Alloc>
00703 //typename CGAL__HDS_IP_List<Traits_, HalfedgeDSItems, Alloc>::Vertex_allocator
00704 //CGAL__HDS_IP_List<Traits_, HalfedgeDSItems, Alloc>::vertex_allocator;
00705 //
00706 //template < class Traits_, class HalfedgeDSItems, class Alloc>
00707 //typename CGAL__HDS_IP_List<Traits_, HalfedgeDSItems, Alloc>::Edge_allocator
00708 //CGAL__HDS_IP_List<Traits_, HalfedgeDSItems, Alloc>::edge_allocator;
00709 //
00710 //template < class Traits_, class HalfedgeDSItems, class Alloc>
00711 //typename CGAL__HDS_IP_List<Traits_, HalfedgeDSItems, Alloc>::Face_allocator
00712 //CGAL__HDS_IP_List<Traits_, HalfedgeDSItems, Alloc>::face_allocator;
00713 
00714 
00715 //  #undef CGAL__HDS_IP_List
00716 
00717 CGAL_END_NAMESPACE
00718 #endif // CGAL_HALFEDGEDS_LIST_H //
00719 // EOF //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines