mirror of https://github.com/CGAL/cgal
Callbacks in most Point Set Processing functions
This commit is contained in:
parent
08f4afd00e
commit
7703236025
|
|
@ -30,6 +30,7 @@
|
||||||
#include <CGAL/point_set_processing_assertions.h>
|
#include <CGAL/point_set_processing_assertions.h>
|
||||||
#include <CGAL/unordered.h>
|
#include <CGAL/unordered.h>
|
||||||
#include <CGAL/Iterator_range.h>
|
#include <CGAL/Iterator_range.h>
|
||||||
|
#include <CGAL/function.h>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
|
|
||||||
#include <CGAL/boost/graph/named_function_params.h>
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
|
|
@ -204,6 +205,8 @@ grid_simplify_point_set(
|
||||||
|
|
||||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::const_type PointMap;
|
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::const_type PointMap;
|
||||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||||
|
const cpp11::function<bool(double)>& callback = choose_param(get_param(np, internal_np::callback),
|
||||||
|
cpp11::function<bool(double)>());
|
||||||
|
|
||||||
// actual type of input points
|
// actual type of input points
|
||||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Enriched_point;
|
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Enriched_point;
|
||||||
|
|
@ -214,12 +217,15 @@ grid_simplify_point_set(
|
||||||
// points_to_keep[] will contain 1 point per cell; the others will be in points_to_remove[].
|
// points_to_keep[] will contain 1 point per cell; the others will be in points_to_remove[].
|
||||||
Epsilon_point_set_3<Enriched_point, PointMap> points_to_keep(epsilon, point_map);
|
Epsilon_point_set_3<Enriched_point, PointMap> points_to_keep(epsilon, point_map);
|
||||||
std::deque<Enriched_point> points_to_remove;
|
std::deque<Enriched_point> points_to_remove;
|
||||||
for (typename PointRange::iterator it = points.begin(); it != points.end(); it++)
|
std::size_t nb = 0, nb_points = points.size();
|
||||||
|
for (typename PointRange::iterator it = points.begin(); it != points.end(); it++, ++ nb)
|
||||||
{
|
{
|
||||||
std::pair<typename Epsilon_point_set_3<Enriched_point, PointMap>::iterator,bool> result;
|
std::pair<typename Epsilon_point_set_3<Enriched_point, PointMap>::iterator,bool> result;
|
||||||
result = points_to_keep.insert(*it);
|
result = points_to_keep.insert(*it);
|
||||||
if (!result.second) // if not inserted
|
if (!result.second) // if not inserted
|
||||||
points_to_remove.push_back(*it);
|
points_to_remove.push_back(*it);
|
||||||
|
if (callback && !callback ((nb+1) / double(nb_points)))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replaces `[first, beyond)` range by the content of points_to_keep, then points_to_remove.
|
// Replaces `[first, beyond)` range by the content of points_to_keep, then points_to_remove.
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include <CGAL/PCA_util.h>
|
#include <CGAL/PCA_util.h>
|
||||||
#include <CGAL/squared_distance_3.h>
|
#include <CGAL/squared_distance_3.h>
|
||||||
#include <CGAL/Iterator_range.h>
|
#include <CGAL/Iterator_range.h>
|
||||||
|
#include <CGAL/function.h>
|
||||||
|
|
||||||
#include <CGAL/boost/graph/named_function_params.h>
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
@ -167,6 +168,8 @@ namespace CGAL {
|
||||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||||
unsigned int size = choose_param(get_param(np, internal_np::size), 10);
|
unsigned int size = choose_param(get_param(np, internal_np::size), 10);
|
||||||
double var_max = choose_param(get_param(np, internal_np::maximum_variation), 1./3.);
|
double var_max = choose_param(get_param(np, internal_np::maximum_variation), 1./3.);
|
||||||
|
const cpp11::function<bool(double)>& callback = choose_param(get_param(np, internal_np::callback),
|
||||||
|
cpp11::function<bool(double)>());
|
||||||
|
|
||||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Input_type;
|
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Input_type;
|
||||||
|
|
||||||
|
|
@ -192,6 +195,8 @@ namespace CGAL {
|
||||||
std::list<Input_type> points_to_keep;
|
std::list<Input_type> points_to_keep;
|
||||||
std::list<Input_type> points_to_remove;
|
std::list<Input_type> points_to_remove;
|
||||||
|
|
||||||
|
std::size_t nb_done = 0;
|
||||||
|
|
||||||
while (!(clusters_stack.empty ()))
|
while (!(clusters_stack.empty ()))
|
||||||
{
|
{
|
||||||
cluster_iterator current_cluster = clusters_stack.begin ();
|
cluster_iterator current_cluster = clusters_stack.begin ();
|
||||||
|
|
@ -203,6 +208,7 @@ namespace CGAL {
|
||||||
points_to_keep.splice (points_to_keep.end (), current_cluster->first,
|
points_to_keep.splice (points_to_keep.end (), current_cluster->first,
|
||||||
current_cluster->first.begin ());
|
current_cluster->first.begin ());
|
||||||
clusters_stack.pop_front ();
|
clusters_stack.pop_front ();
|
||||||
|
++ nb_done;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,6 +274,7 @@ namespace CGAL {
|
||||||
cluster_iterator nonempty = (current_cluster->first.empty ()
|
cluster_iterator nonempty = (current_cluster->first.empty ()
|
||||||
? negative_side : current_cluster);
|
? negative_side : current_cluster);
|
||||||
|
|
||||||
|
nb_done += nonempty->first.size();
|
||||||
// Compute the centroid
|
// Compute the centroid
|
||||||
nonempty->second = internal::hsps_centroid (nonempty->first.begin (),
|
nonempty->second = internal::hsps_centroid (nonempty->first.begin (),
|
||||||
nonempty->first.end (),
|
nonempty->first.end (),
|
||||||
|
|
@ -279,6 +286,7 @@ namespace CGAL {
|
||||||
point_map,
|
point_map,
|
||||||
nonempty->second,
|
nonempty->second,
|
||||||
Kernel ());
|
Kernel ());
|
||||||
|
|
||||||
clusters_stack.pop_front ();
|
clusters_stack.pop_front ();
|
||||||
clusters_stack.pop_front ();
|
clusters_stack.pop_front ();
|
||||||
}
|
}
|
||||||
|
|
@ -311,6 +319,7 @@ namespace CGAL {
|
||||||
// and output point
|
// and output point
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
nb_done += current_cluster->first.size();
|
||||||
internal::hsc_terminate_cluster (current_cluster->first,
|
internal::hsc_terminate_cluster (current_cluster->first,
|
||||||
points_to_keep,
|
points_to_keep,
|
||||||
points_to_remove,
|
points_to_remove,
|
||||||
|
|
@ -319,7 +328,14 @@ namespace CGAL {
|
||||||
Kernel ());
|
Kernel ());
|
||||||
clusters_stack.pop_front ();
|
clusters_stack.pop_front ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (callback && !callback (nb_done / double (points.size())))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (callback)
|
||||||
|
callback (1.);
|
||||||
|
|
||||||
typename PointRange::iterator first_point_to_remove =
|
typename PointRange::iterator first_point_to_remove =
|
||||||
std::copy (points_to_keep.begin(), points_to_keep.end(), points.begin());
|
std::copy (points_to_keep.begin(), points_to_keep.end(), points.begin());
|
||||||
std::copy (points_to_remove.begin(), points_to_remove.end(), first_point_to_remove);
|
std::copy (points_to_remove.begin(), points_to_remove.end(), first_point_to_remove);
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,11 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
#include <CGAL/internal/Parallel_callback.h>
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/blocked_range.h>
|
#include <tbb/blocked_range.h>
|
||||||
#include <tbb/scalable_allocator.h>
|
#include <tbb/scalable_allocator.h>
|
||||||
|
#include <tbb/atomic.h>
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -125,17 +127,28 @@ jet_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute
|
||||||
const unsigned int degree_fitting;
|
const unsigned int degree_fitting;
|
||||||
const std::vector<Point>& input;
|
const std::vector<Point>& input;
|
||||||
std::vector<Vector>& output;
|
std::vector<Vector>& output;
|
||||||
|
tbb::atomic<std::size_t>& advancement;
|
||||||
|
tbb::atomic<bool>& interrupted;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Jet_estimate_normals(Tree& tree, unsigned int k, std::vector<Point>& points,
|
Jet_estimate_normals(Tree& tree, unsigned int k, std::vector<Point>& points,
|
||||||
unsigned int degree_fitting, std::vector<Vector>& output)
|
unsigned int degree_fitting, std::vector<Vector>& output,
|
||||||
|
tbb::atomic<std::size_t>& advancement,
|
||||||
|
tbb::atomic<bool>& interrupted)
|
||||||
: tree(tree), k (k), degree_fitting (degree_fitting), input (points), output (output)
|
: tree(tree), k (k), degree_fitting (degree_fitting), input (points), output (output)
|
||||||
|
, advancement (advancement)
|
||||||
|
, interrupted (interrupted)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
||||||
{
|
{
|
||||||
for( std::size_t i = r.begin(); i != r.end(); ++i)
|
for( std::size_t i = r.begin(); i != r.end(); ++i)
|
||||||
|
{
|
||||||
|
if (interrupted)
|
||||||
|
break;
|
||||||
output[i] = CGAL::internal::jet_estimate_normal<Kernel,SvdTraits>(input[i], tree, k, degree_fitting);
|
output[i] = CGAL::internal::jet_estimate_normal<Kernel,SvdTraits>(input[i], tree, k, degree_fitting);
|
||||||
|
++ advancement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -212,6 +225,8 @@ jet_estimate_normals(
|
||||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||||
NormalMap normal_map = choose_param(get_param(np, internal_np::normal_map), NormalMap());
|
NormalMap normal_map = choose_param(get_param(np, internal_np::normal_map), NormalMap());
|
||||||
unsigned int degree_fitting = choose_param(get_param(np, internal_np::degree_fitting), 2);
|
unsigned int degree_fitting = choose_param(get_param(np, internal_np::degree_fitting), 2);
|
||||||
|
const cpp11::function<bool(double)>& callback = choose_param(get_param(np, internal_np::callback),
|
||||||
|
cpp11::function<bool(double)>());
|
||||||
|
|
||||||
typedef typename Kernel::Point_3 Point;
|
typedef typename Kernel::Point_3 Point;
|
||||||
|
|
||||||
|
|
@ -254,27 +269,34 @@ jet_estimate_normals(
|
||||||
#else
|
#else
|
||||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||||
{
|
{
|
||||||
|
internal::Point_set_processing_3::Parallel_callback
|
||||||
|
parallel_callback (callback, kd_tree_points.size());
|
||||||
|
|
||||||
std::vector<Vector> normals (kd_tree_points.size ());
|
std::vector<Vector> normals (kd_tree_points.size ());
|
||||||
CGAL::internal::Jet_estimate_normals<Kernel, SvdTraits, Tree>
|
CGAL::internal::Jet_estimate_normals<Kernel, SvdTraits, Tree>
|
||||||
f (tree, k, kd_tree_points, degree_fitting, normals);
|
f (tree, k, kd_tree_points, degree_fitting, normals,
|
||||||
|
parallel_callback.advancement(),
|
||||||
|
parallel_callback.interrupted());
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
||||||
unsigned int i = 0;
|
std::size_t i = 0;
|
||||||
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
||||||
{
|
|
||||||
put (normal_map, *it, normals[i]);
|
put (normal_map, *it, normals[i]);
|
||||||
}
|
|
||||||
|
parallel_callback.join();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
for(it = points.begin(); it != points.end(); it++)
|
std::size_t nb = 0;
|
||||||
|
for(it = points.begin(); it != points.end(); it++, ++ nb)
|
||||||
{
|
{
|
||||||
Vector normal = internal::jet_estimate_normal<Kernel,SvdTraits,Tree>(
|
Vector normal = internal::jet_estimate_normal<Kernel,SvdTraits,Tree>(
|
||||||
get(point_map,*it),
|
get(point_map,*it),
|
||||||
tree, k, degree_fitting);
|
tree, k, degree_fitting);
|
||||||
|
|
||||||
put(normal_map, *it, normal); // normal_map[it] = normal
|
put(normal_map, *it, normal); // normal_map[it] = normal
|
||||||
|
if (callback && !callback ((nb+1) / double(kd_tree_points.size())))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,11 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
#include <CGAL/internal/Parallel_callback.h>
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/blocked_range.h>
|
#include <tbb/blocked_range.h>
|
||||||
#include <tbb/scalable_allocator.h>
|
#include <tbb/scalable_allocator.h>
|
||||||
|
#include <tbb/atomic.h>
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -125,20 +127,31 @@ jet_smooth_point(
|
||||||
unsigned int degree_monge;
|
unsigned int degree_monge;
|
||||||
const std::vector<Point>& input;
|
const std::vector<Point>& input;
|
||||||
std::vector<Point>& output;
|
std::vector<Point>& output;
|
||||||
|
tbb::atomic<std::size_t>& advancement;
|
||||||
|
tbb::atomic<bool>& interrupted;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Jet_smooth_pwns (Tree& tree, unsigned int k, std::vector<Point>& points,
|
Jet_smooth_pwns (Tree& tree, unsigned int k, std::vector<Point>& points,
|
||||||
unsigned int degree_fitting, unsigned int degree_monge, std::vector<Point>& output)
|
unsigned int degree_fitting, unsigned int degree_monge, std::vector<Point>& output,
|
||||||
|
tbb::atomic<std::size_t>& advancement,
|
||||||
|
tbb::atomic<bool>& interrupted)
|
||||||
: tree(tree), k (k), degree_fitting (degree_fitting),
|
: tree(tree), k (k), degree_fitting (degree_fitting),
|
||||||
degree_monge (degree_monge), input (points), output (output)
|
degree_monge (degree_monge), input (points), output (output)
|
||||||
|
, advancement (advancement)
|
||||||
|
, interrupted (interrupted)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
||||||
{
|
{
|
||||||
for( std::size_t i = r.begin(); i != r.end(); ++i)
|
for( std::size_t i = r.begin(); i != r.end(); ++i)
|
||||||
|
{
|
||||||
|
if (interrupted)
|
||||||
|
break;
|
||||||
output[i] = CGAL::internal::jet_smooth_point<Kernel, SvdTraits>(input[i], tree, k,
|
output[i] = CGAL::internal::jet_smooth_point<Kernel, SvdTraits>(input[i], tree, k,
|
||||||
degree_fitting,
|
degree_fitting,
|
||||||
degree_monge);
|
degree_monge);
|
||||||
|
++ advancement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -210,6 +223,8 @@ jet_smooth_point_set(
|
||||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||||
unsigned int degree_fitting = choose_param(get_param(np, internal_np::degree_fitting), 2);
|
unsigned int degree_fitting = choose_param(get_param(np, internal_np::degree_fitting), 2);
|
||||||
unsigned int degree_monge = choose_param(get_param(np, internal_np::degree_monge), 2);
|
unsigned int degree_monge = choose_param(get_param(np, internal_np::degree_monge), 2);
|
||||||
|
const cpp11::function<bool(double)>& callback = choose_param(get_param(np, internal_np::callback),
|
||||||
|
cpp11::function<bool(double)>());
|
||||||
|
|
||||||
typedef typename Kernel::Point_3 Point;
|
typedef typename Kernel::Point_3 Point;
|
||||||
|
|
||||||
|
|
@ -244,27 +259,35 @@ jet_smooth_point_set(
|
||||||
#else
|
#else
|
||||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||||
{
|
{
|
||||||
|
internal::Point_set_processing_3::Parallel_callback
|
||||||
|
parallel_callback (callback, kd_tree_points.size());
|
||||||
|
|
||||||
std::vector<Point> mutated_points (kd_tree_points.size ());
|
std::vector<Point> mutated_points (kd_tree_points.size ());
|
||||||
CGAL::internal::Jet_smooth_pwns<Kernel, SvdTraits, Tree>
|
CGAL::internal::Jet_smooth_pwns<Kernel, SvdTraits, Tree>
|
||||||
f (tree, k, kd_tree_points, degree_fitting, degree_monge,
|
f (tree, k, kd_tree_points, degree_fitting, degree_monge,
|
||||||
mutated_points);
|
mutated_points,
|
||||||
|
parallel_callback.advancement(),
|
||||||
|
parallel_callback.interrupted());
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
||||||
{
|
|
||||||
put(point_map, *it, mutated_points[i]);
|
put(point_map, *it, mutated_points[i]);
|
||||||
|
|
||||||
}
|
parallel_callback.join();
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
for(it = points.begin(); it != points.end(); it++)
|
std::size_t nb = 0;
|
||||||
|
for(it = points.begin(); it != points.end(); it++, ++ nb)
|
||||||
{
|
{
|
||||||
const typename boost::property_traits<PointMap>::reference p = get(point_map, *it);
|
const typename boost::property_traits<PointMap>::reference p = get(point_map, *it);
|
||||||
put(point_map, *it ,
|
put(point_map, *it ,
|
||||||
internal::jet_smooth_point<Kernel, SvdTraits>(
|
internal::jet_smooth_point<Kernel, SvdTraits>(
|
||||||
p,tree,k,degree_fitting,degree_monge) );
|
p,tree,k,degree_fitting,degree_monge) );
|
||||||
|
if (callback && !callback ((nb+1) / double(kd_tree_points.size())))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,11 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
#include <CGAL/internal/Parallel_callback.h>
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/blocked_range.h>
|
#include <tbb/blocked_range.h>
|
||||||
#include <tbb/scalable_allocator.h>
|
#include <tbb/scalable_allocator.h>
|
||||||
|
#include <tbb/atomic.h>
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -117,17 +119,28 @@ pca_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute
|
||||||
const unsigned int k;
|
const unsigned int k;
|
||||||
const std::vector<Point>& input;
|
const std::vector<Point>& input;
|
||||||
std::vector<Vector>& output;
|
std::vector<Vector>& output;
|
||||||
|
tbb::atomic<std::size_t>& advancement;
|
||||||
|
tbb::atomic<bool>& interrupted;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PCA_estimate_normals(Tree& tree, unsigned int k, std::vector<Point>& points,
|
PCA_estimate_normals(Tree& tree, unsigned int k, std::vector<Point>& points,
|
||||||
std::vector<Vector>& output)
|
std::vector<Vector>& output,
|
||||||
|
tbb::atomic<std::size_t>& advancement,
|
||||||
|
tbb::atomic<bool>& interrupted)
|
||||||
: tree(tree), k (k), input (points), output (output)
|
: tree(tree), k (k), input (points), output (output)
|
||||||
|
, advancement (advancement)
|
||||||
|
, interrupted (interrupted)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
||||||
{
|
{
|
||||||
for( std::size_t i = r.begin(); i != r.end(); ++i)
|
for( std::size_t i = r.begin(); i != r.end(); ++i)
|
||||||
|
{
|
||||||
|
if (interrupted)
|
||||||
|
break;
|
||||||
output[i] = CGAL::internal::pca_estimate_normal<Kernel,Tree>(input[i], tree, k);
|
output[i] = CGAL::internal::pca_estimate_normal<Kernel,Tree>(input[i], tree, k);
|
||||||
|
++ advancement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -193,6 +206,8 @@ pca_estimate_normals(
|
||||||
|
|
||||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||||
NormalMap normal_map = choose_param(get_param(np, internal_np::normal_map), NormalMap());
|
NormalMap normal_map = choose_param(get_param(np, internal_np::normal_map), NormalMap());
|
||||||
|
const cpp11::function<bool(double)>& callback = choose_param(get_param(np, internal_np::callback),
|
||||||
|
cpp11::function<bool(double)>());
|
||||||
|
|
||||||
typedef typename Kernel::Point_3 Point;
|
typedef typename Kernel::Point_3 Point;
|
||||||
|
|
||||||
|
|
@ -235,20 +250,26 @@ pca_estimate_normals(
|
||||||
#else
|
#else
|
||||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||||
{
|
{
|
||||||
|
internal::Point_set_processing_3::Parallel_callback
|
||||||
|
parallel_callback (callback, kd_tree_points.size());
|
||||||
|
|
||||||
std::vector<Vector> normals (kd_tree_points.size ());
|
std::vector<Vector> normals (kd_tree_points.size ());
|
||||||
CGAL::internal::PCA_estimate_normals<Kernel, Tree>
|
CGAL::internal::PCA_estimate_normals<Kernel, Tree>
|
||||||
f (tree, k, kd_tree_points, normals);
|
f (tree, k, kd_tree_points, normals,
|
||||||
|
parallel_callback.advancement(),
|
||||||
|
parallel_callback.interrupted());
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
||||||
{
|
|
||||||
put (normal_map, *it, normals[i]);
|
put (normal_map, *it, normals[i]);
|
||||||
}
|
|
||||||
|
parallel_callback.join();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
for(it = points.begin(); it != points.end(); it++)
|
std::size_t nb = 0;
|
||||||
|
for(it = points.begin(); it != points.end(); it++, ++ nb)
|
||||||
{
|
{
|
||||||
Vector normal = internal::pca_estimate_normal<Kernel,Tree>(
|
Vector normal = internal::pca_estimate_normal<Kernel,Tree>(
|
||||||
get(point_map,*it),
|
get(point_map,*it),
|
||||||
|
|
@ -256,6 +277,8 @@ pca_estimate_normals(
|
||||||
k);
|
k);
|
||||||
|
|
||||||
put(normal_map, *it, normal); // normal_map[it] = normal
|
put(normal_map, *it, normal); // normal_map[it] = normal
|
||||||
|
if (callback && !callback ((nb+1) / double(kd_tree_points.size())))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <CGAL/Orthogonal_k_neighbor_search.h>
|
#include <CGAL/Orthogonal_k_neighbor_search.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/point_set_processing_assertions.h>
|
#include <CGAL/point_set_processing_assertions.h>
|
||||||
|
#include <CGAL/function.h>
|
||||||
|
|
||||||
#include <CGAL/boost/graph/named_function_params.h>
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
@ -163,6 +164,8 @@ remove_outliers(
|
||||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||||
double threshold_percent = choose_param(get_param(np, internal_np::threshold_percent), 10.);
|
double threshold_percent = choose_param(get_param(np, internal_np::threshold_percent), 10.);
|
||||||
double threshold_distance = choose_param(get_param(np, internal_np::threshold_distance), 0.);
|
double threshold_distance = choose_param(get_param(np, internal_np::threshold_distance), 0.);
|
||||||
|
const cpp11::function<bool(double)>& callback = choose_param(get_param(np, internal_np::callback),
|
||||||
|
cpp11::function<bool(double)>());
|
||||||
|
|
||||||
typedef typename Kernel::FT FT;
|
typedef typename Kernel::FT FT;
|
||||||
|
|
||||||
|
|
@ -198,12 +201,15 @@ remove_outliers(
|
||||||
|
|
||||||
// iterate over input points and add them to multimap sorted by distance to k
|
// iterate over input points and add them to multimap sorted by distance to k
|
||||||
std::multimap<FT,Enriched_point> sorted_points;
|
std::multimap<FT,Enriched_point> sorted_points;
|
||||||
for(it = points.begin(); it != points.end(); it++)
|
std::size_t nb = 0;
|
||||||
|
for(it = points.begin(); it != points.end(); it++, ++ nb)
|
||||||
{
|
{
|
||||||
FT sq_distance = internal::compute_avg_knn_sq_distance_3<Kernel>(
|
FT sq_distance = internal::compute_avg_knn_sq_distance_3<Kernel>(
|
||||||
get(point_map,*it),
|
get(point_map,*it),
|
||||||
tree, k);
|
tree, k);
|
||||||
sorted_points.insert( std::make_pair(sq_distance, *it) );
|
sorted_points.insert( std::make_pair(sq_distance, *it) );
|
||||||
|
if (callback && !callback ((nb+1) / double(kd_tree_points.size())))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replaces [points.begin(), points.end()) range by the multimap content.
|
// Replaces [points.begin(), points.end()) range by the multimap content.
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,11 @@
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
#include <CGAL/internal/Parallel_callback.h>
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/blocked_range.h>
|
#include <tbb/blocked_range.h>
|
||||||
|
#include <tbb/scalable_allocator.h>
|
||||||
|
#include <tbb/atomic.h>
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
|
@ -354,6 +357,8 @@ class Sample_point_updater
|
||||||
const typename Kernel::FT radius;
|
const typename Kernel::FT radius;
|
||||||
const std::vector<typename Kernel::FT> &original_densities;
|
const std::vector<typename Kernel::FT> &original_densities;
|
||||||
const std::vector<typename Kernel::FT> &sample_densities;
|
const std::vector<typename Kernel::FT> &sample_densities;
|
||||||
|
tbb::atomic<std::size_t>& advancement;
|
||||||
|
tbb::atomic<bool>& interrupted;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sample_point_updater(
|
Sample_point_updater(
|
||||||
|
|
@ -363,20 +368,25 @@ public:
|
||||||
const Tree &_sample_kd_tree,
|
const Tree &_sample_kd_tree,
|
||||||
const typename Kernel::FT _radius,
|
const typename Kernel::FT _radius,
|
||||||
const std::vector<typename Kernel::FT> &_original_densities,
|
const std::vector<typename Kernel::FT> &_original_densities,
|
||||||
const std::vector<typename Kernel::FT> &_sample_densities):
|
const std::vector<typename Kernel::FT> &_sample_densities,
|
||||||
|
tbb::atomic<std::size_t>& advancement,
|
||||||
|
tbb::atomic<bool>& interrupted):
|
||||||
update_sample_points(out),
|
update_sample_points(out),
|
||||||
sample_points(in),
|
sample_points(in),
|
||||||
original_kd_tree(_original_kd_tree),
|
original_kd_tree(_original_kd_tree),
|
||||||
sample_kd_tree(_sample_kd_tree),
|
sample_kd_tree(_sample_kd_tree),
|
||||||
radius(_radius),
|
radius(_radius),
|
||||||
original_densities(_original_densities),
|
original_densities(_original_densities),
|
||||||
sample_densities(_sample_densities){}
|
sample_densities(_sample_densities),
|
||||||
|
advancement (advancement),
|
||||||
|
interrupted (interrupted) {}
|
||||||
|
|
||||||
void operator() ( const tbb::blocked_range<size_t>& r ) const
|
void operator() ( const tbb::blocked_range<size_t>& r ) const
|
||||||
{
|
{
|
||||||
for (size_t i = r.begin(); i != r.end(); ++i)
|
for (size_t i = r.begin(); i != r.end(); ++i)
|
||||||
{
|
{
|
||||||
|
if (interrupted)
|
||||||
|
break;
|
||||||
update_sample_points[i] = simplify_and_regularize_internal::
|
update_sample_points[i] = simplify_and_regularize_internal::
|
||||||
compute_update_sample_point<Kernel, Tree, RandomAccessIterator>(
|
compute_update_sample_point<Kernel, Tree, RandomAccessIterator>(
|
||||||
sample_points[i],
|
sample_points[i],
|
||||||
|
|
@ -385,6 +395,7 @@ public:
|
||||||
radius,
|
radius,
|
||||||
original_densities,
|
original_densities,
|
||||||
sample_densities);
|
sample_densities);
|
||||||
|
++ advancement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -466,6 +477,8 @@ wlop_simplify_and_regularize_point_set(
|
||||||
double radius = choose_param(get_param(np, internal_np::neighbor_radius), -1);
|
double radius = choose_param(get_param(np, internal_np::neighbor_radius), -1);
|
||||||
unsigned int iter_number = choose_param(get_param(np, internal_np::number_of_iterations), 35);
|
unsigned int iter_number = choose_param(get_param(np, internal_np::number_of_iterations), 35);
|
||||||
bool require_uniform_sampling = choose_param(get_param(np, internal_np::require_uniform_sampling), false);
|
bool require_uniform_sampling = choose_param(get_param(np, internal_np::require_uniform_sampling), false);
|
||||||
|
const cpp11::function<bool(double)>& callback = choose_param(get_param(np, internal_np::callback),
|
||||||
|
cpp11::function<bool(double)>());
|
||||||
|
|
||||||
typedef typename Kernel::Point_3 Point;
|
typedef typename Kernel::Point_3 Point;
|
||||||
typedef typename Kernel::FT FT;
|
typedef typename Kernel::FT FT;
|
||||||
|
|
@ -589,6 +602,9 @@ wlop_simplify_and_regularize_point_set(
|
||||||
//parallel
|
//parallel
|
||||||
if (boost::is_convertible<ConcurrencyTag, Parallel_tag>::value)
|
if (boost::is_convertible<ConcurrencyTag, Parallel_tag>::value)
|
||||||
{
|
{
|
||||||
|
internal::Point_set_processing_3::Parallel_callback
|
||||||
|
parallel_callback (callback, iter_number * number_of_sample, iter_n * number_of_sample);
|
||||||
|
|
||||||
tbb::blocked_range<size_t> block(0, number_of_sample);
|
tbb::blocked_range<size_t> block(0, number_of_sample);
|
||||||
Sample_point_updater<Kernel, Kd_Tree, typename PointRange::iterator> sample_updater(
|
Sample_point_updater<Kernel, Kd_Tree, typename PointRange::iterator> sample_updater(
|
||||||
update_sample_points,
|
update_sample_points,
|
||||||
|
|
@ -597,15 +613,28 @@ wlop_simplify_and_regularize_point_set(
|
||||||
sample_kd_tree,
|
sample_kd_tree,
|
||||||
radius2,
|
radius2,
|
||||||
original_density_weights,
|
original_density_weights,
|
||||||
sample_density_weights);
|
sample_density_weights,
|
||||||
|
parallel_callback.advancement(),
|
||||||
|
parallel_callback.interrupted());
|
||||||
|
|
||||||
tbb::parallel_for(block, sample_updater);
|
tbb::parallel_for(block, sample_updater);
|
||||||
|
|
||||||
|
bool interrupted = parallel_callback.interrupted();
|
||||||
|
|
||||||
|
// We interrupt by hand as counter only goes halfway and won't terminate by itself
|
||||||
|
parallel_callback.interrupted() = true;
|
||||||
|
parallel_callback.join();
|
||||||
|
|
||||||
|
// If interrupted during this step, nothing is computed, we return NaN
|
||||||
|
if (interrupted)
|
||||||
|
return output;
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
//sequential
|
//sequential
|
||||||
|
std::size_t nb = iter_n * number_of_sample;
|
||||||
for (sample_iter = sample_points.begin();
|
for (sample_iter = sample_points.begin();
|
||||||
sample_iter != sample_points.end(); ++sample_iter, ++update_iter)
|
sample_iter != sample_points.end(); ++sample_iter, ++update_iter, ++ nb)
|
||||||
{
|
{
|
||||||
*update_iter = simplify_and_regularize_internal::
|
*update_iter = simplify_and_regularize_internal::
|
||||||
compute_update_sample_point<Kernel,
|
compute_update_sample_point<Kernel,
|
||||||
|
|
@ -617,6 +646,8 @@ wlop_simplify_and_regularize_point_set(
|
||||||
radius2,
|
radius2,
|
||||||
original_density_weights,
|
original_density_weights,
|
||||||
sample_density_weights);
|
sample_density_weights);
|
||||||
|
if (callback && !callback ((nb+1) / double(iter_number * number_of_sample)))
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue