// Copyright (c) 2014 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Philipp Möller #ifndef CGAL_PROPERTIES_SURFACE_MESH_H #define CGAL_PROPERTIES_SURFACE_MESH_H #include #ifndef DOXYGEN_RUNNING #include #include #include #include #include #include #include #include #include #include namespace CGAL { template class SM_edge_weight_pmap { typedef CGAL::Surface_mesh SM; public: typedef boost::readable_property_map_tag category; typedef typename CGAL::Kernel_traits::type::FT value_type; typedef value_type reference; typedef typename SM::Edge_index key_type; SM_edge_weight_pmap(const CGAL::Surface_mesh& sm) : pm_(sm. template property_map< typename SM::Vertex_index, typename SM::Point >("v:point").value()), sm_(sm) {} value_type operator[](const key_type& e) const { return approximate_sqrt(CGAL::squared_distance(pm_[source(e, sm_)], pm_[target(e, sm_)])); } friend inline value_type get(const SM_edge_weight_pmap& m, const key_type& k) { return m[k]; } private: typename SM::template Property_map< typename SM::Vertex_index, typename SM::Point > pm_; const SM& sm_; }; template class SM_index_pmap { public: typedef boost::readable_property_map_tag category; typedef std::uint32_t value_type; typedef std::uint32_t reference; typedef VEF key_type; value_type operator[](const key_type& vd) const { return vd; } friend inline value_type get(const SM_index_pmap& m, const key_type& k) { return m[k]; } }; } // CGAL namespace boost { // // edge_weight // template struct property_map, boost::edge_weight_t > { typedef CGAL::SM_edge_weight_pmap type; typedef CGAL::SM_edge_weight_pmap const_type; }; } namespace CGAL{ template typename boost::property_map, boost::edge_weight_t>::const_type get(boost::edge_weight_t, const CGAL::Surface_mesh& sm) { return CGAL::SM_edge_weight_pmap(sm); } // forward declarations, see class SM_Vertex_index; class SM_Edge_index; class SM_Halfedge_index; class SM_Face_index; template typename CGAL::Kernel_traits::type::FT get(boost::edge_weight_t, const CGAL::Surface_mesh& sm, const SM_Edge_index& e) { return CGAL::SM_edge_weight_pmap(sm)[e]; } } // // vertex_index // namespace boost{ template struct property_map, boost::vertex_index_t > { typedef CGAL::SM_index_pmap >::vertex_descriptor> type; typedef CGAL::SM_index_pmap >::vertex_descriptor> const_type; }; } namespace CGAL{ template CGAL::SM_index_pmap get(const boost::vertex_index_t&, const CGAL::Surface_mesh&) { return CGAL::SM_index_pmap >::vertex_descriptor>(); } } // // face_index // namespace boost{ template struct property_map, boost::face_index_t > { typedef CGAL::SM_index_pmap >::face_descriptor> type; typedef CGAL::SM_index_pmap >::face_descriptor> const_type; }; } namespace CGAL{ template CGAL::SM_index_pmap get(const boost::face_index_t&, const CGAL::Surface_mesh&) { return CGAL::SM_index_pmap >::face_descriptor>(); } } // // edge_index // namespace boost{ template struct property_map, boost::edge_index_t > { typedef CGAL::SM_index_pmap >::edge_descriptor> type; typedef CGAL::SM_index_pmap >::edge_descriptor> const_type; }; } namespace CGAL{ template CGAL::SM_index_pmap get(const boost::edge_index_t&, const CGAL::Surface_mesh&) { return CGAL::SM_index_pmap >::edge_descriptor>(); } } // // halfedge_index // namespace boost{ template struct property_map, boost::halfedge_index_t > { typedef CGAL::SM_index_pmap >::halfedge_descriptor> type; typedef CGAL::SM_index_pmap >::halfedge_descriptor> const_type; }; } namespace CGAL{ template CGAL::SM_index_pmap get(const boost::halfedge_index_t&, const CGAL::Surface_mesh&) { return CGAL::SM_index_pmap >::halfedge_descriptor>(); } } // // vertex_point // namespace boost{ template struct property_map, CGAL::vertex_point_t > { typedef CGAL::Surface_mesh

