diff --git a/BGL/examples/BGL_OpenMesh/CMakeLists.txt b/BGL/examples/BGL_OpenMesh/CMakeLists.txt new file mode 100644 index 00000000000..02119ee3340 --- /dev/null +++ b/BGL/examples/BGL_OpenMesh/CMakeLists.txt @@ -0,0 +1,57 @@ +# Created by the script cgal_create_CMakeLists +# This is the CMake script for compiling a set of CGAL applications. + +project( BGL_OpenMesh ) + + +cmake_minimum_required(VERSION 2.8.11) + +# CGAL and its components +find_package( CGAL QUIET COMPONENTS ) + +if ( NOT CGAL_FOUND ) + + message(STATUS "This project requires the CGAL library, and will not be compiled.") + return() + +endif() + +# include helper file +include( ${CGAL_USE_FILE} ) + + +# Boost and its components +find_package( Boost REQUIRED ) + +if ( NOT Boost_FOUND ) + + message(STATUS "This project requires the Boost library, and will not be compiled.") + + return() + +endif() + +find_package( OpenMesh QUIET ) + +if ( OpenMesh_FOUND ) +include( UseOpenMesh ) +else() + message(STATUS "Examples that use OpenMesh will not be compiled.") +endif() + +# include for local directory + +# include for local package +include_directories( BEFORE ../../include ) + + +# Creating entries for all C++ files with "main" routine +# ########################################################## + +include( CGAL_CreateSingleSourceCGALProgram ) + +if(OpenMesh_FOUND) +create_single_source_cgal_program( "TriMesh.cpp" ) + target_link_libraries( TriMesh ${OPENMESH_LIBRARIES} ) +endif() + diff --git a/BGL/examples/BGL_OpenMesh/TriMesh.cpp b/BGL/examples/BGL_OpenMesh/TriMesh.cpp new file mode 100644 index 00000000000..c28e11f7886 --- /dev/null +++ b/BGL/examples/BGL_OpenMesh/TriMesh.cpp @@ -0,0 +1,51 @@ + +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef OpenMesh::TriMesh_ArrayKernelT Mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + +int main(int argc, char** argv ) +{ + Mesh mesh; + + std::vector V; + V.push_back(add_vertex(mesh)); + V.push_back(add_vertex(mesh)); + V.push_back(add_vertex(mesh)); + add_face(V.begin(), V.end(), mesh); + + // OpenMesh::IO::read_mesh(mesh, (argc>1)?argv[1]:"in.off"); + + BOOST_FOREACH(vertex_descriptor vd, vertices(mesh)){ + BOOST_FOREACH(halfedge_descriptor hd, CGAL::halfedges_around_target(vd,mesh)){ + if(! CGAL::is_border(edge(hd,mesh),mesh)){ + CGAL::Euler::flip_edge(hd,mesh); + OpenMesh::IO::write_mesh(mesh, (argc>2)?argv[2]:"out.off"); + return 0; + } + } + } + return 0; +} diff --git a/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h b/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h new file mode 100644 index 00000000000..075cfa52265 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h @@ -0,0 +1,680 @@ +// 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, Philipp Moeller + +#ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H +#define CGAL_BOOST_GRAPH_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +// http://openmesh.org/Documentation/OpenMesh-Doc-Latest/classOpenMesh_1_1Concepts_1_1KernelT.html + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4267) +#endif +namespace CGAL { namespace internal { + + +template +class OMesh_edge { +public: + OMesh_edge() : halfedge_() {} + explicit OMesh_edge(const Halfedge_handle& h) : halfedge_(h) {} + Halfedge_handle halfedge() const { return halfedge_; } + bool is_valid() const { return halfedge_.is_valid(); } + + bool + operator==(const OMesh_edge& other) { + if(halfedge_ == other.halfedge_) { + return true; + } else if(halfedge_ != Halfedge_handle()) { + return opposite() == other.halfedge_; + } else { + return false; + } + } + + bool operator<(const OMesh_edge& other) const + { + return this->idx() < other.idx(); + } + + bool + operator!=(const OMesh_edge& other) { return !(*this == other); } + + Halfedge_handle + opposite() const { return Halfedge_handle((halfedge_.idx() & 1) ? halfedge_.idx()-1 : halfedge_.idx()+1); } + + OMesh_edge + opposite_edge() const { return OMesh_edge(Halfedge_handle((halfedge_.idx() & 1) ? halfedge_.idx()-1 : halfedge_.idx()+1)); } + + unsigned int idx() const { return halfedge_.idx() / 2; } +private: + Halfedge_handle halfedge_; +}; + +template +struct Convert_omesh_edge +{ + typedef OMesh_edge result_type; + result_type operator()(const OMeshEdge& h) const { + return result_type(Halfedge_handle(h.idx() * 2)); + } +}; + +template +struct Construct_omesh_edge +{ + typedef OMesh_edge result_type; + template + result_type operator()(const T& h) const { return result_type(h); } +}; + +template +struct Construct_omesh_edge_opposite +{ + typedef OMesh_edge result_type; + template + result_type operator()(const T& h) const { return result_type(h).opposite_edge(); } +}; + + +} // internal +} // CGAL + + +namespace boost { + +template +struct graph_traits< OpenMesh::TriMesh_ArrayKernelT > +{ +private: + typedef OpenMesh::TriMesh_ArrayKernelT SM; + + struct SM_graph_traversal_category : public virtual boost::bidirectional_graph_tag, + public virtual boost::vertex_list_graph_tag, + public virtual boost::edge_list_graph_tag + {}; + +public: + // Graph + typedef typename SM::VertexHandle vertex_descriptor; + typedef typename SM::Point vertex_property_type; + typedef typename CGAL::internal::OMesh_edge edge_descriptor; + typedef boost::undirected_tag directed_category; + typedef boost::disallow_parallel_edge_tag edge_parallel_category; + typedef SM_graph_traversal_category traversal_category; + + // HalfedgeGraph + typedef typename SM::HalfedgeHandle halfedge_descriptor; + + // FaceGraph + typedef typename SM::FaceHandle face_descriptor; + + // VertexListGraph + typedef typename SM::VertexIter vertex_iterator; + typedef unsigned int vertices_size_type; + // EdgeListGraph + typedef boost::transform_iterator< + CGAL::internal::Convert_omesh_edge, + typename SM::EdgeIter, + edge_descriptor> edge_iterator; + + typedef unsigned int edges_size_type; + // HalfEdgeListGraph + typedef typename SM::HalfedgeIter halfedge_iterator; + typedef unsigned int halfedges_size_type; + // FaceListGraph + typedef typename SM::FaceIter face_iterator; + typedef unsigned int faces_size_type; + + // IncidenceGraph + typedef unsigned int degree_size_type; + + + typedef CGAL::In_edge_iterator in_edge_iterator; + + typedef CGAL::Out_edge_iterator out_edge_iterator; + + // nulls + static vertex_descriptor null_vertex() { return vertex_descriptor(); } + static face_descriptor null_face() { return face_descriptor(); } + static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } +}; + +template +struct graph_traits< const OpenMesh::TriMesh_ArrayKernelT > + : public graph_traits< OpenMesh::TriMesh_ArrayKernelT > +{ }; + +} // namespace boost + +namespace OpenMesh { + +template +typename boost::graph_traits >::vertices_size_type +num_vertices(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.n_vertices(); +} + + +template +typename boost::graph_traits >::edges_size_type +num_edges(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.n_edges(); +} + + +template +typename boost::graph_traits >::degree_size_type +degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::degree_size_type +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::degree_size_type +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.from_vertex_handle(e.halfedge()); +} + +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.from_vertex_handle(h); +} + + +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.to_vertex_handle(e.halfedge()); +} + +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.to_vertex_handle(h); +} + +template +CGAL::Iterator_range >::vertex_iterator> +vertices(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return CGAL::make_range(sm.vertices_sbegin(), sm.vertices_end()); +} + + +template +CGAL::Iterator_range >::edge_iterator> +edges(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::edge_iterator iterator; + iterator beg(sm.edges_sbegin()); + iterator end(sm.edges_end()); + return CGAL::make_range(beg,end); +} + + +template +CGAL::Iterator_range >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::in_edge_iterator Iter; + + return CGAL::make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1)); +} + + +template +CGAL::Iterator_range >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::out_edge_iterator Iter; + return CGAL::make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1)); +} + + +template +std::pair >::edge_descriptor, + bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) { + typename boost::graph_traits >::edge_descriptor + he(sm.find_halfedge(u, v)); + return std::make_pair(he, he.is_valid()); +} + + +// +// HalfedgeGraph +// +template +typename boost::graph_traits >::halfedge_descriptor +next(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.next_halfedge_handle(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +prev(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.prev_halfedge_handle(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +opposite(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.opposite_halfedge_handle(h); +} + +template +typename boost::graph_traits >::edge_descriptor +edge(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& /*sm*/) +{ + return typename boost::graph_traits >::edge_descriptor(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::TriMesh_ArrayKernelT&) +{ + return e.halfedge(); +} + +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + // prev because OpenMesh stores out-going halfedges + // return sm.prev_halfedge_handle(sm.halfedge_handle(v)); + return sm.opposite_halfedge_handle(sm.halfedge_handle(v)); +} + + +template +std::pair< + typename boost::graph_traits >::halfedge_descriptor, + bool +> +halfedge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typename boost::graph_traits >::halfedge_descriptor h = sm.find_halfedge(u, v); + return std::make_pair(h, h.is_valid()); +} + + + +// +// HalfedgeListGraph +// +template +CGAL::Iterator_range >::halfedge_iterator> +halfedges(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return CGAL::make_range(sm.halfedges_sbegin(), sm.halfedges_end()); +} + +template +typename boost::graph_traits >::halfedges_size_type +num_halfedges(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.n_halfedges(); +} + + + +// +// MutableHalfedgeGraph +// +template +void +set_next(typename boost::graph_traits >::halfedge_descriptor h1, + typename boost::graph_traits >::halfedge_descriptor h2, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_next_halfedge_handle(h1, h2); +} + + + +template +void +set_target(typename boost::graph_traits >::halfedge_descriptor h, + typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_vertex_handle(h, v); +} + + +template +void +set_halfedge(typename boost::graph_traits >::vertex_descriptor v, + typename boost::graph_traits >::halfedge_descriptor h, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_halfedge_handle(v, sm.opposite_halfedge_handle(h)); +} + + +template +void +adjust_border_halfedge(typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.adjust_outgoing_halfedge(v); +} + +template +void +garbage_collection(OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.garbage_collection(); +} + +template +typename boost::graph_traits >::edge_descriptor +add_edge(OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return edge(sm.new_edge(boost::graph_traits >::null_vertex(), + boost::graph_traits >::null_vertex() ), sm); +} + + +// +// FaceGraph +// +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::face_descriptor f, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.halfedge_handle(f); +} + +template +typename boost::graph_traits >::face_descriptor +face(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.face_handle(h); +} + + + +// +// MutableFaceGraph +// +template +void +set_face(typename boost::graph_traits >::halfedge_descriptor h, + typename boost::graph_traits >::face_descriptor f, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_face_handle(h, f); +} + + +template +void +set_halfedge(typename boost::graph_traits >::face_descriptor f, + typename boost::graph_traits >::halfedge_descriptor h, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_halfedge_handle(f, h); +} + + +// +// FaceListGraph +// +template +typename boost::graph_traits >::faces_size_type +num_faces(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.n_faces(); +} + +template +CGAL::Iterator_range >::face_iterator> +faces(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return CGAL::make_range(sm.faces_sbegin(), sm.faces_end()); +} + + +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(OpenMesh::TriMesh_ArrayKernelT& sm) { + return sm.new_vertex(); +} + + /* + +// MutableGraph +// add a vertex with a default constructed property +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(OpenMesh::TriMesh_ArrayKernelT& sm) { + return sm.add_vertex(typename boost::graph_traits >::vertex_property_type()); +} + +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(const typename boost::graph_traits >::vertex_property_type& p, OpenMesh::TriMesh_ArrayKernelT& sm) { + return sm.add_vertex(p); +} + +template +void +clear_vertex(typename boost::graph_traits >::vertex_descriptor, + OpenMesh::TriMesh_ArrayKernelT&) { + CGAL_assert(false); +} + + */ + +template +void +remove_vertex(typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::TriMesh_ArrayKernelT& sm) { + + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + sm.set_halfedge_handle(v, typename boost::graph_traits >::halfedge_descriptor()); + sm.status(v).set_deleted(true); +} + + +template +void +remove_edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typename boost::graph_traits >::edge_descriptor e = edge(u, v, sm); + remove_edge(e,sm); +} + +template +void +remove_edge(typename boost::graph_traits >::edge_descriptor e, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + sm.request_edge_status(); + + typedef typename boost::graph_traits >::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor h1 = halfedge(e,sm); + halfedge_descriptor h2 = opposite(halfedge(e,sm),sm); + sm.status(sm.edge_handle(h1)).set_deleted(true); + sm.status(h1).set_deleted(true); + sm.status(h2).set_deleted(true); + +} + + +template +void +remove_edge(typename boost::graph_traits >::edge_iterator eiter, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + remove_edge(*eiter, sm); +} + +template +void +remove_face(typename boost::graph_traits >::face_descriptor f, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + + set_halfedge(f, typename boost::graph_traits >::halfedge_descriptor(), sm); + sm.status(f).set_deleted(true); +} + +#if 0 // conflits with function in Euler_operations.h +template +std::pair >::edge_descriptor, + bool> +add_edge(typename boost::graph_traits >::vertex_descriptor v1, + typename boost::graph_traits >::vertex_descriptor v2, + OpenMesh::TriMesh_ArrayKernelT& sm) { + + return sm.new_edge(v1, v2); +} +#endif + +template +typename boost::graph_traits >::face_descriptor +add_face(OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.new_face(); +} + +template +typename boost::graph_traits >::face_descriptor +add_face(InputIterator begin, InputIterator end, OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::vertex_descriptor vertex_descriptor; + assert(begin!= end); + vertex_descriptor u = *begin; + ++begin; + assert(begin!= end); + vertex_descriptor v = *begin; + ++begin; + assert(begin!= end); + vertex_descriptor w = *begin; + + return sm.add_face(u,v,w); +} + +template +bool is_valid(OpenMesh::TriMesh_ArrayKernelT& sm, bool /* verbose */ = false) +{ + return CGAL::is_valid_polygon_mesh(sm); +} + +} // namespace OpenMesh + + +#ifndef CGAL_NO_DEPRECATED_CODE +#include + +namespace boost { + // The following functions were defined in the namespace boost + using OpenMesh::vertices; + using OpenMesh::edges; + using OpenMesh::num_vertices; + using OpenMesh::num_edges; + using OpenMesh::out_edges; + using OpenMesh::in_edges; + using OpenMesh::target; + using OpenMesh::source; +} // namespace boost +#endif //CGAL_NO_DEPRECATED_CODE + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // CGAL_BOOST_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H diff --git a/BGL/include/CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h b/BGL/include/CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h new file mode 100644 index 00000000000..e26b707c544 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h @@ -0,0 +1,356 @@ +// 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$ +// +// +// Author(s) : Philipp Möller + + +#ifndef CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H +#define CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H + +#include +#include +#include +#include +#include + +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(Mesh& m) + : mesh(m) + {} + + OM_pmap(Mesh& m, H h) + : mesh(m), h(h) + {} + + inline friend reference get(const OM_pmap& pm, key_type k) + { + return pm.mesh.property(pm.h,k); + } + + inline friend void put(const OM_pmap& pm, key_type k, const value_type& v) + { + pm.mesh.property(pm.h,k) = 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::Scalar , OM_edge_weight_pmap > +{ +public: + typedef boost::readable_property_map_tag category; + typedef typename OpenMesh::TriMesh_ArrayKernelT::Scalar value_type; + typedef value_type reference; + typedef typename boost::graph_traits >::edge_descriptor key_type; + + OM_edge_weight_pmap(const OpenMesh::TriMesh_ArrayKernelT& sm) + : sm_(sm) + {} + + value_type operator[](const key_type& e) const + { + return sm_.calc_edge_length(e.halfedge()); + } + +private: + const OpenMesh::TriMesh_ArrayKernelT& 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; + + 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::TriMesh_ArrayKernelT::Point value_type; + typedef const typename OpenMesh::TriMesh_ArrayKernelT::Point& reference; +#else + typedef P value_type; + typedef P reference; +#endif + typedef typename boost::graph_traits< OpenMesh::TriMesh_ArrayKernelT >::vertex_descriptor key_type; + + OM_point_pmap() + : sm_(NULL) + {} + + OM_point_pmap(const OpenMesh::TriMesh_ArrayKernelT& 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::TriMesh_ArrayKernelT::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::TriMesh_ArrayKernelT::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::TriMesh_ArrayKernelT::Point((float)p[0], (float)p[1], (float)p[2])); +#endif + } + + private: + const OpenMesh::TriMesh_ArrayKernelT* sm_; +}; + + +} // CGAL + +// overloads and specializations in the boost namespace +namespace boost { + +// +// edge_weight +// + + +template +struct property_map, boost::edge_weight_t > +{ + typedef CGAL::OM_edge_weight_pmap type; + typedef CGAL::OM_edge_weight_pmap const_type; +}; + + + +// +// vertex_index +// + +template +struct property_map, boost::vertex_index_t > +{ + typedef CGAL::OM_index_pmap >::vertex_descriptor> type; + typedef CGAL::OM_index_pmap >::vertex_descriptor> const_type; +}; + + +// +// face_index +// + +template +struct property_map, boost::face_index_t > +{ + typedef CGAL::OM_index_pmap >::face_descriptor> type; + typedef CGAL::OM_index_pmap >::face_descriptor> const_type; +}; + +// +// edge_index +// + +template +struct property_map, boost::edge_index_t > +{ + typedef CGAL::OM_index_pmap >::edge_descriptor> type; + typedef CGAL::OM_index_pmap >::edge_descriptor> const_type; +}; + +// +// halfedge_index +// + +template +struct property_map, boost::halfedge_index_t > +{ + typedef CGAL::OM_index_pmap >::halfedge_descriptor> type; + typedef CGAL::OM_index_pmap >::halfedge_descriptor> const_type; +}; + + +template +struct property_map, boost::vertex_point_t > +{ + typedef CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; + typedef CGAL::OM_point_pmap type; + typedef type const_type; +}; + +} // namespace boost + +namespace boost { + + +template +typename boost::property_map, boost::edge_weight_t>::const_type +get(boost::edge_weight_t, const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return CGAL::OM_edge_weight_pmap(sm); +} + +template +typename OpenMesh::TriMesh_ArrayKernelT::Scalar +get(boost::edge_weight_t, const OpenMesh::TriMesh_ArrayKernelT& sm, + const typename boost::graph_traits >::edge_descriptor& e) +{ + return CGAL::OM_edge_weight_pmap(sm)[e]; +} + + +template +CGAL::OM_index_pmap >::vertex_descriptor> +get(const boost::vertex_index_t&, const OpenMesh::TriMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::vertex_descriptor>(); +} + +template +typename boost::property_map, boost::face_index_t>::const_type +get(const boost::face_index_t&, const OpenMesh::TriMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::face_descriptor>(); +} + +template +CGAL::OM_index_pmap >::edge_descriptor> +get(const boost::edge_index_t&, const OpenMesh::TriMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::edge_descriptor>(); +} + +template +CGAL::OM_index_pmap >::halfedge_descriptor> +get(const boost::halfedge_index_t&, const OpenMesh::TriMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::halfedge_descriptor>(); +} + +template +CGAL::OM_point_pmap +get(boost::vertex_point_t, const OpenMesh::TriMesh_ArrayKernelT& 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 OpenMesh::TriMesh_ArrayKernelT& sm, \ + typename boost::graph_traits< OpenMesh::TriMesh_ArrayKernelT >::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, OpenMesh::TriMesh_ArrayKernelT& g, + typename boost::graph_traits< OpenMesh::TriMesh_ArrayKernelT >::vertex_descriptor vd, + const typename K::Point& point) +{ + put(get(p,g), vd, point); +} + + +} // namespace boost + + + +#endif /* CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H */