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