ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvCropTool.cpp
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 #include "ecvCropTool.h"
9 
10 // CV_DB_LIB
11 #include <CVLog.h>
12 #include <ecvHObject.h>
13 #include <ecvMaterial.h>
14 #include <ecvMaterialSet.h>
15 #include <ecvMesh.h>
16 #include <ecvPointCloud.h>
17 #include <ecvScalarField.h>
18 
19 // CV_CORE_LIB
21 #include <SimpleMesh.h>
22 
24  const ccBBox& box,
25  bool inside /*=true*/,
26  const ccGLMatrix* meshRotation /*=0*/) {
27  assert(entity);
28  if (!entity) {
29  return 0;
30  }
31 
32  if (entity->isA(CV_TYPES::POINT_CLOUD)) {
33  ccPointCloud* cloud = static_cast<ccPointCloud*>(entity);
34 
35  cloudViewer::ReferenceCloud* selection = cloud->crop(box, inside);
36  if (!selection) {
37  // process failed!
38  CVLog::Warning(QString("[Crop] Failed to crop cloud '%1'!")
39  .arg(cloud->getName()));
40  return 0;
41  }
42 
43  if (selection->size() == 0) {
44  // no points fall inside selection!
46  QString("[Crop] No point of the cloud '%1' falls %2side "
47  "the input box!")
48  .arg(cloud->getName(), (inside ? "in" : "out")));
49  delete selection;
50  return 0;
51  }
52 
53  // crop
54  ccPointCloud* croppedEnt = cloud->partialClone(selection);
55  delete selection;
56  selection = 0;
57 
58  return croppedEnt;
59  } else if (entity->isKindOf(CV_TYPES::MESH)) {
60  ccGenericMesh* mesh = static_cast<ccGenericMesh*>(entity);
62  params.bbMin = CCVector3d::fromArray(box.minCorner().u);
63  params.bbMax = CCVector3d::fromArray(box.maxCorner().u);
64  params.generateOutsideMesh = !inside;
65  params.trackOrigIndexes = mesh->hasColors() ||
66  mesh->hasScalarFields() ||
67  mesh->hasMaterials();
68 
69  ccGenericPointCloud* origVertices = mesh->getAssociatedCloud();
70  assert(origVertices);
71  ccGenericPointCloud* cropVertices = origVertices;
72  if (meshRotation) {
73  ccPointCloud* rotatedVertices = ccPointCloud::From(origVertices);
74  if (!rotatedVertices) {
75  CVLog::Warning(QString("[Crop] Failed to crop mesh '%1'! (not "
76  "enough memory)")
77  .arg(mesh->getName()));
78  return 0;
79  }
80  rotatedVertices->setGLTransformation(*meshRotation);
81  rotatedVertices->applyGLTransformation_recursive();
82  cropVertices = rotatedVertices;
83  }
84 
86  mesh, cropVertices, params)) {
87  // process failed!
88  CVLog::Warning(QString("[Crop] Failed to crop mesh '%1'!")
89  .arg(mesh->getName()));
90  }
91 
92  if (cropVertices != origVertices) {
93  // don't need those anymore
94  delete cropVertices;
95  cropVertices = origVertices;
96  }
97 
98  cloudViewer::SimpleMesh* tempMesh =
99  inside ? params.insideMesh : params.outsideMesh;
100 
101  // output
102  ccMesh* croppedMesh = 0;
103 
104  if (tempMesh) {
105  ccPointCloud* croppedVertices =
106  ccPointCloud::From(tempMesh->vertices());
107  if (croppedVertices) {
108  if (meshRotation) {
109  // apply inverse transformation
110  croppedVertices->setGLTransformation(
111  meshRotation->inverse());
112  croppedVertices->applyGLTransformation_recursive();
113  }
114  croppedMesh = new ccMesh(tempMesh, croppedVertices);
115  croppedMesh->addChild(croppedVertices);
116  croppedVertices->setEnabled(false);
117  if (croppedMesh->size() == 0) {
118  // no points fall inside selection!
119  CVLog::Warning(QString("[Crop] No triangle of the mesh "
120  "'%1' falls %2side the input box!")
121  .arg(mesh->getName(),
122  (inside ? "in" : "out")));
123  delete croppedMesh;
124  croppedMesh = 0;
125  } else {
126  assert(origVertices);
127 
128  // import parameters
129  croppedVertices->importParametersFrom(origVertices);
130  croppedMesh->importParametersFrom(mesh);
131 
132  // compute normals if necessary
133  if (mesh->hasNormals()) {
134  bool success = false;
135  if (mesh->hasTriNormals())
136  success = croppedMesh->computePerTriangleNormals();
137  else
138  success = croppedMesh->computePerVertexNormals();
139 
140  if (!success) {
142  "[Crop] Failed to compute normals on the "
143  "output mesh (not enough memory)");
144  }
145  croppedMesh->showNormals(success &&
146  mesh->normalsShown());
147  }
148 
149  // import other features if necessary
150  if (params.trackOrigIndexes) {
151  const std::vector<unsigned>& origTriIndexes =
152  inside ? params.origTriIndexesMapInside
153  : params.origTriIndexesMapOutside;
154 
155  try {
156  // per vertex features (RGB color & scalar fields)
157  if (origVertices->hasColors() ||
158  origVertices->hasScalarFields()) {
159  // we use flags to avoid processing the same
160  // vertex multiple times
161  std::vector<bool> vertProcessed(
162  croppedVertices->size(), false);
163 
164  // colors
165  bool importColors = false;
166  if (origVertices->hasColors()) {
167  importColors =
168  croppedVertices
169  ->resizeTheRGBTable();
170  if (!importColors)
172  "[Crop] Failed to transfer RGB "
173  "colors on the output mesh "
174  "(not enough memory)");
175  }
176 
177  // scalar fields
178  std::vector<ccScalarField*> importedSFs;
179  ccPointCloud* origVertices_pc = 0;
180  if (origVertices->hasScalarFields()) {
181  origVertices_pc =
182  origVertices->isA(
184  ? static_cast<
185  ccPointCloud*>(
186  origVertices)
187  : 0;
188  unsigned sfCount =
189  origVertices_pc
190  ? origVertices_pc
192  : 1;
193 
194  // now try to import each SF
195  for (unsigned i = 0; i < sfCount; ++i) {
196  int sfIdx = croppedVertices->addScalarField(
197  origVertices_pc
198  ? origVertices_pc
199  ->getScalarField(
200  i)
201  ->getName()
202  : "Scalar field");
203  if (sfIdx >= 0) {
204  ccScalarField* sf = static_cast<
205  ccScalarField*>(
206  croppedVertices
207  ->getScalarField(
208  i));
209  sf->fill(NAN_VALUE);
210  if (origVertices_pc) {
211  // import display parameters if
212  // possible
213  ccScalarField* originSf = static_cast<
214  ccScalarField*>(
215  origVertices_pc
216  ->getScalarField(
217  i));
218  assert(originSf);
219  // copy display parameters
221  originSf);
222  }
223  importedSFs.push_back(sf);
224  } else {
226  "[Crop] Failed to transfer "
227  "one or several scalar "
228  "fields on the output mesh "
229  "(not enough memory)");
230  // we can stop right now as all SFs
231  // have the same size!
232  break;
233  }
234  }
235 
236  // default displayed SF
237  if (origVertices_pc)
238  croppedVertices->setCurrentDisplayedScalarField(std::max(
239  static_cast<int>(
240  croppedVertices
241  ->getNumberOfScalarFields()) -
242  1,
243  origVertices_pc
244  ->getCurrentDisplayedScalarFieldIndex()));
245  else
246  croppedVertices
248  0);
249  }
250  bool importSFs = !importedSFs.empty();
251 
252  if (importColors || importSFs) {
253  // for each new triangle
254  for (unsigned i = 0;
255  i < croppedMesh->size(); ++i) {
256  // get the origin triangle
257  unsigned origTriIndex =
258  origTriIndexes[i];
259  const cloudViewer::VerticesIndexes* tsio =
261  origTriIndex);
262 
263  // get the new triangle
264  const cloudViewer::VerticesIndexes* tsic =
265  croppedMesh
267  i);
268 
269  // we now have to test the 3 vertices of
270  // the new triangle
271  for (unsigned j = 0; j < 3; ++j) {
272  unsigned vertIndex = tsic->i[j];
273 
274  if (vertProcessed[vertIndex]) {
275  // vertex has already been
276  // process
277  continue;
278  }
279 
280  const CCVector3* Vcj =
281  croppedVertices->getPoint(
282  vertIndex);
283 
284  // we'll deduce its color and SFs
285  // values by triangulation
286  if (importColors) {
287  ecvColor::Rgb col;
288  if (mesh->interpolateColors(
289  origTriIndex, *Vcj,
290  col)) {
291  croppedVertices
292  ->setPointColor(
293  vertIndex,
294  col);
295  }
296  }
297 
298  if (importSFs) {
299  CCVector3d w;
301  origTriIndex, *Vcj, w);
302 
303  // import SFs
304  for (unsigned s = 0;
305  s <
306  static_cast<unsigned>(
307  importedSFs
308  .size());
309  ++s) {
310  CCVector3d scalarValues(
311  0, 0, 0);
312  if (origVertices_pc) {
313  const cloudViewer::ScalarField* sf =
314  origVertices_pc
315  ->getScalarField(
316  s);
317  scalarValues.x =
318  sf->getValue(
319  tsio->i1);
320  scalarValues.y =
321  sf->getValue(
322  tsio->i2);
323  scalarValues.z =
324  sf->getValue(
325  tsio->i3);
326  } else {
327  assert(s == 0);
328  scalarValues.x =
329  origVertices->getPointScalarValue(
330  tsio->i1);
331  scalarValues.y =
332  origVertices->getPointScalarValue(
333  tsio->i2);
334  scalarValues.z =
335  origVertices->getPointScalarValue(
336  tsio->i3);
337  }
338 
339  ScalarType sVal = static_cast<
340  ScalarType>(
341  scalarValues.dot(
342  w));
343  importedSFs[s]->setValue(
344  vertIndex, sVal);
345  }
346  }
347 
348  // update 'processed' flag
349  vertProcessed[vertIndex] = true;
350  }
351  }
352 
353  for (size_t s = 0; s < importedSFs.size();
354  ++s) {
355  importedSFs[s]->computeMinAndMax();
356  }
357 
358  croppedVertices->showColors(
359  importColors &&
360  origVertices->colorsShown());
361  croppedVertices->showSF(
362  importSFs &&
363  origVertices->sfShown());
364  croppedMesh->showColors(
365  importColors &&
366  mesh->colorsShown());
367  croppedMesh->showSF(importSFs &&
368  mesh->sfShown());
369  }
370  }
371 
372  // per-triangle features (materials)
373  if (mesh->hasMaterials()) {
374  const ccMaterialSet* origMaterialSet =
375  mesh->getMaterialSet();
376  assert(origMaterialSet);
377 
378  if (origMaterialSet &&
379  !origMaterialSet->empty() &&
380  croppedMesh
382  std::vector<int> materialUsed(
383  origMaterialSet->size(), -1);
384 
385  // per-triangle materials
386  for (unsigned i = 0;
387  i < croppedMesh->size(); ++i) {
388  // get the origin triangle
389  unsigned origTriIndex =
390  origTriIndexes[i];
391  int mtlIndex =
392  mesh->getTriangleMtlIndex(
393  origTriIndex);
394  croppedMesh->addTriangleMtlIndex(
395  mtlIndex);
396 
397  if (mtlIndex >= 0)
398  materialUsed[mtlIndex] = 1;
399  }
400  // import materials
401  {
402  size_t materialUsedCount = 0;
403  {
404  for (size_t i = 0;
405  i < materialUsed.size(); ++i)
406  if (materialUsed[i] == 1)
407  ++materialUsedCount;
408  }
409  if (materialUsedCount ==
410  materialUsed.size()) {
411  // nothing to do, we use all input
412  // materials
413  croppedMesh->setMaterialSet(
414  origMaterialSet->clone());
415  } else {
416  // create a subset of the input
417  // materials
418  ccMaterialSet* matSet =
419  new ccMaterialSet(
420  origMaterialSet
421  ->getName());
422  {
423  matSet->reserve(
424  materialUsedCount);
425  for (size_t i = 0;
426  i < materialUsed.size();
427  ++i) {
428  if (materialUsed[i] >= 0) {
429  matSet->push_back(ccMaterial::Shared(
430  new ccMaterial(
431  *origMaterialSet
432  ->at(i))));
433  // update index
434  materialUsed[i] =
435  static_cast<
436  int>(
437  matSet->size()) -
438  1;
439  }
440  }
441  }
442  croppedMesh->setMaterialSet(matSet);
443 
444  // and update the materials indexes!
445  for (unsigned i = 0;
446  i < croppedMesh->size(); ++i) {
447  int mtlIndex =
448  croppedMesh
450  i);
451  if (mtlIndex >= 0) {
452  assert(mtlIndex <
453  static_cast<int>(
454  materialUsed
455  .size()));
456  croppedMesh->setTriangleMtlIndex(
457  i,
458  materialUsed
459  [mtlIndex]);
460  }
461  }
462  }
463  }
464  croppedMesh->showMaterials(
465  mesh->materialsShown());
466  } else {
468  "[Crop] Failed to transfer "
469  "materials on the output mesh (not "
470  "enough memory)");
471  }
472  // per-triangle texture coordinates
473  if (mesh->hasPerTriangleTexCoordIndexes()) {
474  TextureCoordsContainer* texCoords =
476  if (croppedMesh
477  ->reservePerTriangleTexCoordIndexes() &&
478  texCoords->reserveSafe(
479  croppedMesh->size() * 3)) {
480  // for each new triangle
481  for (unsigned i = 0;
482  i < croppedMesh->size(); ++i) {
483  // get the origin triangle
484  unsigned origTriIndex =
485  origTriIndexes[i];
486  TexCoords2D* tx1 = nullptr;
487  TexCoords2D* tx2 = nullptr;
488  TexCoords2D* tx3 = nullptr;
490  origTriIndex, tx1, tx2,
491  tx3);
492  // get the new triangle
493  const cloudViewer::VerticesIndexes* tsic =
494  croppedMesh
496  i);
497  // for each vertex of the new
498  // triangle
499  int texIndexes[3] = {-1, -1, -1};
500  for (unsigned j = 0; j < 3; ++j) {
501  unsigned vertIndex = tsic->i[j];
502  const CCVector3* Vcj =
503  croppedVertices->getPoint(
504  vertIndex);
505  // intepolation weights
506  CCVector3d w;
508  origTriIndex, *Vcj, w);
509  if ((tx1 ||
510  cloudViewer::
512  w.u[0])) &&
513  (tx2 ||
514  cloudViewer::
516  w.u[1])) &&
517  (tx3 ||
518  cloudViewer::
520  w.u[2]))) {
521  TexCoords2D t(
522  static_cast<float>(
523  (tx1 ? tx1->tx * w.u[0]
524  : 0.0) +
525  (tx2 ? tx2->tx * w.u[1]
526  : 0.0) +
527  (tx3 ? tx3->tx * w.u[2]
528  : 0.0)),
529  static_cast<float>(
530  (tx1 ? tx1->ty * w.u[0]
531  : 0.0) +
532  (tx2 ? tx2->ty * w.u[1]
533  : 0.0) +
534  (tx3 ? tx3->ty * w.u[2]
535  : 0.0)));
536  texCoords->addElement(t);
537  texIndexes[j] =
538  static_cast<int>(
539  texCoords
540  ->currentSize()) -
541  1;
542  }
543  }
544 
545  croppedMesh
547  texIndexes[0],
548  texIndexes[1],
549  texIndexes[2]);
550  }
551  croppedMesh->setTexCoordinatesTable(
552  texCoords);
553  } else {
555  "[Crop] Failed to transfer "
556  "texture coordinates on the "
557  "output mesh (not enough "
558  "memory)");
559  delete texCoords;
560  texCoords = 0;
561  }
562  }
563  }
564  } catch (const std::bad_alloc&) {
566  "[Crop] Failed to transfer per-vertex "
567  "features (color, SF values, etc.) on the "
568  "output mesh (not enough memory)");
569  croppedVertices->unallocateColors();
570  croppedVertices->deleteAllScalarFields();
571  }
572  }
573  }
574  } else {
576  "[Crop] Failed to create output mesh vertices (not "
577  "enough memory)");
578  }
579  }
580 
581  // clean memory
582  if (params.insideMesh) {
583  delete params.insideMesh;
584  params.insideMesh = 0;
585  }
586  if (params.outsideMesh) {
587  delete params.outsideMesh;
588  params.outsideMesh = 0;
589  }
590 
591  // if (croppedMesh)
592  //{
593  // croppedMesh->setDisplay_recursive(entity->getDisplay());
594  // }
595  return croppedMesh;
596  }
597 
598  // unhandled entity
599  CVLog::Warning("[Crop] Unhandled entity type");
600  return 0;
601 }
constexpr ScalarType NAN_VALUE
NaN as a ScalarType value.
Definition: CVConst.h:76
int size
cmdLineReadable * params[]
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
Array of 2D texture coordinates.
Type y
Definition: CVGeom.h:137
Type u[3]
Definition: CVGeom.h:139
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
Type dot(const Vector3Tpl &v) const
Dot product.
Definition: CVGeom.h:408
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
Definition: CVGeom.h:268
bool reserveSafe(size_t count)
Reserves memory (no exception thrown)
Definition: ecvArray.h:56
unsigned currentSize() const
Definition: ecvArray.h:112
void addElement(const Type &value)
Definition: ecvArray.h:105
Bounding box structure.
Definition: ecvBBox.h:25
static ccHObject * Crop(ccHObject *entity, const ccBBox &box, bool inside=true, const ccGLMatrix *meshRotation=0)
Crops the input entity.
Definition: ecvCropTool.cpp:23
virtual bool colorsShown() const
Returns whether colors are shown or not.
virtual bool hasColors() const
Returns whether colors are enabled or not.
virtual bool sfShown() const
Returns whether active scalar field is visible.
virtual bool normalsShown() const
Returns whether normals are shown or not.
virtual bool hasNormals() const
Returns whether normals are enabled or not.
virtual void showColors(bool state)
Sets colors visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
virtual bool hasScalarFields() const
Returns whether one or more scalar fields are instantiated.
virtual void setGLTransformation(const ccGLMatrix &trans)
Associates entity with a GL transformation (rotation + translation)
ccGLMatrixTpl< T > inverse() const
Returns inverse transformation.
Float version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:19
Generic mesh interface.
virtual bool materialsShown() const
Sets whether textures/material should be displayed or not.
void showNormals(bool state) override
Sets normals visibility.
void importParametersFrom(const ccGenericMesh *mesh)
Imports the parameters from another mesh.
virtual bool hasPerTriangleTexCoordIndexes() const =0
Returns whether this mesh as per-triangle triplets of tex coords indexes.
virtual const ccMaterialSet * getMaterialSet() const =0
virtual bool hasTriNormals() const =0
Returns whether the mesh has per-triangle normals.
virtual int getTriangleMtlIndex(unsigned triangleIndex) const =0
Returns a given triangle material indexes.
virtual ccGenericPointCloud * getAssociatedCloud() const =0
Returns the vertices cloud.
virtual bool interpolateColors(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &C)=0
Interpolates RGB colors inside a given triangle.
virtual void computeInterpolationWeights(unsigned triIndex, const CCVector3 &P, CCVector3d &weights) const
Returns the (barycentric) interpolation weights for a given triangle.
virtual void getTriangleTexCoordinates(unsigned triIndex, TexCoords2D *&tx1, TexCoords2D *&tx2, TexCoords2D *&tx3) const =0
Returns per-triangle texture coordinates (pointer to)
virtual void showMaterials(bool state)
Sets whether textures should be displayed or not.
virtual bool hasMaterials() const =0
A 3D cloud interface with associated features (color, normals, octree, etc.)
void importParametersFrom(const ccGenericPointCloud *cloud)
Imports the parameters from another cloud.
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
void applyGLTransformation_recursive(const ccGLMatrix *trans=nullptr)
Applies the active OpenGL transformation to the entity (recursive)
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
Mesh (triangle) material.
ccMaterialSet * clone() const
Clones materials set.
Mesh (triangle) material.
Definition: ecvMaterial.h:28
QSharedPointer< ccMaterial > Shared
Shared type.
Definition: ecvMaterial.h:33
Triangular mesh.
Definition: ecvMesh.h:35
cloudViewer::VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex) override
Returns the indexes of the vertices of a given triangle.
bool reservePerTriangleMtlIndexes()
Reserves memory to store per-triangle material index.
void addTriangleMtlIndex(int mtlIndex)
Adds triangle material index for next triangle.
void setTriangleMtlIndex(unsigned triangleIndex, int mtlIndex)
Sets triangle material indexes.
bool computePerTriangleNormals()
Computes per-triangle normals.
void setMaterialSet(ccMaterialSet *materialSet, bool autoReleaseOldMaterialSet=true)
Sets associated material set (may be shared)
void addTriangleTexCoordIndexes(int i1, int i2, int i3)
Adds a triplet of tex coords indexes for next triangle.
void setTexCoordinatesTable(TextureCoordsContainer *texCoordsTable, bool autoReleaseOldTable=true)
Sets per-triangle texture coordinates array (may be shared)
bool computePerVertexNormals()
Computes per-vertex normals.
virtual unsigned size() const override
Returns the number of triangles.
int getTriangleMtlIndex(unsigned triangleIndex) const override
Returns a given triangle material indexes.
virtual QString getName() const
Returns object name.
Definition: ecvObject.h:72
bool isA(CV_CLASS_ENUM type) const
Definition: ecvObject.h:131
virtual void setEnabled(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:102
bool isKindOf(CV_CLASS_ENUM type) const
Definition: ecvObject.h:128
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
void unallocateColors()
Erases the cloud colors.
void deleteAllScalarFields() override
Deletes all scalar fields associated to this cloud.
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
bool resizeTheRGBTable(bool fillWithWhite=false)
Resizes the RGB colors array.
cloudViewer::ReferenceCloud * crop(const ccBBox &box, bool inside=true) override
Crops the cloud inside (or outside) a bounding box.
static ccPointCloud * From(const cloudViewer::GenericIndexedCloud *cloud, const ccGenericPointCloud *sourceCloud=nullptr)
Creates a new point cloud object from a GenericIndexedCloud.
void setPointColor(size_t pointIndex, const ecvColor::Rgb &col)
Sets a particular point color.
ccPointCloud * partialClone(const cloudViewer::ReferenceCloud *selection, int *warnings=nullptr, bool withChildEntities=true) const
Creates a new point cloud object from a ReferenceCloud (selection)
A scalar field associated to display-related parameters.
void importParametersFrom(const ccScalarField *sf)
Imports the parameters from another scalar field.
const Vector3Tpl< T > & maxCorner() const
Returns max corner (const)
Definition: BoundingBox.h:156
const Vector3Tpl< T > & minCorner() const
Returns min corner (const)
Definition: BoundingBox.h:154
virtual ScalarType getPointScalarValue(unsigned pointIndex) const =0
Returns the ith point associated scalar value.
virtual VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex)=0
Returns the indexes of the vertices of a given triangle.
static bool segmentMeshWithAABox(GenericIndexedMesh *mesh, GenericIndexedCloudPersist *vertices, MeshCutterParams &ioParams, GenericProgressCallback *progressCb=nullptr)
ScalarField * getScalarField(int index) const
Returns a pointer to a specific scalar field.
unsigned getNumberOfScalarFields() const
Returns the number of associated (and active) scalar fields.
unsigned size() const override
Definition: PointCloudTpl.h:38
const CCVector3 * getPoint(unsigned index) const override
A very simple point cloud (no point duplication)
unsigned size() const override
Returns the number of points.
A simple scalar field (to be associated to a point cloud)
Definition: ScalarField.h:25
void fill(ScalarType fillValue=0)
Fills the array with a particular value.
Definition: ScalarField.h:77
ScalarType & getValue(std::size_t index)
Definition: ScalarField.h:92
A simple mesh structure, with index-based vertex access.
Definition: SimpleMesh.h:26
const GenericIndexedCloud * vertices() const
Returns the vertices.
Definition: SimpleMesh.h:67
RGB color structure.
Definition: ecvColorTypes.h:49
int max(int a, int b)
Definition: cutil_math.h:48
@ MESH
Definition: CVTypes.h:105
@ POINT_CLOUD
Definition: CVTypes.h:104
Generic file read and write utility for python interface.
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
Definition: CVMath.h:23
Rgb at(size_t color_id)
2D texture coordinates
Input/output parameters for the segmentMeshWithAAPlane method.
Triangle described by the indexes of its 3 vertices.