BWAPI
|
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 //