BWAPI
|
00001 // Copyright (c) 2006 Tel-Aviv University (Israel). 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/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h $ 00015 // $Id: Arr_dcel_base.h 46826 2008-11-12 08:37:24Z lrineau $ 00016 // 00017 // 00018 // Author(s) : Ron Wein <wein@post.tau.ac.il> 00019 // (based on old version by: Iddo Hanniel and Oren Nechushtan) 00020 00021 #ifndef CGAL_ARR_DCEL_BASE_H 00022 #define CGAL_ARR_DCEL_BASE_H 00023 00029 #include <CGAL/basic.h> 00030 #include <CGAL/Arr_enums.h> 00031 #include <list> 00032 #include <map> 00033 #include <CGAL/N_step_adaptor_derived.h> 00034 #include <CGAL/In_place_list.h> 00035 #include <CGAL/function_objects.h> 00036 #include <CGAL/Iterator_project.h> 00037 #include <CGAL/Arrangement_2/Arrangement_2_iterators.h> 00038 00039 CGAL_BEGIN_NAMESPACE 00040 00041 inline void* _clean_pointer (const void* p) 00042 { 00043 const size_t mask = ~1; 00044 const size_t val = (reinterpret_cast<size_t>(p) & mask); 00045 00046 return (reinterpret_cast<void*> (val)); 00047 } 00048 00049 inline void* _set_lsb (const void* p) 00050 { 00051 const size_t mask = 1; 00052 const size_t val = (reinterpret_cast<size_t>(p) | mask); 00053 00054 return (reinterpret_cast<void*> (val)); 00055 } 00056 00057 inline bool _is_lsb_set (const void* p) 00058 { 00059 const size_t mask = 1; 00060 const size_t val = reinterpret_cast<size_t>(p); 00061 00062 return ((val & mask) != 0); 00063 } 00064 00068 template <class Point_> class Arr_vertex_base 00069 { 00070 public: 00071 00072 typedef Point_ Point; 00073 00077 template<typename PNT> 00078 struct rebind 00079 { 00080 typedef Arr_vertex_base<PNT> other; 00081 }; 00082 00083 protected: 00084 00085 void *p_inc; // An incident halfedge pointing at the vertex, 00086 // or the isolated vertex information (in case it is 00087 // isolated). The LSB of the pointer indicates whether 00088 // the vertex is isolated. 00089 Point *p_pt; // The point associated with the vertex. 00090 char pss[2]; // The x and y parameter spaces (condensed in two bytes). 00091 00092 public: 00093 00095 Arr_vertex_base() : 00096 p_inc (NULL), 00097 p_pt (NULL) 00098 { 00099 pss[0] = pss[1] = static_cast<char> (CGAL::ARR_INTERIOR); 00100 } 00101 00103 virtual ~Arr_vertex_base() {} 00104 00106 bool has_null_point () const 00107 { 00108 return (p_pt == NULL); 00109 } 00110 00112 const Point& point() const 00113 { 00114 CGAL_assertion (p_pt != NULL); 00115 return (*p_pt); 00116 } 00117 00119 Point& point() 00120 { 00121 CGAL_assertion (p_pt != NULL); 00122 return (*p_pt); 00123 } 00124 00126 void set_point (Point *p) 00127 { 00128 p_pt = p; 00129 } 00130 00132 Arr_parameter_space parameter_space_in_x () const 00133 { 00134 return (Arr_parameter_space (pss[0])); 00135 } 00136 00138 Arr_parameter_space parameter_space_in_y () const 00139 { 00140 return (Arr_parameter_space (pss[1])); 00141 } 00142 00144 void set_boundary (Arr_parameter_space ps_x, Arr_parameter_space ps_y) 00145 { 00146 pss[0] = static_cast<char> (ps_x); 00147 pss[1] = static_cast<char> (ps_y); 00148 return; 00149 } 00150 00152 virtual void assign (const Arr_vertex_base<Point>& v) 00153 { 00154 p_pt = v.p_pt; 00155 pss[0] = v.pss[0]; 00156 pss[1] = v.pss[1]; 00157 } 00158 }; 00159 00163 template <class X_monotone_curve_> class Arr_halfedge_base 00164 { 00165 public: 00166 00167 typedef X_monotone_curve_ X_monotone_curve; 00168 00172 template<typename XCV> 00173 struct rebind 00174 { 00175 typedef Arr_halfedge_base<XCV> other; 00176 }; 00177 00178 protected: 00179 00180 void *p_opp; // The opposite halfedge. 00181 void *p_prev; // The previous halfedge in the component boundary. 00182 void *p_next; // The next halfedge in the component boundary. 00183 00184 void *p_v; // The incident vertex (the target of the halfedge). 00185 // The LSB of this pointer is used to store the 00186 // direction of the halfedge. 00187 void *p_comp; // The component this halfedge belongs to: the incident 00188 // face for outer CCBs and the inner CCB information for 00189 // inner CCBs. The LSB of the pointer indicates whether 00190 // the halfedge lies on the boundary of an inner CCB. 00191 00192 X_monotone_curve *p_cv; // The associated x-monotone curve. 00193 00194 public: 00195 00197 Arr_halfedge_base() : 00198 p_opp (NULL), 00199 p_prev (NULL), 00200 p_next (NULL), 00201 p_v (NULL), 00202 p_comp (NULL), 00203 p_cv (NULL) 00204 {} 00205 00207 virtual ~Arr_halfedge_base() 00208 {} 00209 00211 bool has_null_curve () const 00212 { 00213 return (p_cv == NULL); 00214 } 00215 00217 const X_monotone_curve& curve() const 00218 { 00219 CGAL_precondition (p_cv != NULL); 00220 return (*p_cv); 00221 } 00222 00224 X_monotone_curve& curve () 00225 { 00226 CGAL_precondition (p_cv != NULL); 00227 return (*p_cv); 00228 } 00229 00231 void set_curve (X_monotone_curve* c) 00232 { 00233 p_cv = c; 00234 00235 // Set the curve for the opposite halfedge as well. 00236 Arr_halfedge_base<X_monotone_curve>* opp = 00237 reinterpret_cast<Arr_halfedge_base<X_monotone_curve>* > (p_opp); 00238 00239 opp->p_cv = c; 00240 } 00241 00243 virtual void assign (const Arr_halfedge_base<X_monotone_curve>& he) 00244 { 00245 p_cv = he.p_cv; 00246 } 00247 }; 00248 00252 class Arr_face_base 00253 { 00254 public: 00255 00256 typedef std::list<void*> Outer_ccbs_container; 00257 typedef Outer_ccbs_container::iterator Outer_ccb_iterator; 00258 typedef Outer_ccbs_container::const_iterator Outer_ccb_const_iterator; 00259 00260 typedef std::list<void*> Inner_ccbs_container; 00261 typedef Inner_ccbs_container::iterator Inner_ccb_iterator; 00262 typedef Inner_ccbs_container::const_iterator Inner_ccb_const_iterator; 00263 00264 typedef std::list<void*> Isolated_vertices_container; 00265 typedef Isolated_vertices_container::iterator Isolated_vertex_iterator; 00266 typedef Isolated_vertices_container::const_iterator 00267 Isolated_vertex_const_iterator; 00268 00269 protected: 00270 00271 enum 00272 { 00273 IS_UNBOUNDED = 1, 00274 IS_FICTITIOUS = 2 00275 }; 00276 00277 int flags; // Face flags. 00278 Outer_ccbs_container outer_ccbs; // The outer CCBs of the faces. 00279 Inner_ccbs_container inner_ccbs; // The holes inside the face. 00280 Isolated_vertices_container iso_verts; // The isolated vertices inside 00281 // the face. 00282 00283 public: 00284 00286 Arr_face_base() : 00287 flags (0) 00288 {} 00289 00291 virtual ~Arr_face_base() 00292 {} 00293 00295 bool is_unbounded () const 00296 { 00297 return ((flags & IS_UNBOUNDED) != 0); 00298 } 00299 00301 void set_unbounded (bool unbounded) 00302 { 00303 flags = (unbounded) ? (flags | IS_UNBOUNDED) : (flags & ~IS_UNBOUNDED); 00304 } 00305 00307 bool is_fictitious () const 00308 { 00309 return ((flags & IS_FICTITIOUS) != 0); 00310 } 00311 00313 void set_fictitious (bool fictitious) 00314 { 00315 flags = (fictitious) ? (flags | IS_FICTITIOUS) : (flags & ~IS_FICTITIOUS); 00316 } 00317 00319 virtual void assign (const Arr_face_base& f) 00320 { 00321 flags = f.flags; 00322 } 00323 }; 00324 00325 // Forward declarations: 00326 template <class V, class H, class F> class Arr_vertex; 00327 template <class V, class H, class F> class Arr_halfedge; 00328 template <class V, class H, class F> class Arr_face; 00329 template <class V, class H, class F> class Arr_outer_ccb; 00330 template <class V, class H, class F> class Arr_inner_ccb; 00331 template <class V, class H, class F> class Arr_isolated_vertex; 00332 00336 template <class V, class H, class F> 00337 class Arr_vertex : public V, 00338 public In_place_list_base<Arr_vertex<V,H,F> > 00339 { 00340 public: 00341 00342 typedef V Base; 00343 typedef Arr_vertex<V,H,F> Vertex; 00344 typedef Arr_halfedge<V,H,F> Halfedge; 00345 typedef Arr_isolated_vertex<V,H,F> Isolated_vertex; 00346 00348 Arr_vertex() 00349 {} 00350 00352 bool is_isolated () const 00353 { 00354 // Note that we use the LSB of the p_inc pointer as a Boolean flag. 00355 return (_is_lsb_set (this->p_inc)); 00356 } 00357 00359 const Halfedge* halfedge () const 00360 { 00361 CGAL_precondition (! is_isolated()); 00362 return (reinterpret_cast<const Halfedge*>(this->p_inc)); 00363 } 00364 00366 Halfedge* halfedge () 00367 { 00368 CGAL_precondition (! is_isolated()); 00369 return (reinterpret_cast<Halfedge*>(this->p_inc)); 00370 } 00371 00373 void set_halfedge (Halfedge* he) 00374 { 00375 // Set the halfedge pointer and reset the LSB. 00376 this->p_inc = he; 00377 } 00378 00380 const Isolated_vertex* isolated_vertex () const 00381 { 00382 CGAL_precondition (is_isolated()); 00383 return (reinterpret_cast<const Isolated_vertex*>(_clean_pointer 00384 (this->p_inc))); 00385 } 00386 00388 Isolated_vertex* isolated_vertex () 00389 { 00390 CGAL_precondition (is_isolated()); 00391 return (reinterpret_cast<Isolated_vertex*>(_clean_pointer (this->p_inc))); 00392 } 00393 00395 void set_isolated_vertex (Isolated_vertex* iv) 00396 { 00397 // Set the isolated vertex-information pointer and set its LSB. 00398 this->p_inc = _set_lsb (iv); 00399 } 00400 }; 00401 00405 template <class V, class H, class F> 00406 class Arr_halfedge : public H, 00407 public In_place_list_base<Arr_halfedge<V,H,F> > 00408 { 00409 public: 00410 00411 typedef H Base; 00412 typedef Arr_vertex<V,H,F> Vertex; 00413 typedef Arr_halfedge<V,H,F> Halfedge; 00414 typedef Arr_face<V,H,F> Face; 00415 typedef Arr_outer_ccb<V,H,F> Outer_ccb; 00416 typedef Arr_inner_ccb<V,H,F> Inner_ccb; 00417 00419 Arr_halfedge() 00420 {} 00421 00423 const Halfedge* opposite () const 00424 { 00425 return (reinterpret_cast<const Halfedge*>(this->p_opp)); 00426 } 00427 00429 Halfedge* opposite () 00430 { 00431 return (reinterpret_cast<Halfedge*>(this->p_opp)); 00432 } 00433 00435 void set_opposite (Halfedge* he) 00436 { 00437 this->p_opp = he; 00438 } 00439 00441 Arr_halfedge_direction direction () const 00442 { 00443 // Note that we use the LSB of the p_v pointer as a Boolean flag. 00444 if (_is_lsb_set (this->p_v)) 00445 return (ARR_LEFT_TO_RIGHT); 00446 else 00447 return (ARR_RIGHT_TO_LEFT); 00448 } 00449 00451 void set_direction (Arr_halfedge_direction dir) 00452 { 00453 Halfedge* opp = reinterpret_cast<Halfedge*> (this->p_opp); 00454 00455 if (dir == ARR_LEFT_TO_RIGHT) 00456 { 00457 this->p_v = _set_lsb (this->p_v); 00458 opp->p_v = _clean_pointer (opp->p_v); 00459 } 00460 else 00461 { 00462 this->p_v = _clean_pointer (this->p_v); 00463 opp->p_v = _set_lsb (opp->p_v); 00464 } 00465 } 00466 00468 const Halfedge* prev () const 00469 { 00470 return (reinterpret_cast<const Halfedge*>(this->p_prev)); 00471 } 00472 00474 Halfedge* prev () 00475 { 00476 return (reinterpret_cast<Halfedge*>(this->p_prev)); 00477 } 00478 00480 void set_prev (Halfedge* he) 00481 { 00482 this->p_prev = he; 00483 he->p_next = this; 00484 } 00485 00487 const Halfedge* next () const 00488 { 00489 return (reinterpret_cast<const Halfedge*>(this->p_next)); 00490 } 00491 00493 Halfedge* next () 00494 { 00495 return (reinterpret_cast<Halfedge*>(this->p_next)); 00496 } 00497 00499 void set_next (Halfedge* he) 00500 { 00501 this->p_next = he; 00502 he->p_prev = this; 00503 } 00504 00506 const Vertex* vertex () const 00507 { 00508 return (reinterpret_cast<const Vertex*>(_clean_pointer (this->p_v))); 00509 } 00510 00512 Vertex* vertex () 00513 { 00514 return (reinterpret_cast<Vertex*>(_clean_pointer (this->p_v))); 00515 } 00516 00518 void set_vertex (Vertex* v) 00519 { 00520 // Set the vertex pointer, preserving the content of the LSB. 00521 if (_is_lsb_set (this->p_v)) 00522 this->p_v = _set_lsb (v); 00523 else 00524 this->p_v = v; 00525 } 00526 00528 bool is_on_inner_ccb () const 00529 { 00530 return (_is_lsb_set (this->p_comp)); 00531 } 00532 00537 const Outer_ccb* outer_ccb () const 00538 { 00539 CGAL_precondition (! is_on_inner_ccb()); 00540 return (reinterpret_cast<const Outer_ccb*>(this->p_comp)); 00541 } 00542 00547 Outer_ccb* outer_ccb () 00548 { 00549 CGAL_precondition (! is_on_inner_ccb()); 00550 return (reinterpret_cast<Outer_ccb*>(this->p_comp)); 00551 } 00552 00554 void set_outer_ccb (Outer_ccb *oc) 00555 { 00556 // Set the component pointer and reset its LSB. 00557 this->p_comp = oc; 00558 } 00559 00564 const Inner_ccb* inner_ccb () const 00565 { 00566 CGAL_precondition (is_on_inner_ccb()); 00567 return (reinterpret_cast<const Inner_ccb*>(_clean_pointer (this->p_comp))); 00568 } 00569 00574 Inner_ccb* inner_ccb () 00575 { 00576 CGAL_precondition (is_on_inner_ccb()); 00577 return (reinterpret_cast<Inner_ccb*> (_clean_pointer (this->p_comp))); 00578 } 00579 00581 void set_inner_ccb (Inner_ccb *ic) 00582 { 00583 // Set the component pointer and set its LSB. 00584 this->p_comp = _set_lsb (ic); 00585 } 00586 }; 00587 00591 template <class V, class H, class F> 00592 class Arr_face : public F, 00593 public In_place_list_base<Arr_face<V,H,F> > 00594 { 00595 public: 00596 00597 typedef F Base; 00598 typedef Arr_vertex<V,H,F> Vertex; 00599 typedef Arr_halfedge<V,H,F> Halfedge; 00600 typedef Arr_face<V,H,F> Face; 00601 typedef Arr_outer_ccb<V,H,F> Outer_ccb; 00602 typedef Arr_inner_ccb<V,H,F> Inner_ccb; 00603 typedef Arr_isolated_vertex<V,H,F> Isolated_vertex; 00604 00605 private: 00606 00607 typedef Cast_function_object<void*, 00608 Halfedge*> _Ccb_to_halfedge_cast; 00609 typedef Cast_function_object<const void*, 00610 const Halfedge*> _Const_ccb_to_halfedge_cast; 00611 00612 00613 public: 00614 00616 Arr_face() 00617 {} 00618 00619 // Definition of the outer CCB iterators: 00620 typedef Iterator_project<typename F::Outer_ccb_iterator, 00621 _Ccb_to_halfedge_cast> Outer_ccb_iterator; 00622 00623 typedef Iterator_project<typename F::Outer_ccb_const_iterator, 00624 _Const_ccb_to_halfedge_cast> 00625 Outer_ccb_const_iterator; 00626 00628 size_t number_of_outer_ccbs () const 00629 { 00630 return (this->outer_ccbs.size()); 00631 } 00632 00634 Outer_ccb_iterator outer_ccbs_begin() 00635 { 00636 return (this->outer_ccbs.begin()); 00637 } 00638 00640 Outer_ccb_iterator outer_ccbs_end() 00641 { 00642 return (this->outer_ccbs.end()); 00643 } 00644 00646 Outer_ccb_const_iterator outer_ccbs_begin() const 00647 { 00648 return (this->outer_ccbs.begin()); 00649 } 00650 00652 Outer_ccb_const_iterator outer_ccbs_end() const 00653 { 00654 return (this->outer_ccbs.end()); 00655 } 00656 00658 void add_outer_ccb (Outer_ccb *oc, Halfedge *h) 00659 { 00660 oc->set_iterator (this->outer_ccbs.insert (this->outer_ccbs.end(), h)); 00661 return; 00662 } 00663 00665 void erase_outer_ccb (Outer_ccb *oc) 00666 { 00667 this->outer_ccbs.erase (oc->iterator().current_iterator()); 00668 } 00669 00670 // Definition of the inner CCB iterators: 00671 typedef Iterator_project<typename F::Inner_ccb_iterator, 00672 _Ccb_to_halfedge_cast> Inner_ccb_iterator; 00673 00674 typedef Iterator_project<typename F::Inner_ccb_const_iterator, 00675 _Const_ccb_to_halfedge_cast> 00676 Inner_ccb_const_iterator; 00677 00679 size_t number_of_inner_ccbs () const 00680 { 00681 return (this->inner_ccbs.size()); 00682 } 00683 00685 Inner_ccb_iterator inner_ccbs_begin() 00686 { 00687 return (this->inner_ccbs.begin()); 00688 } 00689 00691 Inner_ccb_iterator inner_ccbs_end() 00692 { 00693 return (this->inner_ccbs.end()); 00694 } 00695 00697 Inner_ccb_const_iterator inner_ccbs_begin() const 00698 { 00699 return (this->inner_ccbs.begin()); 00700 } 00701 00703 Inner_ccb_const_iterator inner_ccbs_end() const 00704 { 00705 return (this->inner_ccbs.end()); 00706 } 00707 00709 void add_inner_ccb (Inner_ccb *ic, Halfedge *h) 00710 { 00711 ic->set_iterator (this->inner_ccbs.insert (this->inner_ccbs.end(), h)); 00712 return; 00713 } 00714 00716 void erase_inner_ccb (Inner_ccb *ic) 00717 { 00718 this->inner_ccbs.erase (ic->iterator().current_iterator()); 00719 } 00720 00721 // Definition of the isloated vertices iterators: 00722 typedef I_Dereference_iterator< 00723 typename F::Isolated_vertex_iterator, 00724 Vertex, 00725 typename F::Isolated_vertex_iterator::difference_type, 00726 typename F::Isolated_vertex_iterator::iterator_category> 00727 Isolated_vertex_iterator; 00728 00729 typedef I_Dereference_const_iterator< 00730 typename F::Isolated_vertex_const_iterator, 00731 typename F::Isolated_vertex_iterator, 00732 Vertex, 00733 typename F::Isolated_vertex_iterator::difference_type, 00734 typename F::Isolated_vertex_iterator::iterator_category> 00735 Isolated_vertex_const_iterator; 00736 00738 size_t number_of_isolated_vertices() const 00739 { 00740 return (this->iso_verts.size()); 00741 } 00742 00744 Isolated_vertex_iterator isolated_vertices_begin() 00745 { 00746 return (this->iso_verts.begin()); 00747 } 00748 00750 Isolated_vertex_iterator isolated_vertices_end() 00751 { 00752 return (this->iso_verts.end()); 00753 } 00754 00756 Isolated_vertex_const_iterator isolated_vertices_begin() const 00757 { 00758 return (this->iso_verts.begin()); 00759 } 00760 00763 Isolated_vertex_const_iterator isolated_vertices_end() const 00764 { 00765 return (this->iso_verts.end()); 00766 } 00767 00769 void add_isolated_vertex (Isolated_vertex *iv, Vertex* v) 00770 { 00771 iv->set_iterator (this->iso_verts.insert (this->iso_verts.end(), v)); 00772 return; 00773 } 00774 00776 void erase_isolated_vertex (Isolated_vertex *iv) 00777 { 00778 this->iso_verts.erase (iv->iterator().current_iterator()); 00779 return; 00780 } 00781 00782 }; 00783 00787 template <class V, class H, class F> 00788 class Arr_outer_ccb : public In_place_list_base<Arr_outer_ccb<V,H,F> > 00789 { 00790 public: 00791 00792 typedef Arr_outer_ccb<V,H,F> Self; 00793 typedef Arr_halfedge<V,H,F> Halfedge; 00794 typedef Arr_face<V,H,F> Face; 00795 typedef typename Face::Outer_ccb_iterator Outer_ccb_iterator; 00796 00797 private: 00798 00799 Face *p_f; // The face the contains the CCB in its interior. 00800 Outer_ccb_iterator iter; // The outer CCB identifier. 00801 bool iter_is_not_singular; 00802 00803 public: 00804 00806 Arr_outer_ccb () : 00807 p_f (NULL), iter_is_not_singular(false) 00808 {} 00809 00811 Arr_outer_ccb (const Arr_outer_ccb& other ) 00812 : p_f (other.p_f), iter_is_not_singular(other.iter_is_not_singular) 00813 { 00814 if(other.iter_is_not_singular) { 00815 iter = other.iter; 00816 } 00817 } 00818 00820 const Halfedge* halfedge () const 00821 { 00822 return (*iter); 00823 } 00824 00826 Halfedge* halfedge () 00827 { 00828 return (*iter); 00829 } 00830 00832 void set_halfedge (Halfedge *he) 00833 { 00834 *iter = he; 00835 return; 00836 } 00837 00839 const Face* face () const 00840 { 00841 return (p_f); 00842 } 00843 00845 Face* face () 00846 { 00847 return (p_f); 00848 } 00849 00851 void set_face (Face* f) 00852 { 00853 p_f = f; 00854 return; 00855 } 00856 00858 Outer_ccb_iterator iterator () const 00859 { 00860 CGAL_assertion(iter_is_not_singular); 00861 return (iter); 00862 } 00863 00865 Outer_ccb_iterator iterator () 00866 { 00867 CGAL_assertion(iter_is_not_singular); 00868 return (iter); 00869 } 00870 00872 void set_iterator (Outer_ccb_iterator it) 00873 { 00874 iter = it; 00875 iter_is_not_singular = true; 00876 return; 00877 } 00878 }; 00879 00883 template <class V, class H, class F> 00884 class Arr_inner_ccb : public In_place_list_base<Arr_inner_ccb<V,H,F> > 00885 { 00886 public: 00887 00888 typedef Arr_inner_ccb<V,H,F> Self; 00889 typedef Arr_halfedge<V,H,F> Halfedge; 00890 typedef Arr_face<V,H,F> Face; 00891 typedef typename Face::Inner_ccb_iterator Inner_ccb_iterator; 00892 00893 private: 00894 00895 Face *p_f; // The face the contains the CCB in its interior. 00896 Inner_ccb_iterator iter; // The inner CCB identifier. 00897 bool iter_is_not_singular; 00898 00899 public: 00900 00902 Arr_inner_ccb () : 00903 p_f (NULL), iter_is_not_singular(false) 00904 {} 00905 00907 Arr_inner_ccb (const Arr_inner_ccb& other ) 00908 : p_f (other.p_f), iter_is_not_singular(other.iter_is_not_singular) 00909 { 00910 if(other.iter_is_not_singular) { 00911 iter = other.iter; 00912 } 00913 } 00914 00916 const Halfedge* halfedge () const 00917 { 00918 return (*iter); 00919 } 00920 00922 Halfedge* halfedge () 00923 { 00924 return (*iter); 00925 } 00926 00928 void set_halfedge (Halfedge *he) 00929 { 00930 *iter = he; 00931 return; 00932 } 00933 00935 const Face* face () const 00936 { 00937 return (p_f); 00938 } 00939 00941 Face* face () 00942 { 00943 return (p_f); 00944 } 00945 00947 void set_face (Face* f) 00948 { 00949 p_f = f; 00950 return; 00951 } 00952 00954 Inner_ccb_iterator iterator () const 00955 { 00956 CGAL_assertion(iter_is_not_singular); 00957 return (iter); 00958 } 00959 00961 Inner_ccb_iterator iterator () 00962 { 00963 CGAL_assertion(iter_is_not_singular); 00964 return (iter); 00965 } 00966 00968 void set_iterator (Inner_ccb_iterator it) 00969 { 00970 iter = it; 00971 iter_is_not_singular = true; 00972 return; 00973 } 00974 }; 00975 00979 template <class V, class H, class F> 00980 class Arr_isolated_vertex : 00981 public In_place_list_base<Arr_isolated_vertex<V,H,F> > 00982 { 00983 public: 00984 00985 typedef Arr_isolated_vertex<V,H,F> Self; 00986 typedef Arr_face<V,H,F> Face; 00987 typedef typename Face::Isolated_vertex_iterator Isolated_vertex_iterator; 00988 00989 private: 00990 00991 Face *p_f; // The face containing the hole. 00992 Isolated_vertex_iterator iv_it; // The isolated vertex identifier. 00993 bool iter_is_not_singular; 00994 00995 public: 00996 00998 Arr_isolated_vertex (): 00999 p_f (NULL), iter_is_not_singular(false) 01000 {} 01001 01003 Arr_isolated_vertex (const Arr_isolated_vertex& other ) 01004 : p_f (other.p_f), iter_is_not_singular(other.iter_is_not_singular) 01005 { 01006 if(other.iter_is_not_singular) { 01007 iv_it = other.iv_it; 01008 } 01009 } 01010 01012 const Face* face () const 01013 { 01014 return (p_f); 01015 } 01016 01018 Face* face () 01019 { 01020 return (p_f); 01021 } 01022 01024 void set_face (Face* f) 01025 { 01026 p_f = f; 01027 return; 01028 } 01029 01031 Isolated_vertex_iterator iterator () const 01032 { 01033 CGAL_assertion(iter_is_not_singular); 01034 return (iv_it); 01035 } 01036 01038 Isolated_vertex_iterator iterator () 01039 { 01040 CGAL_assertion(iter_is_not_singular); 01041 return (iv_it); 01042 } 01043 01045 void set_iterator (Isolated_vertex_iterator iv) 01046 { 01047 iv_it = iv; 01048 iter_is_not_singular = true; 01049 return; 01050 } 01051 }; 01052 01056 template <class V, class H, class F, 01057 class Allocator = CGAL_ALLOCATOR(int) > 01058 class Arr_dcel_base 01059 { 01060 public: 01061 01062 // Define the vertex, halfedge and face types. 01063 typedef Arr_dcel_base<V,H,F> Self; 01064 typedef Arr_vertex<V,H,F> Vertex; 01065 typedef Arr_halfedge<V,H,F> Halfedge; 01066 typedef Arr_face<V,H,F> Face; 01067 typedef Arr_outer_ccb<V,H,F> Outer_ccb; 01068 typedef Arr_inner_ccb<V,H,F> Inner_ccb; 01069 typedef Arr_isolated_vertex<V,H,F> Isolated_vertex; 01070 01071 protected: 01072 01073 // The vetices, halfedges and faces are stored in three in-place lists. 01074 typedef In_place_list<Vertex, false> Vertex_list; 01075 typedef In_place_list<Halfedge, false> Halfedge_list; 01076 typedef In_place_list<Face, false> Face_list; 01077 typedef In_place_list<Outer_ccb, false> Outer_ccb_list; 01078 typedef In_place_list<Inner_ccb, false> Inner_ccb_list; 01079 typedef In_place_list<Isolated_vertex, false> Iso_vert_list; 01080 01081 // Vertex allocator. 01082 typedef typename Allocator::template rebind<Vertex> Vertex_alloc_rebind; 01083 typedef typename Vertex_alloc_rebind::other Vertex_allocator; 01084 01085 // Halfedge allocator. 01086 typedef typename Allocator::template rebind<Halfedge> Halfedge_alloc_rebind; 01087 typedef typename Halfedge_alloc_rebind::other Halfedge_allocator; 01088 01089 // Face allocator. 01090 typedef typename Allocator::template rebind<Face> Face_alloc_rebind; 01091 typedef typename Face_alloc_rebind::other Face_allocator; 01092 01093 // Outer CCB allocator. 01094 typedef typename Allocator::template rebind<Outer_ccb> Out_ccb_alloc_rebind; 01095 typedef typename Out_ccb_alloc_rebind::other Outer_ccb_allocator; 01096 01097 // Inner CCB allocator. 01098 typedef typename Allocator::template rebind<Inner_ccb> In_ccb_alloc_rebind; 01099 typedef typename In_ccb_alloc_rebind::other Inner_ccb_allocator; 01100 01101 // Isolated vertex allocator. 01102 typedef typename Allocator::template rebind<Isolated_vertex> 01103 Iso_vert_alloc_rebind; 01104 typedef typename Iso_vert_alloc_rebind::other Iso_vert_allocator; 01105 01106 public: 01107 01108 typedef typename Halfedge_list::size_type Size; 01109 typedef typename Halfedge_list::size_type size_type; 01110 typedef typename Halfedge_list::difference_type difference_type; 01111 typedef typename Halfedge_list::difference_type Difference; 01112 typedef std::bidirectional_iterator_tag iterator_category; 01113 01114 protected: 01115 01116 Vertex_list vertices; // The vertices container. 01117 Halfedge_list halfedges; // The halfedges container. 01118 Face_list faces; // The faces container. 01119 Outer_ccb_list out_ccbs; // The outer CCBs. 01120 Inner_ccb_list in_ccbs; // The inner CCBs. 01121 Iso_vert_list iso_verts; // The isolated vertices. 01122 01123 Vertex_allocator vertex_alloc; // An allocator for vertices. 01124 Halfedge_allocator halfedge_alloc; // An allocator for halfedges. 01125 Face_allocator face_alloc; // An allocator for faces. 01126 Outer_ccb_allocator out_ccb_alloc; // An allocator for outer CCBs. 01127 Inner_ccb_allocator in_ccb_alloc; // An allocator for inner CCBs. 01128 Iso_vert_allocator iso_vert_alloc; // Allocator for isolated vertices. 01129 01130 public: 01131 01132 // Definitions of iterators. 01133 typedef typename Vertex_list::iterator Vertex_iterator; 01134 typedef typename Halfedge_list::iterator Halfedge_iterator; 01135 typedef typename Face_list::iterator Face_iterator; 01136 typedef CGAL::N_step_adaptor_derived<Halfedge_iterator, 2> 01137 Edge_iterator; 01138 01139 // Definitions of const iterators. 01140 typedef typename Vertex_list::const_iterator Vertex_const_iterator; 01141 typedef typename Halfedge_list::const_iterator Halfedge_const_iterator; 01142 typedef typename Face_list::const_iterator Face_const_iterator; 01143 typedef CGAL::N_step_adaptor_derived<Halfedge_const_iterator, 2> 01144 Edge_const_iterator; 01145 01146 private: 01147 01148 // Copy constructor - not supported. 01149 Arr_dcel_base (const Self&) ; 01150 01151 // Assignment operator - not supported. 01152 Self& operator= (const Self&); 01153 01154 public: 01155 01157 01158 01159 Arr_dcel_base () 01160 {} 01161 01163 ~Arr_dcel_base () 01164 { 01165 delete_all(); 01166 } 01168 01170 01171 01172 Size size_of_vertices () const 01173 { 01174 return (vertices.size()); 01175 } 01176 01178 Size size_of_halfedges () const 01179 { 01180 return (halfedges.size()); 01181 } 01182 01184 Size size_of_faces() const 01185 { 01186 return (faces.size()); 01187 } 01188 01190 Size size_of_outer_ccbs() const 01191 { 01192 return (out_ccbs.size()); 01193 } 01194 01196 Size size_of_inner_ccbs() const 01197 { 01198 return (in_ccbs.size()); 01199 } 01200 01202 Size size_of_isolated_vertices () const 01203 { 01204 return (iso_verts.size()); 01205 } 01207 01209 01210 Vertex_iterator vertices_begin() { return vertices.begin(); } 01211 Vertex_iterator vertices_end() { return vertices.end(); } 01212 Halfedge_iterator halfedges_begin() { return halfedges.begin();} 01213 Halfedge_iterator halfedges_end() { return halfedges.end(); } 01214 Face_iterator faces_begin() { return faces.begin(); } 01215 Face_iterator faces_end() { return faces.end(); } 01216 Edge_iterator edges_begin() { return halfedges.begin(); } 01217 Edge_iterator edges_end() { return halfedges.end(); } 01219 01221 01222 Vertex_const_iterator vertices_begin() const { return vertices.begin(); } 01223 Vertex_const_iterator vertices_end() const { return vertices.end(); } 01224 Halfedge_const_iterator halfedges_begin() const { return halfedges.begin(); } 01225 Halfedge_const_iterator halfedges_end() const { return halfedges.end(); } 01226 Face_const_iterator faces_begin() const { return faces.begin(); } 01227 Face_const_iterator faces_end() const { return faces.end(); } 01228 Edge_const_iterator edges_begin() const { return halfedges.begin(); } 01229 Edge_const_iterator edges_end() const { return halfedges.end(); } 01231 01232 // \name Creation of new DCEL features. 01234 01235 Vertex* new_vertex() 01236 { 01237 Vertex *v = vertex_alloc.allocate (1); 01238 01239 vertex_alloc.construct (v, Vertex()); 01240 vertices.push_back (*v); 01241 return v; 01242 } 01243 01245 Halfedge* new_edge() 01246 { 01247 // Create two new halfedges. 01248 Halfedge *h1 = _new_halfedge (); 01249 Halfedge *h2 = _new_halfedge (); 01250 01251 // Pair them together. 01252 h1->set_opposite (h2); 01253 h2->set_opposite (h1); 01254 01255 return (h1); 01256 } 01257 01259 Face* new_face() 01260 { 01261 Face *f = face_alloc.allocate (1); 01262 01263 face_alloc.construct (f, Face()); 01264 faces.push_back (*f); 01265 return (f); 01266 } 01267 01269 Outer_ccb* new_outer_ccb () 01270 { 01271 Outer_ccb *oc = out_ccb_alloc.allocate (1); 01272 out_ccb_alloc.construct (oc, Outer_ccb()); 01273 out_ccbs.push_back (*oc); 01274 return (oc); 01275 } 01276 01278 Inner_ccb* new_inner_ccb () 01279 { 01280 Inner_ccb *ic = in_ccb_alloc.allocate (1); 01281 01282 in_ccb_alloc.construct (ic, Inner_ccb()); 01283 in_ccbs.push_back (*ic); 01284 return (ic); 01285 } 01286 01288 Isolated_vertex* new_isolated_vertex () 01289 { 01290 Isolated_vertex *iv = iso_vert_alloc.allocate (1); 01291 01292 iso_vert_alloc.construct (iv, Isolated_vertex()); 01293 iso_verts.push_back (*iv); 01294 return (iv); 01295 } 01297 01299 01300 01301 void delete_vertex (Vertex *v) 01302 { 01303 vertices.erase (v); 01304 vertex_alloc.destroy (v); 01305 vertex_alloc.deallocate (v,1); 01306 } 01307 01309 void delete_edge (Halfedge *h) 01310 { 01311 Halfedge *h_opp = h->opposite(); 01312 01313 _delete_halfedge (h); 01314 _delete_halfedge (h_opp); 01315 } 01316 01318 void delete_face(Face *f) 01319 { 01320 faces.erase (f); 01321 face_alloc.destroy (f); 01322 face_alloc.deallocate (f, 1); 01323 } 01324 01326 void delete_outer_ccb (Outer_ccb *oc) 01327 { 01328 out_ccbs.erase (oc); 01329 out_ccb_alloc.destroy (oc); 01330 out_ccb_alloc.deallocate (oc, 1); 01331 } 01332 01334 void delete_inner_ccb (Inner_ccb *ic) 01335 { 01336 in_ccbs.erase (ic); 01337 in_ccb_alloc.destroy (ic); 01338 in_ccb_alloc.deallocate (ic, 1); 01339 } 01340 01342 void delete_isolated_vertex (Isolated_vertex *iv) 01343 { 01344 iso_verts.erase (iv); 01345 iso_vert_alloc.destroy (iv); 01346 iso_vert_alloc.deallocate (iv, 1); 01347 } 01348 01350 void delete_all() 01351 { 01352 // Free all vertices. 01353 Vertex_iterator vit = vertices.begin(), v_curr; 01354 01355 while (vit != vertices.end()) 01356 { 01357 v_curr = vit; 01358 ++vit; 01359 delete_vertex (&(*v_curr)); 01360 } 01361 01362 // Free all halfedges. 01363 Halfedge_iterator hit = halfedges.begin(), h_curr; 01364 01365 while (hit != halfedges.end()) 01366 { 01367 h_curr = hit; 01368 ++hit; 01369 _delete_halfedge (&(*h_curr)); 01370 } 01371 01372 // Free all faces. 01373 Face_iterator fit = faces.begin(), f_curr; 01374 01375 while (fit != faces.end()) 01376 { 01377 f_curr = fit; 01378 ++fit; 01379 delete_face (&(*f_curr)); 01380 } 01381 01382 // Free all outer CCBs. 01383 typename Outer_ccb_list::iterator ocit = out_ccbs.begin(), oc_curr; 01384 01385 while (ocit != out_ccbs.end()) 01386 { 01387 oc_curr = ocit; 01388 ++ocit; 01389 delete_outer_ccb (&(*oc_curr)); 01390 } 01391 01392 // Free all inner CCBs. 01393 typename Inner_ccb_list::iterator icit = in_ccbs.begin(), ic_curr; 01394 01395 while (icit != in_ccbs.end()) 01396 { 01397 ic_curr = icit; 01398 ++icit; 01399 delete_inner_ccb (&(*ic_curr)); 01400 } 01401 01402 // Free all isolated vertices. 01403 typename Iso_vert_list::iterator ivit = iso_verts.begin(), iv_curr; 01404 01405 while (ivit != iso_verts.end()) 01406 { 01407 iv_curr = ivit; 01408 ++ivit; 01409 delete_isolated_vertex (&(*iv_curr)); 01410 } 01411 } 01413 01417 void assign (const Self& dcel) 01418 { 01419 // Clear the current contents of the DCEL. 01420 delete_all(); 01421 01422 // Create duplicated of the DCEL features and map the features of the 01423 // given DCEL to their corresponding duplicates. 01424 typedef std::map<const Vertex*, Vertex*> Vertex_map; 01425 typedef std::map<const Halfedge*, Halfedge*> Halfedge_map; 01426 typedef std::map<const Face*, Face*> Face_map; 01427 typedef std::map<const Outer_ccb*, Outer_ccb*> Outer_ccb_map; 01428 typedef std::map<const Inner_ccb*, Inner_ccb*> Inner_ccb_map; 01429 typedef std::map<const Isolated_vertex*, Isolated_vertex*> Iso_vert_map; 01430 01431 Vertex_map v_map; 01432 Vertex_const_iterator vit; 01433 Vertex *dup_v; 01434 01435 for (vit = dcel.vertices_begin(); vit != dcel.vertices_end(); ++vit) 01436 { 01437 dup_v = new_vertex(); 01438 dup_v->assign (*vit); 01439 v_map.insert (typename Vertex_map::value_type (&(*vit), dup_v)); 01440 } 01441 01442 Halfedge_map he_map; 01443 Halfedge_const_iterator hit; 01444 Halfedge *dup_h; 01445 01446 for (hit = dcel.halfedges_begin(); hit != dcel.halfedges_end(); ++hit) 01447 { 01448 dup_h = _new_halfedge(); 01449 dup_h->assign (*hit); 01450 he_map.insert (typename Halfedge_map::value_type(&(*hit), dup_h)); 01451 } 01452 01453 Face_map f_map; 01454 Face_const_iterator fit; 01455 Face *dup_f; 01456 01457 for (fit = dcel.faces_begin(); fit != dcel.faces_end(); ++fit) 01458 { 01459 dup_f = new_face(); 01460 dup_f->assign (*fit); 01461 f_map.insert (typename Face_map::value_type(&(*fit), dup_f)); 01462 } 01463 01464 Outer_ccb_map oc_map; 01465 typename Outer_ccb_list::const_iterator ocit; 01466 Outer_ccb *dup_oc; 01467 01468 for (ocit = dcel.out_ccbs.begin(); ocit != dcel.out_ccbs.end(); ++ocit) 01469 { 01470 dup_oc = new_outer_ccb(); 01471 oc_map.insert (typename Outer_ccb_map::value_type(&(*ocit), dup_oc)); 01472 } 01473 01474 Inner_ccb_map ic_map; 01475 typename Inner_ccb_list::const_iterator icit; 01476 Inner_ccb *dup_ic; 01477 01478 for (icit = dcel.in_ccbs.begin(); icit != dcel.in_ccbs.end(); ++icit) 01479 { 01480 dup_ic = new_inner_ccb(); 01481 ic_map.insert (typename Inner_ccb_map::value_type(&(*icit), dup_ic)); 01482 } 01483 01484 Iso_vert_map iv_map; 01485 typename Iso_vert_list::const_iterator ivit; 01486 Isolated_vertex *dup_iv; 01487 01488 for (ivit = dcel.iso_verts.begin(); ivit != dcel.iso_verts.end(); ++ivit) 01489 { 01490 dup_iv = new_isolated_vertex(); 01491 iv_map.insert (typename Iso_vert_map::value_type(&(*ivit), dup_iv)); 01492 } 01493 01494 // Update the vertex records. 01495 const Vertex *v; 01496 const Halfedge *h; 01497 const Face *f; 01498 const Outer_ccb *oc; 01499 const Inner_ccb *ic; 01500 const Isolated_vertex *iv; 01501 01502 for (vit = dcel.vertices_begin(); vit != dcel.vertices_end(); ++vit) 01503 { 01504 v = &(*vit); 01505 dup_v = (v_map.find (v))->second; 01506 01507 if (v->is_isolated()) 01508 { 01509 // Isolated vertex - set its information. 01510 iv = v->isolated_vertex(); 01511 dup_iv = (iv_map.find (iv))->second; 01512 01513 dup_v->set_isolated_vertex (dup_iv); 01514 } 01515 else 01516 { 01517 // Regular vertex - set its incident halfedge. 01518 h = v->halfedge(); 01519 dup_h = (he_map.find (h))->second; 01520 01521 dup_v->set_halfedge (dup_h); 01522 } 01523 } 01524 01525 // Update the halfedge records. 01526 const Halfedge *opp, *prev, *next; 01527 Halfedge *dup_opp, *dup_prev, *dup_next; 01528 01529 for (hit = dcel.halfedges_begin(); hit != dcel.halfedges_end(); ++hit) 01530 { 01531 h = &(*hit); 01532 v = h->vertex(); 01533 opp = h->opposite(); 01534 prev = h->prev(); 01535 next = h->next(); 01536 01537 dup_h = (he_map.find (h))->second; 01538 dup_v = (v_map.find (v))->second; 01539 dup_opp = (he_map.find (opp))->second; 01540 dup_prev = (he_map.find (prev))->second; 01541 dup_next = (he_map.find (next))->second; 01542 01543 dup_h->set_vertex (dup_v); 01544 dup_h->set_opposite (dup_opp); 01545 dup_h->set_prev (dup_prev); 01546 dup_h->set_next (dup_next); 01547 dup_h->set_direction (h->direction()); 01548 01549 if (h->is_on_inner_ccb()) 01550 { 01551 // The halfedge lies on an inner CCB - set its inner CCB record. 01552 ic = h->inner_ccb(); 01553 dup_ic = (ic_map.find (ic))->second; 01554 dup_h->set_inner_ccb (dup_ic); 01555 } 01556 else 01557 { 01558 // The halfedge lies on an outer CCB - set its outer CCB record. 01559 oc = h->outer_ccb(); 01560 dup_oc = (oc_map.find (oc))->second; 01561 dup_h->set_outer_ccb (dup_oc); 01562 } 01563 } 01564 01565 // Update the face records, along with the CCB records and isolated vertex 01566 // records. 01567 typename Face::Outer_ccb_const_iterator out_ccb_it; 01568 typename Face::Inner_ccb_const_iterator in_ccb_it; 01569 typename Face::Isolated_vertex_const_iterator iso_vert_it; 01570 const Halfedge *hccb; 01571 const Vertex *iso_vert; 01572 Halfedge *dup_hccb; 01573 Vertex *dup_iso_vert; 01574 01575 for (fit = dcel.faces_begin(); fit != dcel.faces_end(); ++fit) 01576 { 01577 f = &(*fit); 01578 dup_f = (f_map.find (f))->second; 01579 dup_f->set_unbounded (f->is_unbounded()); 01580 dup_f->set_fictitious (f->is_fictitious()); 01581 01582 // Assign the outer CCBs of the face. 01583 for (out_ccb_it = f->outer_ccbs_begin(); 01584 out_ccb_it != f->outer_ccbs_end(); ++out_ccb_it) 01585 { 01586 hccb = *out_ccb_it; 01587 01588 dup_hccb = (he_map.find (hccb))->second; 01589 dup_oc = dup_hccb->outer_ccb(); 01590 01591 dup_oc->set_face (dup_f); 01592 dup_f->add_outer_ccb (dup_oc, dup_hccb); 01593 } 01594 01595 // Assign the inner CCBs of the face. 01596 for (in_ccb_it = f->inner_ccbs_begin(); 01597 in_ccb_it != f->inner_ccbs_end(); ++in_ccb_it) 01598 { 01599 hccb = *in_ccb_it; 01600 01601 dup_hccb = (he_map.find (hccb))->second; 01602 dup_ic = dup_hccb->inner_ccb(); 01603 01604 dup_ic->set_face (dup_f); 01605 dup_f->add_inner_ccb (dup_ic, dup_hccb); 01606 } 01607 01608 // Assign the isolated vertices. 01609 for (iso_vert_it = f->isolated_vertices_begin(); 01610 iso_vert_it != f->isolated_vertices_end(); ++iso_vert_it) 01611 { 01612 iso_vert = &(*iso_vert_it); 01613 01614 dup_iso_vert = (v_map.find (iso_vert))->second; 01615 dup_iv = dup_iso_vert->isolated_vertex(); 01616 01617 dup_iv->set_face (dup_f); 01618 dup_f->add_isolated_vertex (dup_iv, dup_iso_vert); 01619 } 01620 } 01621 01622 return; 01623 } 01624 01625 protected: 01626 01628 Halfedge * _new_halfedge () 01629 { 01630 Halfedge *h = halfedge_alloc.allocate (1); 01631 01632 halfedge_alloc.construct (h, Halfedge()); 01633 halfedges.push_back (*h); 01634 return (h); 01635 } 01636 01638 void _delete_halfedge (Halfedge* h) 01639 { 01640 halfedges.erase (h); 01641 halfedge_alloc.destroy (h); 01642 halfedge_alloc.deallocate (h, 1); 01643 } 01644 }; 01645 01646 CGAL_END_NAMESPACE 01647 01648 #endif