SM; typedef typename SM::template Property_map< typename SM::Vertex_index, P > type; typedef type const_type; }; } namespace CGAL{ namespace internal { template struct Get_vertex_point_map_for_Surface_mesh_return_type { typedef typename boost::property_map < CGAL::Surface_mesh, CGAL::vertex_point_t >::const_type type; }; } // end namespace internal template typename boost::lazy_disable_if < std::is_const, internal::Get_vertex_point_map_for_Surface_mesh_return_type >::type get(CGAL::vertex_point_t, const CGAL::Surface_mesh& g) { return g.points(); } namespace internal { template struct Get_graph_traits_of_SM { typedef boost::graph_traits< CGAL::Surface_mesh > type; }; } // end namespace internal // get for intrinsic properties #define CGAL_SM_INTRINSIC_PROPERTY(RET, PROP, TYPE) \ template \ RET \ get(PROP p, const CGAL::Surface_mesh& sm, \ const TYPE& x) \ { return get(get(p, sm), x); } \ CGAL_SM_INTRINSIC_PROPERTY(std::uint32_t, boost::vertex_index_t, SM_Vertex_index) CGAL_SM_INTRINSIC_PROPERTY(std::uint32_t, boost::edge_index_t, SM_Edge_index) CGAL_SM_INTRINSIC_PROPERTY(std::uint32_t, boost::halfedge_index_t, SM_Halfedge_index) CGAL_SM_INTRINSIC_PROPERTY(std::uint32_t, boost::face_index_t, SM_Face_index) CGAL_SM_INTRINSIC_PROPERTY(Point&, CGAL::vertex_point_t, SM_Vertex_index) #undef CGAL_SM_INTRINSIC_PROPERTY // put for intrinsic properties // only available for vertex_point template void put(CGAL::vertex_point_t p, const CGAL::Surface_mesh& g, typename boost::graph_traits< CGAL::Surface_mesh >::vertex_descriptor x, const Point& point) { typedef CGAL::Surface_mesh SM; CGAL_assertion(g.is_valid(x)); typename SM::template Property_map< typename boost::graph_traits::vertex_descriptor, Point> prop = get(p, g); prop[x] = point; } template struct graph_has_property, boost::vertex_index_t> : CGAL::Tag_true {}; template struct graph_has_property, boost::edge_index_t> : CGAL::Tag_true {}; template struct graph_has_property, boost::halfedge_index_t> : CGAL::Tag_true {}; template struct graph_has_property, boost::face_index_t> : CGAL::Tag_true {}; template struct graph_has_property, CGAL::vertex_point_t> : CGAL::Tag_true {}; template struct graph_has_property, boost::edge_weight_t> : CGAL::Tag_true {}; } // CGAL // dynamic properties namespace boost { template struct property_map, CGAL::dynamic_vertex_property_t > { typedef CGAL::Surface_mesh SM; typedef typename SM:: template Property_map SMPM; typedef CGAL::internal::Dynamic type; typedef CGAL::internal::Dynamic_with_index const_type; }; template struct property_map, CGAL::dynamic_face_property_t > { typedef CGAL::Surface_mesh SM; typedef typename SM:: template Property_map SMPM; typedef CGAL::internal::Dynamic type; typedef CGAL::internal::Dynamic_with_index const_type; }; template struct property_map, CGAL::dynamic_halfedge_property_t > { typedef CGAL::Surface_mesh SM; typedef typename SM:: template Property_map SMPM; typedef CGAL::internal::Dynamic type; typedef CGAL::internal::Dynamic_with_index const_type; }; template struct property_map, CGAL::dynamic_edge_property_t > { typedef CGAL::Surface_mesh SM; typedef typename SM:: template Property_map SMPM; typedef CGAL::internal::Dynamic type; typedef CGAL::internal::Dynamic_with_index const_type; }; } // nmamespace boost namespace CGAL { // get functions for dynamic properties of mutable Surface_mesh template ()>, typename ...Default_value_args> auto get(Dynamic_property_tag, Surface_mesh& sm, Default_value_args&&... default_value_args) { using BPM = typename boost::property_map, Dynamic_property_tag>; using descriptor = typename Dynamic_property_tag::template property_map>::descriptor; using value_type = typename Dynamic_property_tag::value_type; using SMPM = typename BPM::SMPM; using DPM = typename BPM::type; auto&& [sm_property_map, ok] = sm.template add_property_map( std::string(), std::forward(default_value_args)...); CGAL_assume(ok); return DPM(sm, new SMPM(std::forward(sm_property_map))); } // get functions for dynamic properties of const Surface_mesh template ()>, typename... Default_value_args> auto get(Dynamic_property_tag, const Surface_mesh& sm, Default_value_args&&... default_value_args) { using graph_traits = boost::graph_traits>; using face_descriptor = typename graph_traits::face_descriptor; using edge_descriptor = typename graph_traits::edge_descriptor; using halfedge_descriptor = typename graph_traits::halfedge_descriptor; using descriptor = typename Dynamic_property_tag::template property_map>::descriptor; using value_type = typename Dynamic_property_tag::value_type; auto num_elements = num_vertices(sm); if constexpr(std::is_same_v) { num_elements = num_edges(sm); } else if constexpr(std::is_same_v) { num_elements = num_halfedges(sm); } else if constexpr(std::is_same_v) { num_elements = num_faces(sm); } return CGAL::internal::Dynamic_with_index( num_elements, std::forward(default_value_args)...); } // implementation detail: required by Dynamic_property_map_deleter template void remove_property(Pmap pm, CGAL::Surface_mesh

& sm) { return sm.remove_property_map(pm); } template struct Get_pmap_of_surface_mesh { typedef typename boost::property_map, Property_tag >::type type; }; } // namespace CGAL #include #include #endif // DOXYGEN_RUNNING #endif /* CGAL_PROPERTIES_SURFACE_MESH_H */