// 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_POLYMESH_ARRAYKERNELT_H #define CGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYMESH_ARRAYKERNELT_H #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) { 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)); } std::size_t 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::PolyMesh_ArrayKernelT > { private: typedef OpenMesh::PolyMesh_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::PolyMesh_ArrayKernelT > : public graph_traits< OpenMesh::PolyMesh_ArrayKernelT > { }; } // namespace boost namespace OpenMesh { template typename boost::graph_traits >::vertices_size_type num_vertices(const OpenMesh::PolyMesh_ArrayKernelT& sm) { return sm.n_vertices(); } template typename boost::graph_traits >::edges_size_type num_edges(const OpenMesh::PolyMesh_ArrayKernelT& sm) { return sm.n_edges(); } template typename boost::graph_traits >::degree_size_type degree(typename boost::graph_traits >::vertex_descriptor v, const OpenMesh::PolyMesh_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::PolyMesh_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::PolyMesh_ArrayKernelT& sm) { return sm.valence(v); } template typename boost::graph_traits >::vertex_descriptor source(typename boost::graph_traits >::edge_descriptor e, const OpenMesh::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_ArrayKernelT& sm) { return sm.to_vertex_handle(h); } template CGAL::Iterator_range >::vertex_iterator> vertices(const OpenMesh::PolyMesh_ArrayKernelT& sm) { return CGAL::make_range(sm.vertices_sbegin(), sm.vertices_end()); } template CGAL::Iterator_range >::edge_iterator> edges(const OpenMesh::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_ArrayKernelT&) { return e.halfedge(); } template typename boost::graph_traits >::halfedge_descriptor halfedge(typename boost::graph_traits >::vertex_descriptor v, const OpenMesh::PolyMesh_ArrayKernelT& sm) { // prev because OpenMesh stores out-going halfedges return sm.prev_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::PolyMesh_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::PolyMesh_ArrayKernelT& sm) { return CGAL::make_range(sm.halfedges_sbegin(), sm.halfedges_end()); } template typename boost::graph_traits >::halfedges_size_type num_halfedges(const OpenMesh::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_ArrayKernelT& sm) { sm.adjust_outgoing_halfedge(v); } template void garbage_collection(OpenMesh::PolyMesh_ArrayKernelT& sm) { sm.garbage_collection(); } template typename boost::graph_traits >::edge_descriptor add_edge(OpenMesh::PolyMesh_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::PolyMesh_ArrayKernelT& sm) { return sm.halfedge_handle(f); } template typename boost::graph_traits >::face_descriptor face(typename boost::graph_traits >::halfedge_descriptor h, const OpenMesh::PolyMesh_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::PolyMesh_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::PolyMesh_ArrayKernelT& sm) { sm.set_halfedge_handle(f, h); } // // FaceListGraph // template typename boost::graph_traits >::faces_size_type num_faces(const OpenMesh::PolyMesh_ArrayKernelT& sm) { return sm.n_faces(); } template CGAL::Iterator_range >::face_iterator> faces(const OpenMesh::PolyMesh_ArrayKernelT& sm) { return CGAL::make_range(sm.faces_sbegin(), sm.faces_end()); } template typename boost::graph_traits >::vertex_descriptor add_vertex(OpenMesh::PolyMesh_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::PolyMesh_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::PolyMesh_ArrayKernelT& sm) { return sm.add_vertex(p); } template void clear_vertex(typename boost::graph_traits >::vertex_descriptor, OpenMesh::PolyMesh_ArrayKernelT&) { assert(false); } */ template void remove_vertex(typename boost::graph_traits >::vertex_descriptor v, OpenMesh::PolyMesh_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::PolyMesh_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::PolyMesh_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::PolyMesh_ArrayKernelT& sm) { remove_edge(*eiter, sm); } template void remove_face(typename boost::graph_traits >::face_descriptor f, OpenMesh::PolyMesh_ArrayKernelT& sm) { sm.request_face_status(); sm.request_vertex_status(); sm.request_halfedge_status(); set_halfedge(f, typename boost::graph_traits >::halfedge_descriptor(), sm); set_halfedge(f, typename boost::graph_traits >::halfedge_descriptor(), sm); sm.status(f).set_deleted(true); } template std::pair >::edge_descriptor, bool> add_edge(typename boost::graph_traits >::vertex_descriptor v1, typename boost::graph_traits >::vertex_descriptor v2, OpenMesh::PolyMesh_ArrayKernelT& sm) { return sm.new_edge(v1, v2); } template typename boost::graph_traits >::face_descriptor add_face(OpenMesh::PolyMesh_ArrayKernelT& sm) { return sm.new_face(); } template typename boost::graph_traits >::face_descriptor add_face(InputIterator begin, InputIterator end, OpenMesh::PolyMesh_ArrayKernelT& sm) { std::vector >::vertex_descriptor> v(begin, end); return sm.add_face(v); } template bool is_valid(OpenMesh::PolyMesh_ArrayKernelT& sm, bool verbose = false) { return true; } } // 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_POLYMESH_ARRAYKERNELT_H