// Copyright (c) 2007 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : Andreas Fabri, Fernando Cacciola #ifndef CGAL_GRAPH_TRAITS_TRIANGULATION_2_H #define CGAL_GRAPH_TRAITS_TRIANGULATION_2_H #include #include #include #include #include #include #include // The functions and classes in this file allows the user to // treat a CGAL Triangulation_2 object as a boost graph "as is". No // wrapper is needed for the Triangulation_2 object. namespace CGAL { namespace detail { template < class T, class EdgeBase > class Edge : public EdgeBase { typedef typename T::Face_handle Face_handle ; public: Edge() {} Edge(Face_handle fh, int i) : EdgeBase(fh,i) {} Edge(const EdgeBase& e) : EdgeBase(e) {} Edge(const Edge& e) : EdgeBase(e) {} Edge& operator=(const Edge& e) { this->first = e.first; this->second = e.second; return *this; } bool operator==(const Edge& other) const { if((this->first == other.first)&&(this->second == other.second)) return true; Face_handle fh = this->first->neighbor(this->second); if(other.first != fh) return false; int i = fh->index(this->first); return (other.second == i); } bool operator!=(Edge& other) const { return ! (*this == other); } }; template class Out_edge_circulator : public Circ { private: mutable E e; public: typedef E value_type; typedef E* pointer; typedef E& reference; Out_edge_circulator() : Circ() {} Out_edge_circulator(Circ c) : Circ(c) {} const E& operator*() const { E ed = static_cast(this)->operator*(); e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); return e; } }; template class In_edge_circulator : public Circ { private: mutable E e; public: typedef E value_type; typedef E* pointer; typedef E& reference; In_edge_circulator() : Circ() {} In_edge_circulator(Circ c) : Circ(c) {} const E& operator*() const { typename Circ::value_type ed = static_cast(this)->operator*(); e = E(ed); return e; } }; // The vertex iterator of the bgl must evaluate to a vertex handle, not to a vertex template < class T> class boost_all_vertices_iterator { protected: typename T::All_vertices_iterator nt; public: typedef typename T::All_vertices_iterator Iterator; typedef boost_all_vertices_iterator Self; typedef typename std::iterator_traits::iterator_category iterator_category; typedef typename T::Vertex_handle value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef value_type reference; typedef value_type pointer; // CREATION // -------- boost_all_vertices_iterator() {} boost_all_vertices_iterator( Iterator j) : nt(j) {} // OPERATIONS Forward Category // --------------------------- bool operator==( const Self& i) const { return ( nt == i.nt); } bool operator!=( const Self& i) const { return !(nt == i.nt ); } value_type operator*() const { return nt; } value_type operator->() { return nt; } Self& operator++() { ++nt; return *this; } Self operator++(int) { Self tmp = *this; ++*this; return tmp; } Self& operator--() { --nt; return *this; } Self operator--(int) { Self tmp = *this; --*this; return tmp; } }; template < class T> class boost_all_faces_iterator { protected: typename T::All_faces_iterator nt; public: typedef typename T::All_faces_iterator Iterator; typedef boost_all_faces_iterator Self; typedef typename std::iterator_traits::iterator_category iterator_category; typedef typename T::Face_handle value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef value_type reference; typedef value_type pointer; // CREATION // -------- boost_all_faces_iterator() {} boost_all_faces_iterator( Iterator j) : nt(j) {} // OPERATIONS Forward Category // --------------------------- bool operator==( const Self& i) const { return ( nt == i.nt); } bool operator!=( const Self& i) const { return !(nt == i.nt ); } value_type operator*() const { return nt; } value_type operator->() { return nt; } Self& operator++() { ++nt; return *this; } Self operator++(int) { Self tmp = *this; ++*this; return tmp; } Self& operator--() { --nt; return *this; } Self operator--(int) { Self tmp = *this; --*this; return tmp; } }; } // namespace detail } // namespace CGAL namespace boost { template struct graph_traits< CGAL::Triangulation_2 > { struct T2_graph_traversal_category : public virtual bidirectional_graph_tag, public virtual adjacency_graph_tag, public virtual edge_list_graph_tag, public virtual vertex_list_graph_tag { }; typedef CGAL::Triangulation_2 Triangulation; typedef typename CGAL::Triangulation_2::Vertex_handle vertex_descriptor; typedef typename CGAL::Triangulation_2::Face_handle face_descriptor; typedef CGAL::detail::Edge, typename CGAL::Triangulation_2::Edge> edge_descriptor; typedef typename CGAL::Triangulation_2::All_edges_iterator edge_iterator; // with just a typedef to Edge VC++ has ambiguities for function `next()` struct halfedge_descriptor { face_descriptor first; int second; operator std::pair() { return std::make_pair(first,second); } halfedge_descriptor() {} halfedge_descriptor(const typename Triangulation::Edge& e) : first(e.first), second(e.second) {} halfedge_descriptor(face_descriptor fd, int i) : first(fd), second(i) {} bool operator==(const halfedge_descriptor& other) const { return (first == other.first) && (second == other.second); } bool operator!=(const halfedge_descriptor& other) const { return (first != other.first) || (second != other.second); } bool operator<(const halfedge_descriptor& other) const { if(first < other.first) return true; if(first > other.first) return false; return second < other.second; } }; typedef typename CGAL::Triangulation_2::All_halfedges_iterator halfedge_iterator; typedef CGAL::detail::boost_all_vertices_iterator vertex_iterator; typedef CGAL::detail::boost_all_faces_iterator face_iterator; typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; typedef CGAL::Counting_iterator Incident_vertices_iterator; typedef Incident_vertices_iterator adjacency_iterator; typedef undirected_tag directed_category; typedef disallow_parallel_edge_tag edge_parallel_category; typedef T2_graph_traversal_category traversal_category; typedef typename Triangulation::size_type size_type; typedef size_type vertices_size_type; typedef size_type edges_size_type; typedef size_type halfedges_size_type; typedef size_type faces_size_type; typedef size_type degree_size_type; // nulls static vertex_descriptor null_vertex() { return vertex_descriptor(); } static face_descriptor null_face() { return face_descriptor(); } static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } }; } // namespace boost namespace CGAL { template typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor next(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, const Triangulation_2& g) { typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; return halfedge_descriptor(e.first, g.ccw(e.second)); } template typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor prev(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, const Triangulation_2& g) { typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; return halfedge_descriptor(e.first, g.cw(e.second)); } template typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor opposite(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, const Triangulation_2& g) { return g.mirror_edge(e); } template typename boost::graph_traits< Triangulation_2 >::vertex_descriptor source(typename boost::graph_traits< Triangulation_2 >::edge_descriptor e, const Triangulation_2& g) { return e.first->vertex(g.ccw(e.second)); } template typename boost::graph_traits< Triangulation_2 >::vertex_descriptor target(typename boost::graph_traits< Triangulation_2 >::edge_descriptor e, const Triangulation_2& g) { return e.first->vertex(g.cw(e.second)); } template typename boost::graph_traits< Triangulation_2 >::vertex_descriptor source(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, const Triangulation_2& g) { return e.first->vertex(g.ccw(e.second)); } template typename boost::graph_traits< Triangulation_2 >::vertex_descriptor target(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, const Triangulation_2& g) { return e.first->vertex(g.cw(e.second)); } template typename boost::graph_traits< Triangulation_2 >::face_descriptor face(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, const Triangulation_2&) { return e.first; } template typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge(typename boost::graph_traits< Triangulation_2 >::face_descriptor f, const Triangulation_2&) { typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; return halfedge_descriptor(f,0); } template typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge(typename boost::graph_traits< Triangulation_2 >::vertex_descriptor v, const Triangulation_2& g) { typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits< Triangulation_2 >::face_descriptor face_descriptor; face_descriptor fd = v->face(); int i = fd->index(v); return halfedge_descriptor(fd,g.ccw(i)); } template typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge(typename boost::graph_traits< Triangulation_2 >::edge_descriptor e, const Triangulation_2&) { typedef typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor halfedge_descriptor; return halfedge_descriptor(e.first,e.second); } template typename boost::graph_traits< Triangulation_2 >::edge_descriptor edge(typename boost::graph_traits< Triangulation_2 >::halfedge_descriptor e, const Triangulation_2&) { typedef typename boost::graph_traits< Triangulation_2 >::edge_descriptor edge_descriptor; return edge_descriptor(e.first,e.second); } template inline Iterator_range >::vertex_iterator> vertices(const Triangulation_2& g) { typedef typename boost::graph_traits< Triangulation_2 >::vertex_iterator Iter; return make_range( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) ); } template inline Iterator_range >::edge_iterator> edges(const Triangulation_2& g) { return make_range(g.all_edges_begin(), g.all_edges_end()); } template inline Iterator_range >::halfedge_iterator > halfedges(const Triangulation_2& g) { return make_range(g.all_halfedges_begin(), g.all_halfedges_end()); } template inline Iterator_range >::face_iterator > faces(const Triangulation_2& g) { typedef typename boost::graph_traits< Triangulation_2 >::face_iterator Iter; return make_range( Iter(g.all_faces_begin()), Iter(g.all_faces_end()) ); } template typename boost::graph_traits< Triangulation_2 >::degree_size_type out_degree( typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, const Triangulation_2& g) { typename boost::graph_traits< Triangulation_2 >::degree_size_type deg = 0; typename Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); if ( c != 0) { do { ++deg; } while (++c != done); } return deg; } template inline Iterator_range >::out_edge_iterator > out_edges( typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, const Triangulation_2& g) { typename Triangulation_2::Edge_circulator ec(u,u->face()); typename boost::graph_traits< Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename boost::graph_traits< Triangulation_2 > ::out_edge_iterator Iter; return make_range( Iter(ec), Iter(ec,out_deg) ); } template inline Iterator_range >::in_edge_iterator > in_edges( typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, const Triangulation_2& g) { typename Triangulation_2::Edge_circulator ec(u,u->face()); typename boost::graph_traits< Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename boost::graph_traits< Triangulation_2 > ::in_edge_iterator Iter; return make_range( Iter(ec), Iter(ec,out_deg) ); } template inline Iterator_range >::adjacency_iterator> adjacent_vertices( typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, const Triangulation_2& g) { typename Triangulation_2::Vertex_circulator vc = out_edge_iterator(u,u.face()); typename boost::graph_traits< Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename boost::graph_traits< Triangulation_2 > ::adjacency_iterator Iter; return make_range( Iter(vc), Iter(vc,out_deg) ); } template typename boost::graph_traits< Triangulation_2 >::vertices_size_type num_vertices(const Triangulation_2& g) { return g.tds().number_of_vertices(); } template typename boost::graph_traits< Triangulation_2 >::edges_size_type num_edges(const Triangulation_2& g) { return g.tds().number_of_vertices() + g.tds().number_of_faces() - 2; } template typename boost::graph_traits< Triangulation_2 >::halfedges_size_type num_halfedges(const Triangulation_2& g) { return num_edges(g) * 2; } template typename boost::graph_traits< Triangulation_2 >::faces_size_type num_faces(const Triangulation_2& g) { return g.tds().number_of_faces(); } template typename boost::graph_traits< Triangulation_2 >::degree_size_type in_degree( typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, const Triangulation_2& g) { typename boost::graph_traits< Triangulation_2 >::degree_size_type deg = 0; typename Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); if ( c != 0) { do { ++deg; } while (++c != done); } return deg; } template typename boost::graph_traits< Triangulation_2 >::degree_size_type degree( typename boost::graph_traits< Triangulation_2 >::vertex_descriptor u, const Triangulation_2& g) { typename boost::graph_traits< Triangulation_2 >::degree_size_type deg = 0; typename Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); if ( c != 0) { do { ++deg; } while (++c != done); } return deg; } // property maps template class T2_vertex_id_map : public boost::put_get_helper > { public: typedef boost::readable_property_map_tag category; typedef int value_type; typedef int reference; typedef typename CGAL::Triangulation_2::Vertex_handle key_type; T2_vertex_id_map() {} long operator[](key_type vh) const { return vh->id(); } }; template class T2_vertex_point_map { public: typedef boost::lvalue_property_map_tag category; typedef typename Tds::Vertex::Point value_type; typedef value_type& reference; typedef typename CGAL::Triangulation_2::Vertex_handle key_type; friend reference get(T2_vertex_point_map, key_type vh) { return vh->point(); } friend void put(T2_vertex_point_map, key_type vh, const reference v) { vh->point()=v; } reference operator[](key_type vh) const { return vh->point(); } }; template class T2_edge_id_map : public boost::put_get_helper > { public: typedef boost::readable_property_map_tag category; typedef int value_type; typedef int reference; typedef typename CGAL::Triangulation_2::Edge key_type; T2_edge_id_map() {} long operator[](key_type e) const { return (3 * e.first.id()) + e.second; } }; template class T2_edge_weight_map : public boost::put_get_helper > { private: const CGAL::Triangulation_2& tr; public: typedef boost::readable_property_map_tag category; typedef typename Gt::FT value_type; typedef value_type reference; typedef typename CGAL::Triangulation_2::Edge key_type; T2_edge_weight_map(const CGAL::Triangulation_2& tr_) : tr(tr_) { } value_type operator[](key_type e) const { return tr.segment(e).squared_length(); } }; template inline T2_vertex_id_map get(boost::vertex_index_t, const Triangulation_2&) { T2_vertex_id_map m; return m; } template inline T2_vertex_point_map get(boost::vertex_point_t, const Triangulation_2&) { T2_vertex_point_map m; return m; } template inline T2_edge_id_map get(boost::edge_index_t, const Triangulation_2&) { T2_edge_id_map m; return m; } template inline T2_edge_weight_map get(boost::edge_weight_t, const Triangulation_2& g) { T2_edge_weight_map m(g); return m; } template struct T2_property_map { }; template <> struct T2_property_map { template struct bind_ { typedef T2_vertex_id_map type; typedef T2_vertex_id_map const_type; }; }; template <> struct T2_property_map { template struct bind_ { typedef T2_vertex_point_map type; typedef T2_vertex_point_map const_type; }; }; template <> struct T2_property_map { template struct bind_ { typedef T2_edge_id_map type; typedef T2_edge_id_map const_type; }; }; template <> struct T2_property_map { template struct bind_ { typedef T2_edge_weight_map type; typedef T2_edge_weight_map const_type; }; }; } // namespace CGAL namespace boost { // g++ 'enumeral_type' in template unification not implemented workaround template struct property_map, Tag> { typedef typename CGAL::T2_property_map::template bind_ map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; // see struct property_map in Polyehdron for an explanation template struct property_map, Tag> { typedef typename CGAL::T2_property_map::template bind_ map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; } // namespace boost namespace CGAL { template inline typename boost::property_traits< typename boost::property_map,PropertyTag>::const_type>::value_type get(PropertyTag p, const Triangulation_2& g, const Key& key) { return get(get(p, g), key); } template inline void put(PropertyTag p, Triangulation_2& g, const Key& key, const Value& value) { typedef typename boost::property_map, PropertyTag>::type Map; Map pmap = get(p, g); put(pmap, key, value); } } // namespace CGAL namespace boost { // What are those needed for ??? template struct edge_property_type > { typedef void type; }; template struct vertex_property_type > { typedef void type; }; } // namespace boost //#include #endif // CGAL_GRAPH_TRAITS_TRIANGULATION_2_H