BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/graph_traits_Dual_Arrangement_2.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines