Move some functions from PMP to BGL

This commit is contained in:
Mael Rouxel-Labbé 2019-05-08 16:05:26 +02:00
parent 9e8524c29e
commit f14f9ce447
4 changed files with 165 additions and 190 deletions

View File

@ -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 <CGAL/boost/graph/iterator.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Random.h>
#include <CGAL/function_objects.h>
namespace CGAL {
@ -38,6 +41,89 @@ typename boost::graph_traits<Graph>::face_descriptor add_face(const VertexRange&
} // namespace Euler
namespace internal {
template<typename InputIterator>
typename std::iterator_traits<InputIterator>::value_type
random_entity_in_range(InputIterator first, InputIterator beyond,
CGAL::Random& rnd = get_default_random())
{
typedef typename std::iterator_traits<InputIterator>::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 InputIterator>
typename std::iterator_traits<InputIterator>::value_type
random_entity_in_range(const CGAL::Iterator_range<InputIterator>& 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 Graph>
typename boost::graph_traits<Graph>::vertex_descriptor
random_vertex_in_face(typename boost::graph_traits<Graph>::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 Graph>
typename boost::graph_traits<Graph>::halfedge_descriptor
random_halfedge_in_face(typename boost::graph_traits<Graph>::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 Graph>
typename boost::graph_traits<Graph>::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 Graph>
typename boost::graph_traits<Graph>::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 Graph>
typename boost::graph_traits<Graph>::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 Graph>
typename boost::graph_traits<Graph>::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
*

View File

@ -21,7 +21,7 @@
#ifndef CGAL_BOOST_GRAPH_HELPERS_H
#define CGAL_BOOST_GRAPH_HELPERS_H
#include <CGAL/boost/graph/polyhedra.h>
#include <CGAL/boost/graph/generators.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/boost/graph/internal/Has_member_clear.h>
@ -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 <typename Graph>
int vertex_index_in_face(const typename boost::graph_traits<Graph>::vertex_descriptor vd,
const typename boost::graph_traits<Graph>::face_descriptor fd,
const Graph& g)
{
typedef typename boost::graph_traits<Graph>::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 <typename Graph>
int halfedge_index_in_face(typename boost::graph_traits<Graph>::halfedge_descriptor he,
const Graph& g)
{
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor;
CGAL_precondition(he != boost::graph_traits<Graph>::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

View File

@ -18,5 +18,6 @@ Modular_arithmetic
Number_types
Profiling_tools
Property_map
Random_numbers
STL_Extension
Stream_support

View File

@ -257,27 +257,6 @@ snap_location_to_border(typename Locate_types<TriangleMesh>::Face_location& loc,
return snap_coordinates_to_border<TriangleMesh>(loc.second, tolerance);
}
template<typename InputIterator>
typename std::iterator_traits<InputIterator>::value_type
random_entity_in_range(InputIterator first, InputIterator beyond,
CGAL::Random& rnd = get_default_random())
{
typedef typename std::iterator_traits<InputIterator>::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 InputIterator>
typename std::iterator_traits<InputIterator>::value_type
random_entity_in_range(const CGAL::Iterator_range<InputIterator>& range,
CGAL::Random& rnd = get_default_random())
{
return random_entity_in_range(range.begin(), range.end(), rnd);
}
template <typename K, typename P, int = P::Ambient_dimension::value>
struct Barycentric_coordinate_calculator // 2D version
{
@ -393,173 +372,6 @@ struct Barycentric_point_constructor<K, P, 3> // 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 PolygonMesh>
typename boost::graph_traits<PolygonMesh>::vertex_descriptor
random_vertex_in_face(typename boost::graph_traits<PolygonMesh>::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 PolygonMesh>
typename boost::graph_traits<PolygonMesh>::halfedge_descriptor
random_halfedge_in_face(typename boost::graph_traits<PolygonMesh>::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 PolygonMesh>
typename boost::graph_traits<PolygonMesh>::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 PolygonMesh>
typename boost::graph_traits<PolygonMesh>::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 PolygonMesh>
typename boost::graph_traits<PolygonMesh>::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 PolygonMesh>
typename boost::graph_traits<PolygonMesh>::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 <typename PolygonMesh>
int vertex_index_in_face(const typename boost::graph_traits<PolygonMesh>::vertex_descriptor vd,
const typename boost::graph_traits<PolygonMesh>::face_descriptor fd,
const PolygonMesh& pm)
{
typedef typename boost::graph_traits<PolygonMesh>::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 <typename PolygonMesh>
int halfedge_index_in_face(typename boost::graph_traits<PolygonMesh>::halfedge_descriptor he,
const PolygonMesh& pm)
{
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::face_descriptor face_descriptor;
CGAL_precondition(he != boost::graph_traits<PolygonMesh>::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