// Copyright (c) 2016 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) : Guillaume Damiand #ifndef CGAL_BOOST_GRAPH_PROPERTIES_LINEAR_CELL_COMPLEX_H #define CGAL_BOOST_GRAPH_PROPERTIES_LINEAR_CELL_COMPLEX_H #include #include #include #include #define CGAL_LCC_ARGS unsigned int d_, unsigned int ambient_dim, \ class Traits_, \ class Items_, \ class Alloc_, \ template \ class CMap, \ class Storage_ #define CGAL_NAME_LCC_ARGS d_, ambient_dim, \ Traits_, \ Items_, \ Alloc_, \ CMap, \ Storage_ #define CGAL_LCC_TYPE CGAL::Linear_cell_complex_for_combinatorial_map\ namespace CGAL { /*template class LCC_edge_weight_map : public boost::put_get_helper > { public: typedef boost::readable_property_map_tag category; typedef double value_type; typedef double reference; typedef typename boost::graph_traits::edge_descriptor key_type; LCC_edge_weight_map(LCC const& lcc) : m_lcc(lcc) {} // reference operator[](key_type const& e) //{ return CGAL::squared_distance(m_lcc.point(e), m_lcc.point(m_lcc.other_extremity(e))); } reference operator[](key_type const& e) const { return CGAL::squared_distance(m_lcc.point(e), m_lcc.point(m_lcc.other_extremity(e))); } protected: LCC const& m_lcc; }; template class CMap_dart_index_map_external : public boost::put_get_helper > { public: typedef boost::read_write_property_map_tag category; typedef std::size_t value_type; typedef std::size_t& reference; typedef typename boost::graph_traits::edge_descriptor key_type; typedef CGAL::Unique_hash_map Map; CMap_dart_index_map_external(): map(new Map) {} CMap_dart_index_map_external(CMap const& cm): map(new Map) { CMap &cmap = const_cast(cm); typedef typename CMap::Dart_range::iterator Iter; Iter b=cmap.template darts().begin(); Iter e=cmap.template darts().end(); for(value_type i=0; b != e; ++b, ++i) { (*map)[b] = i; } b=cmap.template darts().begin(); for(; b != e; ++b) { value_type v1 = (*map)[b]; value_type v2 = (*map)[cmap.template beta<2>(b)]; CGAL_assertion(v1==v2+1 || v2==v1+1); } } reference operator[](key_type const& e) const { return const_cast(*map)[e]; } private: boost::shared_ptr map; }; template class CMap_vertex_index : public boost::put_get_helper > { public: typedef boost::read_write_property_map_tag category; typedef std::size_t value_type; typedef std::size_t& reference; typedef typename boost::graph_traits::vertex_descriptor key_type; typedef CGAL::Unique_hash_map Map; CMap_vertex_index(): map(new Map) {} CMap_vertex_index(CMap const& cm): map(new Map) { CMap &cmap = const_cast(cm); typedef typename CMap::template Attribute_range<0>::type::iterator Iter; Iter b=cmap.template attributes<0>().begin(); Iter e=cmap.template attributes<0>().end(); for(value_type i=0; b != e; ++b, ++i) { (*map)[b] = i; } } reference operator[](key_type const& e) const { return const_cast(*map)[e]; } private: boost::shared_ptr map; }; template class CMap_face_index : public boost::put_get_helper > { public: typedef boost::read_write_property_map_tag category; typedef std::size_t value_type; typedef std::size_t& reference; typedef typename boost::graph_traits::face_descriptor key_type; CMap_face_index() {} CMap_face_index(CMap const& cm) { CMap &cmap = const_cast(cm); typedef typename CMap::template Attribute_range<2>::type::iterator Iter; Iter b=cmap.template attributes<2>().begin(); Iter e=cmap.template attributes<2>().end(); for(value_type i=0; b != e; ++b, ++i) { map[b] = i; } } reference operator[](key_type const& e) const { return const_cast&>(map)[e]; } private: CGAL::Unique_hash_map map ; }; template class LCC_vertex_point_map : public boost::put_get_helper< typename LCC::Point&, LCC_vertex_point_map > { public: typedef typename LCC::Point Point; typedef boost::lvalue_property_map_tag category; typedef Point value_type; typedef Point& reference; typedef typename boost::graph_traits::vertex_descriptor key_type; LCC_vertex_point_map(LCC& lcc) : m_lcc(lcc) {} reference operator[](key_type const& v) const { return m_lcc.point_of_vertex_attribute(v); } protected: LCC & m_lcc; }; template class LCC_vertex_point_const_map : public boost::put_get_helper< typename LCC::Point const&, LCC_vertex_point_const_map > { public: typedef typename LCC::Point Point; typedef boost::readable_property_map_tag category; typedef Point value_type; typedef Point const& reference; typedef typename boost::graph_traits::vertex_descriptor key_type; LCC_vertex_point_const_map(LCC const& lcc) : m_lcc(lcc) {} reference operator[](key_type const& v) const { return m_lcc.point_of_vertex_attribute(v); } protected: const LCC & m_lcc; }; */ template struct Wrap_squared_lcc : boost::put_get_helper< double, Wrap_squared_lcc > { typedef typename boost::graph_traits::edge_descriptor Handle; typedef FT value_type; typedef FT reference; typedef Handle key_type; typedef boost::readable_property_map_tag category; Wrap_squared_lcc(const LCC& alcc): m_lcc(alcc) {} template FT operator[](const E& e) const { return approximate_sqrt(CGAL::squared_distance (m_lcc.point(e.first_halfedge()), m_lcc.point(e.second_halfedge()))); } private: const LCC& m_lcc; }; // the tag we dispatch on from property_map template struct LCC_property_map {}; // generalized 2-ary get functions template typename boost::property_map::const_type get(PropertyTag, CGAL_LCC_TYPE const&) { return typename boost::property_map::const_type(); } template typename boost::property_map::type get(PropertyTag, CGAL_LCC_TYPE &) { return typename boost::property_map::type(); } // generalized 3-ary get functions template typename boost::property_traits::type>::reference get(PropertyTag p, CGAL_LCC_TYPE& g, const Key& key) { return get(get(p, g), key); } template typename boost::property_traits::const_type>::reference get(PropertyTag p, CGAL_LCC_TYPE const& g, const Key& key) { return get(get(p, g), key); } // generalized put template void put(PropertyTag p, CGAL_LCC_TYPE& g, const Key& key, const Value& value) { typedef typename boost::property_map::type Map; Map pmap = get(p, g); put(pmap, key, value); } } // namespace CGAL // specialization needs to be repeated for halfedge, vertex, face #define CGAL_LCC_INDEX_PM(ENTITY, TAG, ACCESSOR) \ namespace CGAL { \ template<> struct LCC_property_map { \ template \ struct bind_ { \ typedef internal::ACCESSOR##_accessor< \ CGAL_LCC_TYPE, \ typename boost::graph_traits \ ::ENTITY##_descriptor > type; \ typedef type const_type; \ }; \ }; \ } CGAL_LCC_INDEX_PM(halfedge, _index_t, Index) CGAL_LCC_INDEX_PM(vertex, _index_t, Index) CGAL_LCC_INDEX_PM(face, _index_t, Index) #undef CGAL_LCC_INDEX_PM namespace CGAL { // not done with macros, because LCC_edge::id does not return a // reference template <> struct LCC_property_map { template struct bind_ { typedef internal::Edge_index_accessor< typename boost::graph_traits::edge_descriptor> type; typedef type const_type; }; }; template <> struct LCC_property_map { template struct bind_ { typedef typename Traits_::FT FT; typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef Wrap_squared_lcc type; typedef type const_type; }; }; template <> struct LCC_property_map { template struct bind_ { typedef internal::Point_accessor< typename boost::graph_traits::vertex_descriptor, typename Traits_::Point_3, typename Traits_::Point_3&> type; typedef internal::Point_accessor< typename boost::graph_traits::vertex_descriptor, typename Traits_::Point_3, const typename Traits_::Point_3&> const_type; }; }; // // external indices // template <> struct LCC_property_map { template struct bind_ { // typedef internal::Polyhedron_edge_index_map_external type; typedef internal::Edge_index_accessor< typename boost::graph_traits::edge_descriptor> type; typedef type const_type; }; }; template <> struct LCC_property_map { template struct bind_ { //typedef internal::Polyhedron_index_map_external< typedef internal::Index_accessor::halfedge_descriptor> type; typedef type const_type; }; }; template <> struct LCC_property_map { template struct bind_ { //typedef internal::Polyhedron_index_map_external< typedef internal::Index_accessor::vertex_descriptor> type; typedef type const_type; }; }; template <> struct LCC_property_map { template struct bind_ { //typedef internal::Polyhedron_index_map_external< typedef internal::Index_accessor::face_descriptor> type; typedef type const_type; }; }; } // namespace CGAL namespace CGAL{ template typename boost::property_map::const_type get(boost::halfedge_external_index_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map::const_type(); /* CGAL_LCC_TYPE& ncmap=const_cast(cmap); return typename boost::property_map:: const_type(halfedges(ncmap).begin(), halfedges(ncmap).end(), num_halfedges(ncmap)); */ } template typename boost::property_map::const_type get(boost::vertex_external_index_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map::const_type(); /* CGAL_LCC_TYPE& ncmap=const_cast(cmap); return typename boost::property_map:: const_type(vertices(ncmap).begin(), vertices(ncmap).end(), num_vertices(ncmap)); */ } template typename boost::property_map::const_type get(boost::edge_external_index_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map::const_type(); /*return typename boost::property_map:: const_type(const_cast(cmap));*/ } template typename boost::property_map::const_type get(boost::face_external_index_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map::const_type(); /*CGAL_LCC_TYPE& ncmap=const_cast(cmap); return typename boost::property_map:: const_type(faces(ncmap).begin(), faces(ncmap).end(), num_faces(ncmap));*/ } /* template typename boost::property_map::const_type get(boost::edge_index_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map:: const_type(const_cast(cmap)); } template typename boost::property_map::const_type get(boost::halfedge_index_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map:: const_type(const_cast(cmap)); } template typename boost::property_map::const_type get(boost::vertex_index_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map:: const_type(const_cast(cmap)); } template typename boost::property_map::const_type get(boost::face_index_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map:: const_type(const_cast(cmap)); } */ /*template typename boost::property_map::const_type get(boost::vertex_point_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map:: const_type(const_cast(cmap)); } */ template typename boost::property_map::const_type get(boost::edge_weight_t, CGAL_LCC_TYPE const& cmap) { return typename boost::property_map:: const_type(const_cast(cmap)); } // the same blurb for non-const template typename boost::property_map::type get(boost::halfedge_external_index_t, CGAL_LCC_TYPE& cmap) { return typename boost::property_map::type(); /* return typename boost::property_map:: type(halfedges(cmap).begin(), halfedges(cmap).end(), num_halfedges(cmap));*/ } template typename boost::property_map::type get(boost::vertex_external_index_t, CGAL_LCC_TYPE& cmap) { return typename boost::property_map::type(); /* return typename boost::property_map:: type(vertices(cmap).begin(), vertices(cmap).end(), num_vertices(cmap));*/ } template typename boost::property_map::type get(boost::edge_external_index_t, CGAL_LCC_TYPE& cmap) { return typename boost::property_map::type(cmap); /*return typename boost::property_map:: type(const_cast(cmap));*/ } template typename boost::property_map::type get(boost::face_external_index_t, CGAL_LCC_TYPE& cmap) { return typename boost::property_map::type(); /*return typename boost::property_map:: type(faces(cmap).begin(), faces(cmap).end(), num_faces(cmap));*/ } template typename boost::property_map::type get(boost::edge_weight_t, CGAL_LCC_TYPE & cmap) { return typename boost::property_map:: type(cmap); } } // namespace CGAL namespace boost { // property_map dispatcher into LCC template struct property_map { typedef typename CGAL::LCC_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 LCC template struct property_map { typedef typename CGAL::LCC_property_map:: template bind_ map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; } // namespace boost #undef CGAL_LCC_ARGS #undef CGAL_LCC_TYPE #endif // CGAL_BOOST_GRAPH_PROPERTIES_LINEAR_CELL_COMPLEX_H