diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 4d90fe068ed..0e7bc775f7d 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -7,6 +7,7 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/helpers.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/selection.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/split_graph_into_polylines.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/copy_face_graph.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Dual.h EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ ${CGAL_BGL_EXAMPLE_DIR} diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index e6abffa0daf..43ec57af01f 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -152,6 +152,7 @@ user might encounter. - `CGAL::make_hexahedron()` - `CGAL::clear()` +- `CGAL::copy_face_graph()` ## Iterators ## - `CGAL::Halfedge_around_source_iterator` diff --git a/BGL/examples/BGL_polyhedron_3/CMakeLists.txt b/BGL/examples/BGL_polyhedron_3/CMakeLists.txt index a84cf7493c0..1ffa079a833 100644 --- a/BGL/examples/BGL_polyhedron_3/CMakeLists.txt +++ b/BGL/examples/BGL_polyhedron_3/CMakeLists.txt @@ -34,7 +34,8 @@ endif() find_package( OpenMesh QUIET ) if ( OpenMesh_FOUND ) -include( UseOpenMesh ) + include( UseOpenMesh ) + add_definitions( -DCGAL_USE_OPENMESH ) else() message(STATUS "Examples that use OpenMesh will not be compiled.") endif() @@ -64,10 +65,9 @@ create_single_source_cgal_program( "range.cpp" ) create_single_source_cgal_program( "transform_iterator.cpp" ) - +create_single_source_cgal_program( "copy_polyhedron.cpp" ) if(OpenMesh_FOUND) - create_single_source_cgal_program( "polyhedron_2_OpenMesh.cpp" ) - target_link_libraries( polyhedron_2_OpenMesh ${OPENMESH_LIBRARIES} ) + target_link_libraries( copy_polyhedron ${OPENMESH_LIBRARIES} ) endif() diff --git a/BGL/examples/BGL_polyhedron_3/copy_polyhedron.cpp b/BGL/examples/BGL_polyhedron_3/copy_polyhedron.cpp new file mode 100644 index 00000000000..1092d2b5ef2 --- /dev/null +++ b/BGL/examples/BGL_polyhedron_3/copy_polyhedron.cpp @@ -0,0 +1,94 @@ +#include +#include + +#include +#include +#include + +#include +#include + +#if defined(CGAL_USE_OPENMESH) +#include +#include +#include + +namespace OpenMesh { // auxiliary functions so OpenMesh Handles can be hashed +inline std::size_t hash_value(const VertexHandle& i) { return i.idx(); } +inline std::size_t hash_value(const HalfedgeHandle& i) { return i.idx(); } +inline std::size_t hash_value(const FaceHandle& i) { return i.idx(); } +} + +#endif + +#include + +#include + +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef CGAL::Polyhedron_3 Source; +typedef boost::graph_traits::vertex_descriptor sm_vertex_descriptor; +typedef boost::graph_traits::halfedge_descriptor sm_halfedge_descriptor; +typedef boost::graph_traits::face_descriptor sm_face_descriptor; + +typedef CGAL::Exact_predicates_exact_constructions_kernel Other_kernel; +typedef Other_kernel::Point_3 Point; + +int main(int argc, char* argv[]) +{ + Source S; + + std::ifstream in((argc>1)?argv[1]:"cube.off"); + in >> S; + + // Note that the vertex_point property of the Source and Target1 + // come from different kernels. + typedef CGAL::Surface_mesh Target1; + Target1 T1; + { + CGAL::copy_face_graph(S, T1); + std::ofstream out("sm.off"); + out << T1; + } + +#if defined(CGAL_USE_OPENMESH) + typedef OpenMesh::PolyMesh_ArrayKernelT Target2; + Target2 T2; + { + typedef boost::graph_traits::vertex_descriptor tm_vertex_descriptor; + typedef boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; + typedef boost::graph_traits::face_descriptor tm_face_descriptor; + + // Use an unordered_map to keep track of elements. + boost::unordered_map v2v; + boost::unordered_map h2h; + boost::unordered_map f2f; + + CGAL::copy_face_graph(S, T2, std::inserter(v2v, v2v.end()), + std::inserter(h2h, h2h.end()), + std::inserter(f2f, f2f.end())); + OpenMesh::IO::write_mesh(T2, "om.off"); + } +#endif + S.clear(); + { + typedef boost::graph_traits::vertex_descriptor source_vertex_descriptor; + typedef boost::graph_traits::halfedge_descriptor source_halfedge_descriptor; + + typedef boost::graph_traits::vertex_descriptor tm_vertex_descriptor; + typedef boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; + + boost::unordered_map v2v; + boost::unordered_map h2h; + + CGAL::copy_face_graph(T1, S, std::inserter(v2v, v2v.end()), std::inserter(h2h, h2h.end())); + std::ofstream out("reverse.off"); + out << T1; + } + return 0; +} diff --git a/BGL/examples/BGL_polyhedron_3/polyhedron_2_OpenMesh.cpp b/BGL/examples/BGL_polyhedron_3/polyhedron_2_OpenMesh.cpp deleted file mode 100644 index 55f64a8215d..00000000000 --- a/BGL/examples/BGL_polyhedron_3/polyhedron_2_OpenMesh.cpp +++ /dev/null @@ -1,87 +0,0 @@ - -#include - -#include -#include -#include - -#include - -#if 1 -#include -#include -#else -#include -#include -#endif - -#include - -#include - -#include -#include - - -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::Vector_3 Vector; -typedef Kernel::Point_3 Point; -typedef CGAL::Polyhedron_3 Source; - -#if 1 -typedef OpenMesh::PolyMesh_ArrayKernelT Target; -#else -typedef OpenMesh::TriMesh_ArrayKernelT Target; -#endif -typedef boost::graph_traits::vertex_descriptor sm_vertex_descriptor; -typedef boost::graph_traits::vertex_descriptor tm_vertex_descriptor; - -typedef boost::graph_traits::halfedge_descriptor sm_halfedge_descriptor; -typedef boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; - -namespace OpenMesh { - -inline std::size_t hash_value(const VertexHandle& i) - { - return i.idx(); - } - -inline std::size_t hash_value(const HalfedgeHandle& i) - { - return i.idx(); - } - -inline std::size_t hash_value(const FaceHandle& i) - { - return i.idx(); - } - -} - -int main(int argc, char* argv[]) -{ - Source S; - Target T; - std::ifstream in((argc>1)?argv[1]:"cube.off"); - in >> S; - - { - boost::unordered_map v2v; - boost::unordered_map h2h; - - convert_surface_mesh(S,T,v2v,h2h); - OpenMesh::IO::write_mesh(T, "om.off"); - } - S.clear(); - { - boost::unordered_map v2v; - boost::unordered_map h2h; - - convert_surface_mesh(T,S,v2v,h2h); - std::ofstream out("reverse.off"); - out << S << std::endl; - } - - - return 0; -} diff --git a/BGL/include/CGAL/boost/graph/convert_surface_mesh.h b/BGL/include/CGAL/boost/graph/convert_surface_mesh.h deleted file mode 100644 index 7a964e7ccfd..00000000000 --- a/BGL/include/CGAL/boost/graph/convert_surface_mesh.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2015 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 - -#ifndef CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H -#define CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H - -#include -#include -#include -#include - -namespace CGAL { - - template - void convert_surface_mesh(const SourceMesh& sm, TargetMesh& tm, V2V& v2v, H2H& h2h) -{ - typedef typename boost::graph_traits::vertex_descriptor sm_vertex_descriptor; - typedef typename boost::graph_traits::vertex_descriptor tm_vertex_descriptor; - - typedef typename boost::graph_traits::face_descriptor sm_face_descriptor; - typedef typename boost::graph_traits::face_descriptor tm_face_descriptor; - - typedef typename boost::graph_traits::halfedge_descriptor sm_halfedge_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; - - typedef typename boost::property_map::const_type sm_PMap; - typedef typename boost::property_map::type tm_PMap; - - sm_PMap sm_pmap = get(vertex_point, sm); - tm_PMap tm_pmap = get(vertex_point, tm); - - - BOOST_FOREACH(sm_vertex_descriptor svd, vertices(sm)){ - tm_vertex_descriptor tvd = add_vertex(tm); - v2v.insert(std::make_pair(svd, tvd)); - put(tm_pmap, tvd, get(sm_pmap, svd)); - } - - boost::unordered_map f2f; - BOOST_FOREACH(sm_face_descriptor sfd, faces(sm)){ - std::vector tv; - BOOST_FOREACH(sm_vertex_descriptor svd, vertices_around_face(halfedge(sfd,sm),sm)){ - tv.push_back(v2v.at(svd)); - } - f2f[sfd] = Euler::add_face(tv,tm); - } - - BOOST_FOREACH(sm_face_descriptor sfd, faces(sm)){ - sm_halfedge_descriptor shd = halfedge(sfd,sm), done(shd); - tm_halfedge_descriptor thd = halfedge(f2f[sfd],tm); - tm_vertex_descriptor tvd = v2v.at(target(shd,sm)); - while(target(thd,tm) != tvd){ - thd = next(thd,tm); - } - do { - h2h.insert(std::make_pair(shd, thd)); - - if (face(opposite(shd, sm), sm) == boost::graph_traits::null_face()) - h2h.insert(std::make_pair(opposite(shd, sm), opposite(thd, tm))); - - shd = next(shd,sm); - thd = next(thd,tm); - }while(shd != done); - } - -} - -} // namespace CGAL - -#endif // CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H diff --git a/BGL/include/CGAL/boost/graph/copy_face_graph.h b/BGL/include/CGAL/boost/graph/copy_face_graph.h new file mode 100644 index 00000000000..640a5eda961 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/copy_face_graph.h @@ -0,0 +1,156 @@ +// Copyright (c) 2015 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 + +#ifndef CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_H +#define CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_H + +#include +#include +#include +#include + +#include +#include +#include + +#include + +namespace CGAL { + +/*! + \ingroup PkgBGLHelperFct + + copies a source model of `FaceListGraph` into a target model of a + `FaceListGraph`. `OutputIterators` can be provided to produce a + mapping between source and target elements. The target graph is not + cleared. + + \tparam SourceMesh a model of `FaceListGraph` + \tparam TargetMesh a model of `FaceListGraph` + \tparam V2V a model of `OutputIterator` accepting `std::pair` + \tparam H2H a model of `OutputIterator` accepting `std::pair` + \tparam F2F a model of `OutputIterator` accepting `std::pair` + + where the prefix `sm_` and `tm_` mean belonging to the source and + target mesh respectively. + + \param sm the source mesh + \param tm the target mesh + \param v2v pairs of `vertex_descriptors` from `sm` and corresponding `vertex_descriptors` in `tm` are added to `v2v` + \param h2h pairs of `halfedge_descriptors` from `sm` and corresponding `halfedge_descriptors` in `tm` are added to `h2h` + \param f2f pairs of `face_descriptors` from `sm` and corresponding `face_descriptors` in `tm` are added to `f2f` + + This function assumes that both graphs have an internal property + `vertex_point`. Values of that property are converted using + `CGAL::Cartesian_converter`. `SourceKernel` and `TargetKernel` are deduced using + `CGAL::Kernel_traits`. + + Other properties are not copied. +*/ +#if defined(CGAL_CXX11) || defined(DOXYGEN_RUNNING) // Use template default arguments +template +void copy_face_graph(const SourceMesh& sm, TargetMesh& tm, + V2V v2v = V2V(), H2H h2h = H2H(), F2F f2f = F2F()) +#else // use the overloads +template +void copy_face_graph(const SourceMesh& sm, TargetMesh& tm, + V2V v2v, H2H h2h, F2F f2f) +#endif +{ + typedef typename boost::graph_traits::vertex_descriptor sm_vertex_descriptor; + typedef typename boost::graph_traits::vertex_descriptor tm_vertex_descriptor; + + typedef typename boost::graph_traits::face_descriptor sm_face_descriptor; + typedef typename boost::graph_traits::face_descriptor tm_face_descriptor; + + typedef typename boost::graph_traits::halfedge_descriptor sm_halfedge_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; + + typedef typename boost::property_map::const_type sm_PMap; + typedef typename boost::property_map::type tm_PMap; + + Cartesian_converter::value_type>::type, + typename Kernel_traits::value_type>::type > + conv; + + sm_PMap sm_pmap = get(vertex_point, sm); + tm_PMap tm_pmap = get(vertex_point, tm); + + // internal f2f and v2v + boost::unordered_map v2v_; + boost::unordered_map f2f_; + + BOOST_FOREACH(sm_vertex_descriptor svd, vertices(sm)){ + tm_vertex_descriptor tvd = add_vertex(tm); + v2v_[svd] = tvd; + *v2v++ = std::make_pair(svd, tvd); + put(tm_pmap, tvd, conv(get(sm_pmap, svd))); + } + + BOOST_FOREACH(sm_face_descriptor sfd, faces(sm)){ + std::vector tv; + BOOST_FOREACH(sm_vertex_descriptor svd, vertices_around_face(halfedge(sfd,sm),sm)){ + tv.push_back(v2v_.at(svd)); + } + tm_face_descriptor new_face = Euler::add_face(tv,tm); + f2f_[sfd] = new_face; + *f2f++ = std::make_pair(sfd, new_face); + } + + BOOST_FOREACH(sm_face_descriptor sfd, faces(sm)){ + sm_halfedge_descriptor shd = halfedge(sfd,sm), done(shd); + tm_halfedge_descriptor thd = halfedge(f2f_[sfd],tm); + tm_vertex_descriptor tvd = v2v_.at(target(shd,sm)); + while(target(thd,tm) != tvd){ + thd = next(thd,tm); + } + do { + *h2h++ = std::make_pair(shd, thd); + if (face(opposite(shd, sm), sm) == boost::graph_traits::null_face()){ + *h2h++ = std::make_pair(opposite(shd, sm), opposite(thd, tm)); + } + shd = next(shd,sm); + thd = next(thd,tm); + }while(shd != done); + } + +} + +#if !defined(CGAL_CXX11) +template +void copy_face_graph(const SourceMesh& sm, TargetMesh& tm) +{ copy_face_graph(sm, tm, Emptyset_iterator(), Emptyset_iterator(), Emptyset_iterator()); } + +template +void copy_face_graph(const SourceMesh& sm, TargetMesh& tm, V2V v2v) +{ copy_face_graph(sm, tm, v2v, Emptyset_iterator(), Emptyset_iterator()); } + +template +void copy_face_graph(const SourceMesh& sm, TargetMesh& tm, V2V v2v, H2H h2h) +{ copy_face_graph(sm, tm, v2v, h2h, Emptyset_iterator()); } +#endif + +} // namespace CGAL + +#endif // CGAL_BOOST_GRAPH_COPY_FACE_GRAPH_H diff --git a/Installation/changes.html b/Installation/changes.html index 903fb8dd85f..64dd2fa0098 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -151,6 +151,15 @@ and src/ directories). +

