ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
G3PointAction.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 #include <AnglesCustomPlot.h>
11 #include <DgmOctree.h>
12 #include <G3PointDialog.h>
13 #include <G3PointPlots.h>
14 #include <GrainsAsEllipsoids.h>
15 #include <Neighbourhood.h>
16 #include <ecvOctree.h>
17 #include <ecvPointCloud.h>
18 #include <ecvScalarField.h>
19 
20 #include <QObject>
21 #include <nanoflann.hpp>
22 #include <vector>
23 
24 #include "Eigen/Dense"
25 
27 
28 namespace G3Point {
29 class G3PointAction : public QObject {
30  Q_OBJECT
31 
32  typedef Eigen::Array<bool, Eigen::Dynamic, Eigen::Dynamic> XXb;
33  typedef Eigen::Array<bool, Eigen::Dynamic, Eigen::Dynamic> Xb;
34 
35 public:
36  explicit G3PointAction(ccPointCloud* cloud,
37  ecvMainAppInterface* app = nullptr);
39  static void createAction(ecvMainAppInterface* appInterface);
40  static void GetG3PointAction(ccPointCloud* cloud,
41  ecvMainAppInterface* app = nullptr);
42  void segment();
43  void clusterAndOrClean();
44  void getBorders();
45  bool cluster();
46  void fit();
47  void exportResults();
48  void plots();
49  void showWolman(const Eigen::ArrayXf& d_sample,
50  const Eigen::Array3d& dq_final,
51  const Eigen::Array3d& edq);
52  bool wolman();
53  bool angles();
54  bool processNewStacks(std::vector<std::vector<int>>& newStacks,
55  int pointCount);
57  bool merge(XXb& condition);
58  bool keep(Xb& condition);
59  bool cleanLabels();
60  void clean();
61 
62  template <typename T>
63  static bool EigenArrayToFile(QString name, T array);
64 
65  // A small adaptor to let nanoflann access ccPointCloud data
66  struct CloudAdaptor {
68 
69  CloudAdaptor(const ccPointCloud* c) : cloud(c) {}
70 
71  // Must return the number of data points
72  inline size_t kdtree_get_point_count() const { return cloud->size(); }
73 
74  // Returns the dim'th component of the idx'th point
75  inline float kdtree_get_pt(const size_t idx, int dim) const {
76  if (dim == 0)
77  return cloud->getPoint(static_cast<unsigned>(idx))->x;
78  else if (dim == 1)
79  return cloud->getPoint(static_cast<unsigned>(idx))->y;
80  else
81  return cloud->getPoint(static_cast<unsigned>(idx))->z;
82  }
83 
84  // Optional bounding-box computation: return false to default to a
85  // standard bbox computation loop.
86  template <class BBOX>
87  bool kdtree_get_bbox(BBOX&) const {
88  return false;
89  }
90  };
91 
92  // Typedef for a 3D KD-tree index
93  using KDTree = nanoflann::KDTreeSingleIndexAdaptor<
94  nanoflann::L2_Simple_Adaptor<float, CloudAdaptor>,
96  3 /* dim */>;
97 
98 private:
99  bool sfConvertToRandomRGB(const ccHObject::Container& selectedEntities,
100  QWidget* parent);
101  void addToStack(int index,
102  const Eigen::ArrayXi& n_donors,
103  const Eigen::ArrayXXi& donors,
104  std::vector<int>& stack);
105  int segmentLabels(bool useParallelStrategy = true);
106  double angleRot2VecMat(const Eigen::Vector3d& a, const Eigen::Vector3d& b);
107  Eigen::ArrayXXd computeMeanAngleBetweenNormalsAtBorders();
108  bool exportLocalMaximaAsCloud(const Eigen::ArrayXi& localMaximumIndexes);
109  bool updateLocalMaximumIndexes();
110  bool updateLabelsAndColors();
111  bool checkStacks(const std::vector<std::vector<int>>& stacks, int count);
112  void addToStackBraunWillett(int index,
113  const Eigen::ArrayXi& delta,
114  const Eigen::ArrayXi& Di,
115  std::vector<int>& stack,
116  int local_maximum);
117  int segmentLabelsBraunWillett();
118  void getNeighborsDistancesSlopes(unsigned index,
119  std::vector<char>& duplicates);
120  void computeNodeSurfaces();
121  bool computeNormalsAndOrientThem();
122  void orientNormals(const Eigen::Vector3d& sensorCenter);
123  bool findNearestNeighborsNanoFlann(const unsigned int globalIndex,
125  const KDTree* kdTree);
126  bool computeNormWithFlann(unsigned int index,
127  NormsTableType* theNorms,
128  const KDTree* kdTree);
129  bool computeNormals();
130  bool queryNeighbors(ccPointCloud* cloud,
131  ecvMainAppInterface* appInterface,
132  bool useParallelStrategy = true);
133  void init();
134  void showDlg();
135  void resetDlg();
136  bool setCloud(ccPointCloud* cloud);
137  void setKNN();
138 
139  int m_kNN = 20;
140  double m_radiusFactor = 0.6;
141  double m_maxAngle1 = 60;
142  double m_maxAngle2 = 10;
143  int m_nMin = 50;
144  double m_minFlatness = 0.1;
145 
146  ccPointCloud* m_cloud;
147  ecvMainAppInterface* m_app;
148  G3PointDialog* m_dlg;
149 
150  Eigen::ArrayXXi m_neighborsIndexes;
151  Eigen::ArrayXXd m_neighborsDistances;
152  Eigen::ArrayXXd m_neighborsSlopes;
153  Eigen::ArrayXXd m_normals;
154 
155  Eigen::ArrayXi m_initial_labels;
156  Eigen::ArrayXi m_initial_labelsnpoint;
157  Eigen::ArrayXi m_initial_localMaximumIndexes;
158  Eigen::ArrayXi m_labels;
159  Eigen::ArrayXi m_labelsnpoint;
160  Eigen::ArrayXi m_localMaximumIndexes;
161  Eigen::ArrayXi m_ndon;
162  Eigen::ArrayXd m_area;
163 
164  QSharedPointer<RGBAColorsTableType> m_grainColors;
165 
166  std::vector<std::vector<int>> m_initialStacks;
167  std::vector<std::vector<int>> m_stacks;
168 
169  ccOctree::Shared m_octree;
170  unsigned char m_bestOctreeLevel = 0;
172 
173  static std::shared_ptr<G3PointAction> s_g3PointAction;
174 
175  static QPointer<G3PointPlots> s_g3PointPlots;
176 
177  GrainsAsEllipsoids* m_grainsAsEllipsoids;
178 
179  int m_currentNumberOfSteps;
180 };
181 } // namespace G3Point
std::string name
int count
int points
nanoflann::KDTreeSingleIndexAdaptor< nanoflann::L2_Simple_Adaptor< float, CloudAdaptor >, CloudAdaptor, 3 > KDTree
Definition: G3PointAction.h:96
static bool EigenArrayToFile(QString name, T array)
bool buildStacksFromG3PointLabelSF(cloudViewer::ScalarField *g3PointLabel)
void showWolman(const Eigen::ArrayXf &d_sample, const Eigen::Array3d &dq_final, const Eigen::Array3d &edq)
bool keep(Xb &condition)
bool merge(XXb &condition)
G3PointAction(ccPointCloud *cloud, ecvMainAppInterface *app=nullptr)
static void GetG3PointAction(ccPointCloud *cloud, ecvMainAppInterface *app=nullptr)
bool processNewStacks(std::vector< std::vector< int >> &newStacks, int pointCount)
static void createAction(ecvMainAppInterface *appInterface)
Array of (uncompressed) 3D normals (Nx,Ny,Nz)
Type y
Definition: CVGeom.h:137
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
Definition: ecvHObject.h:337
QSharedPointer< ccOctree > Shared
Shared pointer.
Definition: ecvOctree.h:32
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
unsigned size() const override
Definition: PointCloudTpl.h:38
const CCVector3 * getPoint(unsigned index) const override
A very simple point cloud (no point duplication)
A simple scalar field (to be associated to a point cloud)
Definition: ScalarField.h:25
Main application interface (for plugins)
@ BBOX
Definition: CVTypes.h:154
CloudAdaptor(const ccPointCloud *c)
Definition: G3PointAction.h:69
float kdtree_get_pt(const size_t idx, int dim) const
Definition: G3PointAction.h:75
Container of in/out parameters for nearest neighbour(s) search.
Definition: DgmOctree.h:161