mirror of https://github.com/CGAL/cgal
Use new API of PSP with named parameters in include+example
This commit is contained in:
parent
814ad5adf4
commit
86634b3c17
|
|
@ -53,12 +53,11 @@ int main(int argc, char*argv[])
|
|||
{
|
||||
/* double error = */
|
||||
CGAL::bilateral_smooth_point_set <Concurrency_tag>(
|
||||
points.begin(),
|
||||
points.end(),
|
||||
CGAL::First_of_pair_property_map<PointVectorPair>(),
|
||||
CGAL::Second_of_pair_property_map<PointVectorPair>(),
|
||||
k,
|
||||
sharpness_angle);
|
||||
points,
|
||||
k,
|
||||
sharpness_angle,
|
||||
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>()).
|
||||
normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>()));
|
||||
}
|
||||
|
||||
//// Save point set.
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ int main(int argc, char*argv[])
|
|||
|
||||
// simplification by clustering using erase-remove idiom
|
||||
double cell_size = 0.001;
|
||||
points.erase(CGAL::grid_simplify_point_set(points.begin(), points.end(), cell_size),
|
||||
points.erase(CGAL::grid_simplify_point_set(points, cell_size),
|
||||
points.end());
|
||||
|
||||
// Optional: after erase(), use Scott Meyer's "swap trick" to trim excess capacity
|
||||
|
|
|
|||
|
|
@ -33,14 +33,13 @@ int main(int argc, char*argv[])
|
|||
// simplification by clustering using erase-remove idiom
|
||||
double cell_size = 0.05;
|
||||
std::vector<std::size_t>::iterator end;
|
||||
end = CGAL::grid_simplify_point_set(indices.begin(),
|
||||
indices.end(),
|
||||
CGAL::make_property_map(points),
|
||||
cell_size);
|
||||
end = CGAL::grid_simplify_point_set(indices,
|
||||
cell_size,
|
||||
CGAL::parameters::point_map (CGAL::make_property_map(points)));
|
||||
|
||||
std::size_t k = end - indices.begin();
|
||||
|
||||
std::cerr << "Keep " << k << " of " << indices.size() << "indices" << std::endl;
|
||||
std::cerr << "Keep " << k << " of " << indices.size() << " indices" << std::endl;
|
||||
|
||||
{
|
||||
std::vector<Point> tmp_points(k);
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ int main(int argc, char*argv[])
|
|||
CGAL::Timer task_timer; task_timer.start();
|
||||
|
||||
// simplification by clustering using erase-remove idiom
|
||||
points.erase (CGAL::hierarchy_simplify_point_set (points.begin (), points.end (),
|
||||
100, // Max cluster size
|
||||
0.01), // Max surface variation
|
||||
points.erase (CGAL::hierarchy_simplify_point_set (points,
|
||||
CGAL::parameters::size(100). // Max cluster size
|
||||
maximum_variation(0.01)), // Max surface variation
|
||||
points.end ());
|
||||
|
||||
std::size_t memory = CGAL::Memory_sizer().virtual_size();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ int main(void)
|
|||
|
||||
// Smoothing.
|
||||
const unsigned int nb_neighbors = 8; // default is 24 for real-life point sets
|
||||
CGAL::jet_smooth_point_set<Concurrency_tag>(points.begin(), points.end(), nb_neighbors);
|
||||
CGAL::jet_smooth_point_set<Concurrency_tag>(points, nb_neighbors);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,10 +92,12 @@ void run_jet_estimate_normals(PointList& points, // input points + output normal
|
|||
// Estimates normals direction.
|
||||
// Note: jet_estimate_normals() requires an iterator over points
|
||||
// + property maps to access each point's position and normal.
|
||||
CGAL::jet_estimate_normals<Concurrency_tag>(points.begin(), points.end(),
|
||||
CGAL::First_of_pair_property_map<PointVectorPair>(),
|
||||
CGAL::Second_of_pair_property_map<PointVectorPair>(),
|
||||
nb_neighbors_jet_fitting_normals);
|
||||
CGAL::jet_estimate_normals<Concurrency_tag>
|
||||
(points,
|
||||
nb_neighbors_jet_fitting_normals,
|
||||
CGAL::parameters::point_map (CGAL::First_of_pair_property_map<PointVectorPair>()).
|
||||
normal_map (CGAL::Second_of_pair_property_map<PointVectorPair>()));
|
||||
|
||||
|
||||
std::size_t memory = CGAL::Memory_sizer().virtual_size();
|
||||
std::cerr << "done: " << task_timer.time() << " seconds, "
|
||||
|
|
@ -114,11 +116,9 @@ void run_vcm_estimate_normals(PointList &points, // input points + output normal
|
|||
// Estimates normals direction.
|
||||
// Note: vcm_estimate_normals() requires an iterator over points
|
||||
// + property maps to access each point's position and normal.
|
||||
CGAL::vcm_estimate_normals(points.begin(), points.end(),
|
||||
CGAL::First_of_pair_property_map<PointVectorPair>(),
|
||||
CGAL::Second_of_pair_property_map<PointVectorPair>(),
|
||||
R,
|
||||
r);
|
||||
CGAL::vcm_estimate_normals(points, R, r,
|
||||
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>()).
|
||||
normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>()));
|
||||
|
||||
std::size_t memory = CGAL::Memory_sizer().virtual_size();
|
||||
std::cerr << "done: " << task_timer.time() << " seconds, "
|
||||
|
|
@ -138,10 +138,10 @@ void run_mst_orient_normals(PointList& points, // input points + input/output no
|
|||
// Note: mst_orient_normals() requires an iterator over points
|
||||
// as well as property maps to access each point's position and normal.
|
||||
PointList::iterator unoriented_points_begin =
|
||||
CGAL::mst_orient_normals(points.begin(), points.end(),
|
||||
CGAL::First_of_pair_property_map<PointVectorPair>(),
|
||||
CGAL::Second_of_pair_property_map<PointVectorPair>(),
|
||||
nb_neighbors_mst);
|
||||
CGAL::mst_orient_normals(points,
|
||||
nb_neighbors_mst,
|
||||
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<PointVectorPair>()).
|
||||
normal_map(CGAL::Second_of_pair_property_map<PointVectorPair>()));
|
||||
|
||||
// Optional: delete points with an unoriented normal
|
||||
// if you plan to call a reconstruction algorithm that expects oriented normals.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ int main(int argc, char*argv[])
|
|||
|
||||
// Randomly simplifies using erase-remove idiom
|
||||
const double removed_percentage = 97.0; // percentage of points to remove
|
||||
points.erase(CGAL::random_simplify_point_set(points.begin(), points.end(), removed_percentage),
|
||||
points.erase(CGAL::random_simplify_point_set(points, removed_percentage),
|
||||
points.end());
|
||||
|
||||
// Optional: after erase(), use Scott Meyer's "swap trick" to trim excess capacity
|
||||
|
|
|
|||
|
|
@ -33,18 +33,17 @@ int main(int argc, char*argv[])
|
|||
|
||||
// Estimate scale of the point set with average spacing
|
||||
const double average_spacing = CGAL::compute_average_spacing<CGAL::Sequential_tag>
|
||||
(points.begin(), points.end(), nb_neighbors);
|
||||
(points, nb_neighbors);
|
||||
|
||||
//////////////////
|
||||
// FIRST OPTION //
|
||||
// I don't know the ratio of outliers present in the point set
|
||||
std::vector<Point>::iterator first_to_remove
|
||||
= CGAL::remove_outliers(points.begin(), points.end(),
|
||||
CGAL::Identity_property_map<Point>(),
|
||||
nb_neighbors,
|
||||
100., // No limit on the number of outliers to remove
|
||||
2. * average_spacing); // Point with distance above 2*average_spacing are considered outliers
|
||||
|
||||
= CGAL::remove_outliers
|
||||
(points,
|
||||
nb_neighbors,
|
||||
CGAL::parameters::threshold_percent (100.). // No limit on the number of outliers to remove
|
||||
threshold_distance (2. * average_spacing)); // Point with distance above 2*average_spacing are considered outliers
|
||||
|
||||
std::cerr << (100. * std::distance(first_to_remove, points.end()) / (double)(points.size()))
|
||||
<< "% of the points are considered outliers when using a distance threshold of "
|
||||
|
|
@ -56,11 +55,11 @@ int main(int argc, char*argv[])
|
|||
// I know the ratio of outliers present in the point set
|
||||
const double removed_percentage = 5.0; // percentage of points to remove
|
||||
|
||||
points.erase(CGAL::remove_outliers(points.begin(), points.end(),
|
||||
CGAL::Identity_property_map<Point>(),
|
||||
nb_neighbors,
|
||||
removed_percentage, // Minimum percentage to remove
|
||||
0.), // No distance threshold (can be omitted)
|
||||
points.erase(CGAL::remove_outliers
|
||||
(points,
|
||||
nb_neighbors,
|
||||
CGAL::parameters::threshold_percent(removed_percentage). // Minimum percentage to remove
|
||||
threshold_distance(0.)), // No distance threshold (can be omitted)
|
||||
points.end());
|
||||
|
||||
// Optional: after erase(), use Scott Meyer's "swap trick" to trim excess capacity
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ int main (int, char**)
|
|||
queries.push_back (Point_2 (1., 0.));
|
||||
|
||||
std::vector<std::size_t> k_scales;
|
||||
CGAL::estimate_local_k_neighbor_scales (samples.begin(), samples.end(),
|
||||
queries.begin(), queries.end(),
|
||||
CGAL::estimate_local_k_neighbor_scales (samples,
|
||||
queries,
|
||||
std::back_inserter (k_scales));
|
||||
|
||||
// Display results
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ int main (int argc, char** argv)
|
|||
|
||||
// estimate k scale
|
||||
task_timer.start();
|
||||
std::size_t k_scale = CGAL::estimate_global_k_neighbor_scale (points.begin(), points.end());
|
||||
std::size_t k_scale = CGAL::estimate_global_k_neighbor_scale (points);
|
||||
task_timer.stop();
|
||||
|
||||
// Example: use estimated k as scale for jet smoothing
|
||||
|
|
@ -54,7 +54,7 @@ int main (int argc, char** argv)
|
|||
|
||||
// estimate range scale
|
||||
task_timer.start();
|
||||
FT range_scale = CGAL::estimate_global_range_scale (points.begin(), points.end());
|
||||
FT range_scale = CGAL::estimate_global_range_scale (points);
|
||||
task_timer.stop();
|
||||
|
||||
// Example: use estimated range for grid simplification
|
||||
|
|
|
|||
|
|
@ -55,12 +55,14 @@ int main (int argc, char** argv)
|
|||
|
||||
Pwn_vector structured_pts;
|
||||
|
||||
CGAL::structure_point_set (points, Point_map(), Normal_map(),
|
||||
CGAL::structure_point_set (points,
|
||||
planes,
|
||||
CGAL::Shape_detection_3::Plane_map<Traits>(),
|
||||
CGAL::Shape_detection_3::Point_to_shape_index_map<Traits>(points, planes),
|
||||
std::back_inserter (structured_pts),
|
||||
0.015); // epsilon for structuring points
|
||||
0.015, // epsilon for structuring points
|
||||
CGAL::parameters::point_map (Point_map()).
|
||||
normal_map (Normal_map()).
|
||||
plane_map (CGAL::Shape_detection_3::Plane_map<Traits>()).
|
||||
plane_index_map (CGAL::Shape_detection_3::Point_to_shape_index_map<Traits>(points, planes)));
|
||||
|
||||
std::cerr << structured_pts.size ()
|
||||
<< " structured point(s) generated." << std::endl;
|
||||
|
|
|
|||
|
|
@ -40,14 +40,10 @@ int main(int argc, char** argv)
|
|||
const double retain_percentage = 2; // percentage of points to retain.
|
||||
const double neighbor_radius = 0.5; // neighbors size.
|
||||
|
||||
CGAL::wlop_simplify_and_regularize_point_set
|
||||
<Concurrency_tag>
|
||||
(points.begin(),
|
||||
points.end(),
|
||||
std::back_inserter(output),
|
||||
retain_percentage,
|
||||
neighbor_radius
|
||||
);
|
||||
CGAL::wlop_simplify_and_regularize_point_set<Concurrency_tag>
|
||||
(points, std::back_inserter(output),
|
||||
CGAL::parameters::select_percentage(retain_percentage).
|
||||
neighbor_radius (neighbor_radius));
|
||||
|
||||
std::ofstream out(output_filename);
|
||||
if (!out || !CGAL::write_xyz_points(
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
#include <CGAL/Point_with_normal_3.h>
|
||||
#include <CGAL/squared_distance_3.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
|
@ -380,18 +383,18 @@ public:
|
|||
/// \pre Normals must be unit vectors
|
||||
/// \pre k >= 2
|
||||
///
|
||||
/// @tparam Concurrency_tag enables sequential versus parallel algorithm.
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadWritePropertyMap`
|
||||
/// @tparam PointMap is a model of `ReadWritePropertyMap`
|
||||
/// with the value type of `ForwardIterator` as key and `Kernel::Point_3` as value type.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to
|
||||
/// `Kernel::Point_3`.
|
||||
/// @tparam NormalPMap is a model of `ReadWritePropertyMap` with the value type of `ForwardIterator` as key
|
||||
/// @tparam NormalMap is a model of `ReadWritePropertyMap` with the value type of `ForwardIterator` as key
|
||||
/// and `Kernel::Vector_3` as value type.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`
|
||||
/// using `Kernel_traits`.
|
||||
///
|
||||
/// @return Average point movement error. It's a convergence criterium for the algorithm.
|
||||
|
|
@ -399,30 +402,35 @@ public:
|
|||
/// sufficient.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename Concurrency_tag,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename Kernel>
|
||||
template <typename ConcurrencyTag,
|
||||
typename PointRange,
|
||||
typename NamedParameters>
|
||||
double
|
||||
bilateral_smooth_point_set(
|
||||
ForwardIterator first, ///< forward iterator on the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator.
|
||||
PointPMap point_pmap, ///< point property map.
|
||||
NormalPMap normal_pmap, ///< normal property map.
|
||||
PointRange& points,
|
||||
unsigned int k, ///< size of the neighborhood for the implicit surface patch fitting.
|
||||
///< The larger the value is, the smoother the result will be.
|
||||
typename Kernel::FT sharpness_angle, ///< controls the sharpness of the result.
|
||||
double sharpness_angle, ///< controls the sharpness of the result.
|
||||
///< The larger the value is, the smoother the result will be.
|
||||
///< The range of possible value is [0, 90].
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::type NormalMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<NormalMap,
|
||||
Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::NoMap>::value),
|
||||
"Error: no normal map");
|
||||
|
||||
typedef typename CGAL::Point_with_normal_3<Kernel> Pwn;
|
||||
typedef typename std::vector<Pwn,CGAL_PSP3_DEFAULT_ALLOCATOR<Pwn> > Pwns;
|
||||
typedef typename Kernel::FT FT;
|
||||
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
CGAL_point_set_processing_precondition(points.begin() != points.end());
|
||||
CGAL_point_set_processing_precondition(k > 1);
|
||||
|
||||
// types for K nearest neighbors search structure
|
||||
|
|
@ -432,12 +440,15 @@ bilateral_smooth_point_set(
|
|||
typedef CGAL::Orthogonal_k_neighbor_search<Tree_traits> Neighbor_search;
|
||||
typedef typename Neighbor_search::Tree Tree;
|
||||
|
||||
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());
|
||||
|
||||
// copy points and normals
|
||||
Pwns pwns;
|
||||
for(ForwardIterator it = first; it != beyond; ++it)
|
||||
for(typename PointRange::iterator it = points.begin(); it != points.end(); ++it)
|
||||
{
|
||||
typename boost::property_traits<PointPMap>::reference p = get(point_pmap, *it);
|
||||
typename boost::property_traits<NormalPMap>::reference n = get(normal_pmap, *it);
|
||||
typename boost::property_traits<PointMap>::reference p = get(point_map, *it);
|
||||
typename boost::property_traits<NormalMap>::reference n = get(normal_map, *it);
|
||||
CGAL_point_set_processing_precondition(n.squared_length() > 1e-10);
|
||||
|
||||
pwns.push_back(Pwn(p, n));
|
||||
|
|
@ -492,10 +503,10 @@ bilateral_smooth_point_set(
|
|||
pwns_neighbors.resize(nb_points);
|
||||
|
||||
#ifndef CGAL_LINKED_WITH_TBB
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<Concurrency_tag, Parallel_tag>::value),
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||
"Parallel_tag is enabled but TBB is unavailable.");
|
||||
#else
|
||||
if (boost::is_convertible<Concurrency_tag,Parallel_tag>::value)
|
||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||
{
|
||||
Compute_pwns_neighbors<Kernel, Tree> f(k, tree, pwns, pwns_neighbors);
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, nb_points), f);
|
||||
|
|
@ -527,7 +538,7 @@ bilateral_smooth_point_set(
|
|||
Pwns update_pwns(nb_points);
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
if(boost::is_convertible<Concurrency_tag, CGAL::Parallel_tag>::value)
|
||||
if(boost::is_convertible<ConcurrencyTag, CGAL::Parallel_tag>::value)
|
||||
{
|
||||
//tbb::task_scheduler_init init(4);
|
||||
tbb::blocked_range<size_t> block(0, nb_points);
|
||||
|
|
@ -564,67 +575,90 @@ bilateral_smooth_point_set(
|
|||
#endif
|
||||
// save results
|
||||
FT sum_move_error = 0;
|
||||
ForwardIterator it = first;
|
||||
for(unsigned int i = 0 ; it != beyond; ++it, ++i)
|
||||
typename PointRange::iterator it = points.begin();
|
||||
for(unsigned int i = 0 ; it != points.end(); ++it, ++i)
|
||||
{
|
||||
typename boost::property_traits<PointPMap>::reference p = get(point_pmap, *it);
|
||||
typename boost::property_traits<PointMap>::reference p = get(point_map, *it);
|
||||
sum_move_error += CGAL::squared_distance(p, update_pwns[i].position());
|
||||
put (point_pmap, *it, update_pwns[i].position());
|
||||
put (normal_pmap, *it, update_pwns[i].normal());
|
||||
put (point_map, *it, update_pwns[i].position());
|
||||
put (normal_map, *it, update_pwns[i].normal());
|
||||
}
|
||||
|
||||
return sum_move_error / nb_points;
|
||||
}
|
||||
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename Kernel>
|
||||
double
|
||||
bilateral_smooth_point_set(
|
||||
ForwardIterator first, ///< forward iterator on the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator.
|
||||
PointMap point_map, ///< point property map.
|
||||
NormalMap normal_map, ///< normal property map.
|
||||
unsigned int k, ///< size of the neighborhood for the implicit surface patch fitting.
|
||||
///< The larger the value is, the smoother the result will be.
|
||||
typename Kernel::FT sharpness_angle, ///< controls the sharpness of the result.
|
||||
///< The larger the value is, the smoother the result will be.
|
||||
///< The range of possible value is [0, 90].
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("bilateral_smooth_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points = CGAL::make_range (first, beyond);
|
||||
return bilateral_smooth_point_set<ConcurrencyTag>
|
||||
(points,
|
||||
k, sharpness_angle,
|
||||
CGAL::parameters::point_map(point_map).normal_map(normal_map).geom_traits(Kernel()));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap>
|
||||
typename PointMap,
|
||||
typename NormalMap>
|
||||
double
|
||||
bilateral_smooth_point_set(
|
||||
ForwardIterator first, ///< forward iterator to the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator.
|
||||
PointPMap point_pmap, ///< property map OutputIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map ForwardIterator -> Vector_3.
|
||||
PointMap point_map, ///< property map OutputIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map ForwardIterator -> Vector_3.
|
||||
const unsigned int k, ///< number of neighbors.
|
||||
double sharpness_angle ///< control sharpness(0-90)
|
||||
) ///< property map OutputIterator -> Vector_3.
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return bilateral_smooth_point_set<Concurrency_tag>(
|
||||
first, beyond,
|
||||
point_pmap,
|
||||
normal_pmap,
|
||||
k,
|
||||
sharpness_angle,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("bilateral_smooth_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points = CGAL::make_range (first, beyond);
|
||||
return bilateral_smooth_point_set<ConcurrencyTag>
|
||||
(points,
|
||||
k, sharpness_angle,
|
||||
CGAL::parameters::point_map(point_map).normal_map(normal_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant creates a default point property map = Dereference_property_map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename NormalPMap>
|
||||
typename NormalMap>
|
||||
double
|
||||
bilateral_smooth_point_set(
|
||||
ForwardIterator first, ///< forward iterator to the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator.
|
||||
const unsigned int k, ///< number of neighbors.
|
||||
double sharpness_angle, ///< control sharpness(0-90)
|
||||
NormalPMap normal_pmap) ///< property map OutputIterator -> Vector_3.
|
||||
NormalMap normal_map) ///< property map OutputIterator -> Vector_3.
|
||||
{
|
||||
return bilateral_smooth_point_set<Concurrency_tag>(
|
||||
first, beyond,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
normal_pmap,
|
||||
k,
|
||||
sharpness_angle);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("bilateral_smooth_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points = CGAL::make_range (first, beyond);
|
||||
return bilateral_smooth_point_set<ConcurrencyTag>
|
||||
(points,
|
||||
k, sharpness_angle,
|
||||
CGAL::parameters::normal_map(normal_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -138,14 +138,14 @@ compute_average_spacing(const typename Kernel::Point_3& query, ///< 3D point who
|
|||
///
|
||||
/// \pre `k >= 2.`
|
||||
///
|
||||
/// @tparam Concurrency_tag enables sequential versus parallel algorithm.
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `InputIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return average spacing (scalar).
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ double compute_average_spacing(
|
|||
return compute_average_spacing<ConcurrencyTag> (points, k, CGAL::parameters::all_default());
|
||||
}
|
||||
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename InputIterator,
|
||||
typename PointMap,
|
||||
typename Kernel
|
||||
|
|
@ -245,7 +245,7 @@ compute_average_spacing(
|
|||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("compute_average_spacing()");
|
||||
return compute_average_spacing<Concurrency_tag>(
|
||||
return compute_average_spacing<ConcurrencyTag>(
|
||||
CGAL::make_range (first,beyond),
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).geom_traits (Kernel()));
|
||||
|
|
@ -254,7 +254,7 @@ compute_average_spacing(
|
|||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the iterator type.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename InputIterator,
|
||||
typename PointMap
|
||||
>
|
||||
|
|
@ -266,7 +266,7 @@ compute_average_spacing(
|
|||
unsigned int k) ///< number of neighbors
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("compute_average_spacing()");
|
||||
return compute_average_spacing<Concurrency_tag>(
|
||||
return compute_average_spacing<ConcurrencyTag>(
|
||||
CGAL::make_range (first,beyond),
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map));
|
||||
|
|
@ -275,7 +275,7 @@ compute_average_spacing(
|
|||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant creates a default point property map = Identity_property_map.
|
||||
template < typename Concurrency_tag, typename InputIterator >
|
||||
template < typename ConcurrencyTag, typename InputIterator >
|
||||
typename Kernel_traits<typename std::iterator_traits<InputIterator>::value_type>::Kernel::FT
|
||||
compute_average_spacing(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
|
|
@ -283,7 +283,7 @@ compute_average_spacing(
|
|||
unsigned int k) ///< number of neighbors.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("compute_average_spacing()");
|
||||
return compute_average_spacing<Concurrency_tag>(
|
||||
return compute_average_spacing<ConcurrencyTag>(
|
||||
CGAL::make_range (first,beyond), k);
|
||||
}
|
||||
/// @endcond
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
#include <CGAL/Memory_sizer.h>
|
||||
#include <CGAL/compute_average_spacing.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
|
@ -283,7 +286,7 @@ update_new_point(
|
|||
/// in point-based rendering, hole filling, and sparse surface reconstruction.
|
||||
/// Normals of points are required as input. For more details, please refer to \cgalCite{ear-2013}.
|
||||
///
|
||||
/// @tparam Concurrency_tag enables sequential versus parallel
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel
|
||||
/// versions of `compute_average_spacing()` (called internally).
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
|
|
@ -294,63 +297,54 @@ update_new_point(
|
|||
/// <A HREF="http://www.boost.org/libs/iterator/doc/function_output_iterator.html">function_output_iterator</A>
|
||||
/// to match specific needs.
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap`
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap`
|
||||
/// with the value type of `ForwardIterator` as key and `Kernel::Point_3` as value type.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to
|
||||
/// `Kernel::Point_3`.
|
||||
/// @tparam NormalPMap is a model of `ReadablePropertyMap` with the value type of `ForwardIterator` as key
|
||||
/// @tparam NormalMap is a model of `ReadablePropertyMap` with the value type of `ForwardIterator` as key
|
||||
/// and `Kernel::Vector_3` as value type.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`
|
||||
/// using `Kernel_traits`.
|
||||
///
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename PointRange,
|
||||
typename OutputIterator,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename Kernel>
|
||||
typename NamedParameters>
|
||||
OutputIterator
|
||||
edge_aware_upsample_point_set(
|
||||
ForwardIterator first, ///< forward iterator on the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator.
|
||||
const PointRange& points,
|
||||
OutputIterator output, ///< output iterator where output points and normals
|
||||
///< are put.
|
||||
PointPMap point_pmap, ///< point property map.
|
||||
NormalPMap normal_pmap, ///< vector property map.
|
||||
const typename Kernel::FT sharpness_angle, ///<
|
||||
///< controls the preservation of sharp features.
|
||||
///< The larger the value is,
|
||||
///< the smoother the result will be.
|
||||
///< The range of possible values is `[0, 90]`.
|
||||
///< See section \ref Point_set_processing_3Upsample_Parameter2
|
||||
///< for an example.
|
||||
typename Kernel::FT edge_sensitivity, ///<
|
||||
///< larger values of edge-sensitivity give higher priority
|
||||
///< to inserting points along sharp features.
|
||||
///< The range of possible values is `[0, 1]`.
|
||||
///< See section \ref Point_set_processing_3Upsample_Parameter1
|
||||
///< for an example.
|
||||
typename Kernel::FT neighbor_radius, ///<
|
||||
///< indicates the radius of the largest hole that should be filled.
|
||||
///< The default value is set to 3 times the average spacing of the point set.
|
||||
///< If the value given by user is smaller than the average spacing,
|
||||
///< the function will use the default value instead.
|
||||
const std::size_t number_of_output_points,///< number of output
|
||||
///< points to generate.
|
||||
const Kernel& /*kernel*/ ///< geometric traits.
|
||||
)
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::type NormalMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<NormalMap,
|
||||
Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::NoMap>::value),
|
||||
"Error: no normal map");
|
||||
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
typedef typename Kernel::Vector_3 Vector;
|
||||
typedef typename Kernel::FT FT;
|
||||
typedef typename rich_grid_internal::Rich_point<Kernel> Rich_point;
|
||||
|
||||
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());
|
||||
double sharpness_angle = choose_param(get_param(np, internal_np::sharpness_angle), 30.);
|
||||
double edge_sensitivity = choose_param(get_param(np, internal_np::sharpness_angle), 1);
|
||||
double neighbor_radius = choose_param(get_param(np, internal_np::sharpness_angle), -1);
|
||||
std::size_t number_of_output_points = choose_param(get_param(np, internal_np::number_of_output_points), 1000);
|
||||
|
||||
// preconditions
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
CGAL_point_set_processing_precondition(points.begin() != points.end());
|
||||
CGAL_point_set_processing_precondition(sharpness_angle >= 0
|
||||
&&sharpness_angle <= 90);
|
||||
CGAL_point_set_processing_precondition(edge_sensitivity >= 0
|
||||
|
|
@ -359,15 +353,13 @@ edge_aware_upsample_point_set(
|
|||
|
||||
edge_sensitivity *= 10; // just project [0, 1] to [0, 10].
|
||||
|
||||
std::size_t number_of_input = std::distance(first, beyond);
|
||||
std::size_t number_of_input = std::distance(points.begin(), points.end());
|
||||
CGAL_point_set_processing_precondition(number_of_output_points > number_of_input);
|
||||
|
||||
|
||||
const unsigned int nb_neighbors = 6; // 1 ring
|
||||
FT average_spacing = CGAL::compute_average_spacing<Concurrency_tag>(
|
||||
first, beyond,
|
||||
point_pmap,
|
||||
nb_neighbors);
|
||||
FT average_spacing = CGAL::compute_average_spacing<ConcurrencyTag>(
|
||||
points, nb_neighbors, np);
|
||||
|
||||
if (neighbor_radius < average_spacing)
|
||||
{
|
||||
|
|
@ -383,11 +375,11 @@ edge_aware_upsample_point_set(
|
|||
std::vector<Rich_point> rich_point_set(number_of_input);
|
||||
CGAL::Bbox_3 bbox(0., 0., 0., 0., 0., 0.);
|
||||
|
||||
ForwardIterator it = first; // point iterator
|
||||
for(unsigned int i = 0; it != beyond; ++it, ++i)
|
||||
typename PointRange::const_iterator it = points.begin(); // point iterator
|
||||
for(unsigned int i = 0; it != points.end(); ++it, ++i)
|
||||
{
|
||||
rich_point_set[i].pt = get(point_pmap, *it);
|
||||
rich_point_set[i].normal = get(normal_pmap, *it);
|
||||
rich_point_set[i].pt = get(point_map, *it);
|
||||
rich_point_set[i].normal = get(normal_map, *it);
|
||||
|
||||
rich_point_set[i].index = i;
|
||||
bbox += rich_point_set[i].pt.bbox();
|
||||
|
|
@ -434,7 +426,7 @@ edge_aware_upsample_point_set(
|
|||
|
||||
if (iter_time == 0)
|
||||
{
|
||||
//estimate density threshold for the first time
|
||||
//estimate density threshold for the points.begin() time
|
||||
for (unsigned int i = 0; i < rich_point_set.size() * 0.05; ++i)
|
||||
{
|
||||
const Rich_point& v = rich_point_set[i];
|
||||
|
|
@ -580,70 +572,114 @@ edge_aware_upsample_point_set(
|
|||
}
|
||||
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ConcurrencyTag,
|
||||
typename OutputIterator,
|
||||
typename ForwardIterator,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename Kernel>
|
||||
OutputIterator
|
||||
edge_aware_upsample_point_set(
|
||||
ForwardIterator first, ///< forward iterator on the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator.
|
||||
OutputIterator output, ///< output iterator where output points and normals
|
||||
///< are put.
|
||||
PointMap point_map, ///< point property map.
|
||||
NormalMap normal_map, ///< vector property map.
|
||||
const typename Kernel::FT sharpness_angle, ///<
|
||||
///< controls the preservation of sharp features.
|
||||
///< The larger the value is,
|
||||
///< the smoother the result will be.
|
||||
///< The range of possible values is `[0, 90]`.
|
||||
///< See section \ref Point_set_processing_3Upsample_Parameter2
|
||||
///< for an example.
|
||||
typename Kernel::FT edge_sensitivity, ///<
|
||||
///< larger values of edge-sensitivity give higher priority
|
||||
///< to inserting points along sharp features.
|
||||
///< The range of possible values is `[0, 1]`.
|
||||
///< See section \ref Point_set_processing_3Upsample_Parameter1
|
||||
///< for an example.
|
||||
typename Kernel::FT neighbor_radius, ///<
|
||||
///< indicates the radius of the largest hole that should be filled.
|
||||
///< The default value is set to 3 times the average spacing of the point set.
|
||||
///< If the value given by user is smaller than the average spacing,
|
||||
///< the function will use the default value instead.
|
||||
const std::size_t number_of_output_points,///< number of output
|
||||
///< points to generate.
|
||||
const Kernel& /*kernel*/ ///< geometric traits.
|
||||
)
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("edge_aware_upsample_point_set()");
|
||||
return edge_aware_upsample_point_set<ConcurrencyTag>
|
||||
(CGAL::make_range (first, beyond), output,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
sharpness_angle (sharpness_angle).
|
||||
edge_sensitivity (edge_sensitivity).
|
||||
neighbor_radius (neighbor_radius).
|
||||
number_of_output_points (number_of_output_points).
|
||||
geom_traits (Kernel()));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename OutputIterator,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap>
|
||||
typename PointMap,
|
||||
typename NormalMap>
|
||||
OutputIterator
|
||||
edge_aware_upsample_point_set(
|
||||
ForwardIterator first, ///< forward iterator to the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap, ///< property map: `ForwardIterator` -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: `ForwardIterator` -> Vector_3.
|
||||
PointMap point_map, ///< property map: `ForwardIterator` -> Point_3.
|
||||
NormalMap normal_map, ///< property map: `ForwardIterator` -> Vector_3.
|
||||
double sharpness_angle, ///< control sharpness(0-90)
|
||||
double edge_sensitivity, ///< edge sensitivity(0-5)
|
||||
double neighbor_radius, ///< initial size of neighbors.
|
||||
const std::size_t number_of_output_points///< number of iterations.
|
||||
)
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
typedef typename Kernel::FT FT;
|
||||
return edge_aware_upsample_point_set<Concurrency_tag>(
|
||||
first, beyond,
|
||||
output,
|
||||
point_pmap,
|
||||
normal_pmap,
|
||||
static_cast<FT>(sharpness_angle),
|
||||
static_cast<FT>(edge_sensitivity),
|
||||
static_cast<FT>(neighbor_radius),
|
||||
number_of_output_points,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("edge_aware_upsample_point_set()");
|
||||
return edge_aware_upsample_point_set<ConcurrencyTag>
|
||||
(CGAL::make_range (first, beyond), output,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
sharpness_angle (sharpness_angle).
|
||||
edge_sensitivity (edge_sensitivity).
|
||||
neighbor_radius (neighbor_radius).
|
||||
number_of_output_points (number_of_output_points));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename OutputIterator,
|
||||
typename ForwardIterator,
|
||||
typename NormalPMap>
|
||||
typename NormalMap>
|
||||
OutputIterator
|
||||
edge_aware_upsample_point_set(
|
||||
ForwardIterator first, ///< iterator over the first input point
|
||||
ForwardIterator beyond, ///< past-the-end iterator
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
NormalPMap normal_pmap, ///< property map: OutputIterator -> Vector_3.
|
||||
NormalMap normal_map, ///< property map: OutputIterator -> Vector_3.
|
||||
double sharpness_angle = 30, ///< control sharpness(0-90)
|
||||
double edge_sensitivity = 1, ///< edge sensitivity(0-5)
|
||||
double neighbor_radius = -1, ///< initial size of neighbors.
|
||||
const std::size_t number_of_output_points = 1000///< number of output points.
|
||||
)
|
||||
{
|
||||
// just deduce value_type of OutputIterator
|
||||
return edge_aware_upsample_point_set
|
||||
<Concurrency_tag, typename value_type_traits<OutputIterator>::type>(
|
||||
first, beyond,
|
||||
output,
|
||||
normal_pmap,
|
||||
sharpness_angle,
|
||||
edge_sensitivity,
|
||||
neighbor_radius,
|
||||
number_of_output_points);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("edge_aware_upsample_point_set()");
|
||||
return edge_aware_upsample_point_set<ConcurrencyTag>
|
||||
(CGAL::make_range (first, beyond), output,
|
||||
CGAL::parameters::normal_map (normal_map).
|
||||
sharpness_angle (sharpness_angle).
|
||||
edge_sensitivity (edge_sensitivity).
|
||||
neighbor_radius (neighbor_radius).
|
||||
number_of_output_points (number_of_output_points));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@
|
|||
#include <CGAL/random_simplify_point_set.h>
|
||||
#include <CGAL/Point_set_2.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <iterator>
|
||||
|
|
@ -66,13 +69,13 @@ class Quick_multiscale_approximate_knn_distance<Kernel, typename Kernel::Point_3
|
|||
typedef typename Neighbor_search::Tree Tree;
|
||||
typedef typename Neighbor_search::iterator Iterator;
|
||||
|
||||
template <typename ValueType, typename PointPMap>
|
||||
template <typename ValueType, typename PointMap>
|
||||
struct Pmap_unary_function : public CGAL::unary_function<ValueType, typename Kernel::Point_3>
|
||||
{
|
||||
PointPMap point_pmap;
|
||||
Pmap_unary_function (PointPMap point_pmap) : point_pmap (point_pmap) { }
|
||||
typename boost::property_traits<PointPMap>::reference
|
||||
operator() (const ValueType& v) const { return get(point_pmap, v); }
|
||||
PointMap point_map;
|
||||
Pmap_unary_function (PointMap point_map) : point_map (point_map) { }
|
||||
typename boost::property_traits<PointMap>::reference
|
||||
operator() (const ValueType& v) const { return get(point_map, v); }
|
||||
};
|
||||
|
||||
std::size_t m_cluster_size;
|
||||
|
|
@ -82,18 +85,24 @@ class Quick_multiscale_approximate_knn_distance<Kernel, typename Kernel::Point_3
|
|||
|
||||
public:
|
||||
|
||||
template <typename InputIterator, typename PointPMap>
|
||||
template <typename InputIterator, typename PointMap>
|
||||
Quick_multiscale_approximate_knn_distance (InputIterator first,
|
||||
InputIterator beyond,
|
||||
PointPMap point_pmap,
|
||||
PointMap point_map,
|
||||
std::size_t cluster_size = 25)
|
||||
: m_cluster_size (cluster_size)
|
||||
{
|
||||
typedef Pmap_unary_function<typename std::iterator_traits<InputIterator>::value_type,
|
||||
PointPMap> Unary_f;
|
||||
PointMap> Unary_f;
|
||||
|
||||
// Avoid moving points of input as the range is const
|
||||
std::vector<typename Kernel::Point_3> kd_tree_points;
|
||||
std::copy (boost::make_transform_iterator (first, Unary_f(point_map)),
|
||||
boost::make_transform_iterator (beyond, Unary_f(point_map)),
|
||||
std::back_inserter (kd_tree_points));
|
||||
|
||||
|
||||
m_trees.push_back (new Tree (boost::make_transform_iterator (first, Unary_f(point_pmap)),
|
||||
boost::make_transform_iterator (beyond, Unary_f(point_pmap))));
|
||||
m_trees.push_back (new Tree (kd_tree_points.begin(), kd_tree_points.end()));
|
||||
m_weights.push_back (1.);
|
||||
std::size_t nb_pts = m_trees[0]->size();
|
||||
|
||||
|
|
@ -107,17 +116,16 @@ public:
|
|||
m_trees.reserve (nb_trees);
|
||||
m_weights.reserve (nb_trees);
|
||||
|
||||
InputIterator first_unused = beyond;
|
||||
typename std::vector<typename Kernel::Point_3>::iterator first_unused = kd_tree_points.end();
|
||||
|
||||
nb_pts = m_trees[0]->size();
|
||||
for (std::size_t i = 1; i < nb_trees; ++ i)
|
||||
{
|
||||
first_unused
|
||||
= CGAL::hierarchy_simplify_point_set (first, first_unused, point_pmap,
|
||||
= CGAL::hierarchy_simplify_point_set (kd_tree_points.begin(), first_unused,
|
||||
static_cast<unsigned int>(m_cluster_size), 1./3.);
|
||||
|
||||
m_trees.push_back (new Tree(boost::make_transform_iterator (first, Unary_f(point_pmap)),
|
||||
boost::make_transform_iterator (first_unused, Unary_f(point_pmap))));
|
||||
m_trees.push_back (new Tree(kd_tree_points.begin(), first_unused));
|
||||
|
||||
m_weights.push_back (m_trees[0]->size() / (FT)(m_trees.back()->size()));
|
||||
}
|
||||
|
|
@ -129,21 +137,21 @@ public:
|
|||
delete m_trees[i];
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename PointPMap>
|
||||
std::size_t compute_k_scale (InputIterator query, PointPMap point_pmap)
|
||||
template <typename InputIterator, typename PointMap>
|
||||
std::size_t compute_k_scale (InputIterator query, PointMap point_map)
|
||||
{
|
||||
std::size_t out;
|
||||
FT dummy;
|
||||
compute_scale (query, point_pmap, out, dummy);
|
||||
compute_scale (query, point_map, out, dummy);
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename PointPMap>
|
||||
FT compute_range_scale (InputIterator query, PointPMap point_pmap)
|
||||
template <typename InputIterator, typename PointMap>
|
||||
FT compute_range_scale (InputIterator query, PointMap point_map)
|
||||
{
|
||||
std::size_t dummy;
|
||||
FT out;
|
||||
compute_scale (query, point_pmap, dummy, out);
|
||||
compute_scale (query, point_map, dummy, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -166,8 +174,8 @@ public:
|
|||
}
|
||||
|
||||
|
||||
template <typename InputIterator, typename PointPMap>
|
||||
void compute_scale (InputIterator query, PointPMap point_pmap,
|
||||
template <typename InputIterator, typename PointMap>
|
||||
void compute_scale (InputIterator query, PointMap point_map,
|
||||
std::size_t& k, FT& d)
|
||||
{
|
||||
if (m_precomputed_factor.empty())
|
||||
|
|
@ -182,7 +190,7 @@ public:
|
|||
std::size_t index = 0;
|
||||
for (std::size_t t = 0; t < m_trees.size(); ++ t)
|
||||
{
|
||||
Neighbor_search search (*(m_trees[t]), get(point_pmap, *query),
|
||||
Neighbor_search search (*(m_trees[t]), get(point_map, *query),
|
||||
static_cast<unsigned int>((t == (m_trees.size() - 1)
|
||||
? m_trees[t]->size()
|
||||
: m_weights[t+1] / m_weights[t])));
|
||||
|
|
@ -223,29 +231,25 @@ class Quick_multiscale_approximate_knn_distance<Kernel, typename Kernel::Point_2
|
|||
typedef CGAL::Point_set_2<Kernel> Point_set;
|
||||
typedef typename Point_set::Vertex_handle Vertex_handle;
|
||||
|
||||
template <typename ValueType, typename PointPMap>
|
||||
template <typename ValueType, typename PointMap>
|
||||
struct Pmap_unary_function : public CGAL::unary_function<ValueType, typename Kernel::Point_2>
|
||||
{
|
||||
PointPMap point_pmap;
|
||||
Pmap_unary_function (PointPMap point_pmap) : point_pmap (point_pmap) { }
|
||||
typename boost::property_traits<PointPMap>::reference
|
||||
operator() (const ValueType& v) const { return get(point_pmap, v); }
|
||||
PointMap point_map;
|
||||
Pmap_unary_function (PointMap point_map) : point_map (point_map) { }
|
||||
typename boost::property_traits<PointMap>::reference
|
||||
operator() (const ValueType& v) const { return get(point_map, v); }
|
||||
};
|
||||
|
||||
template <typename PointPMap>
|
||||
struct Pmap_to_3d
|
||||
{
|
||||
PointPMap point_pmap;
|
||||
typedef typename Kernel::Point_3 value_type;
|
||||
typedef const value_type& reference;
|
||||
typedef typename boost::property_traits<PointPMap>::key_type key_type;
|
||||
typedef typename Kernel::Point_2 key_type;
|
||||
typedef boost::lvalue_property_map_tag category;
|
||||
Pmap_to_3d () { }
|
||||
Pmap_to_3d (PointPMap point_pmap)
|
||||
: point_pmap (point_pmap) { }
|
||||
friend inline value_type get (const Pmap_to_3d& ppmap, key_type i)
|
||||
|
||||
friend inline value_type get (const Pmap_to_3d&, key_type p)
|
||||
{
|
||||
typename boost::property_traits<PointPMap>::reference
|
||||
typename boost::property_traits<PointMap>::reference
|
||||
p2 = get(ppmap.point_pmap, i);
|
||||
return value_type (p2.x(), p2.y(), 0.);
|
||||
}
|
||||
|
|
@ -271,18 +275,24 @@ class Quick_multiscale_approximate_knn_distance<Kernel, typename Kernel::Point_2
|
|||
|
||||
public:
|
||||
|
||||
template <typename InputIterator, typename PointPMap>
|
||||
template <typename InputIterator, typename PointMap>
|
||||
Quick_multiscale_approximate_knn_distance (InputIterator first,
|
||||
InputIterator beyond,
|
||||
PointPMap point_pmap,
|
||||
PointMap point_map,
|
||||
std::size_t cluster_size = 25)
|
||||
: m_cluster_size (cluster_size)
|
||||
{
|
||||
typedef Pmap_unary_function<typename std::iterator_traits<InputIterator>::value_type,
|
||||
PointPMap> Unary_f;
|
||||
PointMap> Unary_f;
|
||||
|
||||
m_point_sets.push_back (new Point_set (boost::make_transform_iterator (first, Unary_f(point_pmap)),
|
||||
boost::make_transform_iterator (beyond, Unary_f(point_pmap))));
|
||||
// Avoid moving points of input as the range is const
|
||||
std::vector<typename Kernel::Point_2> search_points;
|
||||
std::copy (boost::make_transform_iterator (first, Unary_f(point_map)),
|
||||
boost::make_transform_iterator (beyond, Unary_f(point_map)),
|
||||
std::back_inserter (search_points));
|
||||
|
||||
|
||||
m_point_sets.push_back (new Point_set (search_points.begin(), search_points.end()));
|
||||
m_weights.push_back (1.);
|
||||
|
||||
std::size_t nb_pts = m_point_sets[0]->number_of_vertices();
|
||||
|
|
@ -296,17 +306,16 @@ public:
|
|||
m_point_sets.reserve (nb_trees);
|
||||
m_weights.reserve (nb_trees);
|
||||
|
||||
InputIterator first_unused = beyond;
|
||||
typename std::vector<typename Kernel::Point_2>::iterator first_unused = search_points.end();
|
||||
nb_pts = m_point_sets[0]->number_of_vertices();
|
||||
|
||||
for (std::size_t i = 1; i < nb_trees; ++ i)
|
||||
{
|
||||
first_unused
|
||||
= CGAL::hierarchy_simplify_point_set (first, first_unused, Pmap_to_3d<PointPMap> (point_pmap),
|
||||
= CGAL::hierarchy_simplify_point_set (search_points.begin(), first_unused, Pmap_to_3d(),
|
||||
static_cast<unsigned int>(m_cluster_size), 1./3.);
|
||||
|
||||
m_point_sets.push_back (new Point_set (boost::make_transform_iterator (first, Unary_f(point_pmap)),
|
||||
boost::make_transform_iterator (first_unused, Unary_f(point_pmap))));
|
||||
m_point_sets.push_back (new Point_set (search_points.begin(), first_unused));
|
||||
|
||||
m_weights.push_back (nb_pts / (FT)(m_point_sets.back()->number_of_vertices()));
|
||||
}
|
||||
|
|
@ -320,21 +329,21 @@ public:
|
|||
delete m_point_sets[i];
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename PointPMap>
|
||||
std::size_t compute_k_scale (InputIterator query, PointPMap point_pmap)
|
||||
template <typename InputIterator, typename PointMap>
|
||||
std::size_t compute_k_scale (InputIterator query, PointMap point_map)
|
||||
{
|
||||
std::size_t out;
|
||||
FT dummy;
|
||||
compute_scale (query, point_pmap, out, dummy);
|
||||
compute_scale (query, point_map, out, dummy);
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename PointPMap>
|
||||
FT compute_range_scale (InputIterator query, PointPMap point_pmap)
|
||||
template <typename InputIterator, typename PointMap>
|
||||
FT compute_range_scale (InputIterator query, PointMap point_map)
|
||||
{
|
||||
std::size_t dummy;
|
||||
FT out;
|
||||
compute_scale (query, point_pmap, dummy, out);
|
||||
compute_scale (query, point_map, dummy, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -356,8 +365,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename PointPMap>
|
||||
void compute_scale (InputIterator query, PointPMap point_pmap,
|
||||
template <typename InputIterator, typename PointMap>
|
||||
void compute_scale (InputIterator query, PointMap point_map,
|
||||
std::size_t& k, FT& d)
|
||||
{
|
||||
if (m_precomputed_factor.empty())
|
||||
|
|
@ -371,7 +380,7 @@ public:
|
|||
FT nb = 0.;
|
||||
std::size_t index = 0;
|
||||
|
||||
typename boost::property_traits<PointPMap>::reference
|
||||
typename boost::property_traits<PointMap>::reference
|
||||
pquery = get(point_pmap, *query);
|
||||
for (std::size_t t = 0; t < m_point_sets.size(); ++ t)
|
||||
{
|
||||
|
|
@ -429,7 +438,7 @@ public:
|
|||
///
|
||||
///
|
||||
/// @tparam SamplesInputIterator iterator over input sample points.
|
||||
/// @tparam SamplesPointPMap is a model of `ReadablePropertyMap` with
|
||||
/// @tparam SamplesPointMap is a model of `ReadablePropertyMap` with
|
||||
/// value type `Point_3<Kernel>` or `Point_2<Kernel>`. It can
|
||||
/// be omitted if the value type of `SamplesInputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
|
|
@ -442,42 +451,60 @@ public:
|
|||
/// @tparam OutputIterator is used to store the computed scales. It accepts
|
||||
/// values of type `std::size_t`.
|
||||
/// @tparam Kernel Geometric traits class. It can be omitted and
|
||||
/// deduced automatically from the value type of `SamplesPointPMap`.
|
||||
/// deduced automatically from the value type of `SamplesPointMap`.
|
||||
///
|
||||
/// @note This function accepts both 2D and 3D points, but sample
|
||||
/// points and query must have the same dimension.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename SamplesInputIterator,
|
||||
typename SamplesPointPMap,
|
||||
typename QueriesInputIterator,
|
||||
typename QueriesPointPMap,
|
||||
template <typename PointRange,
|
||||
typename QueryPointRange,
|
||||
typename OutputIterator,
|
||||
typename Kernel
|
||||
typename NamedParameters
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_k_neighbor_scales(
|
||||
SamplesInputIterator first, ///< iterator over the first input sample.
|
||||
SamplesInputIterator beyond, ///< past-the-end iterator over the input samples.
|
||||
SamplesPointPMap samples_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
QueriesInputIterator first_query, ///< iterator over the first point where scale must be estimated
|
||||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
QueriesPointPMap queries_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
const PointRange& points,
|
||||
const QueryPointRange& queries,
|
||||
OutputIterator output, ///< output iterator to store the computed scales
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
const NamedParameters& np)
|
||||
{
|
||||
typedef typename boost::property_traits<SamplesPointPMap>::value_type Point_d;
|
||||
using boost::choose_param;
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::const_type PointMap;
|
||||
typedef typename Point_set_processing_3::GetQueryPointMap<QueryPointRange, NamedParameters>::const_type QueryPointMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
|
||||
typedef typename boost::property_traits<PointMap>::value_type Point_d;
|
||||
|
||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||
QueryPointMap query_point_map = choose_param(get_param(np, internal_np::query_point_map), QueryPointMap());
|
||||
|
||||
// Build multi-scale KD-tree
|
||||
internal::Quick_multiscale_approximate_knn_distance<Kernel, Point_d> kdtree (first, beyond, samples_pmap);
|
||||
internal::Quick_multiscale_approximate_knn_distance<Kernel, Point_d> kdtree (points.begin(),
|
||||
points.end(),
|
||||
point_map);
|
||||
|
||||
// Compute local scales everywhere
|
||||
for (QueriesInputIterator it = first_query; it != beyond_query; ++ it)
|
||||
*(output ++) = kdtree.compute_k_scale (it, queries_pmap);
|
||||
for (typename QueryPointRange::const_iterator it = queries.begin();
|
||||
it != queries.end(); ++ it)
|
||||
*(output ++) = kdtree.compute_k_scale (it, query_point_map);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
template <typename PointRange,
|
||||
typename QueryPointRange,
|
||||
typename OutputIterator
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_k_neighbor_scales(
|
||||
const PointRange& points,
|
||||
const QueryPointRange& queries,
|
||||
OutputIterator output) ///< output iterator to store the computed scales
|
||||
{
|
||||
return estimate_local_k_neighbor_scales
|
||||
(points, queries, output, CGAL::parameters::all_default());
|
||||
}
|
||||
|
||||
/// \ingroup PkgPointSetProcessingAlgorithms
|
||||
|
||||
|
|
@ -488,37 +515,37 @@ estimate_local_k_neighbor_scales(
|
|||
///
|
||||
///
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with
|
||||
/// value type `Point_3<Kernel>` or `Point_2<Kernel>`. It can
|
||||
/// be omitted if the value type of `InputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class. It can be omitted and
|
||||
/// deduced automatically from the value type of `PointPMap`.
|
||||
/// deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @note This function accepts both 2D and 3D points.
|
||||
///
|
||||
/// @return The estimated scale in the K nearest neighbors sense.
|
||||
// This variant requires all parameters.
|
||||
template <typename InputIterator,
|
||||
typename PointPMap,
|
||||
typename Kernel
|
||||
template <typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
std::size_t
|
||||
estimate_global_k_neighbor_scale(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
const PointRange& points,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
std::vector<std::size_t> scales;
|
||||
estimate_local_k_neighbor_scales (first, beyond, point_pmap,
|
||||
first, beyond, point_pmap,
|
||||
std::back_inserter (scales),
|
||||
kernel);
|
||||
estimate_local_k_neighbor_scales (points, points, std::back_inserter (scales), np);
|
||||
std::sort (scales.begin(), scales.end());
|
||||
return scales[scales.size() / 2];
|
||||
}
|
||||
|
||||
template <typename PointRange>
|
||||
std::size_t
|
||||
estimate_global_k_neighbor_scale(const PointRange& points)
|
||||
{
|
||||
return estimate_global_k_neighbor_scale (points, CGAL::parameters::all_default());
|
||||
}
|
||||
|
||||
/// \ingroup PkgPointSetProcessingAlgorithms
|
||||
|
||||
|
|
@ -530,7 +557,7 @@ estimate_global_k_neighbor_scale(
|
|||
///
|
||||
///
|
||||
/// @tparam SamplesInputIterator iterator over input sample points.
|
||||
/// @tparam SamplesPointPMap is a model of `ReadablePropertyMap` with
|
||||
/// @tparam SamplesPointMap is a model of `ReadablePropertyMap` with
|
||||
/// value type `Point_3<Kernel>` or `Point_2<Kernel>`. It can
|
||||
/// be omitted if the value type of `SamplesInputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
|
|
@ -543,42 +570,59 @@ estimate_global_k_neighbor_scale(
|
|||
/// @tparam OutputIterator is used to store the computed scales. It accepts
|
||||
/// values of type `Kernel::FT`.
|
||||
/// @tparam Kernel Geometric traits class. It can be omitted and
|
||||
/// deduced automatically from the value type of `SamplesPointPMap`.
|
||||
/// deduced automatically from the value type of `SamplesPointMap`.
|
||||
///
|
||||
/// @note This function accepts both 2D and 3D points, but sample
|
||||
/// points and query must have the same dimension.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename SamplesInputIterator,
|
||||
typename SamplesPointPMap,
|
||||
typename QueriesInputIterator,
|
||||
typename QueriesPointPMap,
|
||||
template <typename PointRange,
|
||||
typename QueryPointRange,
|
||||
typename OutputIterator,
|
||||
typename Kernel
|
||||
typename NamedParameters
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_range_scales(
|
||||
SamplesInputIterator first, ///< iterator over the first input sample.
|
||||
SamplesInputIterator beyond, ///< past-the-end iterator over the input samples.
|
||||
SamplesPointPMap samples_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
QueriesInputIterator first_query, ///< iterator over the first point where scale must be estimated
|
||||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
QueriesPointPMap queries_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
const PointRange& points,
|
||||
const QueryPointRange& queries,
|
||||
OutputIterator output, ///< output iterator to store the computed scales
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
const NamedParameters& np)
|
||||
{
|
||||
typedef typename boost::property_traits<SamplesPointPMap>::value_type Point_d;
|
||||
using boost::choose_param;
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::const_type PointMap;
|
||||
typedef typename Point_set_processing_3::GetQueryPointMap<QueryPointRange, NamedParameters>::const_type QueryPointMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
|
||||
typedef typename boost::property_traits<PointMap>::value_type Point_d;
|
||||
|
||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||
QueryPointMap query_point_map = choose_param(get_param(np, internal_np::query_point_map), QueryPointMap());
|
||||
|
||||
// Build multi-scale KD-tree
|
||||
internal::Quick_multiscale_approximate_knn_distance<Kernel, Point_d> kdtree (first, beyond, samples_pmap);
|
||||
internal::Quick_multiscale_approximate_knn_distance<Kernel, Point_d> kdtree (points.begin(),
|
||||
points.end(),
|
||||
point_map);
|
||||
|
||||
// Compute local scales everywhere
|
||||
for (QueriesInputIterator it = first_query; it != beyond_query; ++ it)
|
||||
*(output ++) = kdtree.compute_range_scale (it, queries_pmap);
|
||||
for (typename QueryPointRange::const_iterator it = queries.begin(); it != queries.end(); ++ it)
|
||||
*(output ++) = kdtree.compute_range_scale (it, query_point_map);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
template <typename PointRange,
|
||||
typename QueryPointRange,
|
||||
typename OutputIterator
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_range_scales(
|
||||
const PointRange& points,
|
||||
const QueryPointRange& queries,
|
||||
OutputIterator output) ///< output iterator to store the computed scales
|
||||
{
|
||||
return estimate_local_range_scales (points, queries, output,
|
||||
CGAL::parameters::all_default());
|
||||
}
|
||||
|
||||
/// \ingroup PkgPointSetProcessingAlgorithms
|
||||
|
||||
|
|
@ -589,63 +633,122 @@ estimate_local_range_scales(
|
|||
///
|
||||
///
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with
|
||||
/// value type `Point_3<Kernel>` or `Point_2<Kernel>`. It can
|
||||
/// be omitted if the value type of `InputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class. It can be omitted and
|
||||
/// deduced automatically from the value type of `PointPMap`.
|
||||
/// deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @note This function accepts both 2D and 3D points.
|
||||
///
|
||||
/// @return The estimated scale in the range sense.
|
||||
// This variant requires all parameters.
|
||||
template <typename InputIterator,
|
||||
typename PointPMap,
|
||||
typename Kernel
|
||||
template <typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
typename Kernel::FT
|
||||
double
|
||||
estimate_global_range_scale(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_3
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
const PointRange& points,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
std::vector<typename Kernel::FT> scales;
|
||||
estimate_local_range_scales (first, beyond, point_pmap,
|
||||
first, beyond, point_pmap,
|
||||
std::back_inserter (scales),
|
||||
kernel);
|
||||
std::vector<double> scales;
|
||||
estimate_local_range_scales (points, points, std::back_inserter (scales), np);
|
||||
std::sort (scales.begin(), scales.end());
|
||||
return std::sqrt (scales[scales.size() / 2]);
|
||||
}
|
||||
|
||||
template <typename PointRange>
|
||||
double
|
||||
estimate_global_range_scale(const PointRange& points)
|
||||
{
|
||||
return estimate_global_range_scale(points, CGAL::parameters::all_default());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Useful overloads
|
||||
// ----------------------------------------------------------------------------
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
|
||||
/// Estimates the local scale in a K nearest neighbors sense on a set
|
||||
/// of user-defined query points. The computed scales correspond to
|
||||
/// the smallest scales such that the K subsets of points have the
|
||||
/// appearance of a surface in 3D or the appearance of a curve in 2D
|
||||
/// (see \ref Point_set_processing_3Scale).
|
||||
///
|
||||
///
|
||||
/// @tparam SamplesInputIterator iterator over input sample points.
|
||||
/// @tparam SamplesPointMap is a model of `ReadablePropertyMap` with
|
||||
/// value type `Point_3<Kernel>` or `Point_2<Kernel>`. It can
|
||||
/// be omitted if the value type of `SamplesInputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
/// @tparam QueriesInputIterator iterator over points where scale
|
||||
/// should be computed.
|
||||
/// @tparam QueriesInputIterator is a model of `ReadablePropertyMap`
|
||||
/// with value type `Point_3<Kernel>` or `Point_2<Kernel>`. It
|
||||
/// can be omitted if the value type of `QueriesInputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
/// @tparam OutputIterator is used to store the computed scales. It accepts
|
||||
/// values of type `std::size_t`.
|
||||
/// @tparam Kernel Geometric traits class. It can be omitted and
|
||||
/// deduced automatically from the value type of `SamplesPointMap`.
|
||||
///
|
||||
/// @note This function accepts both 2D and 3D points, but sample
|
||||
/// points and query must have the same dimension.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename SamplesInputIterator,
|
||||
typename SamplesPointPMap,
|
||||
typename SamplesPointMap,
|
||||
typename QueriesInputIterator,
|
||||
typename QueriesPointPMap,
|
||||
typename QueriesPointMap,
|
||||
typename OutputIterator,
|
||||
typename Kernel
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_k_neighbor_scales(
|
||||
SamplesInputIterator first, ///< iterator over the first input sample.
|
||||
SamplesInputIterator beyond, ///< past-the-end iterator over the input samples.
|
||||
SamplesPointMap samples_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
QueriesInputIterator first_query, ///< iterator over the first point where scale must be estimated
|
||||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
QueriesPointMap queries_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
OutputIterator output, ///< output iterator to store the computed scales
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_local_k_neighbor_scales()");
|
||||
return estimate_local_k_neighbor_scales
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::make_range (first_query, beyond_query),
|
||||
output,
|
||||
CGAL::parameters::point_map (samples_map).
|
||||
query_point_map (queries_map).
|
||||
geom_traits (Kernel()));
|
||||
}
|
||||
|
||||
|
||||
template <typename SamplesInputIterator,
|
||||
typename SamplesPointMap,
|
||||
typename QueriesInputIterator,
|
||||
typename QueriesPointMap,
|
||||
typename OutputIterator
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_k_neighbor_scales(
|
||||
SamplesInputIterator first, ///< iterator over the first input sample.
|
||||
SamplesInputIterator beyond, ///< past-the-end iterator over the input samples.
|
||||
SamplesPointPMap samples_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
SamplesPointMap samples_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
QueriesInputIterator first_query, ///< iterator over the first point where scale must be estimated
|
||||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
QueriesPointPMap queries_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
QueriesPointMap queries_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
OutputIterator output) ///< output iterator to store the computed scales
|
||||
{
|
||||
typedef typename boost::property_traits<SamplesPointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return estimate_local_k_neighbor_scales (first, beyond, samples_pmap, first_query, beyond_query,
|
||||
queries_pmap, output, Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_local_k_neighbor_scales()");
|
||||
return estimate_local_k_neighbor_scales
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::make_range (first_query, beyond_query),
|
||||
output,
|
||||
CGAL::parameters::point_map (samples_map).
|
||||
query_point_map (queries_map));
|
||||
}
|
||||
|
||||
template <typename SamplesInputIterator,
|
||||
|
|
@ -660,27 +763,63 @@ estimate_local_k_neighbor_scales(
|
|||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
OutputIterator output) ///< output iterator to store the computed scales
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_local_k_neighbor_scales()");
|
||||
return estimate_local_k_neighbor_scales
|
||||
(first, beyond,
|
||||
make_identity_property_map (typename std::iterator_traits<SamplesInputIterator>::value_type()),
|
||||
first_query, beyond_query,
|
||||
make_identity_property_map (typename std::iterator_traits<QueriesInputIterator>::value_type()),
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::make_range (first_query, beyond_query),
|
||||
output);
|
||||
}
|
||||
|
||||
|
||||
/// Estimates the global scale in a K nearest neighbors sense. The
|
||||
/// computed scale corresponds to the smallest scale such that the K
|
||||
/// subsets of points have the appearance of a surface in 3D or the
|
||||
/// appearance of a curve in 2D (see \ref Point_set_processing_3Scale).
|
||||
///
|
||||
///
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with
|
||||
/// value type `Point_3<Kernel>` or `Point_2<Kernel>`. It can
|
||||
/// be omitted if the value type of `InputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class. It can be omitted and
|
||||
/// deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @note This function accepts both 2D and 3D points.
|
||||
///
|
||||
/// @return The estimated scale in the K nearest neighbors sense.
|
||||
// This variant requires all parameters.
|
||||
template <typename InputIterator,
|
||||
typename PointPMap
|
||||
typename PointMap,
|
||||
typename Kernel
|
||||
>
|
||||
std::size_t
|
||||
estimate_global_k_neighbor_scale(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap) ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
PointMap point_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return estimate_global_k_neighbor_scale (first, beyond, point_pmap, Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_global_k_neighbor_scale()");
|
||||
return estimate_global_k_neighbor_scale
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::parameters::point_map (point_map).
|
||||
geom_traits (kernel));
|
||||
}
|
||||
|
||||
template <typename InputIterator,
|
||||
typename PointMap
|
||||
>
|
||||
std::size_t
|
||||
estimate_global_k_neighbor_scale(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointMap point_map) ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_global_k_neighbor_scale()");
|
||||
return estimate_global_k_neighbor_scale
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::parameters::point_map (point_map));
|
||||
}
|
||||
|
||||
template <typename InputIterator
|
||||
|
|
@ -690,81 +829,175 @@ estimate_global_k_neighbor_scale(
|
|||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond) ///< past-the-end iterator over the input points.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_global_k_neighbor_scale()");
|
||||
return estimate_global_k_neighbor_scale
|
||||
(first, beyond, make_identity_property_map (typename std::iterator_traits<InputIterator>::value_type()));
|
||||
(CGAL::make_range (first, beyond));
|
||||
}
|
||||
|
||||
|
||||
/// Estimates the local scale in a range sense on a set of
|
||||
/// user-defined query points. The computed scales correspond to the
|
||||
/// smallest scales such that the subsets of points included in the
|
||||
/// sphere range have the appearance of a surface in 3D or the
|
||||
/// appearance of a curve in 2D (see \ref Point_set_processing_3Scale).
|
||||
///
|
||||
///
|
||||
/// @tparam SamplesInputIterator iterator over input sample points.
|
||||
/// @tparam SamplesPointMap is a model of `ReadablePropertyMap` with
|
||||
/// value type `Point_3<Kernel>` or `Point_2<Kernel>`. It can
|
||||
/// be omitted if the value type of `SamplesInputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
/// @tparam QueriesInputIterator iterator over points where scale
|
||||
/// should be computed.
|
||||
/// @tparam QueriesInputIterator is a model of `ReadablePropertyMap`
|
||||
/// with value type `Point_3<Kernel>` or `Point_2<Kernel>`. It
|
||||
/// can be omitted if the value type of `QueriesInputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
/// @tparam OutputIterator is used to store the computed scales. It accepts
|
||||
/// values of type `Kernel::FT`.
|
||||
/// @tparam Kernel Geometric traits class. It can be omitted and
|
||||
/// deduced automatically from the value type of `SamplesPointMap`.
|
||||
///
|
||||
/// @note This function accepts both 2D and 3D points, but sample
|
||||
/// points and query must have the same dimension.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename SamplesInputIterator,
|
||||
typename SamplesPointPMap,
|
||||
typename SamplesPointMap,
|
||||
typename QueriesInputIterator,
|
||||
typename QueriesPointPMap,
|
||||
typename OutputIterator
|
||||
typename QueriesPointMap,
|
||||
typename OutputIterator,
|
||||
typename Kernel
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_range_scales(
|
||||
SamplesInputIterator first, ///< iterator over the first input sample.
|
||||
SamplesInputIterator beyond, ///< past-the-end iterator over the input samples.
|
||||
SamplesPointPMap samples_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
SamplesPointMap samples_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
QueriesInputIterator first_query, ///< iterator over the first point where scale must be estimated
|
||||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
QueriesPointPMap queries_pmap, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
OutputIterator output) ///< output iterator to store the computed scales
|
||||
{
|
||||
typedef typename boost::property_traits<SamplesPointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return estimate_local_range_scales(first, beyond, samples_pmap, first_query, beyond_query,
|
||||
queries_pmap, output, Kernel());
|
||||
}
|
||||
|
||||
|
||||
template <typename SamplesInputIterator,
|
||||
typename QueriesInputIterator,
|
||||
typename OutputIterator
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_range_scales(
|
||||
SamplesInputIterator first, ///< iterator over the first input sample.
|
||||
SamplesInputIterator beyond, ///< past-the-end iterator over the input samples.
|
||||
QueriesInputIterator first_query, ///< iterator over the first point where scale must be estimated
|
||||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
OutputIterator output) ///< output iterator to store the computed scales
|
||||
QueriesPointMap queries_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
OutputIterator output, ///< output iterator to store the computed scales
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_local_range_scales()");
|
||||
return estimate_local_range_scales
|
||||
(first, beyond,
|
||||
make_identity_property_map (typename std::iterator_traits<SamplesInputIterator>::value_type()),
|
||||
first_query, beyond_query,
|
||||
make_identity_property_map (typename std::iterator_traits<QueriesInputIterator>::value_type()),
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::make_range (first_query, beyond_query),
|
||||
output,
|
||||
CGAL::parameters::point_map (samples_map).
|
||||
query_point_map (queries_map).
|
||||
geom_traits (Kernel()));
|
||||
}
|
||||
|
||||
template <typename SamplesInputIterator,
|
||||
typename SamplesPointMap,
|
||||
typename QueriesInputIterator,
|
||||
typename QueriesPointMap,
|
||||
typename OutputIterator
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_range_scales(
|
||||
SamplesInputIterator first, ///< iterator over the first input sample.
|
||||
SamplesInputIterator beyond, ///< past-the-end iterator over the input samples.
|
||||
SamplesPointMap samples_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
QueriesInputIterator first_query, ///< iterator over the first point where scale must be estimated
|
||||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
QueriesPointMap queries_map, ///< property map: value_type of InputIterator -> Point_3 or Point_2
|
||||
OutputIterator output) ///< output iterator to store the computed scales
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_local_range_scales()");
|
||||
return estimate_local_range_scales
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::make_range (first_query, beyond_query),
|
||||
output,
|
||||
CGAL::parameters::point_map (samples_map).
|
||||
query_point_map (queries_map));
|
||||
}
|
||||
|
||||
|
||||
template <typename SamplesInputIterator,
|
||||
typename QueriesInputIterator,
|
||||
typename OutputIterator
|
||||
>
|
||||
OutputIterator
|
||||
estimate_local_range_scales(
|
||||
SamplesInputIterator first, ///< iterator over the first input sample.
|
||||
SamplesInputIterator beyond, ///< past-the-end iterator over the input samples.
|
||||
QueriesInputIterator first_query, ///< iterator over the first point where scale must be estimated
|
||||
QueriesInputIterator beyond_query, ///< past-the-end iterator over the points where scale must be estimated
|
||||
OutputIterator output) ///< output iterator to store the computed scales
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_local_range_scales()");
|
||||
return estimate_local_range_scales
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::make_range (first_query, beyond_query),
|
||||
output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Estimates the global scale in a range sense. The computed scale
|
||||
/// corresponds to the smallest scale such that the subsets of points
|
||||
/// inside the sphere range have the appearance of a surface in 3D or
|
||||
/// the appearance of a curve in 2D (see \ref Point_set_processing_3Scale).
|
||||
///
|
||||
///
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with
|
||||
/// value type `Point_3<Kernel>` or `Point_2<Kernel>`. It can
|
||||
/// be omitted if the value type of `InputIterator` is
|
||||
/// convertible to `Point_3<Kernel>` or to `Point_2<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class. It can be omitted and
|
||||
/// deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @note This function accepts both 2D and 3D points.
|
||||
///
|
||||
/// @return The estimated scale in the range sense.
|
||||
// This variant requires all parameters.
|
||||
template <typename InputIterator,
|
||||
typename PointPMap
|
||||
typename PointMap,
|
||||
typename Kernel
|
||||
>
|
||||
typename Kernel_traits<typename boost::property_traits<PointPMap>::value_type>::Kernel::FT
|
||||
double
|
||||
estimate_global_range_scale(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap) ///< property map: value_type of InputIterator -> Point_3 or Point_3
|
||||
PointMap point_map, ///< property map: value_type of InputIterator -> Point_3 or Point_3
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return estimate_global_range_scale (first, beyond, point_pmap, Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_global_range_scale()");
|
||||
return estimate_global_range_scale
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::parameters::point_map (point_map).
|
||||
geom_traits (kernel));
|
||||
}
|
||||
|
||||
template <typename InputIterator,
|
||||
typename PointMap
|
||||
>
|
||||
double
|
||||
estimate_global_range_scale(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointMap point_map) ///< property map: value_type of InputIterator -> Point_3 or Point_3
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_global_range_scale()");
|
||||
return estimate_global_range_scale
|
||||
(CGAL::make_range (first, beyond),
|
||||
CGAL::parameters::point_map (point_map));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename InputIterator>
|
||||
typename Kernel_traits<typename std::iterator_traits<InputIterator>::value_type>::Kernel::FT
|
||||
double
|
||||
estimate_global_range_scale(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond) ///< past-the-end iterator over the input points.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("estimate_global_range_scale()");
|
||||
return estimate_global_range_scale
|
||||
(first, beyond, make_identity_property_map (typename std::iterator_traits<InputIterator>::value_type()));
|
||||
|
||||
(CGAL::make_range (first, beyond));
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,12 @@
|
|||
#include <CGAL/Kernel_traits.h>
|
||||
#include <CGAL/point_set_processing_assertions.h>
|
||||
#include <CGAL/unordered.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
|
|
@ -55,25 +59,25 @@ inline double round_epsilon(double value, double epsilon)
|
|||
/// Utility class for grid_simplify_point_set(): Hash_epsilon_points_3
|
||||
/// defines a 3D point hash / 2 points are equal iff they belong to
|
||||
/// the same cell of a grid of cell size = epsilon.
|
||||
template <class Point_3, class PointPMap>
|
||||
template <class Point_3, class PointMap>
|
||||
struct Hash_epsilon_points_3
|
||||
{
|
||||
private:
|
||||
|
||||
double m_epsilon;
|
||||
PointPMap point_pmap;
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
PointMap point_map;
|
||||
typedef typename boost::property_traits<PointMap>::value_type Point;
|
||||
public:
|
||||
|
||||
Hash_epsilon_points_3 (double epsilon, PointPMap p_pmap)
|
||||
: m_epsilon (epsilon), point_pmap(p_pmap)
|
||||
Hash_epsilon_points_3 (double epsilon, PointMap p_map)
|
||||
: m_epsilon (epsilon), point_map(p_map)
|
||||
{
|
||||
CGAL_point_set_processing_precondition(epsilon > 0);
|
||||
}
|
||||
|
||||
std::size_t operator() (const Point_3& a) const
|
||||
{
|
||||
const Point& pa = get(point_pmap,a);
|
||||
const Point& pa = get(point_map,a);
|
||||
std::size_t result = boost::hash_value(round_epsilon(pa.x(), m_epsilon));
|
||||
boost::hash_combine(result, boost::hash_value(round_epsilon(pa.y(), m_epsilon)));
|
||||
boost::hash_combine(result, boost::hash_value(round_epsilon(pa.z(), m_epsilon)));
|
||||
|
|
@ -85,26 +89,26 @@ public:
|
|||
/// Utility class for grid_simplify_point_set(): Hash_epsilon_points_3
|
||||
/// defines a 3D point equality / 2 points are equal iff they belong
|
||||
/// to the same cell of a grid of cell size = epsilon.
|
||||
template <class Point_3, class PointPMap>
|
||||
template <class Point_3, class PointMap>
|
||||
struct Equal_epsilon_points_3
|
||||
{
|
||||
private:
|
||||
|
||||
const double m_epsilon;
|
||||
PointPMap point_pmap;
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
PointMap point_map;
|
||||
typedef typename boost::property_traits<PointMap>::value_type Point;
|
||||
public:
|
||||
|
||||
Equal_epsilon_points_3 (const double& epsilon, PointPMap p_pmap)
|
||||
: m_epsilon (epsilon), point_pmap(p_pmap)
|
||||
Equal_epsilon_points_3 (const double& epsilon, PointMap p_map)
|
||||
: m_epsilon (epsilon), point_map(p_map)
|
||||
{
|
||||
CGAL_point_set_processing_precondition(epsilon > 0);
|
||||
}
|
||||
|
||||
bool operator() (const Point_3& a, const Point_3& b) const
|
||||
{
|
||||
const Point& pa = get(point_pmap,a);
|
||||
const Point& pb = get(point_pmap,b);
|
||||
const Point& pa = get(point_map,a);
|
||||
const Point& pb = get(point_map,b);
|
||||
|
||||
double ra = round_epsilon(pa.x(), m_epsilon);
|
||||
double rb = round_epsilon(pb.x(), m_epsilon);
|
||||
|
|
@ -137,24 +141,24 @@ public:
|
|||
/// This class is a container sorted wrt points position
|
||||
/// => you should not modify directly the order or the position of points.
|
||||
|
||||
template <class Point_3, class PointPMap>
|
||||
template <class Point_3, class PointMap>
|
||||
class Epsilon_point_set_3
|
||||
: public cpp11::unordered_set<Point_3,
|
||||
internal::Hash_epsilon_points_3<Point_3, PointPMap>,
|
||||
internal::Equal_epsilon_points_3<Point_3, PointPMap> >
|
||||
internal::Hash_epsilon_points_3<Point_3, PointMap>,
|
||||
internal::Equal_epsilon_points_3<Point_3, PointMap> >
|
||||
{
|
||||
private:
|
||||
|
||||
// superclass
|
||||
typedef cpp11::unordered_set<Point_3,
|
||||
internal::Hash_epsilon_points_3<Point_3, PointPMap>,
|
||||
internal::Equal_epsilon_points_3<Point_3, PointPMap> > Base;
|
||||
internal::Hash_epsilon_points_3<Point_3, PointMap>,
|
||||
internal::Equal_epsilon_points_3<Point_3, PointMap> > Base;
|
||||
|
||||
public:
|
||||
|
||||
Epsilon_point_set_3 (double epsilon, PointPMap point_pmap)
|
||||
: Base(10, internal::Hash_epsilon_points_3<Point_3, PointPMap>(epsilon, point_pmap),
|
||||
internal::Equal_epsilon_points_3<Point_3, PointPMap>(epsilon, point_pmap))
|
||||
Epsilon_point_set_3 (double epsilon, PointMap point_map)
|
||||
: Base(10, internal::Hash_epsilon_points_3<Point_3, PointMap>(epsilon, point_map),
|
||||
internal::Equal_epsilon_points_3<Point_3, PointMap>(epsilon, point_map))
|
||||
{
|
||||
CGAL_point_set_processing_precondition(epsilon > 0);
|
||||
}
|
||||
|
|
@ -174,68 +178,112 @@ public:
|
|||
/// \pre `epsilon > 0`
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point to remove.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename Kernel>
|
||||
ForwardIterator grid_simplify_point_set(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
template <typename PointRange, typename NamedParameters>
|
||||
typename PointRange::iterator
|
||||
grid_simplify_point_set(
|
||||
PointRange& points,
|
||||
double epsilon, ///< tolerance value when merging 3D points.
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
|
||||
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());
|
||||
|
||||
// actual type of input points
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type Enriched_point;
|
||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Enriched_point;
|
||||
|
||||
CGAL_point_set_processing_precondition(epsilon > 0);
|
||||
|
||||
// Merges points which belong to the same cell of a grid of cell size = epsilon.
|
||||
// points_to_keep[] will contain 1 point per cell; the others will be in points_to_remove[].
|
||||
Epsilon_point_set_3<Enriched_point, PointPMap> points_to_keep(epsilon, point_pmap);
|
||||
Epsilon_point_set_3<Enriched_point, PointMap> points_to_keep(epsilon, point_map);
|
||||
std::deque<Enriched_point> points_to_remove;
|
||||
for (ForwardIterator it=first ; it != beyond ; it++)
|
||||
for (typename PointRange::iterator it = points.begin(); it != points.end(); it++)
|
||||
{
|
||||
std::pair<typename Epsilon_point_set_3<Enriched_point, PointPMap>::iterator,bool> result;
|
||||
result = points_to_keep.insert(*it);
|
||||
if (!result.second) // if not inserted
|
||||
points_to_remove.push_back(*it);
|
||||
std::pair<typename Epsilon_point_set_3<Enriched_point, PointMap>::iterator,bool> result;
|
||||
result = points_to_keep.insert(*it);
|
||||
if (!result.second) // if not inserted
|
||||
points_to_remove.push_back(*it);
|
||||
}
|
||||
|
||||
// Replaces `[first, beyond)` range by the content of points_to_keep, then points_to_remove.
|
||||
ForwardIterator first_point_to_remove =
|
||||
std::copy(points_to_keep.begin(), points_to_keep.end(), first);
|
||||
typename PointRange::iterator first_point_to_remove =
|
||||
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);
|
||||
|
||||
return first_point_to_remove;
|
||||
}
|
||||
|
||||
template <typename PointRange>
|
||||
typename PointRange::iterator
|
||||
grid_simplify_point_set(PointRange& points, double epsilon)
|
||||
{
|
||||
return grid_simplify_point_set (points, epsilon, CGAL::parameters::all_default());
|
||||
}
|
||||
|
||||
/// Merges points which belong to the same cell of a grid of cell size = `epsilon`.
|
||||
///
|
||||
/// This method modifies the order of input points so as to pack all remaining points first,
|
||||
/// and returns an iterator over the first point to remove (see erase-remove idiom).
|
||||
/// For this reason it should not be called on sorted containers.
|
||||
///
|
||||
/// \pre `epsilon > 0`
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point to remove.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ForwardIterator,
|
||||
typename PointMap,
|
||||
typename Kernel>
|
||||
ForwardIterator grid_simplify_point_set(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
double epsilon, ///< tolerance value when merging 3D points.
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("grid_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points = CGAL::make_range (first, beyond);
|
||||
return grid_simplify_point_set
|
||||
(points,
|
||||
epsilon,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
geom_traits (Kernel()));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the iterator type.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap
|
||||
typename PointMap
|
||||
>
|
||||
ForwardIterator
|
||||
grid_simplify_point_set(
|
||||
ForwardIterator first, ///< iterator over the first input point
|
||||
ForwardIterator beyond, ///< past-the-end iterator
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
double epsilon) ///< tolerance value when merging 3D points
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return grid_simplify_point_set(
|
||||
first,beyond,
|
||||
point_pmap,
|
||||
epsilon,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("grid_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points = CGAL::make_range (first, beyond);
|
||||
return grid_simplify_point_set
|
||||
(points,
|
||||
epsilon,
|
||||
CGAL::parameters::point_map (point_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
@ -249,11 +297,11 @@ grid_simplify_point_set(
|
|||
ForwardIterator beyond, ///< past-the-end iterator
|
||||
double epsilon) ///< tolerance value when merging 3D points
|
||||
{
|
||||
return grid_simplify_point_set(
|
||||
first,beyond,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
epsilon);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("grid_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points = CGAL::make_range (first, beyond);
|
||||
return grid_simplify_point_set
|
||||
(points,
|
||||
epsilon);
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@
|
|||
#include <CGAL/Default_diagonalize_traits.h>
|
||||
#include <CGAL/PCA_util.h>
|
||||
#include <CGAL/squared_distance_3.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -44,12 +48,12 @@ namespace CGAL {
|
|||
namespace internal {
|
||||
|
||||
template < typename InputIterator,
|
||||
typename PointPMap,
|
||||
typename PointMap,
|
||||
typename K >
|
||||
typename K::Point_3
|
||||
hsps_centroid(InputIterator begin,
|
||||
InputIterator end,
|
||||
PointPMap& point_pmap,
|
||||
PointMap& point_map,
|
||||
const K&)
|
||||
{
|
||||
typedef typename K::Point_3 Point;
|
||||
|
|
@ -61,8 +65,8 @@ namespace CGAL {
|
|||
unsigned int nb_pts = 0;
|
||||
while(begin != end)
|
||||
{
|
||||
typename boost::property_traits<PointPMap>::reference point =
|
||||
get(point_pmap, *begin);
|
||||
typename boost::property_traits<PointMap>::reference point =
|
||||
get(point_map, *begin);
|
||||
x += point.x (); y += point.y (); z += point.z ();
|
||||
++ nb_pts;
|
||||
++ begin;
|
||||
|
|
@ -71,13 +75,13 @@ namespace CGAL {
|
|||
}
|
||||
|
||||
template < typename Input_type,
|
||||
typename PointPMap,
|
||||
typename PointMap,
|
||||
typename K >
|
||||
void
|
||||
hsc_terminate_cluster (std::list<Input_type>& cluster,
|
||||
std::list<Input_type>& points_to_keep,
|
||||
std::list<Input_type>& points_to_remove,
|
||||
PointPMap& point_pmap,
|
||||
PointMap& point_map,
|
||||
const typename K::Point_3& centroid,
|
||||
const K&)
|
||||
{
|
||||
|
|
@ -89,7 +93,7 @@ namespace CGAL {
|
|||
typename std::list<Input_type>::iterator point_min;
|
||||
for (Iterator it = cluster.begin (); it != cluster.end (); ++ it)
|
||||
{
|
||||
FT dist = CGAL::squared_distance (get(point_pmap, *it), centroid);
|
||||
FT dist = CGAL::squared_distance (get(point_map, *it), centroid);
|
||||
if (dist < dist_min)
|
||||
{
|
||||
dist_min = dist;
|
||||
|
|
@ -121,7 +125,7 @@ namespace CGAL {
|
|||
/// \pre `size > 0`
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam DiagonalizeTraits is a model of `DiagonalizeTraits`. It
|
||||
/// can be omitted: if Eigen 3 (or greater) is available and
|
||||
|
|
@ -129,29 +133,35 @@ namespace CGAL {
|
|||
/// `Eigen_diagonalize_traits` is provided. Otherwise, the internal
|
||||
/// implementation `Internal_diagonalize_traits` is used.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point to remove.
|
||||
|
||||
|
||||
// This variant requires all parameters.
|
||||
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename DiagonalizeTraits,
|
||||
typename Kernel>
|
||||
ForwardIterator hierarchy_simplify_point_set (ForwardIterator begin,
|
||||
ForwardIterator end,
|
||||
PointPMap point_pmap,
|
||||
const unsigned int size,
|
||||
const double var_max,
|
||||
const DiagonalizeTraits&,
|
||||
const Kernel&)
|
||||
template <typename PointRange,
|
||||
typename NamedParameters>
|
||||
typename PointRange::iterator
|
||||
hierarchy_simplify_point_set (PointRange& points,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type Input_type;
|
||||
typedef typename Kernel::FT FT;
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
using boost::choose_param;
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
typedef typename GetDiagonalizeTraits<NamedParameters, double, 3>::type DiagonalizeTraits;
|
||||
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
typedef typename Kernel::Vector_3 Vector;
|
||||
typedef typename Kernel::FT FT;
|
||||
|
||||
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);
|
||||
double var_max = choose_param(get_param(np, internal_np::maximum_variation), 1./3.);
|
||||
|
||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Input_type;
|
||||
|
||||
// We define a cluster as a point set + its centroid (useful for
|
||||
// faster computations of centroids - to be implemented)
|
||||
|
|
@ -160,17 +170,17 @@ namespace CGAL {
|
|||
std::list<cluster> clusters_stack;
|
||||
typedef typename std::list<cluster>::iterator cluster_iterator;
|
||||
|
||||
CGAL_precondition (begin != end);
|
||||
CGAL_precondition (points.begin() != points.end());
|
||||
CGAL_point_set_processing_precondition (size > 0);
|
||||
CGAL_point_set_processing_precondition (var_max > 0.0);
|
||||
|
||||
// The first cluster is the whole input point set
|
||||
clusters_stack.push_front (cluster (std::list<Input_type>(), Point (0., 0., 0.)));
|
||||
std::copy (begin, end, std::back_inserter (clusters_stack.front ().first));
|
||||
std::copy (points.begin(), points.end(), std::back_inserter (clusters_stack.front ().first));
|
||||
|
||||
clusters_stack.front ().second = internal::hsps_centroid (clusters_stack.front ().first.begin (),
|
||||
clusters_stack.front ().first.end (),
|
||||
point_pmap, Kernel());
|
||||
clusters_stack.front ().first.end (),
|
||||
point_map, Kernel());
|
||||
|
||||
std::list<Input_type> points_to_keep;
|
||||
std::list<Input_type> points_to_remove;
|
||||
|
|
@ -195,7 +205,7 @@ namespace CGAL {
|
|||
for (typename std::list<Input_type>::iterator it = current_cluster->first.begin ();
|
||||
it != current_cluster->first.end (); ++ it)
|
||||
{
|
||||
const Point& point = get(point_pmap, *it);
|
||||
const Point& point = get(point_map, *it);
|
||||
Vector d = point - current_cluster->second;
|
||||
covariance[0] += d.x () * d.x ();
|
||||
covariance[1] += d.x () * d.y ();
|
||||
|
|
@ -234,7 +244,7 @@ namespace CGAL {
|
|||
while (it != current_cluster->first.end ())
|
||||
{
|
||||
typename std::list<Input_type>::iterator current = it ++;
|
||||
const Point& point = get(point_pmap, *current);
|
||||
const Point& point = get(point_map, *current);
|
||||
|
||||
// Test if point is on negative side of plane and
|
||||
// transfer it to the negative_side cluster if it is
|
||||
|
|
@ -254,12 +264,12 @@ namespace CGAL {
|
|||
// Compute the centroid
|
||||
nonempty->second = internal::hsps_centroid (nonempty->first.begin (),
|
||||
nonempty->first.end (),
|
||||
point_pmap, Kernel());
|
||||
point_map, Kernel());
|
||||
|
||||
internal::hsc_terminate_cluster (nonempty->first,
|
||||
points_to_keep,
|
||||
points_to_remove,
|
||||
point_pmap,
|
||||
point_map,
|
||||
nonempty->second,
|
||||
Kernel ());
|
||||
clusters_stack.pop_front ();
|
||||
|
|
@ -273,7 +283,7 @@ namespace CGAL {
|
|||
// Compute the first centroid
|
||||
current_cluster->second = internal::hsps_centroid (current_cluster->first.begin (),
|
||||
current_cluster->first.end (),
|
||||
point_pmap, Kernel());
|
||||
point_map, Kernel());
|
||||
|
||||
// The second centroid can be computed with the first and
|
||||
// the old ones :
|
||||
|
|
@ -297,14 +307,14 @@ namespace CGAL {
|
|||
internal::hsc_terminate_cluster (current_cluster->first,
|
||||
points_to_keep,
|
||||
points_to_remove,
|
||||
point_pmap,
|
||||
point_map,
|
||||
current_cluster->second,
|
||||
Kernel ());
|
||||
clusters_stack.pop_front ();
|
||||
}
|
||||
}
|
||||
ForwardIterator first_point_to_remove =
|
||||
std::copy (points_to_keep.begin(), points_to_keep.end(), begin);
|
||||
typename PointRange::iterator first_point_to_remove =
|
||||
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);
|
||||
|
||||
return first_point_to_remove;
|
||||
|
|
@ -312,40 +322,96 @@ namespace CGAL {
|
|||
}
|
||||
/// @endcond
|
||||
|
||||
/// Recursively split the point set in smaller clusters until the
|
||||
/// clusters have less than `size` elements or until their variation
|
||||
/// factor is below `var_max`.
|
||||
///
|
||||
/// This method modifies the order of input points so as to pack all remaining points first,
|
||||
/// and returns an iterator over the first point to remove (see erase-remove idiom).
|
||||
/// For this reason it should not be called on sorted containers.
|
||||
///
|
||||
/// \pre `0 < var_max < 1/3`
|
||||
/// \pre `size > 0`
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam DiagonalizeTraits is a model of `DiagonalizeTraits`. It
|
||||
/// can be omitted: if Eigen 3 (or greater) is available and
|
||||
/// `CGAL_EIGEN3_ENABLED` is defined then an overload using
|
||||
/// `Eigen_diagonalize_traits` is provided. Otherwise, the internal
|
||||
/// implementation `Internal_diagonalize_traits` is used.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point to remove.
|
||||
|
||||
|
||||
// This variant requires all parameters.
|
||||
|
||||
template <typename ForwardIterator,
|
||||
typename PointMap,
|
||||
typename DiagonalizeTraits,
|
||||
typename Kernel>
|
||||
ForwardIterator hierarchy_simplify_point_set (ForwardIterator begin,
|
||||
ForwardIterator end,
|
||||
PointMap point_map,
|
||||
const unsigned int size,
|
||||
const double var_max,
|
||||
const DiagonalizeTraits&,
|
||||
const Kernel&)
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("hierarchy_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (begin, end);
|
||||
return hierarchy_simplify_point_set
|
||||
(points,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
size (size).
|
||||
maximum_variation (var_max).
|
||||
diagonalize_traits (DiagonalizeTraits()).
|
||||
geom_traits(Kernel()));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the iterator type.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename PointMap,
|
||||
typename DiagonalizeTraits>
|
||||
ForwardIterator hierarchy_simplify_point_set (ForwardIterator begin,
|
||||
ForwardIterator end,
|
||||
PointPMap point_pmap,
|
||||
PointMap point_map,
|
||||
const unsigned int size,
|
||||
const double var_max,
|
||||
const DiagonalizeTraits& diagonalize_traits)
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return hierarchy_simplify_point_set (begin, end, point_pmap, size, var_max,
|
||||
diagonalize_traits, Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("hierarchy_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (begin, end);
|
||||
return hierarchy_simplify_point_set
|
||||
(points,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
size (size).
|
||||
maximum_variation (var_max).
|
||||
diagonalize_traits (diagonalize_traits));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant uses default diagonalize traits
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap >
|
||||
typename PointMap >
|
||||
ForwardIterator hierarchy_simplify_point_set (ForwardIterator begin,
|
||||
ForwardIterator end,
|
||||
PointPMap point_pmap,
|
||||
PointMap point_map,
|
||||
const unsigned int size,
|
||||
const double var_max)
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return hierarchy_simplify_point_set (begin, end, point_pmap, size, var_max,
|
||||
Default_diagonalize_traits<double, 3> (), Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("hierarchy_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (begin, end);
|
||||
return hierarchy_simplify_point_set
|
||||
(points,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
size (size).
|
||||
maximum_variation (var_max));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
@ -357,10 +423,12 @@ namespace CGAL {
|
|||
const unsigned int size = 10,
|
||||
const double var_max = 0.333)
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("hierarchy_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (begin, end);
|
||||
return hierarchy_simplify_point_set
|
||||
(begin, end,
|
||||
make_identity_property_map (typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
size, var_max);
|
||||
(points,
|
||||
CGAL::parameters::size (size).
|
||||
maximum_variation (var_max));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
#include <CGAL/point_set_processing_assertions.h>
|
||||
#include <CGAL/Memory_sizer.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
|
||||
|
|
@ -155,43 +158,54 @@ jet_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute
|
|||
///
|
||||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam Concurrency_tag enables sequential versus parallel algorithm.
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam ForwardIterator iterator model of the concept of the same name over input points and able to store output normals.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalPMap is a model of `WritablePropertyMap` with value type `Vector_3<Kernel>`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with value type `Vector_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
/// @tparam SvdTraits template parameter for the class `Monge_via_jet_fitting` that
|
||||
/// can be ommited under conditions described in the documentation of `Monge_via_jet_fitting`.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename Concurrency_tag,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename Kernel,
|
||||
typename SvdTraits
|
||||
template <typename ConcurrencyTag,
|
||||
typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
void
|
||||
jet_estimate_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
PointRange& points,
|
||||
unsigned int k, ///< number of neighbors.
|
||||
const Kernel& /*kernel*/, ///< geometric traits.
|
||||
unsigned int degree_fitting = 2) ///< fitting degree
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
|
||||
CGAL_TRACE("Calls jet_estimate_normals()\n");
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::type NormalMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
typedef typename GetSvdTraits<NamedParameters>::type SvdTraits;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<NormalMap,
|
||||
Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::NoMap>::value),
|
||||
"Error: no normal map");
|
||||
CGAL_static_assertion_msg(!(boost::is_same<SvdTraits,
|
||||
GetSvdTraits<NamedParameters>::NoMap>::value),
|
||||
"Error: no SVD traits");
|
||||
|
||||
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());
|
||||
unsigned int degree_fitting = choose_param(get_param(np, internal_np::degree_fitting), 2);
|
||||
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
|
||||
// Input points types
|
||||
typedef typename boost::property_traits<NormalPMap>::value_type Vector;
|
||||
typedef typename boost::property_traits<NormalMap>::value_type Vector;
|
||||
|
||||
// types for K nearest neighbors search structure
|
||||
typedef typename CGAL::Search_traits_3<Kernel> Tree_traits;
|
||||
|
|
@ -201,7 +215,7 @@ jet_estimate_normals(
|
|||
// precondition: at least one element in the container.
|
||||
// to fix: should have at least three distinct points
|
||||
// but this is costly to check
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
CGAL_point_set_processing_precondition(points.begin() != points.end());
|
||||
|
||||
// precondition: at least 2 nearest neighbors
|
||||
CGAL_point_set_processing_precondition(k >= 2);
|
||||
|
|
@ -209,13 +223,13 @@ jet_estimate_normals(
|
|||
std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20);
|
||||
CGAL_TRACE(" Creates KD-tree\n");
|
||||
|
||||
ForwardIterator it;
|
||||
typename PointRange::iterator it;
|
||||
|
||||
// Instanciate a KD-tree search.
|
||||
// Note: We have to convert each input iterator to Point_3.
|
||||
std::vector<Point> kd_tree_points;
|
||||
for(it = first; it != beyond; it++)
|
||||
kd_tree_points.push_back(get(point_pmap, *it));
|
||||
for(it = points.begin(); it != points.end(); it++)
|
||||
kd_tree_points.push_back(get(point_map, *it));
|
||||
Tree tree(kd_tree_points.begin(), kd_tree_points.end());
|
||||
|
||||
memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20);
|
||||
|
|
@ -224,31 +238,31 @@ jet_estimate_normals(
|
|||
// iterate over input points, compute and output normal
|
||||
// vectors (already normalized)
|
||||
#ifndef CGAL_LINKED_WITH_TBB
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<Concurrency_tag, Parallel_tag>::value),
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||
"Parallel_tag is enabled but TBB is unavailable.");
|
||||
#else
|
||||
if (boost::is_convertible<Concurrency_tag,Parallel_tag>::value)
|
||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||
{
|
||||
std::vector<Vector> normals (kd_tree_points.size ());
|
||||
CGAL::internal::Jet_estimate_normals<Kernel, SvdTraits, Tree>
|
||||
f (tree, k, kd_tree_points, degree_fitting, normals);
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
||||
unsigned int i = 0;
|
||||
for(it = first; it != beyond; ++ it, ++ i)
|
||||
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
||||
{
|
||||
put (normal_pmap, *it, normals[i]);
|
||||
put (normal_map, *it, normals[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for(it = first; it != beyond; it++)
|
||||
for(it = points.begin(); it != points.end(); it++)
|
||||
{
|
||||
Vector normal = internal::jet_estimate_normal<Kernel,SvdTraits,Tree>(
|
||||
get(point_pmap,*it),
|
||||
get(point_map,*it),
|
||||
tree, k, degree_fitting);
|
||||
|
||||
put(normal_pmap, *it, normal); // normal_pmap[it] = normal
|
||||
put(normal_map, *it, normal); // normal_map[it] = normal
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -258,20 +272,68 @@ jet_estimate_normals(
|
|||
CGAL_TRACE("End of jet_estimate_normals()\n");
|
||||
}
|
||||
|
||||
/// \ingroup PkgPointSetProcessingAlgorithms
|
||||
/// Estimates normal directions of the `[first, beyond)` range of points
|
||||
/// using jet fitting on the k nearest neighbors.
|
||||
/// The output normals are randomly oriented.
|
||||
///
|
||||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam ForwardIterator iterator model of the concept of the same name over input points and able to store output normals.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with value type `Vector_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
/// @tparam SvdTraits template parameter for the class `Monge_via_jet_fitting` that
|
||||
/// can be ommited under conditions described in the documentation of `Monge_via_jet_fitting`.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename Kernel,
|
||||
typename SvdTraits
|
||||
>
|
||||
void
|
||||
jet_estimate_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k, ///< number of neighbors.
|
||||
const Kernel& /*kernel*/, ///< geometric traits.
|
||||
unsigned int degree_fitting = 2) ///< fitting degree
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("jet_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return jet_estimate_normals<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
degree_fitting (degree_fitting).
|
||||
geom_traits(Kernel()));
|
||||
}
|
||||
|
||||
#if defined(CGAL_EIGEN3_ENABLED) || defined(CGAL_LAPACK_ENABLED)
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename Kernel
|
||||
>
|
||||
void
|
||||
jet_estimate_normals(
|
||||
ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
PointPMap point_pmap,
|
||||
NormalPMap normal_pmap,
|
||||
PointMap point_map,
|
||||
NormalMap normal_map,
|
||||
unsigned int k,
|
||||
const Kernel& kernel,
|
||||
unsigned int degree_fitting = 2)
|
||||
|
|
@ -281,59 +343,67 @@ jet_estimate_normals(
|
|||
#else
|
||||
typedef Lapack_svd SvdTraits;
|
||||
#endif
|
||||
jet_estimate_normals<Concurrency_tag,ForwardIterator,PointPMap,NormalPMap,Kernel,SvdTraits>(
|
||||
first, beyond, point_pmap, normal_pmap, k, kernel, degree_fitting);
|
||||
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("jet_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return jet_estimate_normals<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
degree_fitting (degree_fitting).
|
||||
svd_traits (SvdTraits()).
|
||||
geom_traits(kernel));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap
|
||||
typename PointMap,
|
||||
typename NormalMap
|
||||
>
|
||||
void
|
||||
jet_estimate_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k, ///< number of neighbors.
|
||||
unsigned int degree_fitting = 2)
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
jet_estimate_normals<Concurrency_tag>(
|
||||
first,beyond,
|
||||
point_pmap,
|
||||
normal_pmap,
|
||||
k,
|
||||
Kernel(),
|
||||
degree_fitting);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("jet_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return jet_estimate_normals<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
degree_fitting (degree_fitting));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant creates a default point property map = Identity_property_map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename NormalPMap
|
||||
typename NormalMap
|
||||
>
|
||||
void
|
||||
jet_estimate_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k, ///< number of neighbors.
|
||||
unsigned int degree_fitting = 2)
|
||||
{
|
||||
jet_estimate_normals<Concurrency_tag>(
|
||||
first,beyond,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
normal_pmap,
|
||||
k,
|
||||
degree_fitting);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("jet_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return jet_estimate_normals<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::normal_map (normal_map).
|
||||
degree_fitting (degree_fitting));
|
||||
}
|
||||
/// @endcond
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/point_set_processing_assertions.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
|
||||
|
|
@ -159,35 +162,43 @@ jet_smooth_point(
|
|||
///
|
||||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam Concurrency_tag enables sequential versus parallel algorithm.
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadWritePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadWritePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `InputIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
/// @tparam SvdTraits template parameter for the class `Monge_via_jet_fitting` that
|
||||
/// can be ommited under conditions described in the documentation of `Monge_via_jet_fitting`.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename Concurrency_tag,
|
||||
typename InputIterator,
|
||||
typename PointPMap,
|
||||
typename Kernel,
|
||||
typename SvdTraits
|
||||
template <typename ConcurrencyTag,
|
||||
typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
void
|
||||
jet_smooth_point_set(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of InputIterator -> Point_3.
|
||||
PointRange& points,
|
||||
unsigned int k, ///< number of neighbors.
|
||||
const Kernel& /*kernel*/, ///< geometric traits.
|
||||
unsigned int degree_fitting = 2, ///< fitting degree
|
||||
unsigned int degree_monge = 2) ///< Monge degree
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
typedef typename GetSvdTraits<NamedParameters>::type SvdTraits;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<SvdTraits,
|
||||
GetSvdTraits<NamedParameters>::NoMap>::value),
|
||||
"Error: no SVD traits");
|
||||
|
||||
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_monge = choose_param(get_param(np, internal_np::degree_monge), 2);
|
||||
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
|
||||
// types for K nearest neighbors search structure
|
||||
|
|
@ -198,28 +209,28 @@ jet_smooth_point_set(
|
|||
// precondition: at least one element in the container.
|
||||
// to fix: should have at least three distinct points
|
||||
// but this is costly to check
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
CGAL_point_set_processing_precondition(points.begin() != points.end());
|
||||
|
||||
// precondition: at least 2 nearest neighbors
|
||||
CGAL_point_set_processing_precondition(k >= 2);
|
||||
|
||||
InputIterator it;
|
||||
typename PointRange::iterator it;
|
||||
|
||||
// Instanciate a KD-tree search.
|
||||
// Note: We have to convert each input iterator to Point_3.
|
||||
std::vector<Point> kd_tree_points;
|
||||
for(it = first; it != beyond; it++)
|
||||
kd_tree_points.push_back(get(point_pmap, *it));
|
||||
for(it = points.begin(); it != points.end(); it++)
|
||||
kd_tree_points.push_back(get(point_map, *it));
|
||||
Tree tree(kd_tree_points.begin(), kd_tree_points.end());
|
||||
|
||||
// Iterates over input points and mutates them.
|
||||
// Implementation note: the cast to Point& allows to modify only the point's position.
|
||||
|
||||
#ifndef CGAL_LINKED_WITH_TBB
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<Concurrency_tag, Parallel_tag>::value),
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||
"Parallel_tag is enabled but TBB is unavailable.");
|
||||
#else
|
||||
if (boost::is_convertible<Concurrency_tag,Parallel_tag>::value)
|
||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||
{
|
||||
std::vector<Point> mutated_points (kd_tree_points.size ());
|
||||
CGAL::internal::Jet_smooth_pwns<Kernel, SvdTraits, Tree>
|
||||
|
|
@ -227,38 +238,94 @@ jet_smooth_point_set(
|
|||
mutated_points);
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
||||
unsigned int i = 0;
|
||||
for(it = first; it != beyond; ++ it, ++ i)
|
||||
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
||||
{
|
||||
put(point_pmap, *it, mutated_points[i]);
|
||||
put(point_map, *it, mutated_points[i]);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for(it = first; it != beyond; it++)
|
||||
for(it = points.begin(); it != points.end(); it++)
|
||||
{
|
||||
const typename boost::property_traits<PointPMap>::reference p = get(point_pmap, *it);
|
||||
put(point_pmap, *it ,
|
||||
const typename boost::property_traits<PointMap>::reference p = get(point_map, *it);
|
||||
put(point_map, *it ,
|
||||
internal::jet_smooth_point<Kernel, SvdTraits>(
|
||||
p,tree,k,degree_fitting,degree_monge) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ConcurrencyTag,
|
||||
typename PointRange>
|
||||
void
|
||||
jet_smooth_point_set(
|
||||
PointRange& points,
|
||||
unsigned int k) ///< number of neighbors.
|
||||
{
|
||||
jet_smooth_point_set<ConcurrencyTag> (points, k, CGAL::parameters::all_default());
|
||||
}
|
||||
|
||||
|
||||
/// Smoothes the `[first, beyond)` range of points using jet fitting on the k
|
||||
/// nearest neighbors and reprojection onto the jet.
|
||||
/// As this method relocates the points, it
|
||||
/// should not be called on containers sorted w.r.t. point locations.
|
||||
///
|
||||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadWritePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `InputIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
/// @tparam SvdTraits template parameter for the class `Monge_via_jet_fitting` that
|
||||
/// can be ommited under conditions described in the documentation of `Monge_via_jet_fitting`.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ConcurrencyTag,
|
||||
typename InputIterator,
|
||||
typename PointMap,
|
||||
typename Kernel,
|
||||
typename SvdTraits
|
||||
>
|
||||
void
|
||||
jet_smooth_point_set(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointMap point_map, ///< property map: value_type of InputIterator -> Point_3.
|
||||
unsigned int k, ///< number of neighbors.
|
||||
const Kernel& /*kernel*/, ///< geometric traits.
|
||||
unsigned int degree_fitting = 2, ///< fitting degree
|
||||
unsigned int degree_monge = 2) ///< Monge degree
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("jet_smooth_point_set()");
|
||||
CGAL::Iterator_range<InputIterator> points (first, beyond);
|
||||
return jet_smooth_point_set<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
degree_fitting (degree_fitting).
|
||||
degree_monge (degree_monge).
|
||||
geom_traits(Kernel()));
|
||||
}
|
||||
|
||||
#if defined(CGAL_EIGEN3_ENABLED) || defined(CGAL_LAPACK_ENABLED)
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename InputIterator,
|
||||
typename PointPMap,
|
||||
typename PointMap,
|
||||
typename Kernel
|
||||
>
|
||||
void
|
||||
jet_smooth_point_set(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of InputIterator -> Point_3.
|
||||
PointMap point_map, ///< property map: value_type of InputIterator -> Point_3.
|
||||
unsigned int k, ///< number of neighbors.
|
||||
const Kernel& kernel, ///< geometric traits.
|
||||
unsigned int degree_fitting = 2, ///< fitting degree
|
||||
|
|
@ -269,39 +336,47 @@ jet_smooth_point_set(
|
|||
#else
|
||||
typedef Lapack_svd SvdTraits;
|
||||
#endif
|
||||
jet_smooth_point_set<Concurrency_tag, InputIterator, PointPMap, Kernel, SvdTraits>(
|
||||
first, beyond, point_pmap, k, kernel, degree_fitting, degree_monge);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("jet_smooth_point_set()");
|
||||
CGAL::Iterator_range<InputIterator> points (first, beyond);
|
||||
return jet_smooth_point_set<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
degree_fitting (degree_fitting).
|
||||
degree_monge (degree_monge).
|
||||
svd_traits (SvdTraits()),
|
||||
geom_traits(kernel));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename InputIterator,
|
||||
typename PointPMap
|
||||
typename PointMap
|
||||
>
|
||||
void
|
||||
jet_smooth_point_set(
|
||||
InputIterator first, ///< iterator over the first input point
|
||||
InputIterator beyond, ///< past-the-end iterator
|
||||
PointPMap point_pmap, ///< property map: value_type of InputIterator -> Point_3
|
||||
PointMap point_map, ///< property map: value_type of InputIterator -> Point_3
|
||||
unsigned int k, ///< number of neighbors.
|
||||
const unsigned int degree_fitting = 2,
|
||||
const unsigned int degree_monge = 2)
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
jet_smooth_point_set<Concurrency_tag>(
|
||||
first,beyond,
|
||||
point_pmap,
|
||||
k,
|
||||
Kernel(),
|
||||
degree_fitting,degree_monge);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("jet_smooth_point_set()");
|
||||
CGAL::Iterator_range<InputIterator> points (first, beyond);
|
||||
return jet_smooth_point_set<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
degree_fitting (degree_fitting).
|
||||
degree_monge (degree_monge));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant creates a default point property map = Identity_property_map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename InputIterator
|
||||
>
|
||||
void
|
||||
|
|
@ -312,12 +387,13 @@ jet_smooth_point_set(
|
|||
const unsigned int degree_fitting = 2,
|
||||
const unsigned int degree_monge = 2)
|
||||
{
|
||||
jet_smooth_point_set<Concurrency_tag>(
|
||||
first,beyond,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<InputIterator>::value_type()),
|
||||
k,
|
||||
degree_fitting,degree_monge);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("jet_smooth_point_set()");
|
||||
CGAL::Iterator_range<InputIterator> points (first, beyond);
|
||||
return jet_smooth_point_set<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::degree_fitting (degree_fitting).
|
||||
degree_monge (degree_monge));
|
||||
}
|
||||
/// @endcond
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@
|
|||
#include <CGAL/point_set_processing_assertions.h>
|
||||
#include <CGAL/use.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <climits>
|
||||
|
|
@ -102,7 +105,7 @@ struct MST_graph_vertex_properties {
|
|||
bool is_oriented; ///< Is input point's normal oriented?
|
||||
};
|
||||
template <typename ForwardIterator, ///< Input point iterator
|
||||
typename NormalPMap, ///< property map: value_type of ForwardIterator -> Normal
|
||||
typename NormalMap, ///< property map: value_type of ForwardIterator -> Normal
|
||||
typename Kernel ///< Geometric traits class
|
||||
>
|
||||
class MST_graph
|
||||
|
|
@ -111,10 +114,10 @@ class MST_graph
|
|||
MST_graph_vertex_properties<ForwardIterator> >
|
||||
{
|
||||
public:
|
||||
MST_graph(NormalPMap normal_pmap) : m_normal_pmap(normal_pmap) {}
|
||||
MST_graph(NormalMap normal_map) : m_normal_map(normal_map) {}
|
||||
|
||||
// Public data
|
||||
const NormalPMap m_normal_pmap;
|
||||
const NormalMap m_normal_map;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -130,17 +133,17 @@ public:
|
|||
/// \pre `0 < angle_max <= PI/2`
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam NormalPMap is a model of `ReadWritePropertyMap`.
|
||||
/// @tparam NormalMap is a model of `ReadWritePropertyMap`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
|
||||
template <typename ForwardIterator, ///< Input point iterator
|
||||
typename NormalPMap, ///< property map: value_type of ForwardIterator -> Normal
|
||||
typename NormalMap, ///< property map: value_type of ForwardIterator -> Normal
|
||||
typename Kernel
|
||||
>
|
||||
struct Propagate_normal_orientation
|
||||
: public boost::base_visitor< Propagate_normal_orientation<ForwardIterator, NormalPMap, Kernel> >
|
||||
: public boost::base_visitor< Propagate_normal_orientation<ForwardIterator, NormalMap, Kernel> >
|
||||
{
|
||||
typedef internal::MST_graph<ForwardIterator, NormalPMap, Kernel> MST_graph;
|
||||
typedef internal::MST_graph<ForwardIterator, NormalMap, Kernel> MST_graph;
|
||||
typedef boost::on_examine_edge event_filter;
|
||||
|
||||
Propagate_normal_orientation(double angle_max = CGAL_PI/2.) ///< max angle to propagate the normal orientation (radians)
|
||||
|
|
@ -153,16 +156,16 @@ struct Propagate_normal_orientation
|
|||
template <class Edge>
|
||||
void operator()(Edge& edge, const MST_graph& mst_graph)
|
||||
{
|
||||
typedef typename boost::property_traits<NormalPMap>::reference Vector_ref;
|
||||
typedef typename boost::property_traits<NormalMap>::reference Vector_ref;
|
||||
typedef typename MST_graph::vertex_descriptor vertex_descriptor;
|
||||
|
||||
// Gets source normal
|
||||
vertex_descriptor source_vertex = source(edge, mst_graph);
|
||||
Vector_ref source_normal = get(mst_graph.m_normal_pmap, *(mst_graph[source_vertex].input_point) );
|
||||
Vector_ref source_normal = get(mst_graph.m_normal_map, *(mst_graph[source_vertex].input_point) );
|
||||
const bool source_normal_is_oriented = mst_graph[source_vertex].is_oriented;
|
||||
// Gets target normal
|
||||
vertex_descriptor target_vertex = target(edge, mst_graph);
|
||||
Vector_ref target_normal = get( mst_graph.m_normal_pmap, *(mst_graph[target_vertex].input_point) );
|
||||
Vector_ref target_normal = get( mst_graph.m_normal_map, *(mst_graph[target_vertex].input_point) );
|
||||
bool& target_normal_is_oriented = ((MST_graph&)mst_graph)[target_vertex].is_oriented;
|
||||
if ( ! target_normal_is_oriented )
|
||||
{
|
||||
|
|
@ -171,7 +174,7 @@ struct Propagate_normal_orientation
|
|||
double normals_dot = source_normal * target_normal;
|
||||
if (normals_dot < 0)
|
||||
{
|
||||
put( mst_graph.m_normal_pmap, *(mst_graph[target_vertex].input_point), -target_normal );
|
||||
put( mst_graph.m_normal_map, *(mst_graph[target_vertex].input_point), -target_normal );
|
||||
}
|
||||
|
||||
// Is orientation robust?
|
||||
|
|
@ -190,29 +193,29 @@ private:
|
|||
/// Orients the normal of the point with maximum Z towards +Z axis.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = Point_3<Kernel>.
|
||||
/// @tparam NormalPMap is a model of `ReadWritePropertyMap` with a value_type = Vector_3<Kernel>.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = Point_3<Kernel>.
|
||||
/// @tparam NormalMap is a model of `ReadWritePropertyMap` with a value_type = Vector_3<Kernel>.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
///
|
||||
/// @return iterator over the top point.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename Kernel
|
||||
>
|
||||
ForwardIterator
|
||||
mst_find_source(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_TRACE(" mst_find_source()\n");
|
||||
|
||||
// Input points types
|
||||
typedef typename boost::property_traits<NormalPMap>::value_type Vector;
|
||||
typedef typename boost::property_traits<NormalPMap>::reference Vector_ref;
|
||||
typedef typename boost::property_traits<NormalMap>::value_type Vector;
|
||||
typedef typename boost::property_traits<NormalMap>::reference Vector_ref;
|
||||
|
||||
// Precondition: at least one element in the container
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
|
|
@ -222,19 +225,19 @@ mst_find_source(
|
|||
for (ForwardIterator v = ++first; v != beyond; v++)
|
||||
{
|
||||
|
||||
double top_z = get(point_pmap,*top_point).z(); // top_point's Z coordinate
|
||||
double z = get(point_pmap,*v).z();
|
||||
double top_z = get(point_map,*top_point).z(); // top_point's Z coordinate
|
||||
double z = get(point_map,*v).z();
|
||||
|
||||
if (top_z < z)
|
||||
top_point = v;
|
||||
}
|
||||
|
||||
// Orients its normal towards +Z axis
|
||||
Vector_ref normal = get(normal_pmap,*top_point);
|
||||
Vector_ref normal = get(normal_map,*top_point);
|
||||
const Vector Z(0, 0, 1);
|
||||
if (Z * normal < 0) {
|
||||
CGAL_TRACE(" Flip top point normal\n");
|
||||
put(normal_pmap,*top_point, -normal);
|
||||
put(normal_map,*top_point, -normal);
|
||||
}
|
||||
|
||||
return top_point;
|
||||
|
|
@ -250,31 +253,31 @@ mst_find_source(
|
|||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam IndexPMap is a model of `ReadablePropertyMap` with an integral value_type.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = Point_3<Kernel>.
|
||||
/// @tparam NormalPMap is a model of `ReadWritePropertyMap` with a value_type = Vector_3<Kernel>.
|
||||
/// @tparam IndexMap is a model of `ReadablePropertyMap` with an integral value_type.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = Point_3<Kernel>.
|
||||
/// @tparam NormalMap is a model of `ReadWritePropertyMap` with a value_type = Vector_3<Kernel>.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
///
|
||||
/// @return the Riemannian graph
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename IndexPMap,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename IndexMap,
|
||||
typename Kernel
|
||||
>
|
||||
Riemannian_graph<ForwardIterator>
|
||||
create_riemannian_graph(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3
|
||||
IndexPMap index_pmap, ///< property map ForwardIterator -> index
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3
|
||||
IndexMap index_map, ///< property map ForwardIterator -> index
|
||||
unsigned int k, ///< number of neighbors
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
// Input points types
|
||||
typedef typename boost::property_traits<PointPMap>::reference Point_ref;
|
||||
typedef typename boost::property_traits<NormalPMap>::reference Vector_ref;
|
||||
typedef typename boost::property_traits<PointMap>::reference Point_ref;
|
||||
typedef typename boost::property_traits<NormalMap>::reference Vector_ref;
|
||||
|
||||
// Types for K nearest neighbors search structure
|
||||
typedef Point_vertex_handle_3<ForwardIterator> Point_vertex_handle_3;
|
||||
|
|
@ -307,7 +310,7 @@ create_riemannian_graph(
|
|||
for (ForwardIterator it = first; it != beyond; it++)
|
||||
{
|
||||
|
||||
Point_ref point = get(point_pmap, *it);
|
||||
Point_ref point = get(point_map, *it);
|
||||
Point_vertex_handle_3 point_wrapper(point.x(), point.y(), point.z(), it);
|
||||
kd_tree_points.push_back(point_wrapper);
|
||||
}
|
||||
|
|
@ -330,7 +333,7 @@ create_riemannian_graph(
|
|||
for (ForwardIterator it = first; it != beyond; it++)
|
||||
{
|
||||
typename Riemannian_graph::vertex_descriptor v = add_vertex(riemannian_graph);
|
||||
CGAL_point_set_processing_assertion(v == get(index_pmap,it));
|
||||
CGAL_point_set_processing_assertion(v == get(index_map,it));
|
||||
riemannian_graph[v].input_point = it;
|
||||
}
|
||||
//
|
||||
|
|
@ -338,15 +341,15 @@ create_riemannian_graph(
|
|||
Riemannian_graph_weight_map riemannian_graph_weight_map = get(boost::edge_weight, riemannian_graph);
|
||||
for (ForwardIterator it = first; it != beyond; it++)
|
||||
{
|
||||
std::size_t it_index = get(index_pmap,it);
|
||||
Vector_ref it_normal_vector = get(normal_pmap,*it);
|
||||
std::size_t it_index = get(index_map,it);
|
||||
Vector_ref it_normal_vector = get(normal_map,*it);
|
||||
|
||||
// Gather set of (k+1) neighboring points.
|
||||
// Perform k+1 queries (as in point set, the query point is
|
||||
// output first). Search may be aborted if k is greater
|
||||
// than number of input points.
|
||||
|
||||
Point_ref point = get(point_pmap, *it);
|
||||
Point_ref point = get(point_map, *it);
|
||||
Point_vertex_handle_3 point_wrapper(point.x(), point.y(), point.z(), it);
|
||||
Neighbor_search search(*tree, point_wrapper, k+1);
|
||||
Search_iterator search_iterator = search.begin();
|
||||
|
|
@ -356,7 +359,7 @@ create_riemannian_graph(
|
|||
break; // premature ending
|
||||
|
||||
ForwardIterator neighbor = search_iterator->first;
|
||||
std::size_t neighbor_index = get(index_pmap,neighbor);
|
||||
std::size_t neighbor_index = get(index_map,neighbor);
|
||||
if (neighbor_index > it_index) // undirected graph
|
||||
{
|
||||
// Add edge
|
||||
|
|
@ -371,7 +374,7 @@ create_riemannian_graph(
|
|||
// Computes edge weight = 1 - | normal1 * normal2 |
|
||||
// where normal1 and normal2 are the normal at the edge extremities.
|
||||
|
||||
Vector_ref neighbor_normal_vector = get(normal_pmap,*neighbor);
|
||||
Vector_ref neighbor_normal_vector = get(normal_map,*neighbor);
|
||||
double weight = 1.0 - std::abs(it_normal_vector * neighbor_normal_vector);
|
||||
if (weight < 0)
|
||||
weight = 0; // safety check
|
||||
|
|
@ -393,32 +396,32 @@ create_riemannian_graph(
|
|||
/// \pre Normals must be unit vectors.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam IndexPMap is a model of `ReadablePropertyMap` with an integral value_type.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = Point_3<Kernel>.
|
||||
/// @tparam NormalPMap is a model of `ReadWritePropertyMap` with a value_type = Vector_3<Kernel>.
|
||||
/// @tparam IndexMap is a model of `ReadablePropertyMap` with an integral value_type.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = Point_3<Kernel>.
|
||||
/// @tparam NormalMap is a model of `ReadWritePropertyMap` with a value_type = Vector_3<Kernel>.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
///
|
||||
/// @return the MST graph.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename IndexPMap,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename IndexMap,
|
||||
typename Kernel
|
||||
>
|
||||
MST_graph<ForwardIterator, NormalPMap, Kernel>
|
||||
MST_graph<ForwardIterator, NormalMap, Kernel>
|
||||
create_mst_graph(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3
|
||||
IndexPMap index_pmap, ///< property map ForwardIterator -> index
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3
|
||||
IndexMap index_map, ///< property map ForwardIterator -> index
|
||||
unsigned int k, ///< number of neighbors
|
||||
const Kernel& kernel, ///< geometric traits.
|
||||
const Riemannian_graph<ForwardIterator>& riemannian_graph, ///< graph connecting each vertex to its knn
|
||||
ForwardIterator source_point) ///< source point (with an oriented normal)
|
||||
{
|
||||
// prevents warnings
|
||||
CGAL_USE(point_pmap);
|
||||
CGAL_USE(point_map);
|
||||
CGAL_USE(k);
|
||||
CGAL_USE(kernel);
|
||||
|
||||
|
|
@ -430,7 +433,7 @@ create_mst_graph(
|
|||
typedef typename boost::property_map<Riemannian_graph, boost::edge_weight_t>::const_type Riemannian_graph_weight_map;
|
||||
|
||||
// MST_graph types
|
||||
typedef internal::MST_graph<ForwardIterator, NormalPMap, Kernel> MST_graph;
|
||||
typedef internal::MST_graph<ForwardIterator, NormalMap, Kernel> MST_graph;
|
||||
|
||||
// Precondition: at least one element in the container.
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
|
|
@ -442,7 +445,7 @@ create_mst_graph(
|
|||
CGAL_TRACE(" Calls boost::prim_minimum_spanning_tree()\n");
|
||||
|
||||
// Computes Minimum Spanning Tree.
|
||||
std::size_t source_point_index = get(index_pmap, source_point);
|
||||
std::size_t source_point_index = get(index_map, source_point);
|
||||
Riemannian_graph_weight_map riemannian_graph_weight_map = get(boost::edge_weight, riemannian_graph);
|
||||
typedef std::vector<typename Riemannian_graph::vertex_descriptor> PredecessorMap;
|
||||
PredecessorMap predecessor(num_input_points);
|
||||
|
|
@ -457,7 +460,7 @@ create_mst_graph(
|
|||
// - vertices are numbered like the input points index.
|
||||
// - vertices contain the corresponding input point iterator.
|
||||
// - we add the edge (predecessor[i], i) for each element of the predecessor map.
|
||||
MST_graph mst_graph(normal_pmap);
|
||||
MST_graph mst_graph(normal_map);
|
||||
//
|
||||
// Add vertices. source_point is the unique point marked "oriented".
|
||||
for (ForwardIterator it = first; it != beyond; it++)
|
||||
|
|
@ -466,7 +469,7 @@ create_mst_graph(
|
|||
// 1.56 and 1.57:
|
||||
// https://svn.boost.org/trac/boost/ticket/10382
|
||||
typename MST_graph::vertex_descriptor v = add_vertex(mst_graph);
|
||||
CGAL_point_set_processing_assertion(v == get(index_pmap,it));
|
||||
CGAL_point_set_processing_assertion(v == get(index_map,it));
|
||||
mst_graph[v].input_point = it;
|
||||
mst_graph[v].is_oriented = (it == source_point);
|
||||
}
|
||||
|
|
@ -508,47 +511,55 @@ create_mst_graph(
|
|||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalPMap is a model of `ReadWritePropertyMap` with value type `Vector_3<Kernel>` .
|
||||
/// @tparam NormalMap is a model of `ReadWritePropertyMap` with value type `Vector_3<Kernel>` .
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point with an unoriented normal.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename Kernel
|
||||
template <typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
ForwardIterator
|
||||
typename PointRange::iterator
|
||||
mst_orient_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k, ///< number of neighbors
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
PointRange& points,
|
||||
unsigned int k, ///< number of neighbors
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
CGAL_TRACE("Calls mst_orient_normals()\n");
|
||||
|
||||
// Bring private stuff to scope
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::type NormalMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<NormalMap,
|
||||
Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::NoMap>::value),
|
||||
"Error: no normal map");
|
||||
|
||||
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());
|
||||
Kernel kernel;
|
||||
|
||||
// Bring private stuff to scope
|
||||
using namespace internal;
|
||||
|
||||
// Input points types
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type Enriched_point; // actual type of input points
|
||||
// Property map ForwardIterator -> index
|
||||
typedef Index_property_map<ForwardIterator> IndexPMap;
|
||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Enriched_point; // actual type of input points
|
||||
// Property map typename PointRange::iterator -> index
|
||||
typedef Index_property_map<typename PointRange::iterator> IndexMap;
|
||||
|
||||
// Riemannian_graph types
|
||||
typedef Riemannian_graph<ForwardIterator> Riemannian_graph;
|
||||
typedef Riemannian_graph<typename PointRange::iterator> Riemannian_graph;
|
||||
|
||||
// MST_graph types
|
||||
typedef MST_graph<ForwardIterator, NormalPMap, Kernel> MST_graph;
|
||||
typedef MST_graph<typename PointRange::iterator, NormalMap, Kernel> MST_graph;
|
||||
|
||||
// Precondition: at least one element in the container.
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
CGAL_point_set_processing_precondition(points.begin() != points.end());
|
||||
|
||||
// Precondition: at least 2 nearest neighbors
|
||||
CGAL_point_set_processing_precondition(k >= 2);
|
||||
|
|
@ -557,16 +568,16 @@ mst_orient_normals(
|
|||
CGAL_TRACE(" Create Index_property_map\n");
|
||||
|
||||
// Create a property map Iterator -> index.
|
||||
// - if ForwardIterator is a random access iterator (typically vector and deque),
|
||||
// - if typename PointRange::iterator is a random access iterator (typically vector and deque),
|
||||
// get() just calls std::distance() and is very efficient;
|
||||
// - else, the property map allocates a std::map to store indices
|
||||
// and get() requires a lookup in the map.
|
||||
IndexPMap index_pmap(first, beyond);
|
||||
IndexMap index_map(points.begin(), points.end());
|
||||
|
||||
// Orients the normal of the point with maximum Z towards +Z axis.
|
||||
ForwardIterator source_point
|
||||
= mst_find_source(first, beyond,
|
||||
point_pmap, normal_pmap,
|
||||
typename PointRange::iterator source_point
|
||||
= mst_find_source(points.begin(), points.end(),
|
||||
point_map, normal_map,
|
||||
kernel);
|
||||
|
||||
// Iterates over input points and creates Riemannian Graph:
|
||||
|
|
@ -575,14 +586,14 @@ mst_orient_normals(
|
|||
// - we add the edge (i, j) if either vertex i is in the k-neighborhood of vertex j,
|
||||
// or vertex j is in the k-neighborhood of vertex i.
|
||||
Riemannian_graph riemannian_graph
|
||||
= create_riemannian_graph(first, beyond,
|
||||
point_pmap, normal_pmap, index_pmap,
|
||||
= create_riemannian_graph(points.begin(), points.end(),
|
||||
point_map, normal_map, index_map,
|
||||
k,
|
||||
kernel);
|
||||
|
||||
// Creates a Minimum Spanning Tree starting at source_point
|
||||
MST_graph mst_graph = create_mst_graph(first, beyond,
|
||||
point_pmap, normal_pmap, index_pmap,
|
||||
MST_graph mst_graph = create_mst_graph(points.begin(), points.end(),
|
||||
point_map, normal_map, index_map,
|
||||
k,
|
||||
kernel,
|
||||
riemannian_graph,
|
||||
|
|
@ -592,17 +603,17 @@ mst_orient_normals(
|
|||
CGAL_TRACE(" Calls boost::breadth_first_search()\n");
|
||||
|
||||
// Traverse the point set along the MST to propagate source_point's orientation
|
||||
Propagate_normal_orientation<ForwardIterator, NormalPMap, Kernel> orienter;
|
||||
std::size_t source_point_index = get(index_pmap, source_point);
|
||||
Propagate_normal_orientation<typename PointRange::iterator, NormalMap, Kernel> orienter;
|
||||
std::size_t source_point_index = get(index_map, source_point);
|
||||
boost::breadth_first_search(mst_graph,
|
||||
vertex(source_point_index, mst_graph), // source
|
||||
visitor(boost::make_bfs_visitor(orienter)));
|
||||
|
||||
// Copy points with robust normal orientation to oriented_points[], the others to unoriented_points[].
|
||||
std::deque<Enriched_point> oriented_points, unoriented_points;
|
||||
for (ForwardIterator it = first; it != beyond; it++)
|
||||
for (typename PointRange::iterator it = points.begin(); it != points.end(); it++)
|
||||
{
|
||||
std::size_t it_index = get(index_pmap,it);
|
||||
std::size_t it_index = get(index_map,it);
|
||||
typename MST_graph::vertex_descriptor v = vertex(it_index, mst_graph);
|
||||
if (mst_graph[v].is_oriented)
|
||||
oriented_points.push_back(*it);
|
||||
|
|
@ -610,9 +621,9 @@ mst_orient_normals(
|
|||
unoriented_points.push_back(*it);
|
||||
}
|
||||
|
||||
// Replaces [first, beyond) range by the content of oriented_points[], then unoriented_points[].
|
||||
ForwardIterator first_unoriented_point =
|
||||
std::copy(oriented_points.begin(), oriented_points.end(), first);
|
||||
// Replaces [points.begin(), points.end()) range by the content of oriented_points[], then unoriented_points[].
|
||||
typename PointRange::iterator first_unoriented_point =
|
||||
std::copy(oriented_points.begin(), oriented_points.end(), points.begin());
|
||||
std::copy(unoriented_points.begin(), unoriented_points.end(), first_unoriented_point);
|
||||
|
||||
// At this stage, we have typically 0 unoriented normals if k is large enough
|
||||
|
|
@ -624,49 +635,94 @@ mst_orient_normals(
|
|||
return first_unoriented_point;
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
/// Orients the normals of the `[first, beyond)` range of points using the propagation
|
||||
/// of a seed orientation through a minimum spanning tree of the Riemannian graph [Hoppe92].
|
||||
///
|
||||
/// This method modifies the order of input points so as to pack all sucessfully oriented points first,
|
||||
/// and returns an iterator over the first point with an unoriented normal (see erase-remove idiom).
|
||||
/// For this reason it should not be called on sorted containers.
|
||||
/// \warning This function may fail when Boost version 1.54 is used,
|
||||
/// because of the following bug: https://svn.boost.org/trac/boost/ticket/9012
|
||||
///
|
||||
/// \pre Normals must be unit vectors
|
||||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalMap is a model of `ReadWritePropertyMap` with value type `Vector_3<Kernel>` .
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point with an unoriented normal.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename Kernel
|
||||
>
|
||||
ForwardIterator
|
||||
mst_orient_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k, ///< number of neighbors
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("mst_orient_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return mst_orient_normals
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
geom_traits(kernel));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
template <typename ForwardIterator,
|
||||
typename PointMap,
|
||||
typename NormalMap
|
||||
>
|
||||
ForwardIterator
|
||||
mst_orient_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k) ///< number of neighbors
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return mst_orient_normals(
|
||||
first,beyond,
|
||||
point_pmap,
|
||||
normal_pmap,
|
||||
k,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("mst_orient_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return mst_orient_normals
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant creates a default point property map = Identity_property_map.
|
||||
template <typename ForwardIterator,
|
||||
typename NormalPMap
|
||||
typename NormalMap
|
||||
>
|
||||
ForwardIterator
|
||||
mst_orient_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k) ///< number of neighbors
|
||||
{
|
||||
return mst_orient_normals(
|
||||
first,beyond,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
normal_pmap,
|
||||
k);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("mst_orient_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return mst_orient_normals
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::normal_map (normal_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@
|
|||
#include <CGAL/point_set_processing_assertions.h>
|
||||
#include <CGAL/Memory_sizer.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
|
||||
|
|
@ -146,39 +149,46 @@ pca_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute
|
|||
///
|
||||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam Concurrency_tag enables sequential versus parallel algorithm.
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalPMap is a model of `WritablePropertyMap` with value type `Vector_3<Kernel>`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with value type `Vector_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename Concurrency_tag,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename Kernel
|
||||
template <typename ConcurrencyTag,
|
||||
typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
void
|
||||
pca_estimate_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
PointRange& points,
|
||||
unsigned int k, ///< number of neighbors.
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
CGAL_TRACE("Calls pca_estimate_normals()\n");
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::type NormalMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<NormalMap,
|
||||
Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::NoMap>::value),
|
||||
"Error: no normal map");
|
||||
|
||||
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());
|
||||
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
|
||||
// Input points types
|
||||
typedef typename boost::property_traits<NormalPMap>::value_type Vector;
|
||||
typedef typename boost::property_traits<NormalMap>::value_type Vector;
|
||||
|
||||
// types for K nearest neighbors search structure
|
||||
typedef typename CGAL::Search_traits_3<Kernel> Tree_traits;
|
||||
|
|
@ -188,7 +198,7 @@ pca_estimate_normals(
|
|||
// precondition: at least one element in the container.
|
||||
// to fix: should have at least three distinct points
|
||||
// but this is costly to check
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
CGAL_point_set_processing_precondition(points.begin() != points.end());
|
||||
|
||||
// precondition: at least 2 nearest neighbors
|
||||
CGAL_point_set_processing_precondition(k >= 2);
|
||||
|
|
@ -196,13 +206,13 @@ pca_estimate_normals(
|
|||
std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20);
|
||||
CGAL_TRACE(" Creates KD-tree\n");
|
||||
|
||||
ForwardIterator it;
|
||||
typename PointRange::iterator it;
|
||||
|
||||
// Instanciate a KD-tree search.
|
||||
// Note: We have to convert each input iterator to Point_3.
|
||||
std::vector<Point> kd_tree_points;
|
||||
for(it = first; it != beyond; it++)
|
||||
kd_tree_points.push_back(get(point_pmap, *it));
|
||||
for(it = points.begin(); it != points.end(); it++)
|
||||
kd_tree_points.push_back(get(point_map, *it));
|
||||
Tree tree(kd_tree_points.begin(), kd_tree_points.end());
|
||||
|
||||
memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20);
|
||||
|
|
@ -211,32 +221,32 @@ pca_estimate_normals(
|
|||
// iterate over input points, compute and output normal
|
||||
// vectors (already normalized)
|
||||
#ifndef CGAL_LINKED_WITH_TBB
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<Concurrency_tag, Parallel_tag>::value),
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||
"Parallel_tag is enabled but TBB is unavailable.");
|
||||
#else
|
||||
if (boost::is_convertible<Concurrency_tag,Parallel_tag>::value)
|
||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||
{
|
||||
std::vector<Vector> normals (kd_tree_points.size ());
|
||||
CGAL::internal::PCA_estimate_normals<Kernel, Tree>
|
||||
f (tree, k, kd_tree_points, normals);
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, kd_tree_points.size ()), f);
|
||||
unsigned int i = 0;
|
||||
for(it = first; it != beyond; ++ it, ++ i)
|
||||
for(it = points.begin(); it != points.end(); ++ it, ++ i)
|
||||
{
|
||||
put (normal_pmap, *it, normals[i]);
|
||||
put (normal_map, *it, normals[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for(it = first; it != beyond; it++)
|
||||
for(it = points.begin(); it != points.end(); it++)
|
||||
{
|
||||
Vector normal = internal::pca_estimate_normal<Kernel,Tree>(
|
||||
get(point_pmap,*it),
|
||||
get(point_map,*it),
|
||||
tree,
|
||||
k);
|
||||
|
||||
put(normal_pmap, *it, normal); // normal_pmap[it] = normal
|
||||
put(normal_map, *it, normal); // normal_map[it] = normal
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -244,51 +254,92 @@ pca_estimate_normals(
|
|||
CGAL_TRACE("End of pca_estimate_normals()\n");
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
template <typename Concurrency_tag,
|
||||
/// Estimates normal directions of the `[first, beyond)` range of points
|
||||
/// by linear least squares fitting of a plane over the k nearest neighbors.
|
||||
/// The output normals are randomly oriented.
|
||||
///
|
||||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with value type `Vector_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename Kernel
|
||||
>
|
||||
void
|
||||
pca_estimate_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k, ///< number of neighbors.
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("pca_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return pca_estimate_normals<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
geom_traits(Kernel()));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename PointMap,
|
||||
typename NormalMap
|
||||
>
|
||||
void
|
||||
pca_estimate_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k) ///< number of neighbors.
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
pca_estimate_normals<Concurrency_tag>(
|
||||
first,beyond,
|
||||
point_pmap,
|
||||
normal_pmap,
|
||||
k,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("pca_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return pca_estimate_normals<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant creates a default point property map = Identity_property_map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename ForwardIterator,
|
||||
typename NormalPMap
|
||||
typename NormalMap
|
||||
>
|
||||
void
|
||||
pca_estimate_normals(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
unsigned int k) ///< number of neighbors.
|
||||
{
|
||||
pca_estimate_normals<Concurrency_tag>(
|
||||
first,beyond,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
normal_pmap,
|
||||
k);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("pca_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return pca_estimate_normals<ConcurrencyTag>
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::normal_map (normal_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@
|
|||
#undef CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API
|
||||
|
||||
#define CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API(FCT) \
|
||||
std::cerr << "Warning: you are using the deprecated V1 API of the Point Set Processing\n function " \
|
||||
std::cerr << "Warning: you are using the deprecated V1 API of the Point Set Processing\nfunction " \
|
||||
<< FCT << ", please update your code." << std::endl
|
||||
|
||||
/// \endcond
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
#include <CGAL/Kernel_traits.h>
|
||||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/point_set_processing_assertions.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
|
|
@ -43,59 +47,83 @@ namespace CGAL {
|
|||
/// For this reason it should not be called on sorted containers.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point to remove.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename PointRange>
|
||||
typename PointRange::iterator
|
||||
random_simplify_point_set(
|
||||
PointRange& points,
|
||||
double removed_percentage) ///< percentage of points to remove.
|
||||
{
|
||||
CGAL_point_set_processing_precondition(removed_percentage >= 0 && removed_percentage <= 100);
|
||||
|
||||
// Random shuffle
|
||||
std::random_shuffle (points.begin(), points.end());
|
||||
|
||||
// Computes first iterator to remove
|
||||
std::size_t nb_points = std::distance(points.begin(), points.end());
|
||||
std::size_t first_index_to_remove = (std::size_t)(double(nb_points) * ((100.0-removed_percentage)/100.0));
|
||||
typename PointRange::iterator first_point_to_remove = points.begin();
|
||||
std::advance(first_point_to_remove, first_index_to_remove);
|
||||
|
||||
return first_point_to_remove;
|
||||
}
|
||||
|
||||
|
||||
/// Randomly deletes a user-specified fraction of the input points.
|
||||
///
|
||||
/// This method modifies the order of input points so as to pack all remaining points first,
|
||||
/// and returns an iterator over the first point to remove (see erase-remove idiom).
|
||||
/// For this reason it should not be called on sorted containers.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point to remove.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename PointMap,
|
||||
typename Kernel
|
||||
>
|
||||
ForwardIterator
|
||||
random_simplify_point_set(
|
||||
ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap /*point_pmap*/, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
PointMap /*point_map*/, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
double removed_percentage, ///< percentage of points to remove.
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_point_set_processing_precondition(removed_percentage >= 0 && removed_percentage <= 100);
|
||||
|
||||
// Random shuffle
|
||||
std::random_shuffle (first, beyond);
|
||||
|
||||
// Computes first iterator to remove
|
||||
std::size_t nb_points = std::distance(first, beyond);
|
||||
std::size_t first_index_to_remove = (std::size_t)(double(nb_points) * ((100.0-removed_percentage)/100.0));
|
||||
ForwardIterator first_point_to_remove = first;
|
||||
std::advance(first_point_to_remove, first_index_to_remove);
|
||||
|
||||
return first_point_to_remove;
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("random_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return random_simplify_point_set (points, removed_percentage);
|
||||
}
|
||||
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the iterator type.
|
||||
template <typename ForwardIterator,
|
||||
typename PointPMap
|
||||
typename PointMap
|
||||
>
|
||||
ForwardIterator
|
||||
random_simplify_point_set(
|
||||
ForwardIterator first, ///< iterator over the first input point
|
||||
ForwardIterator beyond, ///< past-the-end iterator
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
PointMap, ///< property map: value_type of ForwardIterator -> Point_3
|
||||
double removed_percentage) ///< percentage of points to remove
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return random_simplify_point_set(
|
||||
first,beyond,
|
||||
point_pmap,
|
||||
removed_percentage,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("random_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return random_simplify_point_set (points, removed_percentage);
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
@ -109,11 +137,9 @@ random_simplify_point_set(
|
|||
ForwardIterator beyond, ///< past-the-end iterator
|
||||
double removed_percentage) ///< percentage of points to remove
|
||||
{
|
||||
return random_simplify_point_set(
|
||||
first,beyond,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
removed_percentage);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("random_simplify_point_set()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
return random_simplify_point_set (points, removed_percentage);
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@
|
|||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/point_set_processing_assertions.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
|
@ -115,10 +118,10 @@ compute_avg_knn_sq_distance_3(
|
|||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted ifthe value type of `InputIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point to remove.
|
||||
///
|
||||
|
|
@ -131,31 +134,32 @@ compute_avg_knn_sq_distance_3(
|
|||
/// taken into account.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename InputIterator,
|
||||
typename PointPMap,
|
||||
typename Kernel
|
||||
template <typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
InputIterator
|
||||
typename PointRange::iterator
|
||||
remove_outliers(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of InputIterator -> Point_3
|
||||
PointRange& points,
|
||||
unsigned int k, ///< number of neighbors.
|
||||
double threshold_percent, ///< maximum percentage of points to remove.
|
||||
double threshold_distance, ///< minimum distance for a point to be
|
||||
///< considered as outlier (distance here is the square root of the average
|
||||
///< squared distance to K nearest
|
||||
///< neighbors)
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
|
||||
// geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
|
||||
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_distance = choose_param(get_param(np, internal_np::threshold_distance), 0.);
|
||||
|
||||
typedef typename Kernel::FT FT;
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
|
||||
// actual type of input points
|
||||
typedef typename std::iterator_traits<InputIterator>::value_type Enriched_point;
|
||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Enriched_point;
|
||||
|
||||
// types for K nearest neighbors search structure
|
||||
typedef typename CGAL::Search_traits_3<Kernel> Tree_traits;
|
||||
|
|
@ -165,36 +169,36 @@ remove_outliers(
|
|||
// precondition: at least one element in the container.
|
||||
// to fix: should have at least three distinct points
|
||||
// but this is costly to check
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
CGAL_point_set_processing_precondition(points.begin() != points.end());
|
||||
|
||||
// precondition: at least 2 nearest neighbors
|
||||
CGAL_point_set_processing_precondition(k >= 2);
|
||||
|
||||
CGAL_point_set_processing_precondition(threshold_percent >= 0 && threshold_percent <= 100);
|
||||
|
||||
InputIterator it;
|
||||
typename PointRange::iterator it;
|
||||
|
||||
// Instanciate a KD-tree search.
|
||||
// Note: We have to convert each input iterator to Point_3.
|
||||
std::vector<Point> kd_tree_points;
|
||||
for(it = first; it != beyond; it++)
|
||||
kd_tree_points.push_back( get(point_pmap, *it) );
|
||||
for(it = points.begin(); it != points.end(); it++)
|
||||
kd_tree_points.push_back( get(point_map, *it) );
|
||||
Tree tree(kd_tree_points.begin(), kd_tree_points.end());
|
||||
|
||||
// iterate over input points and add them to multimap sorted by distance to k
|
||||
std::multimap<FT,Enriched_point> sorted_points;
|
||||
for(it = first; it != beyond; it++)
|
||||
for(it = points.begin(); it != points.end(); it++)
|
||||
{
|
||||
FT sq_distance = internal::compute_avg_knn_sq_distance_3<Kernel>(
|
||||
get(point_pmap,*it),
|
||||
get(point_map,*it),
|
||||
tree, k);
|
||||
sorted_points.insert( std::make_pair(sq_distance, *it) );
|
||||
}
|
||||
|
||||
// Replaces [first, beyond) range by the multimap content.
|
||||
// Replaces [points.begin(), points.end()) range by the multimap content.
|
||||
// Returns the iterator after the (100-threshold_percent) % best points.
|
||||
InputIterator first_point_to_remove = first;
|
||||
InputIterator dst = first;
|
||||
typename PointRange::iterator first_point_to_remove = points.begin();
|
||||
typename PointRange::iterator dst = points.begin();
|
||||
int first_index_to_remove = int(double(sorted_points.size()) * ((100.0-threshold_percent)/100.0));
|
||||
typename std::multimap<FT,Enriched_point>::iterator src;
|
||||
int index;
|
||||
|
|
@ -211,28 +215,84 @@ remove_outliers(
|
|||
return first_point_to_remove;
|
||||
}
|
||||
|
||||
/// Removes outliers:
|
||||
/// - computes average squared distance to the K nearest neighbors,
|
||||
/// - and sorts the points in increasing order of average distance.
|
||||
///
|
||||
/// This method modifies the order of input points so as to pack all remaining points first,
|
||||
/// and returns an iterator over the first point to remove (see erase-remove idiom).
|
||||
/// For this reason it should not be called on sorted containers.
|
||||
///
|
||||
/// \pre `k >= 2`
|
||||
///
|
||||
/// @tparam InputIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted ifthe value type of `InputIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
///
|
||||
/// @return iterator over the first point to remove.
|
||||
///
|
||||
/// @note There are two thresholds that can be used:
|
||||
/// `threshold_percent` and `threshold_distance`. This function
|
||||
/// returns the smallest number of outliers such that at least one of
|
||||
/// these threshold is fullfilled. This means that if
|
||||
/// `threshold_percent=100`, only `threshold_distance` is taken into
|
||||
/// account; if `threshold_distance=0` only `threshold_percent` is
|
||||
/// taken into account.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename InputIterator,
|
||||
typename PointMap,
|
||||
typename Kernel
|
||||
>
|
||||
InputIterator
|
||||
remove_outliers(
|
||||
InputIterator first, ///< iterator over the first input point.
|
||||
InputIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointMap point_map, ///< property map: value_type of InputIterator -> Point_3
|
||||
unsigned int k, ///< number of neighbors.
|
||||
double threshold_percent, ///< maximum percentage of points to remove.
|
||||
double threshold_distance, ///< minimum distance for a point to be
|
||||
///< considered as outlier (distance here is the square root of the average
|
||||
///< squared distance to K nearest
|
||||
///< neighbors)
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("remove_outliers()");
|
||||
CGAL::Iterator_range<InputIterator> points (first, beyond);
|
||||
return remove_outliers
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
threshold_percent (threshold_percent).
|
||||
threshold_distance (threshold_distance).
|
||||
geom_traits(Kernel()));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the iterator type.
|
||||
template <typename InputIterator,
|
||||
typename PointPMap
|
||||
typename PointMap
|
||||
>
|
||||
InputIterator
|
||||
remove_outliers(
|
||||
InputIterator first, ///< iterator over the first input point
|
||||
InputIterator beyond, ///< past-the-end iterator
|
||||
PointPMap point_pmap, ///< property map: value_type of InputIterator -> Point_3
|
||||
PointMap point_map, ///< property map: value_type of InputIterator -> Point_3
|
||||
unsigned int k, ///< number of neighbors.
|
||||
double threshold_percent, ///< percentage of points to remove
|
||||
double threshold_distance = 0.0) ///< minimum average squared distance to K nearest neighbors
|
||||
///< for a point to be removed.
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return remove_outliers(
|
||||
first,beyond,
|
||||
point_pmap,
|
||||
k, threshold_percent, threshold_distance,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("remove_outliers()");
|
||||
CGAL::Iterator_range<InputIterator> points (first, beyond);
|
||||
return remove_outliers
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
threshold_percent (threshold_percent).
|
||||
threshold_distance (threshold_distance));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
@ -249,11 +309,13 @@ remove_outliers(
|
|||
double threshold_distance = 0.0) ///< minimum average squared distance to K nearest neighbors
|
||||
///< for a point to be removed.
|
||||
{
|
||||
return remove_outliers(
|
||||
first,beyond,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<InputIterator>::value_type()),
|
||||
k, threshold_percent, threshold_distance);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("remove_outliers()");
|
||||
CGAL::Iterator_range<InputIterator> points (first, beyond);
|
||||
return remove_outliers
|
||||
(points,
|
||||
k,
|
||||
CGAL::parameters::threshold_percent (threshold_percent).
|
||||
threshold_distance (threshold_distance));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@
|
|||
#include <CGAL/Delaunay_triangulation_3.h>
|
||||
#include <CGAL/Triangulation_vertex_base_with_info_3.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <limits>
|
||||
|
|
@ -1450,6 +1453,75 @@ private:
|
|||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
|
||||
// This variant requires all parameters
|
||||
template <typename PointRange,
|
||||
typename PlaneRange,
|
||||
typename OutputIterator,
|
||||
typename NamedParameters
|
||||
>
|
||||
OutputIterator
|
||||
structure_point_set (const PointRange& points, ///< range of points.
|
||||
const PlaneRange& planes, ///< range of planes.
|
||||
OutputIterator output, ///< output iterator where output points are written.
|
||||
double epsilon, ///< size parameter.
|
||||
const NamedParameters& np)
|
||||
{
|
||||
using boost::choose_param;
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::type NormalMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
typedef typename Point_set_processing_3::GetPlaneMap<PlaneRange, NamedParameters>::type PlaneMap;
|
||||
typedef typename Point_set_processing_3::GetPlaneIndexMap<NamedParameters>::type PlaneIndexMap;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<NormalMap,
|
||||
Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::NoMap>::value),
|
||||
"Error: no normal map");
|
||||
CGAL_static_assertion_msg(!(boost::is_same<PlaneIndexMap,
|
||||
Point_set_processing_3::GetPlaneIndexMap<NamedParameters>::NoMap>::value),
|
||||
"Error: no plane index map");
|
||||
|
||||
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());
|
||||
PlaneMap plane_map = choose_param(get_param(np, internal_np::plane_map), PlaneMap());
|
||||
PlaneIndexMap plane_index_map = choose_param(get_param(np, internal_np::plane_index_map), PlaneIndexMap());
|
||||
double attraction_factor = choose_param(get_param(np, internal_np::attraction_factor), 3.);
|
||||
|
||||
Point_set_with_structure<Kernel> pss (points, point_map, normal_map, planes, plane_map, plane_index_map,
|
||||
epsilon, attraction_factor);
|
||||
|
||||
for (std::size_t i = 0; i < pss.size(); ++ i)
|
||||
*(output ++) = pss[i];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/// This is an implementation of the Point Set Structuring algorithm. This
|
||||
/// algorithm takes advantage of a set of detected planes: it detects adjacency
|
||||
/// relationships between planes and resamples the detected planes, edges and
|
||||
/// corners to produce a structured point set.
|
||||
///
|
||||
/// The size parameter `epsilon` is used both for detecting adjacencies and for
|
||||
/// setting the sampling density of the structured point set.
|
||||
///
|
||||
/// For more details, please refer to \cgalCite{cgal:la-srpss-13}.
|
||||
///
|
||||
/// @tparam PointRange range of points, model of `ConstRange`
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with value type `Kernel::Point_3`.
|
||||
/// It can be omitted if the value type of the iterator of `PointRange` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalMap is a model of `ReadablePropertyMap` with value type `Kernel::Vector_3`.
|
||||
/// @tparam PlaneRange range of planes, model of `ConstRange`
|
||||
/// @tparam PlaneMap is a model of `ReadablePropertyMap` with value type `Kernel::Plane_3`.
|
||||
/// It can be omitted if the value type of the iterator of `PlaneRange` is convertible to `Plane_3<Kernel>`.
|
||||
/// @tparam IndexMap is a model of `ReadablePropertyMap` with value type `std::size_t`.
|
||||
/// @tparam OutputIterator Type of the output iterator. The type of the objects
|
||||
/// put in it is `std::pair<Kernel::Point_3, Kernel::Vector_3>`. Note that the
|
||||
/// user may use a <A HREF="http://www.boost.org/libs/iterator/doc/function_output_iterator.html">function_output_iterator</A>
|
||||
/// to match specific needs.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`.
|
||||
|
||||
// This variant requires all parameters
|
||||
template <typename PointRange,
|
||||
typename PointMap,
|
||||
|
|
@ -1472,15 +1544,17 @@ structure_point_set (const PointRange& points, ///< range of points.
|
|||
double epsilon, ///< size parameter.
|
||||
double attraction_factor = 3.) ///< attraction factor.
|
||||
{
|
||||
Point_set_with_structure<Kernel> pss (points, point_map, normal_map, planes, plane_map, index_map,
|
||||
epsilon, attraction_factor);
|
||||
|
||||
for (std::size_t i = 0; i < pss.size(); ++ i)
|
||||
*(output ++) = pss[i];
|
||||
|
||||
return output;
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("structure_point_set()");
|
||||
return structure_point_set
|
||||
(points, planes, output, epsilon,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
plane_map (plane_map).
|
||||
plane_index_map (index_map).
|
||||
attraction_factor (attraction_factor).
|
||||
geom_traits (Kernel()));
|
||||
}
|
||||
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
|
||||
// This variant deduces the kernel from the point property map.
|
||||
|
|
@ -1503,11 +1577,14 @@ structure_point_set (const PointRange& points,
|
|||
double epsilon, ///< size parameter
|
||||
double attraction_factor = 3.) ///< attraction factor
|
||||
{
|
||||
typedef typename boost::property_traits<PointMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
|
||||
return structure_point_set(points, point_map, normal_map, planes, plane_map, index_map, output,
|
||||
Kernel(), epsilon, attraction_factor);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("structure_point_set()");
|
||||
return structure_point_set
|
||||
(points, planes, output, epsilon,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
plane_map (plane_map).
|
||||
plane_index_map (index_map).
|
||||
attraction_factor (attraction_factor));
|
||||
}
|
||||
|
||||
// This variant creates a default point property map = Identity_property_map.
|
||||
|
|
@ -1526,17 +1603,12 @@ structure_point_set (const PointRange& points,
|
|||
double epsilon, ///< size parameter
|
||||
double attraction_factor = 3.) ///< attraction factor
|
||||
{
|
||||
return structure_point_set(points,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<typename PointRange::const_iterator>::value_type()),
|
||||
normal_map,
|
||||
planes,
|
||||
make_identity_property_map(
|
||||
typename std::iterator_traits<typename PlaneRange::const_iterator>::value_type()),
|
||||
index_map,
|
||||
output,
|
||||
epsilon,
|
||||
attraction_factor);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("structure_point_set()");
|
||||
return structure_point_set
|
||||
(points, planes, output, epsilon,
|
||||
CGAL::parameters::normal_map (normal_map).
|
||||
plane_index_map (index_map).
|
||||
attraction_factor (attraction_factor));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@
|
|||
#include <CGAL/Orthogonal_k_neighbor_search.h>
|
||||
#include <CGAL/Fuzzy_sphere.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <CGAL/Default_diagonalize_traits.h>
|
||||
|
||||
#include <iterator>
|
||||
|
|
@ -56,18 +59,18 @@ namespace internal {
|
|||
/// by `N` planes.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam K Geometric traits class.
|
||||
/// @tparam Covariance Covariance matrix type. It is similar to an array with a length of 6.
|
||||
template < typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename PointMap,
|
||||
class K,
|
||||
class Covariance
|
||||
>
|
||||
void
|
||||
vcm_offset (ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
std::vector<Covariance> &cov, ///< vector of covariance matrices.
|
||||
double offset_radius, ///< radius of the sphere.
|
||||
std::size_t N, ///< number of planes used to discretize the sphere.
|
||||
|
|
@ -80,7 +83,7 @@ vcm_offset (ForwardIterator first, ///< iterator over the first input point.
|
|||
std::vector<typename K::Point_3> points;
|
||||
points.reserve(std::distance(first, beyond));
|
||||
for (ForwardIterator it = first; it != beyond; ++it)
|
||||
points.push_back(get(point_pmap, *it));
|
||||
points.push_back(get(point_map, *it));
|
||||
|
||||
typedef Delaunay_triangulation_3<K> DT;
|
||||
DT dt(points.begin(), points.end());
|
||||
|
|
@ -102,23 +105,23 @@ vcm_offset (ForwardIterator first, ///< iterator over the first input point.
|
|||
/// @cond SKIP_IN_MANUAL
|
||||
// Convolve using a radius.
|
||||
template < class ForwardIterator,
|
||||
class PointPMap,
|
||||
class PointMap,
|
||||
class K,
|
||||
class Covariance
|
||||
>
|
||||
void
|
||||
vcm_convolve (ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
PointPMap point_pmap,
|
||||
PointMap point_map,
|
||||
const std::vector<Covariance> &cov,
|
||||
std::vector<Covariance> &ncov,
|
||||
double convolution_radius,
|
||||
const K &)
|
||||
{
|
||||
typedef std::pair<typename K::Point_3, std::size_t> Tree_point;
|
||||
typedef First_of_pair_property_map< Tree_point > Tree_pmap;
|
||||
typedef First_of_pair_property_map< Tree_point > Tree_map;
|
||||
typedef Search_traits_3<K> Traits_base;
|
||||
typedef Search_traits_adapter<Tree_point, Tree_pmap, Traits_base> Traits;
|
||||
typedef Search_traits_adapter<Tree_point, Tree_map, Traits_base> Traits;
|
||||
typedef Kd_tree<Traits> Tree;
|
||||
typedef Fuzzy_sphere<Traits> Fuzzy_sphere;
|
||||
|
||||
|
|
@ -127,7 +130,7 @@ vcm_convolve (ForwardIterator first,
|
|||
tree.reserve(cov.size());
|
||||
std::size_t i=0;
|
||||
for (ForwardIterator it = first; it != beyond; ++it, ++i)
|
||||
tree.insert( Tree_point(get(point_pmap, *it), i) );
|
||||
tree.insert( Tree_point(get(point_map, *it), i) );
|
||||
|
||||
// Convolving
|
||||
ncov.clear();
|
||||
|
|
@ -135,7 +138,7 @@ vcm_convolve (ForwardIterator first,
|
|||
for (ForwardIterator it = first; it != beyond; ++it) {
|
||||
std::vector<Tree_point> nn;
|
||||
tree.search(std::back_inserter(nn),
|
||||
Fuzzy_sphere (get(point_pmap, *it), convolution_radius));
|
||||
Fuzzy_sphere (get(point_map, *it), convolution_radius));
|
||||
|
||||
Covariance m;
|
||||
std::fill(m.begin(), m.end(), typename K::FT(0));
|
||||
|
|
@ -153,23 +156,23 @@ vcm_convolve (ForwardIterator first,
|
|||
/// @cond SKIP_IN_MANUAL
|
||||
// Convolve using neighbors.
|
||||
template < class ForwardIterator,
|
||||
class PointPMap,
|
||||
class PointMap,
|
||||
class K,
|
||||
class Covariance
|
||||
>
|
||||
void
|
||||
vcm_convolve (ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
PointPMap point_pmap,
|
||||
PointMap point_map,
|
||||
const std::vector<Covariance> &cov,
|
||||
std::vector<Covariance> &ncov,
|
||||
unsigned int nb_neighbors_convolve,
|
||||
const K &)
|
||||
{
|
||||
typedef std::pair<typename K::Point_3, std::size_t> Tree_point;
|
||||
typedef First_of_pair_property_map< Tree_point > Tree_pmap;
|
||||
typedef First_of_pair_property_map< Tree_point > Tree_map;
|
||||
typedef Search_traits_3<K> Traits_base;
|
||||
typedef Search_traits_adapter<Tree_point, Tree_pmap, Traits_base> Traits;
|
||||
typedef Search_traits_adapter<Tree_point, Tree_map, Traits_base> Traits;
|
||||
typedef Orthogonal_k_neighbor_search<Traits> Neighbor_search;
|
||||
typedef typename Neighbor_search::Tree Tree;
|
||||
|
||||
|
|
@ -178,13 +181,13 @@ vcm_convolve (ForwardIterator first,
|
|||
tree.reserve(cov.size());
|
||||
std::size_t i=0;
|
||||
for (ForwardIterator it = first; it != beyond; ++it, ++i)
|
||||
tree.insert( Tree_point(get(point_pmap, *it), i) );
|
||||
tree.insert( Tree_point(get(point_map, *it), i) );
|
||||
|
||||
// Convolving
|
||||
ncov.clear();
|
||||
ncov.reserve(cov.size());
|
||||
for (ForwardIterator it = first; it != beyond; ++it) {
|
||||
Neighbor_search search(tree, get(point_pmap, *it), nb_neighbors_convolve);
|
||||
Neighbor_search search(tree, get(point_map, *it), nb_neighbors_convolve);
|
||||
|
||||
Covariance m;
|
||||
for (typename Neighbor_search::iterator nit = search.begin();
|
||||
|
|
@ -233,8 +236,8 @@ vcm_convolve (ForwardIterator first,
|
|||
*/
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam CovariancePMap is a model of `ReadWritePropertyMap` with a value_type = `cpp11::array<Kernel::FT,6>`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam CovarianceMap is a model of `ReadWritePropertyMap` with a value_type = `cpp11::array<Kernel::FT,6>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
///
|
||||
/// \sa `CGAL::vcm_is_on_feature_edge()`
|
||||
|
|
@ -242,13 +245,13 @@ vcm_convolve (ForwardIterator first,
|
|||
///
|
||||
/// \todo replace ccov by a property map.
|
||||
template < class ForwardIterator,
|
||||
class PointPMap,
|
||||
class PointMap,
|
||||
class Kernel
|
||||
>
|
||||
void
|
||||
compute_vcm (ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
PointPMap point_pmap,
|
||||
PointMap point_map,
|
||||
std::vector< cpp11::array<typename Kernel::FT, 6> > &ccov,
|
||||
double offset_radius,
|
||||
double convolution_radius,
|
||||
|
|
@ -258,7 +261,7 @@ compute_vcm (ForwardIterator first,
|
|||
std::vector< cpp11::array<typename Kernel::FT, 6> > cov;
|
||||
std::size_t N = 20;
|
||||
internal::vcm_offset (first, beyond,
|
||||
point_pmap,
|
||||
point_map,
|
||||
cov,
|
||||
offset_radius,
|
||||
N,
|
||||
|
|
@ -269,7 +272,7 @@ compute_vcm (ForwardIterator first,
|
|||
std::copy(cov.begin(), cov.end(), std::back_inserter(ccov));
|
||||
} else {
|
||||
internal::vcm_convolve(first, beyond,
|
||||
point_pmap,
|
||||
point_map,
|
||||
cov,
|
||||
ccov,
|
||||
convolution_radius,
|
||||
|
|
@ -283,8 +286,8 @@ compute_vcm (ForwardIterator first,
|
|||
/// The output normals are randomly oriented.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam NormalPMap is a model of `WritablePropertyMap` with a value_type = `Kernel::Vector_3`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with a value_type = `Kernel::Vector_3`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// @tparam Covariance Covariance matrix type. It is similar to an array with a length of 6.
|
||||
/// @pre If `nb_neighbors_convolve` is equal to -1, then the convolution is made using a radius.
|
||||
|
|
@ -294,15 +297,15 @@ compute_vcm (ForwardIterator first,
|
|||
// This variant requires all of the parameters.
|
||||
template < typename VCMTraits,
|
||||
typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename Kernel
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
double offset_radius, ///< offset radius.
|
||||
double convolution_radius, ///< convolution radius.
|
||||
const Kernel & kernel, ///< geometric traits.
|
||||
|
|
@ -314,14 +317,14 @@ vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input
|
|||
std::vector<Covariance> cov;
|
||||
if (nb_neighbors_convolve == -1) {
|
||||
compute_vcm(first, beyond,
|
||||
point_pmap,
|
||||
point_map,
|
||||
cov,
|
||||
offset_radius,
|
||||
convolution_radius,
|
||||
kernel);
|
||||
} else {
|
||||
internal::vcm_offset(first, beyond,
|
||||
point_pmap,
|
||||
point_map,
|
||||
cov,
|
||||
offset_radius,
|
||||
20,
|
||||
|
|
@ -332,7 +335,7 @@ vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input
|
|||
std::vector<Covariance> ccov;
|
||||
ccov.reserve(cov.size());
|
||||
internal::vcm_convolve(first, beyond,
|
||||
point_pmap,
|
||||
point_map,
|
||||
cov,
|
||||
ccov,
|
||||
(unsigned int) nb_neighbors_convolve,
|
||||
|
|
@ -353,7 +356,7 @@ vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input
|
|||
typename Kernel::Vector_3 normal(enormal[0],
|
||||
enormal[1],
|
||||
enormal[2]);
|
||||
put(normal_pmap, *it, normal);
|
||||
put(normal_map, *it, normal);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
@ -368,8 +371,55 @@ vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input
|
|||
/// and of the Voronoi Covariance Measure.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam NormalPMap is a model of `WritablePropertyMap` with a value_type = `Kernel::Vector_3`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with a value_type = `Kernel::Vector_3`.
|
||||
/// \tparam VCMTraits is a model of `DiagonalizeTraits`. It can be
|
||||
/// omitted: if Eigen 3 (or greater) is available and
|
||||
/// `CGAL_EIGEN3_ENABLED` is defined then an overload using
|
||||
/// `Eigen_diagonalize_traits` is provided. Otherwise, the internal
|
||||
/// implementation `Diagonalize_traits` is used.
|
||||
// This variant deduces the kernel from the point property map
|
||||
// and uses a radius for the convolution.
|
||||
template <typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (PointRange& points,
|
||||
double offset_radius, ///< offset radius.
|
||||
double convolution_radius, ///< convolution radius.
|
||||
const NamedParameters& np
|
||||
)
|
||||
{
|
||||
using boost::choose_param;
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::type NormalMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
typedef typename GetDiagonalizeTraits<NamedParameters, double, 3>::type DiagonalizeTraits;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<NormalMap,
|
||||
Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::NoMap>::value),
|
||||
"Error: no normal map");
|
||||
|
||||
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());
|
||||
|
||||
vcm_estimate_normals<DiagonalizeTraits>(points.begin(), points.end(),
|
||||
point_map, normal_map,
|
||||
offset_radius, convolution_radius,
|
||||
Kernel());
|
||||
}
|
||||
|
||||
/// Estimates normal directions of the points in the range `[first, beyond)`
|
||||
/// using the Voronoi Covariance Measure with a radius for the convolution.
|
||||
/// The output normals are randomly oriented.
|
||||
///
|
||||
/// See `compute_vcm()` for a detailed description of the parameters `offset_radius` and `convolution_radius`
|
||||
/// and of the Voronoi Covariance Measure.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with a value_type = `Kernel::Vector_3`.
|
||||
/// \tparam VCMTraits is a model of `DiagonalizeTraits`. It can be
|
||||
/// omitted: if Eigen 3 (or greater) is available and
|
||||
/// `CGAL_EIGEN3_ENABLED` is defined then an overload using
|
||||
|
|
@ -378,27 +428,28 @@ vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input
|
|||
// This variant deduces the kernel from the point property map
|
||||
// and uses a radius for the convolution.
|
||||
template < typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename VCMTraits
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
double offset_radius, ///< offset radius.
|
||||
double convolution_radius, ///< convolution radius.
|
||||
VCMTraits
|
||||
)
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
|
||||
vcm_estimate_normals<VCMTraits>(first, beyond,
|
||||
point_pmap, normal_pmap,
|
||||
offset_radius, convolution_radius,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("vcm_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
vcm_estimate_normals
|
||||
(points,
|
||||
offset_radius, convolution_radius,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
diagonalize_traits (VCMTraits()));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -411,8 +462,57 @@ vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input
|
|||
/// and of the Voronoi Covariance Measure.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam NormalPMap is a model of `WritablePropertyMap` with a value_type = `Kernel::Vector_3`.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with a value_type = `Kernel::Vector_3`.
|
||||
/// \tparam VCMTraits is a model of `DiagonalizeTraits`. It can be
|
||||
/// omitted: if Eigen 3 (or greater) is available and
|
||||
/// `CGAL_EIGEN3_ENABLED` is defined then an overload using
|
||||
/// `Eigen_diagonalize_traits` is provided. Otherwise, the internal
|
||||
/// implementation `Diagonalize_traits` is used.
|
||||
|
||||
// This variant deduces the kernel from the point property map
|
||||
// and uses a number of neighbors for the convolution.
|
||||
template < typename PointRange,
|
||||
typename NamedParameters
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (PointRange& points,
|
||||
double offset_radius, ///< offset radius.
|
||||
unsigned int k, ///< number of neighbor points used for the convolution.
|
||||
const NamedParameters& np
|
||||
)
|
||||
{
|
||||
using boost::choose_param;
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::type NormalMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
typedef typename GetDiagonalizeTraits<NamedParameters, double, 3>::type DiagonalizeTraits;
|
||||
|
||||
CGAL_static_assertion_msg(!(boost::is_same<NormalMap,
|
||||
Point_set_processing_3::GetNormalMap<PointRange, NamedParameters>::NoMap>::value),
|
||||
"Error: no normal map");
|
||||
|
||||
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());
|
||||
|
||||
vcm_estimate_normals<DiagonalizeTraits>(points.begin(), points.end(),
|
||||
point_map, normal_map,
|
||||
offset_radius, 0,
|
||||
Kernel(),
|
||||
k);
|
||||
}
|
||||
|
||||
/// Estimates normal directions of the points in the range `[first, beyond)`
|
||||
/// using the Voronoi Covariance Measure with a number of neighbors for the convolution.
|
||||
/// The output normals are randomly oriented.
|
||||
///
|
||||
/// See `compute_vcm()` for a detailed description of the parameter `offset_radius`
|
||||
/// and of the Voronoi Covariance Measure.
|
||||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `Kernel::Point_3`.
|
||||
/// @tparam NormalMap is a model of `WritablePropertyMap` with a value_type = `Kernel::Vector_3`.
|
||||
/// \tparam VCMTraits is a model of `DiagonalizeTraits`. It can be
|
||||
/// omitted: if Eigen 3 (or greater) is available and
|
||||
/// `CGAL_EIGEN3_ENABLED` is defined then an overload using
|
||||
|
|
@ -422,62 +522,70 @@ vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input
|
|||
// This variant deduces the kernel from the point property map
|
||||
// and uses a number of neighbors for the convolution.
|
||||
template < typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename PointMap,
|
||||
typename NormalMap,
|
||||
typename VCMTraits
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (ForwardIterator first, ///< iterator over the first input point.
|
||||
ForwardIterator beyond, ///< past-the-end iterator over the input points.
|
||||
PointPMap point_pmap, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3.
|
||||
NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3.
|
||||
double offset_radius, ///< offset radius.
|
||||
unsigned int k, ///< number of neighbor points used for the convolution.
|
||||
VCMTraits
|
||||
)
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
|
||||
vcm_estimate_normals<VCMTraits>(first, beyond,
|
||||
point_pmap, normal_pmap,
|
||||
offset_radius, 0,
|
||||
Kernel(),
|
||||
k);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("vcm_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
vcm_estimate_normals
|
||||
(points,
|
||||
offset_radius, k,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map).
|
||||
diagonalize_traits (VCMTraits()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template < typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap
|
||||
typename PointMap,
|
||||
typename NormalMap
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
PointPMap point_pmap,
|
||||
NormalPMap normal_pmap,
|
||||
PointMap point_map,
|
||||
NormalMap normal_map,
|
||||
double offset_radius,
|
||||
double convolution_radius)
|
||||
{
|
||||
vcm_estimate_normals(first, beyond, point_pmap, normal_pmap, offset_radius, convolution_radius,
|
||||
CGAL::Default_diagonalize_traits<double, 3>());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("vcm_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
vcm_estimate_normals
|
||||
(points,
|
||||
offset_radius, convolution_radius,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map));
|
||||
}
|
||||
|
||||
template < typename ForwardIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap
|
||||
typename PointMap,
|
||||
typename NormalMap
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
PointPMap point_pmap,
|
||||
NormalPMap normal_pmap,
|
||||
PointMap point_map,
|
||||
NormalMap normal_map,
|
||||
double offset_radius,
|
||||
unsigned int nb_neighbors_convolve)
|
||||
{
|
||||
vcm_estimate_normals(first, beyond, point_pmap, normal_pmap, offset_radius, nb_neighbors_convolve,
|
||||
CGAL::Default_diagonalize_traits<double, 3>());
|
||||
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("vcm_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
vcm_estimate_normals
|
||||
(points,
|
||||
offset_radius, nb_neighbors_convolve,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
normal_map (normal_map));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -485,18 +593,20 @@ vcm_estimate_normals (ForwardIterator first,
|
|||
// This variant creates a default point property map = Identity_property_map
|
||||
// and use a radius for the convolution.
|
||||
template < typename ForwardIterator,
|
||||
typename NormalPMap
|
||||
typename NormalMap
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
NormalPMap normal_pmap,
|
||||
NormalMap normal_map,
|
||||
double offset_radius,
|
||||
double convolution_radius) {
|
||||
vcm_estimate_normals(first, beyond,
|
||||
make_identity_property_map(typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
normal_pmap,
|
||||
offset_radius, convolution_radius);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("vcm_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
vcm_estimate_normals
|
||||
(points,
|
||||
offset_radius, convolution_radius,
|
||||
CGAL::parameters::normal_map (normal_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
@ -504,18 +614,20 @@ vcm_estimate_normals (ForwardIterator first,
|
|||
// This variant creates a default point property map = Identity_property_map
|
||||
// and use a number of neighbors for the convolution.
|
||||
template < typename ForwardIterator,
|
||||
typename NormalPMap
|
||||
typename NormalMap
|
||||
>
|
||||
void
|
||||
vcm_estimate_normals (ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
NormalPMap normal_pmap,
|
||||
NormalMap normal_map,
|
||||
double offset_radius,
|
||||
unsigned int nb_neighbors_convolve) {
|
||||
vcm_estimate_normals(first, beyond,
|
||||
make_identity_property_map(typename std::iterator_traits<ForwardIterator>::value_type()),
|
||||
normal_pmap,
|
||||
offset_radius, nb_neighbors_convolve);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("vcm_estimate_normals()");
|
||||
CGAL::Iterator_range<ForwardIterator> points (first, beyond);
|
||||
vcm_estimate_normals
|
||||
(points,
|
||||
offset_radius, nb_neighbors_convolve,
|
||||
CGAL::parameters::normal_map (normal_map));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
#include <CGAL/Memory_sizer.h>
|
||||
#include <CGAL/compute_average_spacing.h>
|
||||
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
|
@ -408,51 +411,44 @@ public:
|
|||
/// See the <a href="http://www.threadingbuildingblocks.org/documentation">TBB documentation</a>
|
||||
/// for more details.
|
||||
///
|
||||
/// @tparam Concurrency_tag enables sequential versus parallel algorithm.
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam OutputIterator Type of the output iterator.
|
||||
/// It must accept objects of type `Kernel::Point_3`.
|
||||
/// @tparam RandomAccessIterator Iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap`
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap`
|
||||
/// with the value type of `ForwardIterator` as key type and `Kernel::Point_3` as value type.
|
||||
/// It can be omitted if the value type of ` RandomAccessIterator` is convertible
|
||||
/// to `Kernel::Point_3`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`
|
||||
/// using `Kernel_traits`.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename PointRange,
|
||||
typename OutputIterator,
|
||||
typename RandomAccessIterator,
|
||||
typename PointPMap,
|
||||
typename Kernel>
|
||||
typename NamedParameters>
|
||||
OutputIterator
|
||||
wlop_simplify_and_regularize_point_set(
|
||||
RandomAccessIterator first, ///< random-access iterator to the first input point.
|
||||
RandomAccessIterator beyond, ///< past-the-end iterator.
|
||||
PointRange& points,
|
||||
OutputIterator output, ///< output iterator where output points are put.
|
||||
PointPMap point_pmap, ///< point property map.
|
||||
double select_percentage, ///< percentage of points to retain.
|
||||
///< The default value is set to 5 (\%).
|
||||
double radius, ///< spherical neighborhood radius.
|
||||
///< This is a key parameter that needs to be finely tuned.
|
||||
///< The result will be irregular if too small, but a larger
|
||||
///< value will impact the runtime.
|
||||
///< In practice, choosing a radius such that the neighborhood of each sample point
|
||||
///< includes at least two rings of neighboring sample points
|
||||
///< gives satisfactory result.
|
||||
///< The default value is set to 8 times the average spacing of the point set.
|
||||
unsigned int iter_number, ///< number of iterations to solve the optimsation problem. The default value is 35.
|
||||
///< More iterations give a more regular result but increase the runtime.
|
||||
bool require_uniform_sampling,///< an optional preprocessing, which will give better result
|
||||
///< if the distribution of the input points is highly non-uniform.
|
||||
///< The default value is `false`.
|
||||
const Kernel& ///< geometric traits.
|
||||
const NamedParameters& np
|
||||
)
|
||||
{
|
||||
using boost::choose_param;
|
||||
|
||||
// basic geometric types
|
||||
typedef typename Point_set_processing_3::GetPointMap<PointRange, NamedParameters>::type PointMap;
|
||||
typedef typename Point_set_processing_3::GetK<PointRange, NamedParameters>::Kernel Kernel;
|
||||
|
||||
PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap());
|
||||
double select_percentage = choose_param(get_param(np, internal_np::select_percentage), 5.);
|
||||
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);
|
||||
bool require_uniform_sampling = choose_param(get_param(np, internal_np::require_uniform_sampling), false);
|
||||
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
typedef typename Kernel::FT FT;
|
||||
|
||||
|
|
@ -465,23 +461,23 @@ wlop_simplify_and_regularize_point_set(
|
|||
// precondition: at least one element in the container.
|
||||
// to fix: should have at least three distinct points
|
||||
// but this is costly to check
|
||||
CGAL_point_set_processing_precondition(first != beyond);
|
||||
CGAL_point_set_processing_precondition(points.begin() != points.end());
|
||||
CGAL_point_set_processing_precondition(select_percentage >= 0
|
||||
&& select_percentage <= 100);
|
||||
|
||||
// Random shuffle
|
||||
std::random_shuffle (first, beyond);
|
||||
std::random_shuffle (points.begin(), points.end());
|
||||
|
||||
// Computes original(input) and sample points size
|
||||
std::size_t number_of_original = std::distance(first, beyond);
|
||||
std::size_t number_of_original = std::distance(points.begin(), points.end());
|
||||
std::size_t number_of_sample = (std::size_t)(FT(number_of_original) *
|
||||
(select_percentage / FT(100.0)));
|
||||
std::size_t first_index_to_sample = number_of_original - number_of_sample;
|
||||
|
||||
// The first point iter of original and sample points
|
||||
RandomAccessIterator it; // point iterator
|
||||
RandomAccessIterator first_original_iter = first;
|
||||
RandomAccessIterator first_sample_iter = first;
|
||||
typename PointRange::iterator it; // point iterator
|
||||
typename PointRange::iterator first_original_iter = points.begin();
|
||||
typename PointRange::iterator first_sample_iter = points.begin();
|
||||
std::advance(first_sample_iter, first_index_to_sample);
|
||||
|
||||
//Copy sample points
|
||||
|
|
@ -489,18 +485,18 @@ wlop_simplify_and_regularize_point_set(
|
|||
sample_points.reserve(number_of_sample);
|
||||
unsigned int i;
|
||||
|
||||
for(it = first_sample_iter; it != beyond; ++it)
|
||||
for(it = first_sample_iter; it != points.end(); ++it)
|
||||
{
|
||||
sample_points.push_back(get(point_pmap, *it));
|
||||
sample_points.push_back(get(point_map, *it));
|
||||
}
|
||||
|
||||
//compute default neighbor_radius, if no radius in
|
||||
if (radius < 0)
|
||||
{
|
||||
const unsigned int nb_neighbors = 6; // 1 ring
|
||||
FT average_spacing = CGAL::compute_average_spacing<Concurrency_tag>(
|
||||
first, beyond,
|
||||
point_pmap,
|
||||
FT average_spacing = CGAL::compute_average_spacing<ConcurrencyTag>(
|
||||
points.begin(), points.end(),
|
||||
point_map,
|
||||
nb_neighbors);
|
||||
radius = average_spacing * 8.0;
|
||||
|
||||
|
|
@ -515,8 +511,8 @@ wlop_simplify_and_regularize_point_set(
|
|||
|
||||
// Initiate a KD-tree search for original points
|
||||
std::vector<Kd_tree_element> original_treeElements;
|
||||
for (it = first_original_iter, i=0 ; it != beyond ; ++it, ++i)
|
||||
original_treeElements.push_back( Kd_tree_element(get(point_pmap, *it), i) );
|
||||
for (it = first_original_iter, i=0 ; it != points.end() ; ++it, ++i)
|
||||
original_treeElements.push_back( Kd_tree_element(get(point_map, *it), i) );
|
||||
Kd_Tree original_kd_tree(original_treeElements.begin(),
|
||||
original_treeElements.end());
|
||||
|
||||
|
|
@ -530,12 +526,12 @@ wlop_simplify_and_regularize_point_set(
|
|||
if (require_uniform_sampling)//default value is false
|
||||
{
|
||||
//todo: this part could also be parallelized if needed
|
||||
for (it = first_original_iter, i = 0; it != beyond ; ++it, ++i)
|
||||
for (it = first_original_iter, i = 0; it != points.end() ; ++it, ++i)
|
||||
{
|
||||
FT density = simplify_and_regularize_internal::
|
||||
compute_density_weight_for_original_point<Kernel, Kd_Tree>
|
||||
(
|
||||
get(point_pmap, *it),
|
||||
get(point_map, *it),
|
||||
original_kd_tree,
|
||||
radius);
|
||||
|
||||
|
|
@ -572,14 +568,14 @@ wlop_simplify_and_regularize_point_set(
|
|||
|
||||
typename std::vector<Point>::iterator update_iter = update_sample_points.begin();
|
||||
#ifndef CGAL_LINKED_WITH_TBB
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<Concurrency_tag, Parallel_tag>::value),
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||
"Parallel_tag is enabled but TBB is unavailable.");
|
||||
#else
|
||||
//parallel
|
||||
if (boost::is_convertible<Concurrency_tag, Parallel_tag>::value)
|
||||
if (boost::is_convertible<ConcurrencyTag, Parallel_tag>::value)
|
||||
{
|
||||
tbb::blocked_range<size_t> block(0, number_of_sample);
|
||||
Sample_point_updater<Kernel, Kd_Tree, RandomAccessIterator> sample_updater(
|
||||
Sample_point_updater<Kernel, Kd_Tree, typename PointRange::iterator> sample_updater(
|
||||
update_sample_points,
|
||||
sample_points,
|
||||
original_kd_tree,
|
||||
|
|
@ -599,7 +595,7 @@ wlop_simplify_and_regularize_point_set(
|
|||
*update_iter = simplify_and_regularize_internal::
|
||||
compute_update_sample_point<Kernel,
|
||||
Kd_Tree,
|
||||
RandomAccessIterator>
|
||||
typename PointRange::iterator>
|
||||
(*sample_iter,
|
||||
original_kd_tree,
|
||||
sample_kd_tree,
|
||||
|
|
@ -628,18 +624,88 @@ wlop_simplify_and_regularize_point_set(
|
|||
return output;
|
||||
}
|
||||
|
||||
/// This is an implementation of the Weighted Locally Optimal Projection (WLOP) simplification algorithm.
|
||||
/// The WLOP simplification algorithm can produce a set of
|
||||
/// denoised, outlier-free and evenly distributed particles over the original
|
||||
/// dense point cloud.
|
||||
/// The core of the algorithm is a Weighted Locally Optimal Projection operator
|
||||
/// with a density uniformization term.
|
||||
/// For more details, please refer to \cgalCite{wlop-2009}.
|
||||
///
|
||||
/// A parallel version of WLOP is provided and requires the executable to be
|
||||
/// linked against the <a href="http://www.threadingbuildingblocks.org">Intel TBB library</a>.
|
||||
/// To control the number of threads used, the user may use the tbb::task_scheduler_init class.
|
||||
/// See the <a href="http://www.threadingbuildingblocks.org/documentation">TBB documentation</a>
|
||||
/// for more details.
|
||||
///
|
||||
/// @tparam ConcurrencyTag enables sequential versus parallel algorithm.
|
||||
/// Possible values are `Sequential_tag`
|
||||
/// and `Parallel_tag`.
|
||||
/// @tparam OutputIterator Type of the output iterator.
|
||||
/// It must accept objects of type `Kernel::Point_3`.
|
||||
/// @tparam RandomAccessIterator Iterator over input points.
|
||||
/// @tparam PointMap is a model of `ReadablePropertyMap`
|
||||
/// with the value type of `ForwardIterator` as key type and `Kernel::Point_3` as value type.
|
||||
/// It can be omitted if the value type of ` RandomAccessIterator` is convertible
|
||||
/// to `Kernel::Point_3`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointMap`
|
||||
/// using `Kernel_traits`.
|
||||
|
||||
// This variant requires all parameters.
|
||||
template <typename ConcurrencyTag,
|
||||
typename OutputIterator,
|
||||
typename RandomAccessIterator,
|
||||
typename PointMap,
|
||||
typename Kernel>
|
||||
OutputIterator
|
||||
wlop_simplify_and_regularize_point_set(
|
||||
RandomAccessIterator first, ///< random-access iterator to the first input point.
|
||||
RandomAccessIterator beyond, ///< past-the-end iterator.
|
||||
OutputIterator output, ///< output iterator where output points are put.
|
||||
PointMap point_map, ///< point property map.
|
||||
double select_percentage, ///< percentage of points to retain.
|
||||
///< The default value is set to 5 (\%).
|
||||
double radius, ///< spherical neighborhood radius.
|
||||
///< This is a key parameter that needs to be finely tuned.
|
||||
///< The result will be irregular if too small, but a larger
|
||||
///< value will impact the runtime.
|
||||
///< In practice, choosing a radius such that the neighborhood of each sample point
|
||||
///< includes at least two rings of neighboring sample points
|
||||
///< gives satisfactory result.
|
||||
///< The default value is set to 8 times the average spacing of the point set.
|
||||
unsigned int iter_number, ///< number of iterations to solve the optimsation problem. The default value is 35.
|
||||
///< More iterations give a more regular result but increase the runtime.
|
||||
bool require_uniform_sampling,///< an optional preprocessing, which will give better result
|
||||
///< if the distribution of the input points is highly non-uniform.
|
||||
///< The default value is `false`.
|
||||
const Kernel& ///< geometric traits.
|
||||
)
|
||||
{
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("wlop_simplify_and_regularize_point_set()");
|
||||
CGAL::Iterator_range<RandomAccessIterator> points (first, beyond);
|
||||
return wlop_simplify_and_regularize_point_set<ConcurrencyTag>
|
||||
(points, output,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
select_percentage (select_percentage).
|
||||
neighbor_radius (radius).
|
||||
number_of_iterations(iter_number).
|
||||
require_uniform_sampling (require_uniform_sampling).
|
||||
geom_traits (Kernel()));
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the iterator type.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename OutputIterator,
|
||||
typename RandomAccessIterator,
|
||||
typename PointPMap>
|
||||
typename PointMap>
|
||||
OutputIterator
|
||||
wlop_simplify_and_regularize_point_set(
|
||||
RandomAccessIterator first, ///< iterator over the first input point
|
||||
RandomAccessIterator beyond, ///< past-the-end iterator
|
||||
OutputIterator output, ///< add back-inserter
|
||||
PointPMap point_pmap, ///< property map RandomAccessIterator -> Point_3
|
||||
PointMap point_map, ///< property map RandomAccessIterator -> Point_3
|
||||
const double select_percentage, ///< percentage of points to retain
|
||||
double neighbor_radius, ///< size of neighbors.
|
||||
const unsigned int max_iter_number, ///< number of iterations.
|
||||
|
|
@ -647,18 +713,15 @@ wlop_simplify_and_regularize_point_set(
|
|||
/// to generate more rugularized result.
|
||||
)
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
|
||||
return wlop_simplify_and_regularize_point_set<Concurrency_tag>(
|
||||
first, beyond,
|
||||
output,
|
||||
point_pmap,
|
||||
select_percentage,
|
||||
neighbor_radius,
|
||||
max_iter_number,
|
||||
require_uniform_sampling,
|
||||
Kernel());
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("wlop_simplify_and_regularize_point_set()");
|
||||
CGAL::Iterator_range<RandomAccessIterator> points (first, beyond);
|
||||
return wlop_simplify_and_regularize_point_set<ConcurrencyTag>
|
||||
(points, output,
|
||||
CGAL::parameters::point_map (point_map).
|
||||
select_percentage (select_percentage).
|
||||
neighbor_radius (neighbor_radius).
|
||||
number_of_iterations(max_iter_number).
|
||||
require_uniform_sampling (require_uniform_sampling));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
@ -666,7 +729,7 @@ wlop_simplify_and_regularize_point_set(
|
|||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
/// This variant creates a default point property map=Dereference_property_map.
|
||||
template <typename Concurrency_tag,
|
||||
template <typename ConcurrencyTag,
|
||||
typename OutputIterator,
|
||||
typename RandomAccessIterator >
|
||||
OutputIterator
|
||||
|
|
@ -681,16 +744,14 @@ wlop_simplify_and_regularize_point_set(
|
|||
///to generate a more uniform result.
|
||||
)
|
||||
{
|
||||
return wlop_simplify_and_regularize_point_set<Concurrency_tag>(
|
||||
first, beyond,
|
||||
output,
|
||||
make_identity_property_map(typename std::iterator_traits
|
||||
<RandomAccessIterator >::
|
||||
value_type()),
|
||||
select_percentage,
|
||||
neighbor_radius,
|
||||
max_iter_number,
|
||||
require_uniform_sampling);
|
||||
CGAL_POINT_SET_PROCESSING_DEPRECATED_V1_API("wlop_simplify_and_regularize_point_set()");
|
||||
CGAL::Iterator_range<RandomAccessIterator> points (first, beyond);
|
||||
return wlop_simplify_and_regularize_point_set<ConcurrencyTag>
|
||||
(points, output,
|
||||
CGAL::parameters::select_percentage (select_percentage).
|
||||
neighbor_radius (neighbor_radius).
|
||||
number_of_iterations(max_iter_number).
|
||||
require_uniform_sampling (require_uniform_sampling));
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue