ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
sm2cc.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 <Utils/sm2cc.h>
9 
10 // Local
11 #include <Utils/PCLConv.h>
12 #include <Utils/my_point_types.h>
13 
14 // PCL
15 #include <pcl/common/io.h>
16 
17 // CV_CORE_LIB
18 #include <CVTools.h>
19 #include <FileSystem.h>
20 
21 // CV_DB_LIB
22 #include <ecvMaterialSet.h>
23 #include <ecvMesh.h>
24 #include <ecvPointCloud.h>
25 #include <ecvScalarField.h>
26 
27 // system
28 #include <assert.h>
29 
30 #include <list>
31 
32 // Qt
33 #include <pcl/PCLPointField.h>
34 
35 #include <QImageReader>
36 typedef pcl::PCLPointField PCLScalarField;
37 
38 // Custom PCL point types
39 template <typename T>
40 struct PointXYZTpl {
41  union EIGEN_ALIGN16 {
42  T data[3];
43  struct {
44  T x;
45  T y;
46  T z;
47  };
48  };
49 };
50 
52  (std::int32_t, x, x)(std::int32_t,
53  y,
54  y)(std::int32_t, z, z))
55 
57  (std::int16_t, x, x)(std::int16_t,
58  y,
59  y)(std::int16_t, z, z))
60 
62  (double, x, x)(double, y, y)(double, z, z))
63 
64 size_t GetNumberOfPoints(const PCLCloud& pclCloud) {
65  return static_cast<size_t>(pclCloud.width) * pclCloud.height;
66 }
67 
68 bool ExistField(const PCLCloud& pclCloud, std::string name) {
69  for (const auto& field : pclCloud.fields)
70  if (field.name == name) return true;
71 
72  return false;
73 }
74 
75 template <class T>
76 void PCLCloudToCCCloud(const PCLCloud& pclCloud, ccPointCloud& ccCloud) {
77  size_t pointCount = GetNumberOfPoints(pclCloud);
78 
79  pcl::PointCloud<T> pcl_cloud;
80  FROM_PCL_CLOUD(pclCloud, pcl_cloud);
81  for (size_t i = 0; i < pointCount; ++i) {
82  CCVector3 P(pcl_cloud.at(i).x, pcl_cloud.at(i).y, pcl_cloud.at(i).z);
83 
84  ccCloud.addPoint(P);
85  }
86 }
87 
88 bool pcl2cc::CopyXYZ(const PCLCloud& pclCloud,
89  ccPointCloud& ccCloud,
90  uint8_t coordinateType) {
91  size_t pointCount = GetNumberOfPoints(pclCloud);
92  if (pointCount == 0) {
93  assert(false);
94  return false;
95  }
96 
97  if (!ccCloud.reserve(static_cast<unsigned>(pointCount))) {
98  return false;
99  }
100 
101  // add xyz to the input cloud taking xyz infos from the sm cloud
102  switch (coordinateType) {
103  case pcl::PCLPointField::INT16:
104  PCLCloudToCCCloud<PointXYZTpl<std::int16_t>>(pclCloud, ccCloud);
105  break;
106  case pcl::PCLPointField::INT32:
107  PCLCloudToCCCloud<PointXYZTpl<std::int32_t>>(pclCloud, ccCloud);
108  break;
109  case pcl::PCLPointField::FLOAT32:
110  PCLCloudToCCCloud<pcl::PointXYZ>(pclCloud, ccCloud);
111  break;
112  case pcl::PCLPointField::FLOAT64:
113  PCLCloudToCCCloud<PointXYZTpl<double>>(pclCloud, ccCloud);
114  break;
115  default:
116  CVLog::Warning("[PCL] Unsupported coordinate type " +
117  QString::number(coordinateType));
118  return false;
119  };
120 
121  return true;
122 }
123 
124 bool pcl2cc::CopyNormals(const PCLCloud& pclCloud, ccPointCloud& ccCloud) {
125  pcl::PointCloud<OnlyNormals>::Ptr pcl_cloud_normals(
126  new pcl::PointCloud<OnlyNormals>);
127  FROM_PCL_CLOUD(pclCloud, *pcl_cloud_normals);
128 
129  if (!ccCloud.reserveTheNormsTable()) return false;
130 
131  size_t pointCount = GetNumberOfPoints(pclCloud);
132 
133  // loop
134  for (size_t i = 0; i < pointCount; ++i) {
135  CCVector3 N(static_cast<PointCoordinateType>(
136  pcl_cloud_normals->at(i).normal_x),
137  static_cast<PointCoordinateType>(
138  pcl_cloud_normals->at(i).normal_y),
139  static_cast<PointCoordinateType>(
140  pcl_cloud_normals->at(i).normal_z));
141 
142  ccCloud.addNorm(N);
143  }
144 
145  ccCloud.showNormals(true);
146 
147  return true;
148 }
149 
150 bool pcl2cc::CopyRGB(const PCLCloud& pclCloud, ccPointCloud& ccCloud) {
151  pcl::PointCloud<OnlyRGB>::Ptr pcl_cloud_rgb(new pcl::PointCloud<OnlyRGB>);
152  FROM_PCL_CLOUD(pclCloud, *pcl_cloud_rgb);
153  size_t pointCount = GetNumberOfPoints(pclCloud);
154  if (pointCount == 0) return true;
155  if (!ccCloud.reserveTheRGBTable()) return false;
156 
157  // loop
158  for (size_t i = 0; i < pointCount; ++i) {
159  ecvColor::Rgb C(static_cast<ColorCompType>(pcl_cloud_rgb->points[i].r),
160  static_cast<ColorCompType>(pcl_cloud_rgb->points[i].g),
161  static_cast<ColorCompType>(pcl_cloud_rgb->points[i].b));
162  ccCloud.addRGBColor(C);
163  }
164 
165  ccCloud.showColors(true);
166 
167  return true;
168 }
169 
170 bool pcl2cc::CopyScalarField(const PCLCloud& pclCloud,
171  const std::string& sfName,
172  ccPointCloud& ccCloud,
173  bool overwriteIfExist /*=true*/) {
174  // if the input field already exists...
175  int id = ccCloud.getScalarFieldIndexByName(sfName.c_str());
176  if (id >= 0) {
177  if (overwriteIfExist)
178  // we simply delete it
179  ccCloud.deleteScalarField(id);
180  else
181  // we keep it as is
182  return false;
183  }
184 
185  size_t pointCount = GetNumberOfPoints(pclCloud);
186 
187  // create new scalar field
188  ccScalarField* newSF = new ccScalarField(sfName.c_str());
189  if (!newSF->reserveSafe(static_cast<unsigned>(pointCount))) {
190  newSF->release();
191  return false;
192  }
193 
194  // get PCL field
195  int field_index = pcl::getFieldIndex(pclCloud, sfName);
196  if (field_index < 0) {
197  newSF->release();
198  return false;
199  }
200  const PCLScalarField& pclField = pclCloud.fields[field_index];
201  // temporary change the name of the given field to something else -> S5c4laR
202  // should be a pretty uncommon name,
203  const_cast<PCLScalarField&>(pclField).name = "S5c4laR";
204 
205  switch (pclField.datatype) {
206  case PCLScalarField::FLOAT32: {
207  pcl::PointCloud<FloatScalar> pclScalar;
208  FROM_PCL_CLOUD(pclCloud, pclScalar);
209 
210  for (unsigned i = 0; i < pointCount; ++i) {
211  ScalarType scalar =
212  static_cast<ScalarType>(pclScalar.points[i].S5c4laR);
213  newSF->addElement(scalar);
214  }
215  } break;
216 
217  case PCLScalarField::FLOAT64: {
218  pcl::PointCloud<DoubleScalar> pclScalar;
219  FROM_PCL_CLOUD(pclCloud, pclScalar);
220 
221  for (unsigned i = 0; i < pointCount; ++i) {
222  ScalarType scalar =
223  static_cast<ScalarType>(pclScalar.points[i].S5c4laR);
224  newSF->addElement(scalar);
225  }
226  } break;
227 
228  case PCLScalarField::INT8: {
229  pcl::PointCloud<Int8Scalar> pclScalar;
230  FROM_PCL_CLOUD(pclCloud, pclScalar);
231 
232  for (unsigned i = 0; i < pointCount; ++i) {
233  ScalarType scalar =
234  static_cast<ScalarType>(pclScalar.points[i].S5c4laR);
235  newSF->addElement(scalar);
236  }
237  } break;
238 
239  case PCLScalarField::UINT8: {
240  pcl::PointCloud<UInt8Scalar> pclScalar;
241  FROM_PCL_CLOUD(pclCloud, pclScalar);
242 
243  for (unsigned i = 0; i < pointCount; ++i) {
244  ScalarType scalar =
245  static_cast<ScalarType>(pclScalar.points[i].S5c4laR);
246  newSF->addElement(scalar);
247  }
248  } break;
249 
250  case PCLScalarField::INT16: {
251  pcl::PointCloud<ShortScalar> pclScalar;
252  FROM_PCL_CLOUD(pclCloud, pclScalar);
253 
254  for (unsigned i = 0; i < pointCount; ++i) {
255  ScalarType scalar =
256  static_cast<ScalarType>(pclScalar.points[i].S5c4laR);
257  newSF->addElement(scalar);
258  }
259  } break;
260 
261  case PCLScalarField::UINT16: {
262  pcl::PointCloud<UShortScalar> pclScalar;
263  FROM_PCL_CLOUD(pclCloud, pclScalar);
264 
265  for (unsigned i = 0; i < pointCount; ++i) {
266  ScalarType scalar =
267  static_cast<ScalarType>(pclScalar.points[i].S5c4laR);
268  newSF->addElement(scalar);
269  }
270  } break;
271 
272  case PCLScalarField::UINT32: {
273  pcl::PointCloud<UIntScalar> pclScalar;
274  FROM_PCL_CLOUD(pclCloud, pclScalar);
275 
276  for (unsigned i = 0; i < pointCount; ++i) {
277  ScalarType scalar =
278  static_cast<ScalarType>(pclScalar.points[i].S5c4laR);
279  newSF->addElement(scalar);
280  }
281  } break;
282 
283  case PCLScalarField::INT32: {
284  pcl::PointCloud<IntScalar> pclScalar;
285  FROM_PCL_CLOUD(pclCloud, pclScalar);
286 
287  for (unsigned i = 0; i < pointCount; ++i) {
288  ScalarType scalar =
289  static_cast<ScalarType>(pclScalar.points[i].S5c4laR);
290  newSF->addElement(scalar);
291  }
292  } break;
293 
294  default:
295  CVLog::Warning(QString("[PCL] Field with an unmanaged type (= %1)")
296  .arg(pclField.datatype));
297  newSF->release();
298  return false;
299  }
300  newSF->computeMinAndMax();
301  int sfIdex = ccCloud.addScalarField(newSF);
302  ccCloud.setCurrentDisplayedScalarField(sfIdex);
303  ccCloud.showSF(true);
304 
305  // restore old name for the scalar field
306  const_cast<PCLScalarField&>(pclField).name = sfName;
307 
308  return true;
309 }
310 
311 void pcl2cc::FromPCLMaterial(const PCLMaterial& inMaterial,
312  ccMaterial::Shared& outMaterial) {
313  QString cPath = CVTools::ToQString(inMaterial.tex_file);
314  QString parentPath = CVTools::ToQString(
316  inMaterial.tex_file));
317  outMaterial->setName(inMaterial.tex_name.c_str());
318 
319  cPath = CVTools::ToNativeSeparators(cPath);
320 
321  if (QFile::exists(cPath)) {
322  QImageReader reader(cPath);
323 
324  QImage image = reader.read();
325  if (image.isNull()) {
327  QString("[pcl2ccMaterial] failed to read image %1, %2")
328  .arg(cPath)
329  .arg(reader.errorString()));
330  }
331 
332  if (!image.isNull()) {
333  outMaterial->setTexture(image, parentPath, false);
334  }
335  }
336 
337  std::string texName = inMaterial.tex_name;
338  // FIX special symbols bugs in vtk rendering system!
339  texName = CVTools::ExtractDigitAlpha(texName);
340  const ecvColor::Rgbaf ambientColor(inMaterial.tex_Ka.r, inMaterial.tex_Ka.g,
341  inMaterial.tex_Ka.b, inMaterial.tex_d);
342  const ecvColor::Rgbaf diffuseColor(inMaterial.tex_Kd.r, inMaterial.tex_Kd.g,
343  inMaterial.tex_Kd.b, inMaterial.tex_d);
344  const ecvColor::Rgbaf specularColor(inMaterial.tex_Ks.r,
345  inMaterial.tex_Ks.g,
346  inMaterial.tex_Ks.b, inMaterial.tex_d);
347  float shininess = inMaterial.tex_Ns;
348 
349  outMaterial->setDiffuse(diffuseColor);
350  outMaterial->setAmbient(ambientColor);
351  outMaterial->setSpecular(specularColor);
352  outMaterial->setEmission(ecvColor::night);
353  outMaterial->setShininess(shininess);
354  outMaterial->setTransparency(inMaterial.tex_d);
355  outMaterial->setIllum(inMaterial.tex_illum);
356 }
357 
358 ccMesh* pcl2cc::Convert(pcl::TextureMesh::ConstPtr textureMesh) {
359  if (!textureMesh || textureMesh->tex_polygons.empty()) {
360  return nullptr;
361  }
362 
363  // mesh size
364  std::size_t nr_meshes = textureMesh->tex_polygons.size();
365  // number of faces for header
366  std::size_t nr_faces = 0;
367  for (std::size_t m = 0; m < nr_meshes; ++m) {
368  nr_faces += textureMesh->tex_polygons[m].size();
369  }
370 
371  // create mesh from PCLMaterial
372  std::vector<pcl::Vertices> faces;
373  for (std::size_t i = 0; i < textureMesh->tex_polygons.size(); ++i) {
374  faces.insert(faces.end(), textureMesh->tex_polygons[i].begin(),
375  textureMesh->tex_polygons[i].end());
376  }
377  ccMesh* newMesh = Convert(textureMesh->cloud, faces);
378  if (!newMesh) {
379  return nullptr;
380  }
381  QString name("texture-mesh");
382  newMesh->setName(name);
383 
384  // create texture coordinates
386  if (texCoords) {
387  texCoords->reserve(nr_faces);
388 
389  bool allocated = texCoords->isAllocated();
390 
391  allocated &= newMesh->reservePerTriangleTexCoordIndexes();
392  allocated &= newMesh->reservePerTriangleMtlIndexes();
393 
394  if (!allocated) {
395  delete texCoords;
396  CVLog::Warning(QStringLiteral("[pcl2cc::Convert] Cannot allocate "
397  "texture coordinates for mesh '%1'")
398  .arg(name));
399  } else {
400  newMesh->setTexCoordinatesTable(texCoords);
401  }
402 
403  for (std::size_t m = 0; m < nr_meshes; ++m) {
404  if (textureMesh->tex_coordinates.empty()) continue;
405  for (const auto& coordinate : textureMesh->tex_coordinates[m]) {
406  const TexCoords2D coord{coordinate[0], coordinate[1]};
407  texCoords->addElement(coord);
408  }
409  }
410  }
411 
412  // materials and texture file
413  ccMaterialSet* materialSet = new ccMaterialSet("Materials");
414  if (!textureMesh->tex_materials.empty()) {
415  for (std::size_t m = 0; m < nr_meshes; ++m) {
416  auto newMaterial = ccMaterial::Shared(new ccMaterial());
417  FromPCLMaterial(textureMesh->tex_materials[m], newMaterial);
418  materialSet->addMaterial(newMaterial);
419 
420  for (std::size_t i = 0; i < textureMesh->tex_polygons[m].size();
421  ++i) {
422  CCVector3i texCoordIndexes;
423  for (std::size_t j = 0;
424  j < textureMesh->tex_polygons[m][i].vertices.size(); ++j) {
425  texCoordIndexes.u[j] = static_cast<int>(
426  textureMesh->tex_polygons[m][i].vertices[j]);
427  }
428 
429  // texture coordinates
430  newMesh->addTriangleMtlIndex(0);
431  newMesh->addTriangleTexCoordIndexes(texCoordIndexes.x,
432  texCoordIndexes.y,
433  texCoordIndexes.z);
434  }
435  }
436  }
437 
438  if (materialSet != nullptr) {
439  newMesh->setMaterialSet(materialSet);
440  newMesh->showMaterials(true);
441  }
442 
443  if (newMesh->size() == 0) {
445  QStringLiteral(
446  "[pcl2cc::Convert] Mesh '%1' does not have any faces")
447  .arg(name));
448  delete newMesh;
449  return nullptr;
450  }
451 
452  if (!newMesh->getAssociatedCloud()->hasNormals()) {
454  QStringLiteral("[pcl2cc::Convert] Mesh '%1' does not have "
455  "normals - will compute them per vertex")
456  .arg(name));
457  newMesh->computeNormals(true);
458  }
459 
460  newMesh->showNormals(true);
461  newMesh->showColors(newMesh->hasColors());
462  return newMesh;
463 }
464 
466  bool ignoreScalars /* = false*/,
467  bool ignoreRgb /* = false*/) {
468  // retrieve the valid fields
469  std::list<std::string> fields;
470  uint8_t coordinateType = 0;
471  for (const auto& field : pclCloud.fields) {
472  if (field.name != "_") // PCL padding fields
473  {
474  fields.push_back(field.name);
475  }
476 
477  if (coordinateType == 0 &&
478  (field.name == "x" || field.name == "y" || field.name == "z")) {
479  coordinateType = field.datatype;
480  }
481  }
482 
483  // begin with checks and conversions
484  // be sure we have x, y, and z fields
485  if (!ExistField(pclCloud, "x") || !ExistField(pclCloud, "y") ||
486  !ExistField(pclCloud, "z")) {
487  return nullptr;
488  }
489 
490  // create cloud
491  ccPointCloud* ccCloud = new ccPointCloud();
492  size_t expectedPointCount = GetNumberOfPoints(pclCloud);
493  if (expectedPointCount != 0) {
494  // push points inside
495  if (!CopyXYZ(pclCloud, *ccCloud, coordinateType)) {
496  delete ccCloud;
497  return nullptr;
498  }
499  }
500 
501  // remove x,y,z fields from the vector of field names
502  fields.remove("x");
503  fields.remove("y");
504  fields.remove("z");
505 
506  // do we have normals?
507  if (ExistField(pclCloud, "normal_x") || ExistField(pclCloud, "normal_y") ||
508  ExistField(pclCloud, "normal_z")) {
509  CopyNormals(pclCloud, *ccCloud);
510 
511  // remove the corresponding fields
512  fields.remove("normal_x");
513  fields.remove("normal_y");
514  fields.remove("normal_z");
515  }
516 
517  // do we have colors?
518  if (!ignoreRgb) {
519  // The same for colors
520  if (ExistField(pclCloud, "rgb")) {
521  CopyRGB(pclCloud, *ccCloud);
522 
523  // remove the corresponding field
524  fields.remove("rgb");
525  }
526  // The same for colors
527  else if (ExistField(pclCloud, "rgba")) {
528  CopyRGB(pclCloud, *ccCloud);
529 
530  // remove the corresponding field
531  fields.remove("rgba");
532  }
533  }
534 
535  // All the remaining fields will be stored as scalar fields
536  if (!ignoreScalars) {
537  for (const std::string& name : fields) {
538  CopyScalarField(pclCloud, name, *ccCloud);
539  }
540  }
541 
542  return ccCloud;
543 }
544 
545 ccMesh* pcl2cc::Convert(const PCLCloud& pclCloud,
546  const std::vector<pcl::Vertices>& polygons,
547  bool ignoreScalars /* = false*/,
548  bool ignoreRgb /* = false*/) {
549  ccPointCloud* vertices = Convert(pclCloud, ignoreScalars, ignoreRgb);
550  if (!vertices) return nullptr;
551  vertices->setName("vertices");
552  // vertices->showNormals(false);
553 
554  // mesh
555  ccMesh* mesh = new ccMesh(vertices);
556  mesh->setName("Mesh");
557 
558  size_t triNum = polygons.size();
559 
560  if (!mesh->reserve(triNum)) {
561  assert(false);
562  return nullptr;
563  }
564  for (size_t i = 0; i < triNum; ++i) {
565  const pcl::Vertices& tri = polygons[i];
566  mesh->addTriangle(tri.vertices[0], tri.vertices[1], tri.vertices[2]);
567  }
568 
569  // do some cleaning
570  {
571  vertices->shrinkToFit();
572  mesh->shrinkToFit();
574  if (normals) {
575  normals->shrink_to_fit();
576  }
577  }
578 
579  vertices->setEnabled(false);
580  // DGM: no need to lock it as it is only used by one mesh!
581  vertices->setLocked(false);
582  mesh->addChild(vertices);
583 
584  return mesh;
585 }
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
std::shared_ptr< core::Tensor > image
std::vector< PCLPointField > fields
std::string name
pcl::TexMaterial PCLMaterial
Definition: PCLCloud.h:32
pcl::PCLPointCloud2 PCLCloud
Definition: PCLCloud.h:34
#define FROM_PCL_CLOUD
Definition: PCLConv.h:11
virtual void release()
Decrease counter and deletes object when 0.
Definition: CVShareable.cpp:35
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
static std::string ExtractDigitAlpha(const std::string &str)
Definition: CVTools.cpp:80
static QString ToQString(const std::string &s)
Definition: CVTools.cpp:92
static QString ToNativeSeparators(const QString &path)
Definition: CVTools.cpp:45
Array of compressed 3D normals (single index)
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
bool isAllocated() const
Returns whether some memory has been allocated or not.
Definition: ecvArray.h:67
void addElement(const Type &value)
Definition: ecvArray.h:105
virtual bool hasNormals() const
Returns whether normals are enabled or not.
virtual void showNormals(bool state)
Sets normals visibility.
virtual void showColors(bool state)
Sets colors visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
void showNormals(bool state) override
Sets normals visibility.
virtual void showMaterials(bool state)
Sets whether textures should be displayed or not.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
Definition: ecvHObject.cpp:534
Mesh (triangle) material.
int addMaterial(ccMaterial::CShared mat, bool allowDuplicateNames=false)
Adds a material.
Mesh (triangle) material.
Definition: ecvMaterial.h:28
QSharedPointer< ccMaterial > Shared
Shared type.
Definition: ecvMaterial.h:33
Triangular mesh.
Definition: ecvMesh.h:35
NormsIndexesTableType * getTriNormsTable() const override
Returns per-triangle normals shared array.
Definition: ecvMesh.h:344
bool reservePerTriangleMtlIndexes()
Reserves memory to store per-triangle material index.
Definition: ecvMesh.cpp:3734
virtual unsigned size() const override
Returns the number of triangles.
Definition: ecvMesh.cpp:2143
bool hasColors() const override
Returns whether colors are enabled or not.
Definition: ecvMesh.cpp:221
void addTriangleMtlIndex(int mtlIndex)
Adds triangle material index for next triangle.
Definition: ecvMesh.cpp:3751
void setMaterialSet(ccMaterialSet *materialSet, bool autoReleaseOldMaterialSet=true)
Sets associated material set (may be shared)
Definition: ecvMesh.cpp:492
bool reserve(std::size_t n)
Reserves the memory to store the vertex indexes (3 per triangle)
Definition: ecvMesh.cpp:2475
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
Definition: ecvMesh.h:143
void addTriangleTexCoordIndexes(int i1, int i2, int i3)
Adds a triplet of tex coords indexes for next triangle.
Definition: ecvMesh.cpp:3678
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
Definition: ecvMesh.cpp:2428
void setTexCoordinatesTable(TextureCoordsContainer *texCoordsTable, bool autoReleaseOldTable=true)
Sets per-triangle texture coordinates array (may be shared)
Definition: ecvMesh.cpp:3598
bool reservePerTriangleTexCoordIndexes()
Reserves memory to store per-triangle triplets of tex coords indexes.
Definition: ecvMesh.cpp:3659
void shrinkToFit()
Removes unused capacity.
Definition: ecvMesh.h:302
bool computeNormals(bool perVertex)
Computes normals.
Definition: ecvMesh.cpp:242
virtual void setLocked(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:117
virtual void setName(const QString &name)
Sets object name.
Definition: ecvObject.h:75
virtual void setEnabled(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:102
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
void addNorm(const CCVector3 &N)
Pushes a normal vector on stack (shortcut)
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool reserveTheNormsTable()
Reserves memory to store the compressed normals.
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
void deleteScalarField(int index) override
Deletes a specific scalar field.
void shrinkToFit()
Removes unused capacity.
void addRGBColor(const ecvColor::Rgb &C)
Pushes an RGB color on stack.
A scalar field associated to display-related parameters.
void computeMinAndMax() override
Determines the min and max values.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
void addElement(ScalarType value)
Definition: ScalarField.h:99
bool reserveSafe(std::size_t count)
Reserves memory (no exception thrown)
Definition: ScalarField.cpp:71
RGB color structure.
Definition: ecvColorTypes.h:49
RGBA color structure.
static bool CopyNormals(const PCLCloud &pclCloud, ccPointCloud &ccCloud)
Definition: sm2cc.cpp:124
static void FromPCLMaterial(const PCLMaterial &inMaterial, ccMaterial::Shared &outMaterial)
Definition: sm2cc.cpp:311
static bool CopyXYZ(const PCLCloud &pclCloud, ccPointCloud &ccCloud, uint8_t coordinateType)
Definition: sm2cc.cpp:88
static ccMesh * Convert(PCLTextureMesh::ConstPtr textureMesh)
Converts a PCL point cloud to a ccPointCloud.
static bool CopyRGB(const PCLCloud &pclCloud, ccPointCloud &ccCloud)
Definition: sm2cc.cpp:150
static bool CopyScalarField(const PCLCloud &pclCloud, const std::string &sfName, ccPointCloud &ccCloud, bool overwriteIfExist=true)
Definition: sm2cc.cpp:170
double normals[3]
unsigned char ColorCompType
Default color components type (R,G and B)
Definition: ecvColorTypes.h:29
normal_z y
normal_z x
normal_z z
normal_z scalar
std::string GetFileParentDirectory(const std::string &filename)
Definition: FileSystem.cpp:314
constexpr Rgbaf night(0.00f, 0.00f, 0.00f, 1.00F)
bool ExistField(const PCLCloud &pclCloud, std::string name)
Definition: sm2cc.cpp:68
pcl::PCLPointField PCLScalarField
Definition: sm2cc.cpp:36
POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZTpl< std::int32_t >,(std::int32_t, x, x)(std::int32_t, y, y)(std::int32_t, z, z)) POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZTpl< std
Definition: sm2cc.cpp:51
void PCLCloudToCCCloud(const PCLCloud &pclCloud, ccPointCloud &ccCloud)
Definition: sm2cc.cpp:76
2D texture coordinates