Implementation:

- cherry-pick Random_generator
- implement hausdorff distance functions
- implement sample_triangle_mesh
This commit is contained in:
Maxime Gimeno 2016-08-16 16:49:50 +02:00 committed by Sébastien Loriot
parent 62e78f34e5
commit 0f13cde758
1 changed files with 63 additions and 28 deletions

View File

@ -249,53 +249,88 @@ double approximated_symmetric_Hausdorff_distance(
); );
} }
/// \todo add a function `sample_triangle_mesh()` (or better name) that provide different sampling methods: /// \todo test different strategies and put the better one in `approximated_Hausdorff_distance()`
/// - random uniform ( points/area unit)
/// - grid (warning mininum 1 pt / triangle) (parameter = distance between points?)
/// - monte carlo? (random points in each triangle proportional to the face area with 1 pt mini per triangle)
/// The goal is to test different strategies and put the better one in `approximated_Hausdorff_distance()`
/// for particular cases one can still use a specific sampling method together with `max_distance_to_triangle_mesh()` /// for particular cases one can still use a specific sampling method together with `max_distance_to_triangle_mesh()`
enum Sampling_method{ enum Sampling_method{
RANDOM_UNIFORM =0, RANDOM_UNIFORM =0, /**< points are generated in a random and uniform way, depending on the area of each triangle.*/
GRID, GRID,/**< points are generated in a grid, with a minimum of one point per triangle.*/
MONTE_CARLO }; MONTE_CARLO /**< points are generated randomly in each triangle, proportionally to the face area with a minimum
* of 1 pt per triangle.*/
};
/** fills `sampled_points` with points taken on the mesh in a manner depending on `method`.
* @tparam TriangleMesh a model of the concept `FaceListGraph` that has an internal property map
* for `CGAL::vertex_point_t`
* @param m the triangle mesh that will be sampled
* @param precision depends on the value of `method` :
* case RANDOM_UNIFORM : the number of points per squared area unit
* case GRID : the distance between the points
* case MONTE_CARLO : the number of points per squared area unit
* @tparam method a Sampling_method.
* @tparam Sampling_method defines the method of sampling.
* Possible values are `RANDOM_UNIFORM`,
* and `GRID` and `MONTE_CARLO.
*/
template<class Kernel, class TriangleMesh> template<class Kernel, class TriangleMesh>
void sample_triangle_mesh(TriangleMesh& m, void sample_triangle_mesh(const TriangleMesh& m,
double precision, double precision,
std::vector<typename Kernel::Point_3>& sampled_points, std::vector<typename Kernel::Point_3>& sampled_points,
Sampling_method method = RANDOM_UNIFORM) Sampling_method method = RANDOM_UNIFORM)
{ {
switch(method) switch(method)
{
case RANDOM_UNIFORM:
{ {
std::size_t nb_points = std::ceil(precision * PMP::area(m, std::size_t nb_points = std::ceil(precision * PMP::area(m,
PMP::parameters::geom_traits(Kernel()))); PMP::parameters::geom_traits(Kernel())));
case RANDOM_UNIFORM:
Random_points_in_triangle_mesh_3<TriangleMesh> Random_points_in_triangle_mesh_3<TriangleMesh>
g(m); g(m);
CGAL::cpp11::copy_n(g, nb_points, std::back_inserter(sampled_points)); CGAL::cpp11::copy_n(g, nb_points, std::back_inserter(sampled_points));
return; return;
}
case GRID: case GRID:
{ {
typedef typename boost::property_map<TriangleMesh, CGAL::vertex_point_t>::type Pmap; typedef typename boost::property_map<TriangleMesh, CGAL::vertex_point_t>::type Pmap;
CGAL::Property_map_to_unary_function<Pmap> pmap(&m); Pmap pmap = get(vertex_point, m);
BOOST_FOREACH(typename TriangleMesh::face_iterator f, faces(m)) BOOST_FOREACH(typename boost::graph_traits<TriangleMesh>::face_descriptor f, faces(m))
{ {
typename Kernel::Point_3 points[3]; typename Kernel::Point_3 points[3];
typename TriangleMesh::Halfedge_around_face_circulator hc = halfedge(f,m); typename TriangleMesh::Halfedge_around_face_circulator hc(halfedge(f,m), m);
for(int i=0; i<3; ++i) for(int i=0; i<3; ++i)
{ {
points[i] = get(pmap, target(hc, m)); points[i] = get(pmap, target(*hc, m));
++hc; ++hc;
} }
internal::triangle_grid_sampling(points[0], points[1], points[2],100.0/nb_points, std::back_inserter(sampled_points)); internal::triangle_grid_sampling<Kernel>(points[0], points[1], points[2],precision, std::back_inserter(sampled_points));
} }
return; return;
} }
case MONTE_CARLO: case MONTE_CARLO:
std::size_t nb_points = std::ceil(precision * PMP::area(m,
break; PMP::parameters::geom_traits(Kernel())));
typedef typename boost::property_map<TriangleMesh, CGAL::vertex_point_t>::type Pmap;
Pmap pmap = get(vertex_point, m);
std::vector<typename Kernel::Triangle_3> triangles;
BOOST_FOREACH(typename boost::graph_traits<TriangleMesh>::face_descriptor f, faces(m))
{
//create the triangles and store them
typename Kernel::Point_3 points[3];
typename TriangleMesh::Halfedge_around_face_circulator hc(halfedge(f,m), m);
for(int i=0; i<3; ++i)
{
points[i] = get(pmap, target(*hc, m));
++hc;
}
triangles.push_back(typename Kernel::Triangle_3(points[0], points[1], points[2]));
//sample a single point in all triangles(to have at least 1 pt/triangle)
Random_points_in_triangle_3<typename Kernel::Point_3> g(points[0], points[1], points[2]);
CGAL::cpp11::copy_n(g, 1, std::back_inserter(sampled_points));
}
//sample the triangle range uniformly
Random_points_in_triangles_3<typename Kernel::Point_3 >
g(triangles);
CGAL::cpp11::copy_n(g, nb_points, std::back_inserter(sampled_points));
return;
} }
} }
/// \todo add a plugin in the demo to display the distance between 2 meshes as a texture (if not complicated) /// \todo add a plugin in the demo to display the distance between 2 meshes as a texture (if not complicated)