Cgals's mst_orient_normals()
method modifies the order of input points so as to pack all successfully oriented points first, and returns an iterator over the first point with an unoriented normal. I would like to maintain the order of my input points. To achieve this I currently need to use a dedicated index as shown below (note that this code is indicative only). Is there a more efficient way to achieve this that does not involve adding an index to the tuple and then sorting by this index?
#include <CGAL/pca_estimate_normals.h>
#include <CGAL/mst_orient_normals.h>
#include <CGAL/property_map.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/tags.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point3;
typedef Kernel::Vector_3 Vector;
typedef std::tuple<int, Point3, Vector> PointVectorTuple;
typedef std::vector<PointVectorTuple> PointListwithindex;
typedef CGAL::Parallel_if_available_tag Concurrency_tag;
int main(int argc, char*argv[])
{
unsigned int nb_neighbors_pca_normals = 18; // K-nearest neighbors = 3 rings (estimate normals by PCA)
unsigned int nb_neighbors_mst = 18; // K-nearest neighbors (orient normals by MST)
PointListwithindex pointswithindex;
/**
Load indices, coordinates, and zero vector (normal in this case) into pointswithindex
**/
// Estimates normals direction.
CGAL::pca_estimate_normals<Concurrency_tag>(pointswithindex,
nb_neighbors_pca_normals,
CGAL::parameters::point_map (CGAL::Nth_of_tuple_property_map<1,PointVectorTuple>()).
normal_map (CGAL::Nth_of_tuple_property_map<2,PointVectorTuple>()));
// Orients normals.
PointListwithindex::iterator unoriented_points_begin =
CGAL::mst_orient_normals(pointswithindex,
nb_neighbors_mst,
CGAL::parameters::point_map (CGAL::Nth_of_tuple_property_map<1,PointVectorTuple>()).
normal_map(CGAL::Nth_of_tuple_property_map<2,PointVectorTuple>()));
// Sort list back by into original order using the index
std::sort(pointswithindex.begin(), pointswithindex.end(),
[](const PointVectorTuple & a,
const PointVectorTuple & b) {
return (std::get<0>(a) < std::get<0>(b));
});
}
Aucun commentaire:
Enregistrer un commentaire