// Copyright (c) 2014 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) : Philipp Möller #include #include #include #include #ifndef OPEN_MESH_CLASS #error OPEN_MESH_CLASS is not defined #endif // note only the properties below are protected by the macro, // the rest of the file is the shared implementation of properties for // OpenMesh::PolyMesh_ArrayKernelT and OpenMesh::TriMesh_ArrayKernelT #ifndef CGAL_BOOST_GRAPH_PROPERTIES_OPENMESH_H #define CGAL_BOOST_GRAPH_PROPERTIES_OPENMESH_H namespace CGAL { template class OM_pmap { public: typedef typename boost::mpl::if_::vertex_descriptor>, OpenMesh::VPropHandleT, typename boost::mpl::if_::face_descriptor>, OpenMesh::FPropHandleT, typename boost::mpl::if_::halfedge_descriptor>, OpenMesh::HPropHandleT, OpenMesh::EPropHandleT >::type>::type>::type H; typedef boost::read_write_property_map_tag category; typedef Descriptor key_type; typedef Value value_type; typedef value_type& reference; OM_pmap() {} OM_pmap(Mesh& m) : mesh(&m) { mesh->add_property(h); } OM_pmap(Mesh& m, H h) : mesh(&m), h(h) { mesh->add_property(h); } inline friend reference get(const OM_pmap& pm, typename boost::graph_traits::vertex_descriptor k) { return pm.mesh->property(pm.h,k); } inline friend reference get(const OM_pmap& pm, typename boost::graph_traits::face_descriptor k) { return pm.mesh->property(pm.h,k); } inline friend reference get(const OM_pmap& pm, typename boost::graph_traits::halfedge_descriptor k) { return pm.mesh->property(pm.h,k); } inline friend reference get(const OM_pmap& pm, typename boost::graph_traits::edge_descriptor k) { typename Mesh::EdgeHandle eh(k.idx()); return pm.mesh->property(pm.h,eh); } inline friend void put(const OM_pmap& pm, typename boost::graph_traits::vertex_descriptor k, const value_type& v) { pm.mesh->property(pm.h,k) = v; } inline friend void put(const OM_pmap& pm, typename boost::graph_traits::face_descriptor k, const value_type& v) { pm.mesh->property(pm.h,k) = v; } inline friend void put(const OM_pmap& pm, typename boost::graph_traits::halfedge_descriptor k, const value_type& v) { pm.mesh->property(pm.h,k) = v; } inline friend void put(const OM_pmap& pm, typename boost::graph_traits::edge_descriptor k, const value_type& v) { typename Mesh::EdgeHandle eh(k.idx()); pm.mesh->property(pm.h,eh) = v; } reference operator[](key_type k) { return mesh->property(h,k); } H handle() const { return h; } H& handle() { return h; } Mesh* mesh; H h; }; template class OM_edge_weight_pmap : public boost::put_get_helper > { public: typedef boost::readable_property_map_tag category; typedef typename OpenMesh::Scalar value_type; typedef value_type reference; typedef typename boost::graph_traits::edge_descriptor key_type; OM_edge_weight_pmap(const OpenMesh& sm) : sm_(sm) {} value_type operator[](const key_type& e) const { return sm_.calc_edge_length(e.halfedge()); } private: const OpenMesh& sm_; }; template class OM_index_pmap : public boost::put_get_helper > { public: typedef boost::readable_property_map_tag category; typedef unsigned int value_type; typedef unsigned int reference; typedef VEF key_type; OM_index_pmap() {} value_type operator[](const key_type& vd) const { return vd.idx(); } }; template class OM_point_pmap //: public boost::put_get_helper > { public: typedef boost::read_write_property_map_tag category; #if defined(CGAL_USE_OM_POINTS) typedef typename OpenMesh::Point value_type; typedef const typename OpenMesh::Point& reference; #else typedef P value_type; typedef P reference; #endif typedef typename boost::graph_traits::vertex_descriptor key_type; OM_point_pmap() : sm_(NULL) {} OM_point_pmap(const OpenMesh& sm) : sm_(&sm) {} OM_point_pmap(const OM_point_pmap& pm) : sm_(pm.sm_) {} value_type operator[](key_type v) { #if defined(CGAL_USE_OM_POINTS) return sm_->point(v); #else CGAL_assertion(sm_!=NULL); typename OpenMesh::Point const& omp = sm_->point(v); return value_type(omp[0], omp[1], omp[2]); #endif } inline friend reference get(const OM_point_pmap& pm, key_type v) { CGAL_precondition(pm.sm_!=NULL); #if defined(CGAL_USE_OM_POINTS) return pm.sm_->point(v); #else CGAL_assertion(pm.sm_!=NULL); typename OpenMesh::Point const& omp = pm.sm_->point(v); return value_type(omp[0], omp[1], omp[2]); #endif } inline friend void put(const OM_point_pmap& pm, key_type v, const value_type& p) { CGAL_precondition(pm.sm_!=NULL); #if defined(CGAL_USE_OM_POINTS) const_cast(*pm.sm_).set_point(v,p); #else const_cast(*pm.sm_).set_point (v, typename OpenMesh::Point((float)p[0], (float)p[1], (float)p[2])); #endif } private: const OpenMesh* sm_; }; } // CGAL #endif // CGAL_BOOST_GRAPH_PROPERTIES_OPENMESH_H // overloads and specializations in the boost namespace namespace boost { // // edge_weight // template struct property_map { typedef OPEN_MESH_CLASS Mesh; typedef CGAL::OM_edge_weight_pmap type; typedef CGAL::OM_edge_weight_pmap const_type; }; // // vertex_index // template struct property_map { typedef OPEN_MESH_CLASS Mesh; typedef CGAL::OM_index_pmap::vertex_descriptor> type; typedef CGAL::OM_index_pmap::vertex_descriptor> const_type; }; // // face_index // template struct property_map { typedef OPEN_MESH_CLASS Mesh; typedef CGAL::OM_index_pmap::face_descriptor> type; typedef CGAL::OM_index_pmap::face_descriptor> const_type; }; // // edge_index // template struct property_map { typedef OPEN_MESH_CLASS Mesh; typedef CGAL::OM_index_pmap::edge_descriptor> type; typedef CGAL::OM_index_pmap::edge_descriptor> const_type; }; // // halfedge_index // template struct property_map { typedef OPEN_MESH_CLASS Mesh; typedef CGAL::OM_index_pmap::halfedge_descriptor> type; typedef CGAL::OM_index_pmap::halfedge_descriptor> const_type; }; template struct property_map { typedef CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; typedef OPEN_MESH_CLASS Mesh; typedef CGAL::OM_point_pmap type; typedef type const_type; }; } // namespace boost namespace CGAL{ template struct graph_has_property : CGAL::Tag_true{}; template struct graph_has_property : CGAL::Tag_true{}; template struct graph_has_property : CGAL::Tag_true{}; template struct graph_has_property : CGAL::Tag_true{}; template struct graph_has_property : CGAL::Tag_true{}; template struct graph_has_property : CGAL::Tag_true{}; } //end CGAL namespace OpenMesh { template typename boost::property_map::const_type get(boost::edge_weight_t, const OPEN_MESH_CLASS& sm) { typedef OPEN_MESH_CLASS Mesh; return CGAL::OM_edge_weight_pmap(sm); } template typename OPEN_MESH_CLASS::Scalar get(boost::edge_weight_t, const OPEN_MESH_CLASS& sm, const typename boost::graph_traits::edge_descriptor& e) { typedef OPEN_MESH_CLASS Mesh; return CGAL::OM_edge_weight_pmap(sm)[e]; } template CGAL::OM_index_pmap::vertex_descriptor> get(const boost::vertex_index_t&, const OPEN_MESH_CLASS&) { typedef OPEN_MESH_CLASS Mesh; return CGAL::OM_index_pmap::vertex_descriptor>(); } template typename boost::property_map::const_type get(const boost::face_index_t&, const OPEN_MESH_CLASS&) { typedef OPEN_MESH_CLASS Mesh; return CGAL::OM_index_pmap::face_descriptor>(); } template CGAL::OM_index_pmap::edge_descriptor> get(const boost::edge_index_t&, const OPEN_MESH_CLASS&) { return CGAL::OM_index_pmap::edge_descriptor>(); } template CGAL::OM_index_pmap::halfedge_descriptor> get(const boost::halfedge_index_t&, const OPEN_MESH_CLASS&) { return CGAL::OM_index_pmap::halfedge_descriptor>(); } template CGAL::OM_point_pmap get(boost::vertex_point_t, const OPEN_MESH_CLASS& g) { typedef typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; return CGAL::OM_point_pmap(g); } // get for intrinsic properties #define CGAL_OM_INTRINSIC_PROPERTY(RET, PROP, TYPE) \ template \ RET \ get(PROP p, const OPEN_MESH_CLASS& sm, \ typename boost::graph_traits< OPEN_MESH_CLASS >::TYPE x) \ { return get(get(p, sm), x); } \ CGAL_OM_INTRINSIC_PROPERTY(int, boost::vertex_index_t, vertex_descriptor) CGAL_OM_INTRINSIC_PROPERTY(int, boost::edge_index_t, edge_descriptor) CGAL_OM_INTRINSIC_PROPERTY(int, boost::halfedge_index_t, halfedge_descriptor) CGAL_OM_INTRINSIC_PROPERTY(int, boost::face_index_t, face_descriptor) // CGAL_OM_INTRINSIC_PROPERTY(std::size_t, boost::halfedge_index_t, face_descriptor) CGAL_OM_INTRINSIC_PROPERTY(typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3, boost::vertex_point_t, vertex_descriptor) #undef CGAL_OM_INTRINSIC_PROPERTY // put for intrinsic properties // only available for vertex_point template void put(boost::vertex_point_t p, OPEN_MESH_CLASS& g, typename boost::graph_traits< OPEN_MESH_CLASS >::vertex_descriptor vd, const typename K::Point& point) { put(get(p,g), vd, point); } } // namespace OpenMesh namespace boost { template struct property_map > { typedef OPEN_MESH_CLASS SM; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef CGAL::OM_pmap SMPM; typedef CGAL::internal::Dynamic type; typedef type const_type; }; template struct property_map > { typedef OPEN_MESH_CLASS SM; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef CGAL::OM_pmap SMPM; typedef CGAL::internal::Dynamic type; typedef type const_type; }; template struct property_map > { typedef OPEN_MESH_CLASS SM; typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef CGAL::OM_pmap SMPM; typedef CGAL::internal::Dynamic type; typedef type const_type; }; template struct property_map > { typedef OPEN_MESH_CLASS SM; typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef CGAL::OM_pmap SMPM; typedef CGAL::internal::Dynamic type; typedef type const_type; }; } // namespace boost namespace OpenMesh { template typename boost::property_map >::const_type get(CGAL::dynamic_vertex_property_t, OPEN_MESH_CLASS& om) { typedef OPEN_MESH_CLASS OM; typedef typename boost::property_map >::SMPM SMPM; typedef typename boost::property_map >::const_type DPM; return DPM(om, new SMPM(om)); } template typename boost::property_map >::const_type get(CGAL::dynamic_halfedge_property_t, OPEN_MESH_CLASS& om) { typedef OPEN_MESH_CLASS OM; typedef typename boost::property_map >::SMPM SMPM; typedef typename boost::property_map >::const_type DPM; return DPM(om, new SMPM(om)); } template typename boost::property_map >::const_type get(CGAL::dynamic_edge_property_t, OPEN_MESH_CLASS& om) { typedef OPEN_MESH_CLASS OM; typedef typename boost::property_map >::SMPM SMPM; typedef typename boost::property_map >::const_type DPM; return DPM(om, new SMPM(om)); } template typename boost::property_map >::const_type get(CGAL::dynamic_face_property_t, OPEN_MESH_CLASS& om) { typedef OPEN_MESH_CLASS OM; typedef typename boost::property_map >::SMPM SMPM; typedef typename boost::property_map >::const_type DPM; return DPM(om, new SMPM(om)); } // implementation detail: required by Dynamic_property_map_deleter template void remove_property(Pmap pm, OPEN_MESH_CLASS& om) { om.remove_property(pm.handle()); } } // namespace OpenMesh #undef OPEN_MESH_CLASS