From f14f9ce4474c35ebf6b02ce8cedb36b6070a2ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 8 May 2019 16:05:26 +0200 Subject: [PATCH] Move some functions from PMP to BGL --- BGL/include/CGAL/boost/graph/generators.h | 88 +++++++- BGL/include/CGAL/boost/graph/helpers.h | 78 +++++++- BGL/package_info/BGL/dependencies | 1 + .../CGAL/Polygon_mesh_processing/locate.h | 188 ------------------ 4 files changed, 165 insertions(+), 190 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/generators.h b/BGL/include/CGAL/boost/graph/generators.h index 051178b5ad1..4df1422d895 100644 --- a/BGL/include/CGAL/boost/graph/generators.h +++ b/BGL/include/CGAL/boost/graph/generators.h @@ -16,13 +16,16 @@ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ // -// Author(s) : Maxime Gimeno +// Author(s) : Maxime Gimeno, +// Mael Rouxel-Labbé #ifndef CGAL_BOOST_GRAPH_GENERATORS_H #define CGAL_BOOST_GRAPH_GENERATORS_H #include #include + +#include #include namespace CGAL { @@ -38,6 +41,89 @@ typename boost::graph_traits::face_descriptor add_face(const VertexRange& } // namespace Euler +namespace internal { + +template +typename std::iterator_traits::value_type +random_entity_in_range(InputIterator first, InputIterator beyond, + CGAL::Random& rnd = get_default_random()) +{ + typedef typename std::iterator_traits::difference_type size_type; + + size_type zero = 0, ne = std::distance(first, beyond); + std::advance(first, rnd.uniform_int(zero, ne - 1)); + + return *first; +} + +template +typename std::iterator_traits::value_type +random_entity_in_range(const CGAL::Iterator_range& range, + CGAL::Random& rnd = get_default_random()) +{ + return random_entity_in_range(range.begin(), range.end(), rnd); +} + +// \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `g`. +// \tparam Graph A model of `HalfedgeGraph` +template +typename boost::graph_traits::vertex_descriptor +random_vertex_in_face(typename boost::graph_traits::face_descriptor fd, + const Graph& g, + CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(vertices_around_face(halfedge(fd, g), g), rnd); +} + +// \brief returns a random non-null halfedge incident to the face `fd` of the polygon mesh `g`. +// \tparam Graph A model of `HalfedgeGraph` +template +typename boost::graph_traits::halfedge_descriptor +random_halfedge_in_face(typename boost::graph_traits::face_descriptor fd, + const Graph& g, + CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(halfedges_around_face(halfedge(fd, g), g), rnd); +} + +// \brief returns a random non-null vertex of the polygon mesh `g`. +// \tparam Graph A model of `VertexListGraph` +template +typename boost::graph_traits::vertex_descriptor +random_vertex_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(vertices(g), rnd); +} + +// \brief returns a random non-null halfedge of the polygon mesh `g`. +// \tparam Graph A model of `HalfedgeListGraph` +template +typename boost::graph_traits::halfedge_descriptor +random_halfedge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(halfedges(g), rnd); +} + +// \brief returns a random non-null edge of the polygon mesh `g`. +// \tparam Graph A model of `EdgeListGraph` +template +typename boost::graph_traits::edge_descriptor +random_edge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(edges(g), rnd); +} + +// \brief returns a random non-null face of the polygon mesh `g`. +// \tparam Graph A model of `FaceListGraph` +template +typename boost::graph_traits::face_descriptor +random_face_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random()) +{ + return internal::random_entity_in_range(faces(g), rnd); +} + +} // namespace internal + /** * \ingroup PkgBGLHelperFct * diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 75b8f0d0ee4..f4836c7f1dc 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -21,7 +21,7 @@ #ifndef CGAL_BOOST_GRAPH_HELPERS_H #define CGAL_BOOST_GRAPH_HELPERS_H -#include +#include #include #include #include @@ -829,6 +829,82 @@ bool is_empty(const FaceGraph& g) return boost::empty(vertices(g)); } +/// \ingroup PkgBGLHelperFct +/// +/// \brief returns the number of calls to `next()` one has to apply to the halfedge `hd` +/// for `source(hd, mesh) == vd` to be true, starting from `hd = halfedge(fd, tm)`. +/// +/// \tparam Graph A model of `FaceGraph` +/// +/// \param vd a vertex of `g` whose index is sought +/// \param fd a face of `g` in which the index of `vd` is sought +/// \param g a mesh of type `Graph` +/// +/// \pre `vd` is a vertex of `fd`. +template +int vertex_index_in_face(const typename boost::graph_traits::vertex_descriptor vd, + const typename boost::graph_traits::face_descriptor fd, + const Graph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor start = halfedge(fd, g); + halfedge_descriptor current = start; + int counter = 0; + + do + { + if(source(current, g) == vd) + break; + + ++counter; + current = next(current, g); + } + while(current != start); + + if(counter != 0 && current == start) + { + CGAL_assertion_msg(false, "Could not find vertex in face"); + return -1; + } + + return counter; +} + +/// \ingroup PkgBGLHelperFct +/// +/// \brief returns the number of calls to `next(hd, tm)` one has to apply to `hd` for `hd == he` +/// to be true, starting from `hd = halfedge(face(he, tm), tm)`. +/// +/// \tparam Graph A model of `FaceGraph`. +/// +/// \param he a halfedge of `g` whose index in `face(he, tm)` is sought +/// \param g an object of type `Graph` +/// +template +int halfedge_index_in_face(typename boost::graph_traits::halfedge_descriptor he, + const Graph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + CGAL_precondition(he != boost::graph_traits::null_halfedge()); + CGAL_precondition(!is_border(he, g)); + + face_descriptor f = face(he, g); + halfedge_descriptor start = halfedge(f, g); + halfedge_descriptor current = start; + int count = 0; + + while(current != he) + { + current = next(current, g); + ++count; + } + + return count; +} + } // namespace CGAL #endif // CGAL_BOOST_GRAPH_HELPERS_H diff --git a/BGL/package_info/BGL/dependencies b/BGL/package_info/BGL/dependencies index 4a55ee6163f..ebc36eadd85 100644 --- a/BGL/package_info/BGL/dependencies +++ b/BGL/package_info/BGL/dependencies @@ -18,5 +18,6 @@ Modular_arithmetic Number_types Profiling_tools Property_map +Random_numbers STL_Extension Stream_support diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index 7c5065f9057..4adef39c82a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -257,27 +257,6 @@ snap_location_to_border(typename Locate_types::Face_location& loc, return snap_coordinates_to_border(loc.second, tolerance); } -template -typename std::iterator_traits::value_type -random_entity_in_range(InputIterator first, InputIterator beyond, - CGAL::Random& rnd = get_default_random()) -{ - typedef typename std::iterator_traits::difference_type size_type; - - size_type zero = 0, ne = std::distance(first, beyond); - std::advance(first, rnd.uniform_int(zero, ne - 1)); - - return *first; -} - -template -typename std::iterator_traits::value_type -random_entity_in_range(const CGAL::Iterator_range& range, - CGAL::Random& rnd = get_default_random()) -{ - return random_entity_in_range(range.begin(), range.end(), rnd); -} - template struct Barycentric_coordinate_calculator // 2D version { @@ -393,173 +372,6 @@ struct Barycentric_point_constructor // 3D version } // namespace internal -/// \name Random Simplex Generation -/// @{ - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `HalfedgeGraph` -template -typename boost::graph_traits::vertex_descriptor -random_vertex_in_face(typename boost::graph_traits::face_descriptor fd, - const PolygonMesh& pm, - CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(vertices_around_face(halfedge(fd, pm), pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null halfedge incident to the face `fd` of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `HalfedgeGraph` -/// -template -typename boost::graph_traits::halfedge_descriptor -random_halfedge_in_face(typename boost::graph_traits::face_descriptor fd, - const PolygonMesh& pm, - CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(halfedges_around_face(halfedge(fd, pm), pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null vertex of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `VertexListGraph` -/// -template -typename boost::graph_traits::vertex_descriptor -random_vertex_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(vertices(pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null halfedge of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `HalfedgeListGraph` -/// -template -typename boost::graph_traits::halfedge_descriptor -random_halfedge_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(halfedges(pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null edge of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `EdgeListGraph` -/// -template -typename boost::graph_traits::edge_descriptor -random_edge_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(edges(pm), rnd); -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns a random non-null face of the polygon mesh `pm`. -/// -/// \tparam PolygonMesh A model of `FaceListGraph` -/// -template -typename boost::graph_traits::face_descriptor -random_face_in_mesh(const PolygonMesh& pm, CGAL::Random& rnd = get_default_random()) -{ - return internal::random_entity_in_range(faces(pm), rnd); -} - -/// @} - -/// \name Simplex Index -/// @{ - -/// \ingroup PMP_locate_grp -/// -/// \brief returns the number of calls to `next()` one has to apply to the halfedge `hd` -/// for `source(hd, mesh) == vd` to be true, starting from `hd = halfedge(fd, tm)`. -/// -/// \tparam PolygonMesh A model of `FaceGraph` -/// -/// \param vd a vertex of `pm` whose index we seek -/// \param fd a face of `pm` in which we seek the index of `vd` -/// \param pm a mesh of type `PolygonMesh` -/// -/// \pre `vd` is a vertex of `fd`. -template -int vertex_index_in_face(const typename boost::graph_traits::vertex_descriptor vd, - const typename boost::graph_traits::face_descriptor fd, - const PolygonMesh& pm) -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - halfedge_descriptor start = halfedge(fd, pm); - halfedge_descriptor current = start; - int counter = 0; - - do - { - if(source(current, pm) == vd) - break; - - ++counter; - current = next(current, pm); - } - while(current != start); - - if(counter != 0 && current == start) - { - CGAL_assertion_msg(false, "Could not find vertex in face"); - return -1; - } - - return counter; -} - -/// \ingroup PMP_locate_grp -/// -/// \brief returns the number of `next` one has to apply to `hd` for `hd == he` -/// to be true, starting from `hd = halfedge(face(hd, tm), tm)`. -/// -/// \tparam PolygonMesh A model of `FaceGraph`. -/// -/// \param he a halfedge of `pm` whose index in `face(he, tm)` we seek -/// \param pm an object of type `PolygonMesh` -/// -template -int halfedge_index_in_face(typename boost::graph_traits::halfedge_descriptor he, - const PolygonMesh& pm) -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - - CGAL_precondition(he != boost::graph_traits::null_halfedge()); - CGAL_precondition(!is_border(he, pm)); - - face_descriptor f = face(he, pm); - halfedge_descriptor start = halfedge(f, pm); - halfedge_descriptor current = start; - int count = 0; - - while(current != he) - { - current = next(current, pm); - ++count; - } - - return count; -} - -/// @} - /// \ingroup PMP_locate_grp /// /// \brief Given a set of three points and a query point, computes the barycentric