Use new API of PSP with named parameters in include+example

This commit is contained in:
Simon Giraudot 2017-12-05 10:05:16 +01:00
parent 814ad5adf4
commit 86634b3c17
28 changed files with 1997 additions and 997 deletions

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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;
}

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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(

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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));
}

View File

@ -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

View File

@ -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