// 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 // 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; } }; } // 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 CGAL::detail::Edge, typename CGAL::Triangulation_2::Edge> edge_descriptor; typedef typename CGAL::Triangulation_2::All_edges_iterator edge_iterator; typedef CGAL::detail::boost_all_vertices_iterator vertex_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 degree_size_type; }; } // namespace boost namespace boost { template typename graph_traits< CGAL::Triangulation_2 >::vertex_descriptor source(typename graph_traits< CGAL::Triangulation_2 >::edge_descriptor e, const CGAL::Triangulation_2& g) { return e.first->vertex(g.ccw(e.second)); } template typename graph_traits< CGAL::Triangulation_2 >::vertex_descriptor target(typename graph_traits< CGAL::Triangulation_2 >::edge_descriptor e, const CGAL::Triangulation_2& g) { return e.first->vertex(g.cw(e.second)); } template inline std::pair< typename graph_traits< CGAL::Triangulation_2 >::vertex_iterator, typename graph_traits< CGAL::Triangulation_2 >::vertex_iterator > vertices(const CGAL::Triangulation_2& g) { typedef typename graph_traits< CGAL::Triangulation_2 >::vertex_iterator Iter; return std::make_pair( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) ); } template inline std::pair< typename graph_traits< CGAL::Triangulation_2 >::edge_iterator, typename graph_traits< CGAL::Triangulation_2 >::edge_iterator > edges(const CGAL::Triangulation_2& g) { return std::make_pair(g.all_edges_begin(), g.all_edges_end()); } template typename graph_traits< CGAL::Triangulation_2 >::degree_size_type out_degree( typename graph_traits< CGAL::Triangulation_2 >::vertex_descriptor u, const CGAL::Triangulation_2& g) { typename graph_traits< CGAL::Triangulation_2 >::degree_size_type deg = 0; typename CGAL::Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); if ( c != 0) { do { ++deg; } while (++c != done); } return deg; } template inline std::pair< typename graph_traits< CGAL::Triangulation_2 >::out_edge_iterator, typename graph_traits< CGAL::Triangulation_2 >::out_edge_iterator > out_edges( typename graph_traits< CGAL::Triangulation_2 >::vertex_descriptor u, const CGAL::Triangulation_2& g) { typename CGAL::Triangulation_2::Edge_circulator ec(u,u->face()); typename graph_traits< CGAL::Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename graph_traits< CGAL::Triangulation_2 > ::out_edge_iterator Iter; return std::make_pair( Iter(ec), Iter(ec,out_deg) ); } template inline std::pair< typename graph_traits< CGAL::Triangulation_2 >::in_edge_iterator, typename graph_traits< CGAL::Triangulation_2 >::in_edge_iterator > in_edges( typename graph_traits< CGAL::Triangulation_2 >::vertex_descriptor u, const CGAL::Triangulation_2& g) { typename CGAL::Triangulation_2::Edge_circulator ec(u,u->face()); typename graph_traits< CGAL::Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename graph_traits< CGAL::Triangulation_2 > ::in_edge_iterator Iter; return std::make_pair( Iter(ec), Iter(ec,out_deg) ); } template inline std::pair< typename graph_traits< CGAL::Triangulation_2 >::adjacency_iterator, typename graph_traits< CGAL::Triangulation_2 >::adjacency_iterator > adjacent_vertices( typename graph_traits< CGAL::Triangulation_2 >::vertex_descriptor u, const CGAL::Triangulation_2& g) { typename CGAL::Triangulation_2::Vertex_circulator vc = out_edge_iterator(u,u.face()); typename graph_traits< CGAL::Triangulation_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename graph_traits< CGAL::Triangulation_2 > ::adjacency_iterator Iter; return std::make_pair( Iter(vc), Iter(vc,out_deg) ); } template typename graph_traits< CGAL::Triangulation_2 >::vertices_size_type num_vertices(const CGAL::Triangulation_2& g) { return g.number_of_vertices()+1; } template typename graph_traits< CGAL::Triangulation_2 >::edges_size_type num_edges(const CGAL::Triangulation_2& g) { return g.number_of_vertices() + 1 + g.number_of_faces() + degree(g.infinite_vertex(), g) - 2; } template typename graph_traits< CGAL::Triangulation_2 >::degree_size_type in_degree( typename graph_traits< CGAL::Triangulation_2 >::vertex_descriptor u, const CGAL::Triangulation_2& g) { typename graph_traits< CGAL::Triangulation_2 >::degree_size_type deg = 0; typename CGAL::Triangulation_2::Edge_circulator c = g.incident_edges(u), done(c); if ( c != 0) { do { ++deg; } while (++c != done); } return deg; } template typename graph_traits< CGAL::Triangulation_2 >::degree_size_type degree( typename graph_traits< CGAL::Triangulation_2 >::vertex_descriptor u, const CGAL::Triangulation_2& g) { typename graph_traits< CGAL::Triangulation_2 >::degree_size_type deg = 0; typename CGAL::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 put_get_helper > { public: typedef 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_edge_id_map : public put_get_helper > { public: typedef 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 put_get_helper > { private: const CGAL::Triangulation_2& tr; public: typedef 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(vertex_index_t, const CGAL::Triangulation_2& g) { T2_vertex_id_map m; return m; } template inline T2_edge_id_map get(edge_index_t, const CGAL::Triangulation_2& g) { T2_edge_id_map m; return m; } template inline T2_edge_weight_map get(edge_weight_t, const CGAL::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_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; }; }; // g++ 'enumeral_type' in template unification not implemented workaround template struct property_map, Tag> { typedef typename 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 T2_property_map::template bind_ map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; template inline typename boost::property_traits< typename boost::property_map,PropertyTag>::const_type>::value_type get(PropertyTag p, const CGAL::Triangulation_2& g, const Key& key) { return get(get(p, g), key); } template inline void put(PropertyTag p, CGAL::Triangulation_2& g, const Key& key, const Value& value) { typedef typename property_map, PropertyTag>::type Map; Map pmap = get(p, g); put(pmap, key, value); } // 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