CGAL and the Boost Graph Library (BGL)

+
    +
  • + Add a helper function CGAL::copy_face_graph() to + copy a source FaceListGraph into another FaceListGraph of + different type. +
  • +
+ diff --git a/Polyhedron/include/CGAL/FaceGraph_to_Polyhedron_3.h b/Polyhedron/include/CGAL/FaceGraph_to_Polyhedron_3.h deleted file mode 100644 index 4981c4bcb32..00000000000 --- a/Polyhedron/include/CGAL/FaceGraph_to_Polyhedron_3.h +++ /dev/null @@ -1,92 +0,0 @@ -// 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 -// 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) : Sebastien Loriot -// - - -#ifndef CGAL_FACEGRAPH_POLYHEDRON_3_H -#define CGAL_FACEGRAPH_POLYHEDRON_3_H 1 - -#include -#include -#include -#include -#include - -#include -#include - -namespace CGAL { - -template < class FaceGraph, class PointPMap, class HDS, bool clear_target_before = true > -class FaceGraph_to_Polyhedron_3 : public Modifier_base { - FaceGraph& fg; - PointPMap ppmap; -public: - typedef HDS Halfedge_data_structure; - FaceGraph_to_Polyhedron_3(const FaceGraph& src, PointPMap map) - : fg(const_cast(src)) - , ppmap(map) - {} - void operator()( HDS& target); -}; - -template < class FaceGraph, class PointPMap, class HDS, bool clear_target_before> -void -FaceGraph_to_Polyhedron_3:: -operator()(HDS& tgt) -{ - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - Cartesian_converter< - typename Kernel_traits::value_type>::Kernel, - typename Kernel_traits::Kernel - > convert; - - if ( clear_target_before ) - tgt.clear(); - - Polyhedron_incremental_builder_3 B(tgt); - B.begin_surface( num_vertices(fg), - num_faces(fg), - num_halfedges(fg)); - std::map indices; - std::size_t i=0; - BOOST_FOREACH(vertex_descriptor vd, vertices(fg) ) - { - B.add_vertex( convert( get(ppmap, vd) ) ); - indices[vd]=i++; - } - - BOOST_FOREACH(face_descriptor fd, faces(fg)) - { - B.begin_facet(); - halfedge_descriptor hd=halfedge(fd, fg), first=hd; - do { - B.add_vertex_to_facet( indices[target(edge(hd,fg), fg)] ); - hd=next(hd,fg);; - } while( hd != first); - B.end_facet(); - } - B.end_surface(); -} - -} //namespace CGAL -#endif // CGAL_FACEGRAPH_POLYHEDRON_3_H // -// EOF // diff --git a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h index 1fcecadb9db..6453e0d3c55 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h +++ b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include @@ -385,7 +385,7 @@ public: const Traits& traits = Traits()) : m_traits(traits), m_weight_calculator(m_tmesh) { - init(tmesh, get(vertex_point, tmesh)); + init(tmesh); } #endif /// @} Constructor @@ -827,18 +827,11 @@ private: } /// Initialize some global data structures such as vertex id. - void init(const TriangleMesh& tmesh, - VertexPointMap vpm) + void init(const TriangleMesh& tmesh) { - // copy the input FaceGraph into a mTriangleMesh - CGAL::FaceGraph_to_Polyhedron_3 modifier(tmesh, vpm); + copy_face_graph(tmesh, m_tmesh); - m_tmesh.delegate(modifier); - - // copy input vertices to keep correspondance + // copy input vertices to keep correspondence typename boost::graph_traits::vertex_iterator vit=vertices(m_tmesh).first; BOOST_FOREACH(Input_vertex_descriptor vd, vertices(tmesh) ) (*vit++)->vertices.push_back(vd); diff --git a/Surface_mesh_skeletonization/include/CGAL/extract_mean_curvature_flow_skeleton.h b/Surface_mesh_skeletonization/include/CGAL/extract_mean_curvature_flow_skeleton.h index b0d6e34a89f..a36f0e0ec41 100644 --- a/Surface_mesh_skeletonization/include/CGAL/extract_mean_curvature_flow_skeleton.h +++ b/Surface_mesh_skeletonization/include/CGAL/extract_mean_curvature_flow_skeleton.h @@ -22,7 +22,6 @@ #include #include -#include #ifdef CGAL_EIGEN3_ENABLED #include // for sparse linear system solver #endif