// Copyright (c) 2018 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$ // SPDX-License-Identifier: LGPL-3.0+ // // // Author(s) : Andreas Fabri #ifndef CGAL_GRAPH_TRAITS_HALFEDGEDS_DEFAULT_H #define CGAL_GRAPH_TRAITS_HALFEDGEDS_DEFAULT_H #include #include #include #include #include namespace CGAL { template class HalfedgeDS_default; } // namespace CGAL namespace boost { template struct graph_traits< CGAL::HalfedgeDS_default > : CGAL::HDS_graph_traits< CGAL::HalfedgeDS_default > { typedef typename T::Point_3 vertex_property_type; }; template struct graph_traits< CGAL::HalfedgeDS_default const > : CGAL::HDS_graph_traits< CGAL::HalfedgeDS_default > // See NOTE above! {}; } // namespace boost namespace CGAL { template typename boost::graph_traits< HalfedgeDS_default const>::vertices_size_type num_vertices(const HalfedgeDS_default& p) { return p.size_of_vertices(); } template typename boost::graph_traits< HalfedgeDS_default const>::edges_size_type num_edges(const HalfedgeDS_default& p) { return p.size_of_halfedges() / 2; } template typename boost::graph_traits< HalfedgeDS_default const>::degree_size_type degree(typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor v , const HalfedgeDS_default&) { return v->vertex_degree(); } template typename boost::graph_traits< HalfedgeDS_default const>::degree_size_type out_degree(typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor v , const HalfedgeDS_default&) { return v->vertex_degree(); } template typename boost::graph_traits< HalfedgeDS_default const>::degree_size_type in_degree(typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor v , const HalfedgeDS_default&) { return v->vertex_degree(); } template typename boost::graph_traits< HalfedgeDS_default const>::degree_size_type degree(typename boost::graph_traits< HalfedgeDS_default const>::face_descriptor f , const HalfedgeDS_default&) { return f->facet_degree(); } template typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor source(typename boost::graph_traits< HalfedgeDS_default const>::edge_descriptor e , const HalfedgeDS_default & ) { return e.halfedge()->opposite()->vertex(); } template typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor target(typename boost::graph_traits< HalfedgeDS_default const>::edge_descriptor e , const HalfedgeDS_default & ) { return e.halfedge()->vertex(); } template std::pair< typename boost::graph_traits< HalfedgeDS_default const>::edge_descriptor , bool> edge(typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor u , typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor v , const HalfedgeDS_default &) { typedef HalfedgeDS_default P; typedef boost::graph_traits< P > Traits; typedef typename Traits::halfedge_descriptor halfedge_descriptor; typedef typename Traits::edge_descriptor edge; // circulate around the inedges of u halfedge_descriptor c(u->halfedge()), d(u->halfedge()); if(c != halfedge_descriptor()) { do { if(c->opposite()->vertex() == v) { return std::make_pair(edge(c->opposite()), true); } c = c->next()->opposite(); } while (c != d); } return std::make_pair(edge(), false); } template inline Iterator_range const>::vertex_iterator> vertices( const HalfedgeDS_default& p) { typedef typename boost::graph_traits< HalfedgeDS_default const>::vertex_iterator Iter; HalfedgeDS_default& ncp = const_cast&>(p); return make_range( Iter(ncp.vertices_begin()), Iter(ncp.vertices_end()) ); } template inline Iterator_range const>::edge_iterator> edges( const HalfedgeDS_default& p) { typedef typename boost::graph_traits< HalfedgeDS_default const>::edge_iterator_i Iter_i; typedef typename boost::graph_traits< HalfedgeDS_default const>::edge_iterator Iter; HalfedgeDS_default& ncp = const_cast&>(p); return make_range( Iter(Iter_i(ncp.halfedges_begin())), Iter(Iter_i(ncp.halfedges_end()) )); } template inline Iterator_range const>::in_edge_iterator> in_edges( typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor u , const HalfedgeDS_default& p) { typedef typename boost::graph_traits< HalfedgeDS_default const>::in_edge_iterator Iter; return make_range(Iter(halfedge(u,p),p), Iter(halfedge(u,p),p,1)); } template inline Iterator_range const>::out_edge_iterator> out_edges( typename boost::graph_traits< HalfedgeDS_default const>::vertex_descriptor u , const HalfedgeDS_default& p) { typedef typename boost::graph_traits< HalfedgeDS_default const>::out_edge_iterator Iter; return make_range(Iter(halfedge(u,p),p), Iter(halfedge(u,p),p,1)); } // // MutableHalfedgeGraph // template typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor add_vertex(HalfedgeDS_default& g) { return g.vertices_push_back(typename HalfedgeDS_default::Vertex()); } template typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor add_vertex(const typename boost::graph_traits >::vertex_property_type& p , HalfedgeDS_default& g) { return g.vertices_push_back(typename HalfedgeDS_default::Vertex(p)); } template void remove_vertex(typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor v , HalfedgeDS_default& g) { g.vertices_erase(v); } template typename boost::graph_traits< HalfedgeDS_default >::edge_descriptor add_edge(HalfedgeDS_default& g) { return typename boost::graph_traits< HalfedgeDS_default >::edge_descriptor( g.edges_push_back(typename HalfedgeDS_default::Halfedge(), typename HalfedgeDS_default::Halfedge())); } template void remove_edge(typename boost::graph_traits< HalfedgeDS_default >::edge_descriptor e , HalfedgeDS_default& g) { g.edges_erase(e.halfedge()); } template void set_target(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h1 , typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor v , HalfedgeDS_default&) { // set_face has become private in the halfedge provided by // polyhedron for unknown reasons, although it used to be public // once. // We sneak in anyway. Inheritance can't keep us out. typedef typename HalfedgeDS_default::Halfedge::Base Sneak; static_cast(*h1).set_vertex(v); } template void set_next(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h1 , typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h2 , HalfedgeDS_default&) { typedef typename HalfedgeDS_default::Halfedge::Base Sneak; static_cast(*h1).set_next(h2); static_cast(*h2).set_prev(h1); } // // MutableFaceGraph // template typename boost::graph_traits< HalfedgeDS_default >::face_descriptor add_face(HalfedgeDS_default& g) { return g.faces_push_back(typename HalfedgeDS_default::Face()); } template typename boost::graph_traits< HalfedgeDS_default >::face_descriptor add_face(InputIterator begin, InputIterator end, HalfedgeDS_default& g) { return g.add_facet(begin, end); } template void remove_face(typename boost::graph_traits< HalfedgeDS_default >::face_descriptor f , HalfedgeDS_default& g) { g.faces_erase(f); } template void set_face(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h , typename boost::graph_traits< HalfedgeDS_default >::face_descriptor f , const HalfedgeDS_default&) { // set_face has become private in the halfedge provided by // polyhedron for unknown reasons, although it used to be public // once. // We sneak in anyway. Inheritance can't keep us out. typedef typename HalfedgeDS_default::Halfedge::Base Sneak; static_cast(*h).set_face(f); } template void set_halfedge(typename boost::graph_traits< HalfedgeDS_default >::face_descriptor f , typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h , HalfedgeDS_default& g) { typedef HalfedgeDS_default Hds; CGAL::HalfedgeDS_decorator D(g); D.set_face_halfedge(f, h); } template void set_halfedge(typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor v , typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h , const HalfedgeDS_default&) { typedef typename HalfedgeDS_default::Vertex::Base Sneak; static_cast(*v).set_halfedge(h); } // // HalfedgeGraph // template typename boost::graph_traits< HalfedgeDS_default >::edge_descriptor edge(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h , const HalfedgeDS_default&) { return typename boost::graph_traits< HalfedgeDS_default >::edge_descriptor(h); } template typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor halfedge(typename boost::graph_traits< HalfedgeDS_default >::edge_descriptor e , const HalfedgeDS_default&) { return e.halfedge(); } template typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor halfedge(typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor v , const HalfedgeDS_default&) { return v->halfedge(); } template std::pair< typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor , bool> halfedge(typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor u , typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor v , const HalfedgeDS_default& g) { std::pair< typename boost::graph_traits< HalfedgeDS_default >::edge_descriptor , bool> e = edge(u, v, g); return std::make_pair(e.first.halfedge(), e.second); } template typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor opposite(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h , const HalfedgeDS_default&) { return h->opposite(); } template typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor source(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h , const HalfedgeDS_default& g) { return target(opposite(h, g), g); } template typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor target(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h , const HalfedgeDS_default&) { return h->vertex(); } template typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor next(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor outedge , const HalfedgeDS_default&) { return outedge->next(); } template typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor prev(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor outedge , const HalfedgeDS_default&) { return outedge->prev(); } // // HalfedgeListGraph // template Iterator_range >::halfedge_iterator> halfedges(const HalfedgeDS_default& p) { typedef typename boost::graph_traits< HalfedgeDS_default >::halfedge_iterator Iter; HalfedgeDS_default& ncp = const_cast&>(p); return make_range(Iter(ncp.halfedges_begin()), Iter(ncp.halfedges_end())); } template typename boost::graph_traits< HalfedgeDS_default >::halfedges_size_type num_halfedges(const HalfedgeDS_default& p) { return p.size_of_halfedges(); } // FaceGraph template typename boost::graph_traits< HalfedgeDS_default >::face_descriptor face(typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor h , const HalfedgeDS_default&) { return h->face(); } template typename boost::graph_traits< HalfedgeDS_default >::halfedge_descriptor halfedge(typename boost::graph_traits< HalfedgeDS_default >::face_descriptor f , const HalfedgeDS_default&) { return f->halfedge(); } template inline Iterator_range const>::face_iterator > faces(const HalfedgeDS_default& p) { typedef typename boost::graph_traits< HalfedgeDS_default const>::face_iterator face_iterator; HalfedgeDS_default& ncp = const_cast&>(p); return make_range( face_iterator(ncp.faces_begin()), face_iterator(ncp.faces_end())); } template typename boost::graph_traits< HalfedgeDS_default const>::faces_size_type num_faces(const HalfedgeDS_default& p) { return p.size_of_faces(); } template struct HDS_property_map; template <> struct HDS_property_map { template struct bind_ { typedef internal::Point_accessor< typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor, typename T::Point_3, typename T::Point_3&> type; typedef internal::Point_accessor< typename boost::graph_traits< HalfedgeDS_default >::vertex_descriptor, typename T::Point_3, const typename T::Point_3&> const_type; }; }; }// namespace CGAL namespace boost { // property_map dispatcher into Polyhedron template struct property_map, Tag> { typedef typename CGAL::HDS_property_map:: template bind_ map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; // property_map dispatcher into const Polyhedron template struct property_map, Tag> { typedef typename CGAL::HDS_property_map:: template bind_ map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; } // namespace boost namespace CGAL { // generalized 2-ary get functions template typename boost::property_map< CGAL::HalfedgeDS_default, PropertyTag >::const_type get(PropertyTag, CGAL::HalfedgeDS_default const&) { return typename boost::property_map< CGAL::HalfedgeDS_default, PropertyTag >::const_type(); } template typename boost::property_map< CGAL::HalfedgeDS_default, PropertyTag >::type get(PropertyTag, CGAL::HalfedgeDS_default&) { return typename boost::property_map< CGAL::HalfedgeDS_default, PropertyTag >::type(); } } // namespace CGAL #endif