// 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_BOOST_GRAPH_PROPERTIES_POLYHEDRON_3_H #define CGAL_BOOST_GRAPH_PROPERTIES_POLYHEDRON_3_H #include #include #include #include #include #include #define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS namespace CGAL { namespace internal { template class Polyhedron_index_map_external : public boost::put_get_helper > { public: typedef boost::readable_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 Polyhedron_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: boost::shared_ptr map_; }; // Special case for edges. template class Polyhedron_edge_index_map_external : public boost::put_get_helper > { public: typedef boost::readable_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: Polyhedron_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(boost::tie(it, end) = edges(p); it != end; ++it, ++data) (*map_)[*it] = data; } reference operator[](const key_type& k) const { return (*map_)[k]; } private: boost::shared_ptr map_; }; template struct Wrap_squared : boost::put_get_helper< double, 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())); } }; template struct Index_accessor : boost::put_get_helper< std::size_t&, Index_accessor > { typedef boost::lvalue_property_map_tag category; typedef std::size_t& reference; typedef std::size_t value_type; typedef Handle key_type; reference operator[](Handle h) const { return h->id(); } }; template struct Edge_index_accessor : boost::put_get_helper< std::size_t, Edge_index_accessor > { typedef boost::readable_property_map_tag category; typedef std::size_t reference; typedef std::size_t value_type; typedef Handle key_type; reference operator[](Handle h) const { return h.id(); } }; template struct Point_accessor : boost::put_get_helper< Reference, Point_accessor > { typedef boost::lvalue_property_map_tag category; typedef Reference reference; typedef ValueType value_type; typedef Handle key_type; reference operator[](Handle h) const { return h->point(); } }; } // internal // the tag we dispatch on from property_map template struct Polyhedron_property_map {}; } // namespace CGAL namespace CGAL { // generalized 2-ary get functions template typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::const_type get(PropertyTag, CGAL::Polyhedron_3 const&) { return typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::const_type(); } template typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::type get(PropertyTag, CGAL::Polyhedron_3&) { return typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::type(); } // generalized 3-ary get functions template typename boost::property_traits< typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::type >::reference get(PropertyTag p, CGAL::Polyhedron_3& g, const Key& key) { return get(get(p, g), key); } template typename boost::property_traits< typename boost::property_map, PropertyTag >::const_type >::reference get(PropertyTag p, CGAL::Polyhedron_3 const& g, const Key& key) { return get(get(p, g), key); } // generalized put template void put(PropertyTag p, CGAL::Polyhedron_3& g, const Key& key, const Value& value) { typedef typename boost::property_map, PropertyTag>::type Map; Map pmap = get(p, g); put(pmap, key, value); } } // boost // specialization needs to be repeated for halfedge, vertex, face #define CGAL_POLYHEDRON_INDEX_PM(ENTITY, TAG, ACCESSOR) \ namespace CGAL { \ template<> struct Polyhedron_property_map { \ template \ struct bind_ { \ typedef internal::ACCESSOR##_accessor< \ CGAL::Polyhedron_3, \ typename boost::graph_traits< CGAL::Polyhedron_3 \ >::ENTITY##_descriptor > type; \ typedef type const_type; \ }; \ }; \ } CGAL_POLYHEDRON_INDEX_PM(halfedge, _index_t, Index) CGAL_POLYHEDRON_INDEX_PM(vertex, _index_t, Index) CGAL_POLYHEDRON_INDEX_PM(face, _index_t, Index) #undef CGAL_POLYHEDRON_INDEX_PM namespace CGAL { // not done with macros, because HDS_edge::id does not return a // reference template <> struct Polyhedron_property_map { template struct bind_ { typedef internal::Edge_index_accessor< typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor > type; typedef type const_type; }; }; template <> struct Polyhedron_property_map { template struct bind_ { typedef typename CGAL::Polyhedron_3::Traits::FT FT; typedef typename boost::graph_traits >::edge_descriptor edge_descriptor; typedef internal::Wrap_squared type; typedef type const_type; }; }; template <> struct Polyhedron_property_map { template struct bind_ { typedef internal::Point_accessor< typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor, typename Gt::Point_3, typename Gt::Point_3&> type; typedef internal::Point_accessor< typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor, typename Gt::Point_3, const typename Gt::Point_3&> const_type; }; }; // // external indices // template <> struct Polyhedron_property_map { template struct bind_ { typedef internal::Polyhedron_edge_index_map_external< CGAL::Polyhedron_3 > type; typedef type const_type; }; }; template <> struct Polyhedron_property_map { template struct bind_ { typedef internal::Polyhedron_index_map_external< typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor > type; typedef type const_type; }; }; template <> struct Polyhedron_property_map { template struct bind_ { typedef internal::Polyhedron_index_map_external< typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor > type; typedef type const_type; }; }; template <> struct Polyhedron_property_map { template struct bind_ { typedef internal::Polyhedron_index_map_external< typename boost::graph_traits< CGAL::Polyhedron_3 >::face_descriptor > type; typedef type const_type; }; }; } // CGAL namespace CGAL { template typename boost::property_map< CGAL::Polyhedron_3, boost::edge_external_index_t >::const_type get(boost::edge_external_index_t, CGAL::Polyhedron_3 const& p) { return typename boost::property_map< CGAL::Polyhedron_3, boost::edge_external_index_t >::const_type( const_cast& >(p)); } template typename boost::property_map< CGAL::Polyhedron_3, boost::halfedge_external_index_t >::const_type get(boost::halfedge_external_index_t, CGAL::Polyhedron_3 const& p) { CGAL::Polyhedron_3& ncp = const_cast&>(p); return typename boost::property_map< CGAL::Polyhedron_3, boost::halfedge_external_index_t >::const_type( ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges()); } template typename boost::property_map< CGAL::Polyhedron_3, boost::vertex_external_index_t >::const_type get(boost::vertex_external_index_t, CGAL::Polyhedron_3 const& p) { CGAL::Polyhedron_3& ncp = const_cast&>(p); return typename boost::property_map< CGAL::Polyhedron_3, boost::vertex_external_index_t >::const_type( ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices()); } template typename boost::property_map< CGAL::Polyhedron_3, boost::face_external_index_t >::const_type get(boost::face_external_index_t, CGAL::Polyhedron_3 const& p) { CGAL::Polyhedron_3& ncp = const_cast&>(p); return typename boost::property_map< CGAL::Polyhedron_3, boost::face_external_index_t >::const_type( ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets()); } // the same blurb for non-const template typename boost::property_map< CGAL::Polyhedron_3, boost::edge_external_index_t >::type get(boost::edge_external_index_t, CGAL::Polyhedron_3& p) { return typename boost::property_map< CGAL::Polyhedron_3, boost::edge_external_index_t >::type( p); } template typename boost::property_map< CGAL::Polyhedron_3, boost::halfedge_external_index_t >::type get(boost::halfedge_external_index_t, CGAL::Polyhedron_3 & ncp) { return typename boost::property_map< CGAL::Polyhedron_3, boost::halfedge_external_index_t >::type( ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges()); } template typename boost::property_map< CGAL::Polyhedron_3, boost::vertex_external_index_t >::type get(boost::vertex_external_index_t, CGAL::Polyhedron_3 & ncp) { return typename boost::property_map< CGAL::Polyhedron_3, boost::vertex_external_index_t >::type( ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices()); } template typename boost::property_map< CGAL::Polyhedron_3, boost::face_external_index_t >::type get(boost::face_external_index_t, CGAL::Polyhedron_3 & ncp) { return typename boost::property_map< CGAL::Polyhedron_3, boost::face_external_index_t >::type( ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets()); } } // namespace CGAL namespace boost { // property_map dispatcher into Polyhedron template struct property_map, Tag> { typedef typename CGAL::Polyhedron_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::Polyhedron_property_map:: template bind_ map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_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; }; } // namespace boost #undef CGAL_HDS_PARAM_ #endif // CGAL_BOOST_GRAPH_PROPERTIES_POLYHEDRON_3_H