From 977aceca2d459bef63ee1ecda6b10d6137aa556c Mon Sep 17 00:00:00 2001 From: Laurent Saboret Date: Fri, 17 Jul 2009 14:42:18 +0000 Subject: [PATCH] * Updated Point_set_processing_3 reference manual to describe the influence of each knn parameter. * Fixed bug in Point_set_processing_3 examples/tests: use reasonable default knn parameters (0.1 or 0.15% of point set was overkill.* Updated the Point Set demo to use the recommended knn values by default. --- .../Point_set_processing_3/normals.tex | 2 +- .../compute_average_spacing.tex | 2 + .../jet_estimate_normals.tex | 8 +++- .../jet_smooth_point_set.tex | 6 +++ .../mst_orient_normals.tex | 10 +++++ .../pca_estimate_normals.tex | 6 +++ .../remove_outliers.tex | 7 +++- .../Dereference_property_map.tex | 2 +- .../First_of_pair_property_map.tex | 2 +- .../Nth_of_tuple_property_map.tex | 4 +- .../Second_of_pair_property_map.tex | 2 +- .../average_spacing_example.cpp | 2 +- .../jet_smoothing_example.cpp | 2 +- .../normal_estimation.cmd | 2 +- .../normal_estimation.cpp | 42 ++++++------------- .../normals_example.cpp | 2 +- .../remove_outliers_example.cpp | 10 ++--- .../include/CGAL/property_map.h | 14 +++---- .../Point_set_processing_3/analysis_test.cpp | 4 +- .../normal_estimation_test.cpp | 34 ++++----------- .../remove_outliers_test.cpp | 17 +++----- .../Point_set_processing_3/smoothing_test.cpp | 17 ++------ .../PS_demo_average_spacing_plugin.cpp | 11 +++-- .../Point_set_demo/PS_demo_cleaning_plugin.ui | 12 ++++-- .../PS_demo_local_spacing_plugin.cpp | 4 +- .../PS_demo_normal_estimation_plugin.ui | 22 +++++----- .../Point_set_demo/PS_demo_poisson_plugin.ui | 10 ++--- .../PS_demo_simplification_plugin.cpp | 15 +++---- .../PS_demo_simplification_plugin.ui | 26 ++++++------ .../PS_demo_smoothing_plugin.cpp | 14 +++---- 30 files changed, 151 insertions(+), 160 deletions(-) diff --git a/Point_set_processing_3/doc_tex/Point_set_processing_3/normals.tex b/Point_set_processing_3/doc_tex/Point_set_processing_3/normals.tex index 80f56f99d44..df52e55dbf9 100644 --- a/Point_set_processing_3/doc_tex/Point_set_processing_3/normals.tex +++ b/Point_set_processing_3/doc_tex/Point_set_processing_3/normals.tex @@ -46,7 +46,7 @@ Function \ccc{CGAL::mst_orient_normals()} orients the normals of a set of points \ccExample -The following example reads a point set from a file, estimates the normals through PCA over the 7 nearest neighbors and orients the normals: +The following example reads a point set from a file, estimates the normals through PCA over the 6 nearest neighbors and orients the normals: \ccIncludeExampleCode{Point_set_processing_3/normals_example.cpp} diff --git a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/compute_average_spacing.tex b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/compute_average_spacing.tex index 3e918ee159a..a42375770ab 100644 --- a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/compute_average_spacing.tex +++ b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/compute_average_spacing.tex @@ -21,6 +21,8 @@ \ccc{CGAL::compute_average_spacing()} computes the average spacing of all points from the input set to their $k$ nearest neighbors. +The average spacing depends on the \ccc{k} parameter. In general, it is set to 1 ring, i.e. 6. + \ccInclude{CGAL/compute_average_spacing.h} % The section below is automatically generated. Do not edit! diff --git a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/jet_estimate_normals.tex b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/jet_estimate_normals.tex index c5513527294..1fab7dfa916 100644 --- a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/jet_estimate_normals.tex +++ b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/jet_estimate_normals.tex @@ -19,7 +19,13 @@ \ccDefinition -\ccc{CGAL::jet_estimate_normals()} estimates normal directions of all points from the input set by fitting jet surfaces over the $k$ nearest neighbors. The default jet surface is a quadric, and the result is an unoriented normal vector for each input point. The complete version of this function requires the kernel. The other deduces it from the input data. +\ccc{CGAL::jet_estimate_normals()} estimates normal directions of all points from the input set by fitting jet surfaces over the $k$ nearest neighbors. The default jet surface is a quadric, and the result is an unoriented normal vector for each input point. + +The quality of the normal estimation algorithm highly depends on the \ccc{k} parameter. +The number of neighbors controls the width of the point subset considered for jet fitting at each input point. +Larger value leads to smoother surface approximations and better normal estimations. Obviously, it also leads to longer computation times. +For clean datasets, this value can be set to a few rings, e.g. 18. On the other hand, as the amount of noise increases, this value should be increased as well. +For these reasons, we do not provide any default value for this parameter. \ccInclude{CGAL/jet_estimate_normals.h} diff --git a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/jet_smooth_point_set.tex b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/jet_smooth_point_set.tex index b7b9e61fdd8..641fd0d6b49 100644 --- a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/jet_smooth_point_set.tex +++ b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/jet_smooth_point_set.tex @@ -21,6 +21,12 @@ \ccc{CGAL::jet_smooth_point_set()} smooths a point set by fitting for each point a jet surface and projecting it onto the jet. The default jet surface is a quadric. +The quality of the smoothing algorithm highly depends on the \ccc{k} parameter. +The number of neighbors controls the width of the point subset considered for jet fitting at each input point. +Larger value leads to smoother surfaces and longer computation times. +For datasets with limited noise, this value can be set to a few rings, e.g. 24. On the other hand, as the amount of noise increases, this value should be increased as well. +For these reasons, we do not provide any default value for this parameter. + \ccInclude{CGAL/jet_smooth_point_set.h} % The section below is automatically generated. Do not edit! diff --git a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/mst_orient_normals.tex b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/mst_orient_normals.tex index 70c84f74120..38fd5f06a89 100644 --- a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/mst_orient_normals.tex +++ b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/mst_orient_normals.tex @@ -21,6 +21,16 @@ \ccc{CGAL::mst_orient_normals()} orients the normals of a point set using the propagation of a seed orientation through a minimum spanning tree computed over the Riemannian graph \cite{cgal:hddms-srup-92}. +The seed is the top point of the point set. Its normal is oriented towards +Z axis. + +The success of the orientation algorithm depends on the \ccc{k} parameter. +The number of neighbors controls the candidates to progagate the orientation around each input point. +In general, a value equal to a few rings, e.g. 18, works well. +With smaller values, the propagation may be blocked by gaps in the point set. +Large values will cause problems with points scattered over thin objects: the algorithm may incorrectly propagate the orientation from one side of the object to the other one. + +In the presence of several clusters of points, this algorithm cannot propagate the orientation from one cluster to the others, and will orient only the top cluster. + This method modifies the order of the input points so as to pack all successfully oriented normals 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. \ccInclude{CGAL/mst_orient_normals.h} diff --git a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/pca_estimate_normals.tex b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/pca_estimate_normals.tex index bfb937b9112..281d6c6c0c9 100644 --- a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/pca_estimate_normals.tex +++ b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/pca_estimate_normals.tex @@ -21,6 +21,12 @@ \ccc{CGAL::pca_estimate_normals()} estimates normal directions at all points of an input point set by linear least squares fitting of a plane over their $k$ nearest neighbors. The result is an unoriented normal for each input point. +The quality of the normal estimation algorithm highly depends on the \ccc{k} parameter. +The number of neighbors controls the width of the point subset considered for plane fitting at each input point. +Larger value leads to smoother surface approximations and better normal estimations. Obviously, it also leads to longer computation times. +For clean datasets, this value can be set to a few rings, e.g. 18. On the other hand, as the amount of noise increases, this value should be increased as well. +For these reasons, we do not provide any default value for this parameter. + \ccInclude{CGAL/pca_estimate_normals.h} % The section below is automatically generated. Do not edit! diff --git a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/remove_outliers.tex b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/remove_outliers.tex index 6c96469b04c..60dd84f0846 100644 --- a/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/remove_outliers.tex +++ b/Point_set_processing_3/doc_tex/Point_set_processing_3_ref/remove_outliers.tex @@ -20,7 +20,12 @@ \ccDefinition -\ccc{CGAL::remove_outliers()} deletes a user-specified fraction of outliers from the input point set. More specifically, it sorts the input points in increasing order of average squared distances to the $k$ nearest neighbors and deletes the points with largest value. +\ccc{CGAL::remove_outliers()} deletes a user-specified fraction of outliers from the input point set. More specifically, it sorts the input points in increasing order of average squared distances to the $k$ nearest neighbors and computes the points with largest value. + +The outliers detection depends on the \ccc{k} parameter, specifically the detection of clusters of outliers. +The number of neighbors should be higher than the size of clusters of outliers in the point set. +For datasets with no cluster of outliers, this value can be set to a few rings, e.g. 24. Larger value leads to longer computation times. +For these reasons, we do not provide any default value for this parameter. This method modifies the order of input points so as to pack all remaining points first, and returns 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. diff --git a/Point_set_processing_3/doc_tex/Property_map_ref/Dereference_property_map.tex b/Point_set_processing_3/doc_tex/Property_map_ref/Dereference_property_map.tex index fdc6a82b15b..6632076c10f 100644 --- a/Point_set_processing_3/doc_tex/Property_map_ref/Dereference_property_map.tex +++ b/Point_set_processing_3/doc_tex/Property_map_ref/Dereference_property_map.tex @@ -22,7 +22,7 @@ % The section below is automatically generated. Do not edit! %START-AUTO(\ccDefinition) -Very simple property map that converts a \ccc{T*} pointer (or in general an iterator over \ccc{T} elements) to the \ccc{T} object. +Property map that converts a \ccc{T*} pointer (or in general an iterator over \ccc{T} elements) to the \ccc{T} object. %END-AUTO(\ccDefinition) diff --git a/Point_set_processing_3/doc_tex/Property_map_ref/First_of_pair_property_map.tex b/Point_set_processing_3/doc_tex/Property_map_ref/First_of_pair_property_map.tex index e4d8cd19ad2..af04fdff104 100644 --- a/Point_set_processing_3/doc_tex/Property_map_ref/First_of_pair_property_map.tex +++ b/Point_set_processing_3/doc_tex/Property_map_ref/First_of_pair_property_map.tex @@ -22,7 +22,7 @@ % The section below is automatically generated. Do not edit! %START-AUTO(\ccDefinition) -Property map that accesses the first item of a \ccc{std::pair} Pair from a Pair$\ast$ pointer (or in general an iterator over Pair elements). +Property map that accesses the first item of a \ccc{std::pair}. %END-AUTO(\ccDefinition) diff --git a/Point_set_processing_3/doc_tex/Property_map_ref/Nth_of_tuple_property_map.tex b/Point_set_processing_3/doc_tex/Property_map_ref/Nth_of_tuple_property_map.tex index e93bf228621..af1669a7d81 100644 --- a/Point_set_processing_3/doc_tex/Property_map_ref/Nth_of_tuple_property_map.tex +++ b/Point_set_processing_3/doc_tex/Property_map_ref/Nth_of_tuple_property_map.tex @@ -22,7 +22,7 @@ % The section below is automatically generated. Do not edit! %START-AUTO(\ccDefinition) -Property map that accesses the Nth item of a \ccc{boost::tuple} Tuple from a Tuple$\ast$ pointer (or in general an iterator over Tuple elements). +Property map that accesses the Nth item of a \ccc{boost::tuple}. %END-AUTO(\ccDefinition) @@ -43,7 +43,7 @@ typename Tuple$>$ \\ struct \ccc{Nth_of_tuple_property_map}; \ccCommentHeading{Parameters} \\ -\ccc{Index}: of the item to access. \ccc{Tuple}: Instance of \ccc{boost::tuple}. +\ccc{N}: Index of the item to access. \ccc{Tuple}: Instance of \ccc{boost::tuple}. %END-AUTO(\ccParameters) diff --git a/Point_set_processing_3/doc_tex/Property_map_ref/Second_of_pair_property_map.tex b/Point_set_processing_3/doc_tex/Property_map_ref/Second_of_pair_property_map.tex index a273e24e0a2..b52363db4f9 100644 --- a/Point_set_processing_3/doc_tex/Property_map_ref/Second_of_pair_property_map.tex +++ b/Point_set_processing_3/doc_tex/Property_map_ref/Second_of_pair_property_map.tex @@ -22,7 +22,7 @@ % The section below is automatically generated. Do not edit! %START-AUTO(\ccDefinition) -Property map that accesses the second item of a \ccc{std::pair} Pair from a Pair$\ast$ pointer (or in general an iterator over Pair elements). +Property map that accesses the second item of a \ccc{std::pair}. %END-AUTO(\ccDefinition) diff --git a/Point_set_processing_3/examples/Point_set_processing_3/average_spacing_example.cpp b/Point_set_processing_3/examples/Point_set_processing_3/average_spacing_example.cpp index 7ece3b2060f..fd2c681e7e2 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/average_spacing_example.cpp +++ b/Point_set_processing_3/examples/Point_set_processing_3/average_spacing_example.cpp @@ -45,7 +45,7 @@ int main(void) } // Computes average spacing. - const unsigned int nb_neighbors = 7; + const unsigned int nb_neighbors = 6; // 1 ring FT average_spacing = CGAL::compute_average_spacing( points.begin(), points.end(), CGAL::Nth_of_tuple_property_map<1,IndexedPointWithColorTuple>(), diff --git a/Point_set_processing_3/examples/Point_set_processing_3/jet_smoothing_example.cpp b/Point_set_processing_3/examples/Point_set_processing_3/jet_smoothing_example.cpp index 895d3ada892..b7a46d35f7e 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/jet_smoothing_example.cpp +++ b/Point_set_processing_3/examples/Point_set_processing_3/jet_smoothing_example.cpp @@ -21,7 +21,7 @@ int main(void) points.push_back(Point( 0.0,-0.1, 0.001)); // Smoothing. - const unsigned int nb_neighbors = 8; + const unsigned int nb_neighbors = 8; // default is 24 for real-life point sets CGAL::jet_smooth_point_set(points.begin(), points.end(), nb_neighbors); return EXIT_SUCCESS; diff --git a/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cmd b/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cmd index 4d54e60612a..c9111081b04 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cmd +++ b/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cmd @@ -1 +1 @@ -data/ChineseDragon-10kv.off ChineseDragon-10kv.pwn -nb_neighbors_jet_fitting 0.1 -nb_neighbors_mst 10 +data/ChineseDragon-10kv.off ChineseDragon-10kv.pwn -nb_neighbors_jet_fitting 10 -nb_neighbors_mst 10 diff --git a/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cpp b/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cpp index 9aaa25c4661..5db59fa4b26 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cpp +++ b/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cpp @@ -52,19 +52,11 @@ typedef std::vector PointList; // Computes normals direction by Principal Component Analysis void run_pca_estimate_normals(PointList& points, // input points + output normals - double nb_neighbors_pca_normals) // number of neighbors (%) + unsigned int nb_neighbors_pca_normals) // number of neighbors { CGAL::Timer task_timer; task_timer.start(); - - // percentage -> number of neighbors - int nb_neighbors = int(double(points.size()) * nb_neighbors_pca_normals / 100.0); - if (nb_neighbors < 7) - nb_neighbors = 7; - if ((unsigned int)nb_neighbors > points.size()-1) - nb_neighbors = points.size()-1; - std::cerr << "Estimates Normals Direction by PCA (k=" - << nb_neighbors_pca_normals << "%=" << nb_neighbors <<")...\n"; + << nb_neighbors_pca_normals << ")...\n"; // Estimates normals direction. // Note: pca_estimate_normals() requires an iterator over points @@ -72,7 +64,7 @@ void run_pca_estimate_normals(PointList& points, // input points + output normal CGAL::pca_estimate_normals(points.begin(), points.end(), CGAL::First_of_pair_property_map(), CGAL::Second_of_pair_property_map(), - nb_neighbors); + nb_neighbors_pca_normals); long memory = CGAL::Memory_sizer().virtual_size(); std::cerr << "done: " << task_timer.time() << " seconds, " @@ -82,19 +74,11 @@ void run_pca_estimate_normals(PointList& points, // input points + output normal // Computes normals direction by Jet Fitting void run_jet_estimate_normals(PointList& points, // input points + output normals - double nb_neighbors_jet_fitting_normals) // number of neighbors (%) + unsigned int nb_neighbors_jet_fitting_normals) // number of neighbors { CGAL::Timer task_timer; task_timer.start(); - - // percentage -> number of neighbors - int nb_neighbors = int(double(points.size()) * nb_neighbors_jet_fitting_normals / 100.0); - if (nb_neighbors < 7) - nb_neighbors = 7; - if ((unsigned int)nb_neighbors > points.size()-1) - nb_neighbors = points.size()-1; - std::cerr << "Estimates Normals Direction by Jet Fitting (k=" - << nb_neighbors_jet_fitting_normals << "%=" << nb_neighbors <<")...\n"; + << nb_neighbors_jet_fitting_normals << ")...\n"; // Estimates normals direction. // Note: jet_estimate_normals() requires an iterator over points @@ -102,7 +86,7 @@ void run_jet_estimate_normals(PointList& points, // input points + output normal CGAL::jet_estimate_normals(points.begin(), points.end(), CGAL::First_of_pair_property_map(), CGAL::Second_of_pair_property_map(), - nb_neighbors); + nb_neighbors_jet_fitting_normals); long memory = CGAL::Memory_sizer().virtual_size(); std::cerr << "done: " << task_timer.time() << " seconds, " @@ -166,9 +150,9 @@ int main(int argc, char * argv[]) std::cerr << " -estimate plane|quadric Estimates normals direction\n"; std::cerr << " using a tangent plane or quadric (default=quadric)\n"; std::cerr << " -nb_neighbors_pca Number of neighbors\n"; - std::cerr << " to compute tangent plane (default=0.15% of points)\n"; + std::cerr << " to compute tangent plane (default=18)\n"; std::cerr << " -nb_neighbors_jet_fitting Number of neighbors\n"; - std::cerr << " to compute quadric (default=default=0.1% of points)\n"; + std::cerr << " to compute quadric (default=18)\n"; std::cerr << " -orient MST Orient normals\n"; std::cerr << " using a Minimum Spanning Tree (default=MST)\n"; std::cerr << " -nb_neighbors_mst Number of neighbors\n"; @@ -177,9 +161,9 @@ int main(int argc, char * argv[]) } // Normals Computing options - double nb_neighbors_pca_normals = 0.15 /* % */; // K-nearest neighbors (estimate normals by PCA) - double nb_neighbors_jet_fitting_normals = 0.1 /* % */; // K-nearest neighbors (estimate normals by Jet Fitting) - unsigned int nb_neighbors_mst = 18; // K-nearest neighbors = 3 rings (orient normals by MST) + unsigned int nb_neighbors_pca_normals = 18; // K-nearest neighbors = 3 rings (estimate normals by PCA) + unsigned int nb_neighbors_jet_fitting_normals = 18; // K-nearest neighbors (estimate normals by Jet Fitting) + unsigned int nb_neighbors_mst = 18; // K-nearest neighbors (orient normals by MST) std::string estimate = "quadric"; // estimate normals by jet fitting std::string orient = "MST"; // orient normals using a Minimum Spanning Tree @@ -194,10 +178,10 @@ int main(int argc, char * argv[]) std::cerr << "invalid option " << argv[i] << "\n"; } else if (std::string(argv[i])=="-nb_neighbors_pca") { - nb_neighbors_pca_normals = atof(argv[++i]); + nb_neighbors_pca_normals = atoi(argv[++i]); } else if (std::string(argv[i])=="-nb_neighbors_jet_fitting") { - nb_neighbors_jet_fitting_normals = atof(argv[++i]); + nb_neighbors_jet_fitting_normals = atoi(argv[++i]); } else if (std::string(argv[i])=="-orient") { orient = argv[++i]; diff --git a/Point_set_processing_3/examples/Point_set_processing_3/normals_example.cpp b/Point_set_processing_3/examples/Point_set_processing_3/normals_example.cpp index 91f00c89871..bed7d7096de 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/normals_example.cpp +++ b/Point_set_processing_3/examples/Point_set_processing_3/normals_example.cpp @@ -33,7 +33,7 @@ int main(void) // Estimates normals direction. // Note: pca_estimate_normals() requires an iterator over points // as well as property maps to access each point's position and normal. - const int nb_neighbors = 7; // K-nearest neighbors + const int nb_neighbors = 18; // K-nearest neighbors = 3 rings CGAL::pca_estimate_normals(points.begin(), points.end(), CGAL::First_of_pair_property_map(), CGAL::Second_of_pair_property_map(), diff --git a/Point_set_processing_3/examples/Point_set_processing_3/remove_outliers_example.cpp b/Point_set_processing_3/examples/Point_set_processing_3/remove_outliers_example.cpp index 3428c821273..4e8fc2a53c9 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/remove_outliers_example.cpp +++ b/Point_set_processing_3/examples/Point_set_processing_3/remove_outliers_example.cpp @@ -27,11 +27,11 @@ int main(void) // Removes outliers using erase-remove idiom. // The Dereference_property_map property map can be omitted here as it is the default value. const double removed_percentage = 5.0; // percentage of points to remove - const int nb_neighbors = 7; // considers 7 nearest neighbor points - points.erase( - CGAL::remove_outliers(points.begin(), points.end(), - CGAL::Dereference_property_map(), - nb_neighbors,removed_percentage), points.end()); + const int nb_neighbors = 24; // considers 24 nearest neighbor points + points.erase(CGAL::remove_outliers(points.begin(), points.end(), + CGAL::Dereference_property_map(), + nb_neighbors, removed_percentage), + points.end()); // Optional: after erase(), use Scott Meyer's "swap trick" to trim excess capacity std::vector(points).swap(points); diff --git a/Point_set_processing_3/include/CGAL/property_map.h b/Point_set_processing_3/include/CGAL/property_map.h index 324c3de6bf3..d78b33b99db 100644 --- a/Point_set_processing_3/include/CGAL/property_map.h +++ b/Point_set_processing_3/include/CGAL/property_map.h @@ -29,7 +29,7 @@ namespace CGAL { -/// Very simple property map that converts a 'T*' pointer (or in general +/// Property map that converts a 'T*' pointer (or in general /// an iterator over 'T' elements) to the 'T' object. /// /// @heading Is Model for the Concepts: @@ -70,8 +70,7 @@ make_dereference_property_map(Iter) // Property maps Pair* -> Pair::first_type // and Pair* -> Pair::second_type. -/// Property map that accesses the first item of a std::pair Pair -/// from a Pair* pointer (or in general an iterator over Pair elements). +/// Property map that accesses the first item of a std::pair. /// /// @heading Is Model for the Concepts: /// Model of boost::LvaluePropertyMap concept. @@ -109,8 +108,7 @@ make_first_of_pair_property_map(Iter) return First_of_pair_property_map::type>(); } -/// Property map that accesses the second item of a std::pair Pair -/// from a Pair* pointer (or in general an iterator over Pair elements). +/// Property map that accesses the second item of a std::pair. /// /// @heading Is Model for the Concepts: /// Model of boost::LvaluePropertyMap concept. @@ -152,14 +150,13 @@ make_second_of_pair_property_map(Iter) //========================================================================= -/// Property map that accesses the Nth item of a boost::tuple Tuple -/// from a Tuple* pointer (or in general an iterator over Tuple elements). +/// Property map that accesses the Nth item of a boost::tuple. /// /// @heading Is Model for the Concepts: /// Model of boost::LvaluePropertyMap concept. /// /// @heading Parameters: -/// @param Index of the item to access. +/// @param N Index of the item to access. /// @param Tuple Instance of boost::tuple. template @@ -183,6 +180,7 @@ struct Nth_of_tuple_property_map /// Free function to create a Nth_of_tuple_property_map property map. /// /// @relates Nth_of_tuple_property_map + template // Type convertible to key_type Nth_of_tuple_property_map::type> make_nth_of_tuple_property_map(Iter) diff --git a/Point_set_processing_3/test/Point_set_processing_3/analysis_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/analysis_test.cpp index 4b06eedcba6..0a5c4a2b167 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/analysis_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/analysis_test.cpp @@ -80,7 +80,7 @@ int main(int argc, char * argv[]) } // Average Spacing options - const unsigned int nb_neighbors = 7; // K-nearest neighbors = 1 ring (average spacing) + const unsigned int nb_neighbors = 6; // K-nearest neighbors = 1 ring (average spacing) // Accumulated errors int accumulated_fatal_err = EXIT_SUCCESS; @@ -119,7 +119,7 @@ int main(int argc, char * argv[]) // Test //*************************************** - test_average_spacing(points,nb_neighbors); + test_average_spacing(points, nb_neighbors); } // for each input file diff --git a/Point_set_processing_3/test/Point_set_processing_3/normal_estimation_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/normal_estimation_test.cpp index 9edc8344f75..0463a4b81b3 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/normal_estimation_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/normal_estimation_test.cpp @@ -119,24 +119,16 @@ bool verify_normal_direction(const PointList& points, // input points + computed // Computes normals direction by Principal Component Analysis // @return true on success. bool run_pca_estimate_normals(PointList& points, // input points + output normals - double nb_neighbors_pca_normals, // number of neighbors (%) + unsigned int nb_neighbors_pca_normals, // number of neighbors const std::vector& original_normals) // may be empty { CGAL::Timer task_timer; task_timer.start(); - - // percentage -> number of neighbors - int nb_neighbors = int(double(points.size()) * nb_neighbors_pca_normals / 100.0); - if (nb_neighbors < 7) - nb_neighbors = 7; - if ((unsigned int)nb_neighbors > points.size()-1) - nb_neighbors = points.size()-1; - std::cerr << "Estimates Normals Direction by PCA (k=" - << nb_neighbors_pca_normals << "%=" << nb_neighbors <<")...\n"; + << nb_neighbors_pca_normals << ")...\n"; CGAL::pca_estimate_normals(points.begin(), points.end(), CGAL::make_normal_of_point_with_normal_pmap(points.begin()), - nb_neighbors); + nb_neighbors_pca_normals); long memory = CGAL::Memory_sizer().virtual_size(); std::cerr << "done: " << task_timer.time() << " seconds, " @@ -151,24 +143,16 @@ bool run_pca_estimate_normals(PointList& points, // input points + output normal // Computes normals direction by Jet Fitting // @return true on success. bool run_jet_estimate_normals(PointList& points, // input points + output normals - double nb_neighbors_jet_fitting_normals, // number of neighbors (%) + unsigned int nb_neighbors_jet_fitting_normals, // number of neighbors const std::vector& original_normals) // may be empty { CGAL::Timer task_timer; task_timer.start(); - - // percentage -> number of neighbors - int nb_neighbors = int(double(points.size()) * nb_neighbors_jet_fitting_normals / 100.0); - if (nb_neighbors < 7) - nb_neighbors = 7; - if ((unsigned int)nb_neighbors > points.size()-1) - nb_neighbors = points.size()-1; - std::cerr << "Estimates Normals Direction by Jet Fitting (k=" - << nb_neighbors_jet_fitting_normals << "%=" << nb_neighbors <<")...\n"; + << nb_neighbors_jet_fitting_normals << ")...\n"; CGAL::jet_estimate_normals(points.begin(), points.end(), CGAL::make_normal_of_point_with_normal_pmap(points.begin()), - nb_neighbors); + nb_neighbors_jet_fitting_normals); long memory = CGAL::Memory_sizer().virtual_size(); std::cerr << "done: " << task_timer.time() << " seconds, " @@ -287,9 +271,9 @@ int main(int argc, char * argv[]) } // Normals Computing options - double nb_neighbors_pca_normals = 0.15 /* % */; // K-nearest neighbors (estimate normals by PCA) - double nb_neighbors_jet_fitting_normals = 0.1 /* % */; // K-nearest neighbors (estimate normals by Jet Fitting) - unsigned int nb_neighbors_mst = 18; // K-nearest neighbors = 3 rings (orient normals by MST) + unsigned int nb_neighbors_pca_normals = 18; // K-nearest neighbors = 3 rings (estimate normals by PCA) + unsigned int nb_neighbors_jet_fitting_normals = 18; // K-nearest neighbors (estimate normals by Jet Fitting) + unsigned int nb_neighbors_mst = 18; // K-nearest neighbors (orient normals by MST) // Accumulated errors int accumulated_fatal_err = EXIT_SUCCESS; diff --git a/Point_set_processing_3/test/Point_set_processing_3/remove_outliers_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/remove_outliers_test.cpp index 6cfe928d80c..a2782229c09 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/remove_outliers_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/remove_outliers_test.cpp @@ -41,24 +41,17 @@ typedef Kernel::Point_3 Point; // Removes outliers void test_avg_knn_sq_distance(std::deque& points, // input point set - double nb_neighbors_remove_outliers, // K-nearest neighbors (%) + unsigned int nb_neighbors_remove_outliers, // K-nearest neighbors double removed_percentage) // percentage of points to remove { CGAL::Timer task_timer; task_timer.start(); - - // percentage -> number of neighbors - int nb_neighbors = int(double(points.size()) * nb_neighbors_remove_outliers / 100.0); - if (nb_neighbors < 7) - nb_neighbors = 7; - if ((unsigned int)nb_neighbors > points.size()-1) - nb_neighbors = points.size()-1; - std::cerr << "Removes outliers wrt average squared distance to k nearest neighbors (remove " << removed_percentage << "%, k=" - << nb_neighbors_remove_outliers << "%=" << nb_neighbors << ")...\n"; + << nb_neighbors_remove_outliers << ")...\n"; // Removes outliers using erase-remove idiom - points.erase(CGAL::remove_outliers(points.begin(), points.end(), nb_neighbors, removed_percentage), + points.erase(CGAL::remove_outliers(points.begin(), points.end(), + nb_neighbors_remove_outliers, removed_percentage), points.end()); // Optional: after erase(), use Scott Meyer's "swap trick" to trim excess capacity @@ -97,7 +90,7 @@ int main(int argc, char * argv[]) // Outlier Removal options const double removed_percentage = 5.0 /* % */; // percentage of outliers to remove - const double nb_neighbors_remove_outliers = 0.05; // K-nearest neighbors (%) + const unsigned int nb_neighbors_remove_outliers = 24; // K-nearest neighbors // Accumulated errors int accumulated_fatal_err = EXIT_SUCCESS; diff --git a/Point_set_processing_3/test/Point_set_processing_3/smoothing_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/smoothing_test.cpp index cc5d47b2de7..7fbc3e9bb52 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/smoothing_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/smoothing_test.cpp @@ -41,21 +41,12 @@ typedef Kernel::Vector_3 Vector; // ---------------------------------------------------------------------------- void test_smooth_jet_fitting(std::deque& points,// input point set - double nb_neighbors_smooth_jet_fitting) // number of neighbors + unsigned int nb_neighbors_smooth_jet_fitting) // number of neighbors { CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Smoothes Point Set (k=" << nb_neighbors_smooth_jet_fitting << ")...\n"; - // percentage -> number of neighbors - int nb_neighbors = int(double(points.size()) * nb_neighbors_smooth_jet_fitting / 100.0); - if (nb_neighbors < 7) - nb_neighbors = 7; - if ((unsigned int)nb_neighbors > points.size()-1) - nb_neighbors = points.size()-1; - - std::cerr << "Smoothes Point Set (k=" - << nb_neighbors_smooth_jet_fitting << "%=" << nb_neighbors << ")...\n"; - - CGAL::jet_smooth_point_set(points.begin(), points.end(), nb_neighbors); + CGAL::jet_smooth_point_set(points.begin(), points.end(), nb_neighbors_smooth_jet_fitting); long memory = CGAL::Memory_sizer().virtual_size(); std::cerr << "ok: " << task_timer.time() << " seconds, " @@ -88,7 +79,7 @@ int main(int argc, char * argv[]) } // Smoothing options - const double nb_neighbors_smooth_jet_fitting = 0.1 /* % */; // K-nearest neighbors (smooth points by Jet Fitting) + const unsigned int nb_neighbors_smooth_jet_fitting = 24; // K-nearest neighbors (smooth points by Jet Fitting) // Accumulated errors int accumulated_fatal_err = EXIT_SUCCESS; diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_average_spacing_plugin.cpp b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_average_spacing_plugin.cpp index d3713decc14..f2ba33e1a00 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_average_spacing_plugin.cpp +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_average_spacing_plugin.cpp @@ -65,8 +65,8 @@ void PS_demo_average_spacing_plugin::on_actionAverageSpacing_triggered() QInputDialog::getInteger((QWidget*)mw, tr("Average Spacing"), // dialog title tr("Number of neighbors:"), // field label - 7, // default value = 1 ring - 7, // min + 6, // default value = 1 ring + 6, // min 1000, // max 1, // step &ok); @@ -80,9 +80,10 @@ void PS_demo_average_spacing_plugin::on_actionAverageSpacing_triggered() // Computes average spacing double average_spacing = CGAL::compute_average_spacing( - points->begin(), points->end(), - nb_neighbors); + points->begin(), points->end(), + nb_neighbors); + // Print result Sphere bsphere = points->bounding_sphere(); FT radius = std::sqrt(bsphere.squared_radius()); long memory = CGAL::Memory_sizer().virtual_size(); @@ -93,8 +94,6 @@ void PS_demo_average_spacing_plugin::on_actionAverageSpacing_triggered() << std::endl; QApplication::restoreOverrideCursor(); - - // Print result QMessageBox::information(NULL, tr("Average Spacing"), tr("Average Spacing = %1 = %2 * point set radius") diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_cleaning_plugin.ui b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_cleaning_plugin.ui index 650a29e96d0..bcf14b1cccf 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_cleaning_plugin.ui +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_cleaning_plugin.ui @@ -10,7 +10,7 @@ - Dialog + Outlier Removal @@ -26,11 +26,14 @@ % - 1.000000000000000 + 0.100000000000000 100.000000000000000 + + 0.100000000000000 + 5.000000000000000 @@ -45,11 +48,14 @@ + + 6 + 9999 - 7 + 24 diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_local_spacing_plugin.cpp b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_local_spacing_plugin.cpp index 95b66b3bea7..b4960b4d933 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_local_spacing_plugin.cpp +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_local_spacing_plugin.cpp @@ -58,8 +58,8 @@ void PS_demo_local_spacing_plugin::on_actionRadiusFromDensity_triggered() QInputDialog::getInteger((QWidget*)mw, tr("Local spacing"), // dialog title tr("Number of neighbors:"), // field label - 16, // default value = fast - 4, // min + 18, // default value = fast + 6, // min 1000, // max 1, // step &ok); diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_normal_estimation_plugin.ui b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_normal_estimation_plugin.ui index d820ce3acee..109d4e7e3cf 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_normal_estimation_plugin.ui +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_normal_estimation_plugin.ui @@ -5,14 +5,14 @@ 0 0 - 279 - 97 + 311 + 120 - Dialog + Normal estimation - + @@ -24,12 +24,12 @@ - plane + quadric - quadric + plane @@ -40,13 +40,13 @@ neighbors - 4 + 6 9999 - 16 + 18 @@ -72,13 +72,13 @@ neighbors - 4 + 6 9999 - 16 + 18 @@ -88,7 +88,7 @@ Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_poisson_plugin.ui b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_poisson_plugin.ui index 006e4d41806..80466cd7da2 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_poisson_plugin.ui +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_poisson_plugin.ui @@ -5,14 +5,14 @@ 0 0 - 305 - 149 + 399 + 155 - Dialog + Poisson reconstruction - + @@ -97,7 +97,7 @@ - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_simplification_plugin.cpp b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_simplification_plugin.cpp index af6f96bb9ac..8586ff1655c 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_simplification_plugin.cpp +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_simplification_plugin.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -13,7 +14,6 @@ #include #include #include -#include #include #include "ui_PS_demo_simplification_plugin.h" @@ -78,7 +78,7 @@ void PS_demo_simplification_plugin::on_actionSimplify_triggered() Point_set_demo_point_set_simplification_dialog dialog; if(!dialog.exec()) return; - + QApplication::setOverrideCursor(Qt::WaitCursor); CGAL::Timer task_timer; task_timer.start(); @@ -97,16 +97,17 @@ void PS_demo_simplification_plugin::on_actionSimplify_triggered() } else if (dialog.simplificationMethod() == "Grid Clustering") { - std::cerr << "Point cloud simplification by clustering (cell size = " << dialog.gridCellSize() <<" * point set radius)...\n"; + std::cerr << "Point cloud simplification by clustering (cell size = " << dialog.gridCellSize() <<" * average spacing)...\n"; - // Gets point set's radius - Sphere bsphere = points->bounding_sphere(); - FT radius = std::sqrt(bsphere.squared_radius()); + // Computes average spacing + double average_spacing = CGAL::compute_average_spacing( + points->begin(), points->end(), + 6 /* knn = 1 ring */); // Computes points to remove by Grid Clustering first_point_to_remove = CGAL::grid_simplify_point_set(points->begin(), points->end(), - dialog.gridCellSize()*radius); + dialog.gridCellSize()*average_spacing); } int nb_points_to_remove = std::distance(first_point_to_remove, points->end()); diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_simplification_plugin.ui b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_simplification_plugin.ui index cf64c50febd..7c45142f0eb 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_simplification_plugin.ui +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_simplification_plugin.ui @@ -5,14 +5,14 @@ 0 0 - 372 - 137 + 403 + 153 - Dialog + Simplification - + @@ -50,13 +50,13 @@ 2 - 1.000000000000000 + 0.100000000000000 100.000000000000000 - 1.000000000000000 + 0.100000000000000 50.000000000000000 @@ -73,22 +73,22 @@ - * point set radius + * average spacing - 7 + 2 - 0.000100000000000 + 0.100000000000000 - 1.000000000000000 + 10.000000000000000 - 0.000100000000000 + 0.100000000000000 - 0.004000000000000 + 1.000000000000000 @@ -98,7 +98,7 @@ Qt::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_smoothing_plugin.cpp b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_smoothing_plugin.cpp index 61c42e60f41..4c1ab5cb162 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_smoothing_plugin.cpp +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/PS_demo_smoothing_plugin.cpp @@ -56,13 +56,13 @@ void PS_demo_smoothing_plugin::on_actionJetSmoothing_triggered() bool ok; const unsigned int nb_neighbors = QInputDialog::getInteger((QWidget*)mw, - tr("Jet Smoothing"), // dialog title - tr("Number of neighbors:"), // field label - 16, // default value = fast - 4, // min - 1000, // max - 1, // step - &ok); + tr("Jet Smoothing"), // dialog title + tr("Number of neighbors:"), // field label + 24, // default value = fast + 6, // min + 1000, // max + 1, // step + &ok); if(!ok) return; QApplication::setOverrideCursor(Qt::WaitCursor);