44         k{Parametrizable::get<std::size_t>(
"k")},
 
   45         sigma{Parametrizable::get<T>(
"sigma")},
 
   46         radius{Parametrizable::get<T>(
"radius")},
 
   47         itMax{Parametrizable::get<std::size_t>(
"itMax")},
 
   48         keepNormals{Parametrizable::get<bool>(
"keepNormals")},
 
   49         keepLabels{Parametrizable::get<bool>(
"keepLabels")},
 
   50         keepLambdas{Parametrizable::get<bool>(
"keepLambdas")},
 
   51         keepTensors{Parametrizable::get<bool>(
"keepTensors")}
 
   60         inPlaceFilter(output);
 
   75         tv.cfvote(cloud, 
true);
 
   78         addDescriptor(cloud, tv, 
false , 
false , 
true , 
false );
 
   82         const std::size_t itMax_ = itMax;
 
   83         const std::size_t k_ = k;
 
   84         std::size_t oldnbPts = nbPts;
 
   86         auto checkConvergence = [&oldnbPts, &it, &itMax_, &k_](
const DataPoints& pts, 
const std::size_t threshold) 
mutable ->
bool{              
 
   87                 const std::size_t nbPts = pts.getNbPoints();
 
   88                 bool ret = (oldnbPts - nbPts) < threshold;
 
   92                 return ret or ++it >= itMax_ or k_ >= nbPts;            
 
   95         const T xi3 = xi_expectation(3, sigma, radius);
 
   96         const T xi2 = xi_expectation(2, sigma, radius);
 
   97         const T xi1 = xi_expectation(1, sigma, radius);
 
  102                 filterPointness(cloud, xi3, tv.k);
 
  104                 filterCurveness(cloud, xi1, tv.k);
 
  106                 filterSurfaceness(cloud, xi2, tv.k);
 
  110                 tv.cfvote(cloud, 
true);
 
  114                 addDescriptor(cloud, tv, 
false , 
false , 
true , 
false );
 
  116         while(not checkConvergence(cloud, 5 ));
 
  119         addDescriptor(cloud, tv, 
false , 
false , 
false , 
true );
 
  126         addDescriptor(cloud, tv, keepNormals, 
true, keepLambdas, keepTensors);
 
  129         removeOutlier(cloud, tv);
 
  133 template <
typename T>
 
  138         Matrix labels  = Matrix::Zero(1, nbPts);
 
  139         Matrix l1  = PM::Matrix::Zero(1, nbPts);        
 
  140         Matrix l2  = PM::Matrix::Zero(1, nbPts);        
 
  141         Matrix l3  = PM::Matrix::Zero(1, nbPts);
 
  143         if(keepLabels_ or keepLambdas_)
 
  145         #pragma omp parallel for 
  146                 for(std::size_t i = 0; i < nbPts; ++i)
 
  153                         Vector coeff = (
Vector(3) << lambda3, (lambda2 - lambda3), (lambda1 - lambda2)).finished();
 
  154                         coeff.maxCoeff(&index);  
 
  156                         labels(i) = index + 1 ;
 
  193             std::cerr << 
"SpectralDecomposition<T>::inPlaceFilter::addDescriptor: Cannot add descriptors to pointcloud" << std::endl;
 
  202 template <
typename T>
 
  205         static constexpr 
int POINT = 0;
 
  206         static constexpr 
int CURVE = 1;
 
  207         static constexpr 
int SURFACE = 2;
 
  209         static constexpr 
T th = 0.1; 
 
  219         for (std::size_t i = 0; i < nbPts; ++i)
 
  226                 (
Vector(3) << pointness, curveness, surfaceness).finished().maxCoeff(&label); 
 
  228                 bool keepPt = ((label == POINT) and  (pointness >= th_p)) 
 
  229                         or ((label == CURVE) and  (curveness >= th_c)) 
 
  230                         or ((label == SURFACE) and  (surfaceness >= th_s));
 
  244 template <
typename T>
 
  247         constexpr std::size_t seed = 1;
 
  248         std::mt19937 gen(seed); 
 
  249         std::uniform_real_distribution<> uni01(0., 1.);
 
  256                 throw InvalidField(
"SpectralDecomposition<T>::filter: Error, lambdas field not found in descriptors.");
 
  264         for (std::size_t i = 0; i < nbPts; ++i)
 
  266                 const T randv = uni01(gen);     
 
  268                 const T nl1 = lambda1(0,i) / k;
 
  269                 const T nl2 = lambda2(0,i) / k;
 
  270                 const T nl3 = lambda3(0,i) / k;
 
  272                 if (nl1 < xi or nl2 < 0.75 * xi or nl3 < 0.75 * xi or randv < 0.5)
 
  281 template <
typename T>
 
  284         constexpr std::size_t seed = 1;
 
  285         std::mt19937 gen(seed); 
 
  286         std::uniform_real_distribution<> uni01(0., 1.);
 
  293                 throw InvalidField(
"SpectralDecomposition<T>::filter: Error, lambdas field not found in descriptors.");
 
  301         for (std::size_t i = 0; i < nbPts; ++i)
 
  303                 const T randv = uni01(gen);     
 
  305                 const T nl1 = lambda1(0,i) / k;
 
  306                 const T nl2 = lambda2(0,i) / k;
 
  307                 const T nl3 = lambda3(0,i) / k;
 
  309                 if (nl1 < xi or nl2 < xi or nl3 < 0.5 * xi or randv < 0.5)
 
  318 template <
typename T>
 
  321         constexpr std::size_t seed = 1;
 
  322         std::mt19937 gen(seed); 
 
  323         std::uniform_real_distribution<> uni01(0., 1.);
 
  330                 throw InvalidField(
"SpectralDecomposition<T>::filter: Error, lambdas field not found in descriptors.");
 
  338         for (std::size_t i = 0; i < nbPts; ++i)
 
  340                 const T randv = uni01(gen);     
 
  342                 const T nl1 = lambda1(0,i) / k;
 
  343                 const T nl2 = lambda2(0,i) / k;
 
  344                 const T nl3 = lambda3(0,i) / k;
 
  346                 if (nl1 < (5./6.) * xi or nl2 < (5./6.) * xi or nl3 < (5./6.) * xi or randv < 0.2)