mercredi 30 juin 2021

Orient point normals using Cgals's mst_orient_normals() while maintaining original point order

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