ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
FeaturesInterface.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 // ##########################################################################
11 // # #
12 // # ACLOUDVIEWER PLUGIN: q3DMASC #
13 // # #
14 // # This program is free software; you can redistribute it and/or modify #
15 // # it under the terms of the GNU General Public License as published by #
16 // # the Free Software Foundation; version 2 or later of the License. #
17 // # #
18 // # This program is distributed in the hope that it will be useful, #
19 // # but WITHOUT ANY WARRANTY; without even the implied warranty of #
20 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
21 // # GNU General Public License for more details. #
22 // # #
23 // # COPYRIGHT: Dimitri Lague / CNRS / UEB #
24 // # #
25 // ##########################################################################
26 
27 // Local
28 #include "CorePoints.h"
29 #include "ScalarFieldCollector.h"
30 #include "ScalarFieldWrappers.h"
31 
32 // Qt
33 #include <QString>
34 
35 // system
36 #include <assert.h>
37 
38 class ccPointCloud;
39 
40 namespace CCLib {
41 class ScalarField;
42 };
43 
44 namespace masc {
46 struct Feature {
47 public: // shortcuts
49  typedef QSharedPointer<Feature> Shared;
50 
52  typedef std::vector<Shared> Set;
53 
54 public: // enumerators
56  enum class Type {
57  PointFeature,
62  Invalid
63  };
64 
65  enum Stat {
68  MODE, // number with the highest frequency
70  STD,
72  SKEW //(SKEW = (MEAN - MODE)/STD)
73  };
74 
75  static QString StatToString(Stat stat) {
76  switch (stat) {
77  case MEAN:
78  return "MEAN";
79  case MODE:
80  return "MODE";
81  case MEDIAN:
82  return "MEDIAN";
83  case STD:
84  return "STD";
85  case RANGE:
86  return "RANGE";
87  case SKEW:
88  return "SKEW";
89  default:
90  break;
91  };
92  return QString();
93  }
94 
96 
97  static QString OpToString(Operation op) {
98  switch (op) {
99  case MINUS:
100  return "MINUS";
101  case PLUS:
102  return "PLUS";
103  case DIVIDE:
104  return "DIVIDE";
105  case MULTIPLY:
106  return "MULTIPLY";
107  default:
108  break;
109  };
110  return QString();
111  }
112 
114  struct Source {
115  using Set = std::vector<Source>;
116 
118  enum Type { ScalarField = 0, DimX, DimY, DimZ, Red, Green, Blue };
119 
120  Source(Type t = ScalarField, QString n = QString())
121  : type(t), name(n) {}
122 
124  QString name;
125  };
126 
128  static bool ExtractSources(const Set& features, Source::Set& sources);
129 
131  static bool SaveSources(const Source::Set& sources, QString filename);
132 
134  static bool LoadSources(Source::Set& sources, QString filename);
135 
136 public: // methods
138  Feature(double p_scale = std::numeric_limits<double>::quiet_NaN(),
140  QString p_sourceName = QString())
141  : scale(p_scale),
142  cloud1(nullptr),
143  cloud2(nullptr),
144  source(p_source, p_sourceName),
145  stat(NO_STAT),
146  op(NO_OPERATION),
147  sf1WasAlreadyExisting(false),
148  sf2WasAlreadyExisting(false) {}
149 
151  virtual ~Feature() {}
152 
154  virtual Type getType() const = 0;
155 
157  virtual QString toString() const = 0;
158 
160  virtual Feature::Shared clone() const = 0;
161 
163  virtual bool prepare(
164  const CorePoints& corePoints,
165  QString& error,
166  cloudViewer::GenericProgressCallback* progressCb = nullptr,
167  SFCollector* generatedScalarFields = nullptr) = 0;
168 
170  virtual bool finish(const CorePoints& corePoints,
171  QString& error) { /* does nothing by default*/
172  return true;
173  }
174 
176  inline bool scaled() const { return std::isfinite(scale); }
177 
179  virtual bool checkValidity(QString corePointRole, QString& error) const {
180  unsigned char cloudCount = (cloud1 ? (cloud2 ? 2 : 1) : 0);
181  if (cloudCount == 0) {
182  error = "feature has no associated cloud";
183  return false;
184  }
185 
186  if (stat != NO_STAT && getType() != Type::PointFeature) {
187  error = "STAT measures can only be defined on Point features";
188  return false;
189  }
190 
191  if (op != NO_OPERATION && cloudCount < 2) {
192  error = "at least two clouds are required to apply math operations";
193  return false;
194  }
195 
196  return true;
197  }
198 
199 public: // helpers
202  static bool CheckSFExistence(ccPointCloud* cloud, const char* resultSFName);
203 
207  ccPointCloud* cloud,
208  const char* resultSFName,
209  SFCollector* generatedScalarFields /*= nullptr*/,
210  SFCollector::Behavior behavior);
211 
213  static ScalarType PerformMathOp(double s1, double s2, Operation op);
214 
217  static bool PerformMathOp(cloudViewer::ScalarField* sf1,
218  const cloudViewer::ScalarField* sf2,
219  Operation op);
220 
223  static bool PerformMathOp(const IScalarFieldWrapper& sf1,
224  const IScalarFieldWrapper& sf2,
225  Operation op,
226  cloudViewer::ScalarField* outSF);
227 
228 public: // members
230  double scale;
231 
234 
235  Source source; // values source
236 
237  Stat stat; // only considered if a scale is defined
238  Operation op; // only considered if 2 clouds are defined
239 
241  bool sf2WasAlreadyExisting; // only considered if a second scalar field may
242  // be necessary (PointFeature,
243  // NeighborhoodFeature)
244 };
245 } // namespace masc
std::string filename
SF collector.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
A simple scalar field (to be associated to a point cloud)
Definition: ScalarField.h:25
static void error(char *msg)
Definition: lsd.c:159
3DMASC classifier
cloudViewer::GenericIndexedCloud * corePoints
Core points descriptor.
Definition: CorePoints.h:39
Sources of values for this feature.
Source(Type t=ScalarField, QString n=QString())
std::vector< Source > Set
Generic feature descriptor.
virtual ~Feature()
Destructor.
static bool CheckSFExistence(ccPointCloud *cloud, const char *resultSFName)
static bool ExtractSources(const Set &features, Source::Set &sources)
Extracts the set of 'sources' from a set of features.
virtual bool checkValidity(QString corePointRole, QString &error) const
Checks the feature definition validity.
static bool SaveSources(const Source::Set &sources, QString filename)
Saves a set of 'sources' to a file.
virtual Feature::Shared clone() const =0
Clones this feature.
std::vector< Shared > Set
Set of features.
virtual bool finish(const CorePoints &corePoints, QString &error)
Finishes the feature preparation (update the scalar field, etc.)
static bool LoadSources(Source::Set &sources, QString filename)
Loads a set of 'sources' from a file.
virtual bool prepare(const CorePoints &corePoints, QString &error, cloudViewer::GenericProgressCallback *progressCb=nullptr, SFCollector *generatedScalarFields=nullptr)=0
Prepares the feature (compute the scalar field, etc.)
ccPointCloud * cloud1
QSharedPointer< Feature > Shared
Shared type.
virtual Type getType() const =0
Returns the type (must be reimplemented by child struct)
bool scaled() const
Returns whether the feature has an associated scale.
static QString StatToString(Stat stat)
virtual QString toString() const =0
Returns the formatted description.
Type
Feature type.
ccPointCloud * cloud2
static ScalarType PerformMathOp(double s1, double s2, Operation op)
Performs a mathematical operation between two scalars.
Feature(double p_scale=std::numeric_limits< double >::quiet_NaN(), Source::Type p_source=Source::ScalarField, QString p_sourceName=QString())
Default constructor.
static QString OpToString(Operation op)
double scale
Scale (diameter)
static cloudViewer::ScalarField * PrepareSF(ccPointCloud *cloud, const char *resultSFName, SFCollector *generatedScalarFields, SFCollector::Behavior behavior)