// Copyright (c) 2007 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Andreas Fabri, Fernando Cacciola // note only the properties below are protected by the macro, // the rest of the file is the shared implementation of properties for // Polyhedron and HalfedgeDS_default #ifndef CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_BASE_H #define CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_BASE_H #include #include #include #include #include #include #include namespace CGAL { namespace internal { template class HDS_index_map_external : public boost::put_get_helper > { public: typedef boost::lvalue_property_map_tag category; typedef std::size_t value_type; typedef std::size_t& reference; typedef Handle key_type; private: typedef CGAL::Unique_hash_map Map; public: template HDS_index_map_external(InputIterator begin, InputIterator end, std::size_t max) : map_(new Map(begin, end, 0, std::size_t(-1), max)) {} reference operator[](const key_type& k) const { return (*map_)[k]; } private: std::shared_ptr map_; }; // Special case for edges. template class HDS_edge_index_map_external : public boost::put_get_helper > { public: typedef boost::lvalue_property_map_tag category; typedef std::size_t value_type; typedef std::size_t& reference; typedef typename boost::graph_traits::edge_descriptor key_type; private: typedef CGAL::Unique_hash_map Map; public: HDS_edge_index_map_external(Polyhedron& p) : map_(new Map(std::size_t(-1), num_halfedges(p))) { unsigned int data = 0; typename boost::graph_traits::edge_iterator it, end; for(std::tie(it, end) = edges(p); it != end; ++it, ++data) (*map_)[*it] = data; } reference operator[](const key_type& k) const { return (*map_)[k]; } private: std::shared_ptr map_; }; template struct HDS_wrap_squared { typedef FT value_type; typedef FT reference; typedef Handle key_type; typedef boost::readable_property_map_tag category; template FT operator[](const E& e) const { return approximate_sqrt(CGAL::squared_distance(e.halfedge()->vertex()->point(), e.halfedge()->opposite()->vertex()->point())); } friend inline value_type get(const HDS_wrap_squared& m, const key_type k) { return m[k]; } }; } // the tag we dispatch on from property_map template struct HDS_property_map {}; } // end of CGAL::internal namespace #endif // CGAL_BOOST_GRAPH_PROPERTIES_HALFEDGEDS_BASE_H #if !defined(CGAL_HDS_TMPLT) || ! defined(CGAL_HDS_CLASS) #error CGAL_HDS_TMPLT or CGAL_HDS_CLASS is not defined #endif namespace CGAL { // generalized 2-ary get functions template typename boost::property_map::const_type get(PropertyTag,CGAL_HDS_CLASS const&) { return typename boost::property_map::const_type(); } template typename boost::property_map::type get(PropertyTag,CGAL_HDS_CLASS&) { return typename boost::property_map::type(); } // generalized 3-ary get functions template> && !std::is_same_v> && !std::is_same_v> && !std::is_same_v> > > typename boost::property_traits< typename boost::property_map::type >::reference get(PropertyTag p,CGAL_HDS_CLASS& g, const Key& key) { return get(get(p, g), key); } template typename boost::property_traits< typename boost::property_map::const_type >::reference get(PropertyTag p,CGAL_HDS_CLASS const& g, const Key& key) { return get(get(p, g), key); } #define DECLARE_HDS_DYNAMIC_PM(TAG, DESCRIPTOR) \ template \ typename boost::property_map::const_type \ get(const TAG&, const CGAL_HDS_CLASS&, const T& dv = T()) \ { \ typedef typename boost::graph_traits< CGAL_HDS_CLASS >::DESCRIPTOR descriptor; \ return internal::Dynamic_property_map(dv); \ } DECLARE_HDS_DYNAMIC_PM(dynamic_vertex_property_t, vertex_descriptor) DECLARE_HDS_DYNAMIC_PM(dynamic_halfedge_property_t, halfedge_descriptor) DECLARE_HDS_DYNAMIC_PM(dynamic_edge_property_t, edge_descriptor) DECLARE_HDS_DYNAMIC_PM(dynamic_face_property_t, face_descriptor) #undef DECLARE_HDS_DYNAMIC_PM // generalized put template void put(PropertyTag p,CGAL_HDS_CLASS& g, const Key& key, const Value& value) { typedef typename boost::property_map::type Map; Map pmap = get(p, g); put(pmap, key, value); } // specialization needs to be repeated for halfedge, vertex, face #define DECLARE_HDS_INDEX_PM(ENTITY, TAG, ACCESSOR) \ template \ struct HDS_property_map { \ struct bind_ { \ typedef internal::ACCESSOR##_accessor< \ CGAL_HDS_CLASS, \ typename boost::graph_traits< CGAL_HDS_CLASS \ >::ENTITY##_descriptor > type;\ typedef type const_type; \ }; \ }; DECLARE_HDS_INDEX_PM(halfedge, _index_t, Index) DECLARE_HDS_INDEX_PM(vertex, _index_t, Index) DECLARE_HDS_INDEX_PM(face, _index_t, Index) } // end of CGAL namespace #undef DECLARE_HDS_INDEX_PM namespace CGAL { // not done with macros, because HDS_edge::id does not return a // reference template struct HDS_property_map { struct bind_ { typedef internal::Edge_index_accessor< typename boost::graph_traits< CGAL_HDS_CLASS >::edge_descriptor > type; typedef type const_type; }; }; template struct HDS_property_map { struct bind_ { typedef typename CGAL_HDS_CLASS::Traits::FT FT; typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef internal::HDS_wrap_squared type; typedef type const_type; }; }; template struct HDS_property_map { struct bind_ { typedef internal::Point_accessor< typename boost::graph_traits< CGAL_HDS_CLASS >::vertex_descriptor, typename Gt::Point_3, typename Gt::Point_3&> type; typedef internal::Point_accessor< typename boost::graph_traits< CGAL_HDS_CLASS >::vertex_descriptor, typename Gt::Point_3, const typename Gt::Point_3&> const_type; }; }; // // external indices // template struct HDS_property_map { struct bind_ { typedef internal::HDS_edge_index_map_external< CGAL_HDS_CLASS > type; typedef type const_type; }; }; template struct HDS_property_map { struct bind_ { typedef internal::HDS_index_map_external< typename boost::graph_traits< CGAL_HDS_CLASS >::halfedge_descriptor > type; typedef type const_type; }; }; template struct HDS_property_map { struct bind_ { typedef internal::HDS_index_map_external< typename boost::graph_traits< CGAL_HDS_CLASS >::vertex_descriptor > type; typedef type const_type; }; }; template struct HDS_property_map { struct bind_ { typedef internal::HDS_index_map_external< typename boost::graph_traits< CGAL_HDS_CLASS >::face_descriptor > type; typedef type const_type; }; }; template typename boost::property_map::const_type get(boost::edge_external_index_t,CGAL_HDS_CLASS const& p) { return typename boost::property_map::const_type( const_cast(p)); } template typename boost::property_map::const_type get(boost::halfedge_external_index_t,CGAL_HDS_CLASS const& p) { CGAL_HDS_CLASS& ncp = const_cast(p); return typename boost::property_map::const_type( ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges()); } template typename boost::property_map::const_type get(boost::vertex_external_index_t,CGAL_HDS_CLASS const& p) { CGAL_HDS_CLASS& ncp = const_cast(p); return typename boost::property_map::const_type( ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices()); } template typename boost::property_map::const_type get(boost::face_external_index_t,CGAL_HDS_CLASS const& p) { CGAL_HDS_CLASS& ncp = const_cast(p); return typename boost::property_map::const_type( ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets()); } // the same blurb for non-const template typename boost::property_map::type get(boost::edge_external_index_t,CGAL_HDS_CLASS& p) { return typename boost::property_map::type( p); } template typename boost::property_map::type get(boost::halfedge_external_index_t,CGAL_HDS_CLASS & ncp) { return typename boost::property_map::type( ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges()); } template typename boost::property_map::type get(boost::vertex_external_index_t,CGAL_HDS_CLASS & ncp) { return typename boost::property_map::type( ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices()); } template typename boost::property_map::type get(boost::face_external_index_t,CGAL_HDS_CLASS & ncp) { return typename boost::property_map::type( ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets()); } } // end of CGAL namespace namespace boost { // property_map dispatcher into Polyhedron template struct property_map { typedef typename CGAL::HDS_property_map:: 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 { typedef typename CGAL::HDS_property_map:: bind_ map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; template struct property_map > { typedef CGAL_HDS_CLASS G; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef CGAL::internal::Dynamic_property_map type; typedef type const_type; }; template struct property_map > { typedef CGAL_HDS_CLASS G; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef CGAL::internal::Dynamic_property_map type; typedef type const_type; }; template struct property_map > { typedef CGAL_HDS_CLASS G; typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef CGAL::internal::Dynamic_property_map type; typedef type const_type; }; template struct property_map > { typedef CGAL_HDS_CLASS G; typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef CGAL::internal::Dynamic_property_map type; typedef type const_type; }; // What are those needed for ??? template struct edge_property_type { typedef edge_weight_t type; }; template struct vertex_property_type { typedef CGAL::vertex_point_t type; }; template struct vertex_property_type { typedef CGAL::vertex_point_t type; }; } // end of boost namespace namespace CGAL{ template struct graph_has_property : CGAL::Tag_true {}; template struct graph_has_property : CGAL::Tag_true {}; template struct graph_has_property : CGAL::Boolean_tag< CGAL::internal::Has_member_id< typename boost::graph_traits::edge_descriptor >::value > {}; template struct graph_has_property : CGAL::Boolean_tag< CGAL::internal::Has_member_id< typename CGAL_HDS_CLASS::Facet >::value > {}; template struct graph_has_property : CGAL::Boolean_tag< CGAL::internal::Has_member_id< typename CGAL_HDS_CLASS::Halfedge >::value > {}; template struct graph_has_property : CGAL::Boolean_tag< CGAL::internal::Has_member_id< typename CGAL_HDS_CLASS::Vertex >::value > {}; }// end of CGAL namespace #undef CGAL_HDS_TMPLT #undef CGAL_HDS_CLASS