* 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.
This commit is contained in:
Laurent Saboret 2009-07-17 14:42:18 +00:00
parent 7473705678
commit 977aceca2d
30 changed files with 151 additions and 160 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -52,19 +52,11 @@ typedef std::vector<PointVectorPair> 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<PointVectorPair>(),
CGAL::Second_of_pair_property_map<PointVectorPair>(),
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<PointVectorPair>(),
CGAL::Second_of_pair_property_map<PointVectorPair>(),
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 <int> 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 <int> 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 <int> 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];

View File

@ -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<PointVectorPair>(),
CGAL::Second_of_pair_property_map<PointVectorPair>(),

View File

@ -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<Point>(),
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<Point>(),
nb_neighbors, removed_percentage),
points.end());
// Optional: after erase(), use Scott Meyer's "swap trick" to trim excess capacity
std::vector<Point>(points).swap(points);

View File

@ -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<typename CGAL::value_type_traits<Iter>::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 <int N, typename Tuple>
@ -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 <int N, class Iter> // Type convertible to key_type
Nth_of_tuple_property_map<N, typename CGAL::value_type_traits<Iter>::type>
make_nth_of_tuple_property_map(Iter)

View File

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

View File

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

View File

@ -41,24 +41,17 @@ typedef Kernel::Point_3 Point;
// Removes outliers
void test_avg_knn_sq_distance(std::deque<Point>& 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;

View File

@ -41,21 +41,12 @@ typedef Kernel::Vector_3 Vector;
// ----------------------------------------------------------------------------
void test_smooth_jet_fitting(std::deque<Point>& 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;

View File

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

View File

@ -10,7 +10,7 @@
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
<string>Outlier Removal</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
@ -26,11 +26,14 @@
<string> %</string>
</property>
<property name="minimum" >
<double>1.000000000000000</double>
<double>0.100000000000000</double>
</property>
<property name="maximum" >
<double>100.000000000000000</double>
</property>
<property name="singleStep" >
<double>0.100000000000000</double>
</property>
<property name="value" >
<double>5.000000000000000</double>
</property>
@ -45,11 +48,14 @@
</item>
<item row="1" column="1" >
<widget class="QSpinBox" name="m_inputNbNeighbors" >
<property name="minimum" >
<number>6</number>
</property>
<property name="maximum" >
<number>9999</number>
</property>
<property name="value" >
<number>7</number>
<number>24</number>
</property>
</widget>
</item>

View File

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

View File

@ -5,14 +5,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>279</width>
<height>97</height>
<width>311</width>
<height>120</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
<string>Normal estimation</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
@ -24,12 +24,12 @@
<widget class="QComboBox" name="m_inputDirection" >
<item>
<property name="text" >
<string>plane</string>
<string>quadric</string>
</property>
</item>
<item>
<property name="text" >
<string>quadric</string>
<string>plane</string>
</property>
</item>
</widget>
@ -40,13 +40,13 @@
<string> neighbors</string>
</property>
<property name="minimum" >
<number>4</number>
<number>6</number>
</property>
<property name="maximum" >
<number>9999</number>
</property>
<property name="value" >
<number>16</number>
<number>18</number>
</property>
</widget>
</item>
@ -72,13 +72,13 @@
<string> neighbors</string>
</property>
<property name="minimum" >
<number>4</number>
<number>6</number>
</property>
<property name="maximum" >
<number>9999</number>
</property>
<property name="value" >
<number>16</number>
<number>18</number>
</property>
</widget>
</item>
@ -88,7 +88,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>

View File

@ -5,14 +5,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>305</width>
<height>149</height>
<width>399</width>
<height>155</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
<string>Poisson reconstruction</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
@ -97,7 +97,7 @@
<item row="3" column="1" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>

View File

@ -5,6 +5,7 @@
#include <CGAL/grid_simplify_point_set.h>
#include <CGAL/random_simplify_point_set.h>
#include <CGAL/compute_average_spacing.h>
#include <CGAL/Timer.h>
#include <CGAL/Memory_sizer.h>
@ -13,7 +14,6 @@
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QInputDialog>
#include <QMessageBox>
#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());

View File

@ -5,14 +5,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>372</width>
<height>137</height>
<width>403</width>
<height>153</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
<string>Simplification</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
@ -50,13 +50,13 @@
<number>2</number>
</property>
<property name="minimum" >
<double>1.000000000000000</double>
<double>0.100000000000000</double>
</property>
<property name="maximum" >
<double>100.000000000000000</double>
</property>
<property name="singleStep" >
<double>1.000000000000000</double>
<double>0.100000000000000</double>
</property>
<property name="value" >
<double>50.000000000000000</double>
@ -73,22 +73,22 @@
<item row="2" column="1" >
<widget class="QDoubleSpinBox" name="m_gridCellSize" >
<property name="suffix" >
<string> * point set radius</string>
<string> * average spacing</string>
</property>
<property name="decimals" >
<number>7</number>
<number>2</number>
</property>
<property name="minimum" >
<double>0.000100000000000</double>
<double>0.100000000000000</double>
</property>
<property name="maximum" >
<double>1.000000000000000</double>
<double>10.000000000000000</double>
</property>
<property name="singleStep" >
<double>0.000100000000000</double>
<double>0.100000000000000</double>
</property>
<property name="value" >
<double>0.004000000000000</double>
<double>1.000000000000000</double>
</property>
</widget>
</item>
@ -98,7 +98,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>

View File

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