BWAPI
|
00001 // Copyright (c) 2005 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/graph_traits_Dual_Arrangement_2.h $ 00015 // $Id: graph_traits_Dual_Arrangement_2.h 48358 2009-03-11 14:28:13Z ophirset $ 00016 // 00017 // 00018 // Author(s) : Ron Wein <wein@post.tau.ac.il> 00019 // Ophir Setter <ophirset@post.tau.ac.il> 00020 00021 #ifndef CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H 00022 #define CGAL_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H 00023 00029 #include <CGAL/Arrangement_on_surface_2.h> 00030 #include <CGAL/Arrangement_2.h> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00034 // Forward declaration. 00035 template <class Type> class Dual; 00036 00040 template <class GeomTraits_, class TopTraits_> 00041 class Dual<Arrangement_on_surface_2<GeomTraits_,TopTraits_> > 00042 { 00043 public: 00044 00045 typedef GeomTraits_ Geometry_traits_2; 00046 typedef TopTraits_ Topology_traits; 00047 typedef CGAL::Arrangement_on_surface_2<Geometry_traits_2, Topology_traits> 00048 Arrangement_on_surface_2; 00049 00050 typedef typename Arrangement_on_surface_2::Size Size; 00051 typedef typename Arrangement_on_surface_2::Face_handle Vertex_handle; 00052 typedef typename Arrangement_on_surface_2::Halfedge_handle Edge_handle; 00053 00054 typedef typename Arrangement_on_surface_2::Face_iterator Vertex_iterator; 00055 typedef typename Arrangement_on_surface_2::Halfedge_iterator Edge_iterator; 00056 00057 protected: 00058 00059 typedef typename Arrangement_on_surface_2::Face_handle Face_handle; 00060 typedef typename Arrangement_on_surface_2::Ccb_halfedge_circulator 00061 Ccb_halfedge_circulator; 00062 typedef typename Arrangement_on_surface_2::Outer_ccb_iterator 00063 Outer_ccb_iterator; 00064 typedef typename Arrangement_on_surface_2::Inner_ccb_iterator 00065 Inner_ccb_iterator; 00066 00073 class Face_neighbor_iterator 00074 { 00075 typedef Face_neighbor_iterator Self; 00076 00077 public: 00078 00079 typedef std::forward_iterator_tag iterator_category; 00080 typedef Edge_handle value_type; 00081 typedef value_type reference; 00082 typedef value_type* pointer; 00083 typedef int difference_type; 00084 00085 private: 00086 00087 Outer_ccb_iterator _outer_ccb_iter; 00088 Inner_ccb_iterator _inner_ccb_iter; 00089 Ccb_halfedge_circulator _ccb_curr; 00090 Ccb_halfedge_circulator _ccb_first; 00091 Face_handle _face; 00092 bool _out; 00093 Edge_handle _hh; 00094 bool _end; 00095 00096 public: 00097 00099 Face_neighbor_iterator () : 00100 _end (true) 00101 {} 00102 00110 Face_neighbor_iterator (Face_handle face, 00111 bool out_edges, 00112 bool start) : 00113 _face (face), 00114 _out (out_edges), 00115 _end (! start) 00116 { 00117 CGAL_precondition (! face->is_fictitious()); 00118 00119 if (start) 00120 { 00121 _outer_ccb_iter = _face->outer_ccbs_begin(); 00122 _inner_ccb_iter = _face->inner_ccbs_begin(); 00123 00124 if (_outer_ccb_iter != _face->outer_ccbs_end()) 00125 { 00126 // Start from the first outer CCB, if one exists. 00127 _ccb_curr = _ccb_first = *_outer_ccb_iter; 00128 } 00129 else if (_inner_ccb_iter != face->inner_ccbs_end()) 00130 { 00131 // Otherwise, start from the first inner CCB. 00132 _ccb_curr = _ccb_first = *_inner_ccb_iter; 00133 } 00134 else 00135 { 00136 // In this case there are no CCBs to traverse: 00137 _end = true; 00138 return; 00139 } 00140 00141 _hh = this->_dereference(); 00142 00143 // In case the incident face of the twin halfedge is fictitious, 00144 // skip it and proceed to the next edge. 00145 if (_hh->is_fictitious()) 00146 ++(*this); 00147 } 00148 else // end iterator. 00149 { 00150 _outer_ccb_iter = _face->outer_ccbs_end(); 00151 _inner_ccb_iter = _face->inner_ccbs_end(); 00152 } 00153 } 00154 00156 bool operator== (const Self& it) const 00157 { 00158 return (this->_equal(it)); 00159 } 00160 00161 bool operator!= (const Self& it) const 00162 { 00163 return (! this->_equal(it)); 00164 } 00165 00167 reference operator* () const 00168 { 00169 return (_hh); 00170 } 00171 00172 pointer operator-> () const 00173 { 00174 return (&_hh); 00175 } 00176 00177 /* Increment operators. */ 00178 Self& operator++ () 00179 { 00180 do 00181 { 00182 this->_increment(); 00183 if (_end) 00184 return (*this); 00185 00186 _hh = this->_dereference(); 00187 00188 } while (_hh->is_fictitious()); 00189 00190 return (*this); 00191 } 00192 00193 Self operator++ (int ) 00194 { 00195 Self tmp = *this; 00196 00197 do 00198 { 00199 this->_increment(); 00200 if (_end) 00201 return (tmp); 00202 00203 _hh = this->_dereference(); 00204 00205 } while (_hh->is_fictitious()); 00206 00207 return (tmp); 00208 } 00209 00210 private: 00211 00213 bool _equal (const Self& it) const 00214 { 00215 return (_out == it._out && _face == it._face && 00216 ((_end && it._end) || 00217 (_outer_ccb_iter == it._outer_ccb_iter && 00218 _inner_ccb_iter == it._inner_ccb_iter && 00219 _ccb_curr == it._ccb_curr))); 00220 } 00221 00223 Edge_handle _dereference () const 00224 { 00225 if (_out) 00226 return (_ccb_curr); 00227 else 00228 return (_ccb_curr->twin()); 00229 } 00230 00231 // Increments of the iterator. 00232 void _increment () 00233 { 00234 CGAL_assertion (! _end); 00235 00236 // If we have not traversed the entire CCB in full, move to the next 00237 // halfedge along the current CCB. 00238 ++_ccb_curr; 00239 00240 if (_ccb_curr != _ccb_first) 00241 return; 00242 00243 // In this case we have completed the current CCB and we have to move 00244 // to the next one. 00245 if (_outer_ccb_iter != _face->outer_ccbs_end()) 00246 { 00247 // Try to move to the next outer CCB. 00248 ++_outer_ccb_iter; 00249 if (_outer_ccb_iter != _face->outer_ccbs_end()) 00250 { 00251 _ccb_curr = _ccb_first = *_outer_ccb_iter; 00252 return; 00253 } 00254 00255 // In this case we start traversing the inner CCBs. 00256 if (_inner_ccb_iter != _face->inner_ccbs_end()) 00257 { 00258 CGAL_assertion (_inner_ccb_iter == _face->inner_ccbs_begin()); 00259 00260 // Otherwise, start from the first inner CCB. 00261 _ccb_curr = _ccb_first = *_inner_ccb_iter; 00262 return; 00263 } 00264 } 00265 else if (_inner_ccb_iter != _face->inner_ccbs_end()) 00266 { 00267 00268 // In this case we have already traversed all outer CCBs (and at least 00269 // one inner CCB), so we try to move to the next inner CCB. 00270 ++_inner_ccb_iter; 00271 if (_inner_ccb_iter != _face->inner_ccbs_end()) 00272 { 00273 // Otherwise, start from the first inner CCB. 00274 _ccb_curr = _ccb_first = *_inner_ccb_iter; 00275 return; 00276 } 00277 } 00278 00279 // In this case we finished traversing all outer and inner CCBs: 00280 _end = true; 00281 return; 00282 } 00283 00284 }; 00285 00286 // Data members: 00287 mutable Arrangement_on_surface_2 *p_arr; // The primal arrangement. 00288 00289 public: 00290 00291 typedef Face_neighbor_iterator Incident_edge_iterator; 00292 00294 Dual () : 00295 p_arr (NULL) 00296 {} 00297 00299 Dual (const Arrangement_on_surface_2& arr) : 00300 p_arr (const_cast<Arrangement_on_surface_2 *> (&arr)) 00301 {} 00302 00304 const Arrangement_on_surface_2* arrangement () const 00305 { 00306 return (p_arr); 00307 } 00308 00310 Arrangement_on_surface_2* arrangement () 00311 { 00312 return (p_arr); 00313 } 00314 00316 Size number_of_vertices () const 00317 { 00318 return (p_arr->number_of_faces()); 00319 } 00320 00322 Vertex_iterator vertices_begin () const 00323 { 00324 return (p_arr->faces_begin()); 00325 } 00326 00327 Vertex_iterator vertices_end () const 00328 { 00329 return (p_arr->faces_end()); 00330 } 00331 00333 Size number_of_edges () const 00334 { 00335 return (p_arr->number_of_halfedges()); 00336 } 00337 00339 Edge_iterator edges_begin () const 00340 { 00341 return (p_arr->halfedges_begin()); 00342 } 00343 00344 Edge_iterator edges_end () const 00345 { 00346 return (p_arr->halfedges_end()); 00347 } 00348 00352 Size degree (Vertex_handle v) const 00353 { 00354 Incident_edge_iterator begin = Incident_edge_iterator (v, true, true); 00355 Incident_edge_iterator end = Incident_edge_iterator (v, false, true); 00356 Size deg = 0; 00357 00358 while (begin != end) 00359 { 00360 deg++; 00361 ++begin; 00362 } 00363 00364 return (deg); 00365 } 00366 00368 Incident_edge_iterator out_edges_begin (Vertex_handle v) const 00369 { 00370 return (Incident_edge_iterator (v, true, true)); 00371 } 00372 00373 Incident_edge_iterator out_edges_end (Vertex_handle v) const 00374 { 00375 return (Incident_edge_iterator (v, true, false)); 00376 } 00377 00379 Incident_edge_iterator in_edges_begin (Vertex_handle v) const 00380 { 00381 return (Incident_edge_iterator (v, false, true)); 00382 } 00383 00384 Incident_edge_iterator in_edges_end (Vertex_handle v) const 00385 { 00386 return (Incident_edge_iterator (v, false, false)); 00387 } 00388 }; 00389 00393 template <class Traits_, class Dcel_> 00394 class Dual<Arrangement_2<Traits_, Dcel_> > : 00395 public Dual<Arrangement_on_surface_2< 00396 typename CGAL::Arrangement_2<Traits_, Dcel_>::Geometry_traits_2, 00397 typename CGAL::Arrangement_2<Traits_, Dcel_>::Topology_traits> > 00398 { 00399 typedef Traits_ Traits_2; 00400 typedef Dcel_ Dcel; 00401 typedef Dual<CGAL::Arrangement_on_surface_2< 00402 typename CGAL::Arrangement_2<Traits_2, Dcel>::Geometry_traits_2, 00403 typename CGAL::Arrangement_2<Traits_2, Dcel>::Topology_traits> > Base; 00404 00405 public: 00406 00408 Dual () : 00409 Base() 00410 {} 00411 00413 Dual (const CGAL::Arrangement_2<Traits_2, Dcel>& arr) : 00414 Base (arr) 00415 {} 00416 }; 00417 00418 CGAL_END_NAMESPACE 00419 00420 #include <boost/graph/graph_concepts.hpp> 00421 #include <boost/iterator/counting_iterator.hpp> 00422 00423 namespace boost { 00424 00433 template <class GeomTraits_, class TopTraits_> 00434 class graph_traits<CGAL::Dual<CGAL::Arrangement_on_surface_2<GeomTraits_, 00435 TopTraits_> > > 00436 { 00437 public: 00438 00439 typedef GeomTraits_ Geometry_traits_2; 00440 typedef TopTraits_ Topology_traits; 00441 typedef CGAL::Arrangement_on_surface_2<Geometry_traits_2, Topology_traits> 00442 Arrangement_on_surface_2; 00443 typedef CGAL::Dual<Arrangement_on_surface_2> Dual_arr_2; 00444 00445 private: 00446 00447 typedef typename Dual_arr_2::Vertex_iterator Vertex_iterator; 00448 typedef typename Dual_arr_2::Edge_iterator Edge_iterator; 00449 typedef typename Dual_arr_2::Incident_edge_iterator Incident_edge_iterator; 00450 00456 struct Dual_arr_traversal_category : 00457 public virtual boost::bidirectional_graph_tag, // This tag refines the 00458 // incidence_graph_tag. 00459 public virtual boost::vertex_list_graph_tag, // Can iterate over vertices. 00460 public virtual boost::edge_list_graph_tag // Can iterate over edges. 00461 {}; 00462 00463 public: 00464 00465 // Types required of the Graph concept: 00466 typedef typename Dual_arr_2::Vertex_handle vertex_descriptor; 00467 typedef boost::directed_tag directed_category; 00468 typedef boost::allow_parallel_edge_tag edge_parallel_category; 00469 00470 typedef Dual_arr_traversal_category traversal_category; 00471 00472 // Types required by the IncidenceGraph concept: 00473 typedef typename Dual_arr_2::Edge_handle edge_descriptor; 00474 typedef Incident_edge_iterator out_edge_iterator; 00475 typedef typename Dual_arr_2::Size degree_size_type; 00476 00477 // Types required by the BidirectionalGraph concept: 00478 typedef Incident_edge_iterator in_edge_iterator; 00479 00480 // Types required by the VertexListGraph concept: 00481 typedef boost::counting_iterator<Vertex_iterator> vertex_iterator; 00482 typedef typename Dual_arr_2::Size vertices_size_type; 00483 00484 // Types required by the EdgeListGraph concept: 00485 typedef boost::counting_iterator<Edge_iterator> edge_iterator; 00486 typedef typename Dual_arr_2::Size edges_size_type; 00487 00488 // Types not required by any of these concepts: 00489 typedef void adjacency_iterator; 00490 00491 }; 00492 00497 template <class Traits_, class Dcel_> 00498 class graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > > : 00499 public graph_traits<CGAL::Dual<CGAL::Arrangement_on_surface_2< 00500 typename CGAL::Arrangement_2<Traits_, Dcel_>::Geometry_traits_2, 00501 typename CGAL::Arrangement_2<Traits_, Dcel_>::Topology_traits> > > 00502 {}; 00503 00504 }; // namespace boost 00505 00506 CGAL_BEGIN_NAMESPACE 00507 00508 // Functions required by the IncidenceGraph concept: 00509 // ------------------------------------------------- 00510 00517 template <class GeomTraits_, class TopTraits_> 00518 typename 00519 boost::graph_traits<CGAL::Dual<CGAL:: 00520 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >::degree_size_type 00521 out_degree(typename 00522 boost::graph_traits<CGAL::Dual<CGAL:: 00523 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00524 vertex_descriptor v, 00525 const CGAL::Dual<CGAL:: 00526 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00527 { 00528 return darr.degree (v); 00529 } 00530 00538 template <class GeomTraits_, class TopTraits_> 00539 std::pair<typename 00540 boost::graph_traits<CGAL::Dual<CGAL:: 00541 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00542 out_edge_iterator, 00543 typename 00544 boost::graph_traits<CGAL::Dual<CGAL:: 00545 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00546 out_edge_iterator> 00547 out_edges(typename 00548 boost::graph_traits<CGAL::Dual<CGAL:: 00549 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00550 vertex_descriptor v, 00551 const CGAL::Dual<CGAL:: 00552 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00553 { 00554 return std::make_pair (darr.out_edges_begin (v), darr.out_edges_end (v)); 00555 } 00556 00563 template <class GeomTraits_, class TopTraits_> 00564 typename 00565 boost::graph_traits<CGAL::Dual<CGAL:: 00566 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >::vertex_descriptor 00567 source(typename 00568 boost::graph_traits<CGAL::Dual<CGAL:: 00569 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00570 edge_descriptor e, 00571 const CGAL::Dual<CGAL:: 00572 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& /* darr */) 00573 { 00574 return e->face(); 00575 } 00576 00583 template <class GeomTraits_, class TopTraits_> 00584 typename 00585 boost::graph_traits<CGAL::Dual<CGAL:: 00586 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >::vertex_descriptor 00587 target(typename 00588 boost::graph_traits<CGAL::Dual<CGAL:: 00589 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00590 edge_descriptor e, 00591 const CGAL::Dual<CGAL:: 00592 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& /* darr */) 00593 { 00594 return e->twin()->face(); 00595 } 00596 00597 // Functions required by the BidirectionalGraph concept: 00598 // ----------------------------------------------------- 00599 00606 template <class GeomTraits_, class TopTraits_> 00607 typename 00608 boost::graph_traits<CGAL::Dual<CGAL:: 00609 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >::degree_size_type 00610 in_degree(typename 00611 boost::graph_traits<CGAL::Dual<CGAL:: 00612 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00613 vertex_descriptor v, 00614 const CGAL::Dual<CGAL:: 00615 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00616 { 00617 return darr.degree (v); 00618 } 00619 00627 template <class GeomTraits_, class TopTraits_> 00628 std::pair<typename 00629 boost::graph_traits<CGAL::Dual<CGAL:: 00630 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00631 in_edge_iterator, 00632 typename 00633 boost::graph_traits<CGAL::Dual<CGAL:: 00634 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00635 in_edge_iterator> 00636 in_edges(typename 00637 boost::graph_traits<CGAL::Dual<CGAL:: 00638 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00639 vertex_descriptor v, 00640 const CGAL::Dual<CGAL:: 00641 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00642 { 00643 return std::make_pair (darr.in_edges_begin (v), darr.in_edges_end (v)); 00644 } 00645 00652 template <class GeomTraits_, class TopTraits_> 00653 typename 00654 boost::graph_traits<CGAL::Dual<CGAL:: 00655 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >::degree_size_type 00656 degree(typename 00657 boost::graph_traits<CGAL::Dual<CGAL:: 00658 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00659 vertex_descriptor v, 00660 const CGAL::Dual<CGAL:: 00661 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00662 { 00663 return (2 * darr.degree (v)); 00664 } 00665 00666 // Functions required by the VertexListGraph concept: 00667 // -------------------------------------------------- 00668 00674 template <class GeomTraits_, class TopTraits_> 00675 typename 00676 boost::graph_traits<CGAL::Dual<CGAL:: 00677 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >::vertices_size_type 00678 num_vertices(const CGAL::Dual<CGAL:: 00679 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00680 { 00681 return darr.number_of_vertices(); 00682 } 00683 00689 template <class GeomTraits_, class TopTraits_> 00690 std::pair<typename 00691 boost::graph_traits<CGAL::Dual<CGAL:: 00692 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00693 vertex_iterator, 00694 typename 00695 boost::graph_traits<CGAL::Dual<CGAL:: 00696 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00697 vertex_iterator> 00698 vertices (const CGAL::Dual<CGAL:: 00699 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00700 { 00701 return std::make_pair (darr.vertices_begin(), darr.vertices_end()); 00702 } 00703 00704 // Functions required by the EdgeListGraph concept: 00705 // ------------------------------------------------ 00706 00712 template <class GeomTraits_, class TopTraits_> 00713 typename 00714 boost::graph_traits<CGAL::Dual<CGAL:: 00715 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >::edges_size_type 00716 num_edges(const CGAL::Dual<CGAL:: 00717 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00718 { 00719 return darr.number_of_edges(); 00720 } 00721 00727 template <class GeomTraits_, class TopTraits_> 00728 std::pair<typename 00729 boost::graph_traits<CGAL::Dual<CGAL:: 00730 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00731 edge_iterator, 00732 typename 00733 boost::graph_traits<CGAL::Dual<CGAL:: 00734 Arrangement_on_surface_2<GeomTraits_, TopTraits_> > >:: 00735 edge_iterator> 00736 edges (const CGAL::Dual<CGAL:: 00737 Arrangement_on_surface_2<GeomTraits_, TopTraits_> >& darr) 00738 { 00739 return std::make_pair (darr.edges_begin(), darr.edges_end()); 00740 } 00741 00742 CGAL_END_NAMESPACE 00743 00744 #endif