ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
DRCFilter.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 "../include/DRCFilter.h"
9 
10 #include "../include/SaveDracoFileDlg.h"
11 
12 // qCC_db
13 #include <CVLog.h>
14 #include <ecvMaterialSet.h>
15 #include <ecvMesh.h>
16 #include <ecvPointCloud.h>
17 #include <ecvScalarField.h>
18 
19 // CVCoreLib
20 #include <CVPlatform.h>
21 
22 // draco
23 #include <draco/compression/decode.h>
24 #include <draco/compression/encode.h>
25 #include <draco/mesh/mesh.h>
26 #include <draco/point_cloud/point_cloud.h>
27 
29  : FileIOFilter({"_Draco DRC Filter",
30  12.0f, // priority
31  QStringList{"drc"}, "drc",
32  QStringList{"DRC cloud or mesh (*.drc)"},
33  QStringList{"DRC cloud or mesh (*.drc)"},
34  Import | Export}) {}
35 
37  bool& multiple,
38  bool& exclusive) const {
39  if (type == static_cast<CV_CLASS_ENUM>(CV_TYPES::POINT_CLOUD) ||
40  type == static_cast<CV_CLASS_ENUM>(CV_TYPES::MESH)) {
41  multiple = false;
42  exclusive = true;
43  return true;
44  }
45  return false;
46 }
47 
49  draco::PointCloud& dracoCloud) {
50  unsigned pointCount = ccCloud.size();
51  dracoCloud.set_num_points(pointCount);
52 
53  draco::DataType dt = draco::DT_FLOAT32;
54  bool shifted = ccCloud.isShifted();
55  if (shifted) {
56  dt = draco::DT_FLOAT64;
57  }
58 
59  // create point attribute
60  {
61  draco::GeometryAttribute ga;
62  ga.Init(draco::GeometryAttribute::POSITION, nullptr, 3, dt, false,
63  DataTypeLength(dt) * 3, 0);
64  const int pointAttributeID =
65  dracoCloud.AddAttribute(ga, true, pointCount);
66  // retrieve it
67  draco::PointAttribute* pointAttribute =
68  dracoCloud.attribute(pointAttributeID);
69  if (nullptr == pointAttribute) {
71  }
72 
73  if (dt == draco::DT_FLOAT32) {
74  for (draco::PointIndex::ValueType i = 0; i < pointCount; ++i) {
75  pointAttribute->SetAttributeValue(draco::AttributeValueIndex(i),
76  ccCloud.getPoint(i)->u);
77  }
78  } else // draco::DT_FLOAT64
79  {
80  for (draco::PointIndex::ValueType i = 0; i < pointCount; ++i) {
81  CCVector3 Plocal = *(ccCloud.getPoint(i));
82  pointAttribute->SetAttributeValue(draco::AttributeValueIndex(i),
83  ccCloud.toGlobal3d(Plocal).u);
84  }
85  }
86  }
87 
88  // create normal attribute (if any)
89  if (ccCloud.hasNormals()) {
90  draco::GeometryAttribute ga;
91  ga.Init(draco::GeometryAttribute::NORMAL, nullptr, 3, draco::DT_FLOAT32,
92  true, DataTypeLength(draco::DT_FLOAT32) * 3, 0);
93  const int normalAttributeID =
94  dracoCloud.AddAttribute(ga, true, pointCount);
95  // retrieve it
96  draco::PointAttribute* normalAttribute =
97  dracoCloud.attribute(normalAttributeID);
98  if (nullptr != normalAttribute) {
99  for (draco::PointIndex::ValueType i = 0; i < pointCount; ++i) {
100  normalAttribute->SetAttributeValue(
101  draco::AttributeValueIndex(i),
102  ccCloud.getPointNormal(i).u);
103  }
104  } else {
105  CVLog::Warning("[DRACO] Failed to export normals");
106  }
107  }
108 
109  // create color attribute (if any)
110  if (ccCloud.hasColors()) {
111  draco::GeometryAttribute ga;
112  ga.Init(draco::GeometryAttribute::COLOR, nullptr, 3, draco::DT_UINT8,
113  false, DataTypeLength(draco::DT_UINT8) * 3, 0);
114  const int colorAttributeID =
115  dracoCloud.AddAttribute(ga, true, pointCount);
116  // retrieve it
117  draco::PointAttribute* colorAttribute =
118  dracoCloud.attribute(colorAttributeID);
119  if (nullptr != colorAttribute) {
120  for (draco::PointIndex::ValueType i = 0; i < pointCount; ++i) {
121  colorAttribute->SetAttributeValue(draco::AttributeValueIndex(i),
122  ccCloud.getPointColor(i).rgb);
123  }
124  } else {
125  CVLog::Warning("[DRACO] Failed to export normals");
126  }
127  }
128 
129  // create generic attribute (if any)
130  if (ccCloud.hasScalarFields()) {
131  if (ccCloud.isA(CV_TYPES::POINT_CLOUD)) {
132  const ccPointCloud& cc = static_cast<const ccPointCloud&>(ccCloud);
133  // DGM: it seems DRACO supports only one "Generic" field
134  if (cc.getNumberOfScalarFields() > 1) {
136  "[DRACO] Cloud %1 has multiple scalar fields, however, "
137  "only one can be saved (the active one by default)");
138  }
139  }
140 
141  draco::GeometryAttribute ga;
142  ga.Init(draco::GeometryAttribute::GENERIC, nullptr, 1,
143  draco::DT_FLOAT32, false, DataTypeLength(draco::DT_FLOAT32), 0);
144  const int sfAttributeID = dracoCloud.AddAttribute(ga, true, pointCount);
145  // retrieve it
146  draco::PointAttribute* sfAttribute =
147  dracoCloud.attribute(sfAttributeID);
148  if (nullptr != sfAttribute) {
149  for (draco::PointIndex::ValueType i = 0; i < pointCount; ++i) {
150  float sfValue = ccCloud.getPointScalarValue(i);
151  sfAttribute->SetAttributeValue(draco::AttributeValueIndex(i),
152  &sfValue);
153  }
154  } else {
155  CVLog::Warning("[DRACO] Failed to export active scalar field");
156  }
157  }
158 
159 #if 0 // DGM: it seems DRACO supports only one "Generic" field
160  // create SF attributes (if any)
161  if (ccCloud.isA(CV_TYPES::POINT_CLOUD) && ccCloud.hasScalarFields())
162  {
163  const ccPointCloud& cc = static_cast<const ccPointCloud&>(ccCloud);
164  for (unsigned k = 0; k < cc.getNumberOfScalarFields(); ++k)
165  {
166  cloudViewer::ScalarField* sf = cc.getScalarField(static_cast<int>(k));
167 
168  draco::GeometryAttribute ga;
169  ga.Init(draco::GeometryAttribute::GENERIC, nullptr, 1, draco::DT_FLOAT32, false, DataTypeLength(draco::DT_FLOAT32), 0);
170  const int sfAttributeID = dracoCloud.AddAttribute(ga, true, pointCount);
171  // retrieve it
172  draco::PointAttribute* sfAttribute = dracoCloud.attribute(sfAttributeID);
173  if (nullptr != sfAttribute)
174  {
175  for (draco::PointIndex::ValueType i = 0; i < pointCount; ++i)
176  {
177  sfAttribute->SetAttributeValue(draco::AttributeValueIndex(i), &sf->getValue(i));
178  }
179  }
180  else
181  {
182  CVLog::Warning("[DRACO] Failed to export scalar field " + QString(sf->getName()));
183  }
184 
185  }
186  }
187 #endif
188 
189  return CC_FERR_NO_ERROR;
190 }
191 
193  draco::Mesh& dracoMesh) {
194  unsigned faceCount = ccMesh.size();
195  dracoMesh.SetNumFaces(faceCount);
196 
197  // save triangles
198  draco::FaceIndex faceIndex(0);
199  for (unsigned i = 0; i < faceCount; ++i) {
200  const auto tri = ccMesh.getTriangleVertIndexes(i);
201  draco::Mesh::Face face;
202  {
203  face[0] = tri->i1;
204  face[1] = tri->i2;
205  face[2] = tri->i3;
206  }
207  dracoMesh.SetFace(faceIndex, face);
208  faceIndex++;
209  }
210 
212  if (!vertices) {
213  assert(false);
215  }
216 
217  // save texture coordinates
219  unsigned vertexCount = vertices->size();
220  if (texCoords && texCoords->size() == ccMesh.size() * 3) {
221  // dracoMesh.SetAttribute
222  draco::GeometryAttribute ga;
223  ga.Init(draco::GeometryAttribute::TEX_COORD, nullptr, 2,
224  draco::DT_FLOAT32, false, DataTypeLength(draco::DT_FLOAT32) * 2,
225  0);
226  const int texCoordAttributeID =
227  dracoMesh.AddAttribute(ga, true, vertexCount);
228  // retrieve it
229  draco::PointAttribute* texCoordAttribute =
230  dracoMesh.attribute(texCoordAttributeID);
231  if (nullptr != texCoordAttribute) {
232  for (draco::PointIndex::ValueType i = 0; i < vertexCount; ++i) {
233  if (i < texCoords->size()) {
234  texCoordAttribute->SetAttributeValue(
235  draco::AttributeValueIndex(i), texCoords->at(i).t);
236  } else {
237  float coord[2];
238  coord[0] = 0.0f;
239  coord[1] = 0.0f;
240  texCoordAttribute->SetAttributeValue(
241  draco::AttributeValueIndex(i), coord);
242  }
243  }
244  } else {
245  CVLog::Warning("[DRACO] Failed to export texture coordinates");
246  }
247  }
248 
249  // save vertices
250  CC_FILE_ERROR error = CCCloudToDraco(*vertices, dracoMesh);
251  if (error != CC_FERR_NO_ERROR) {
252  return error;
253  }
254 
255  return CC_FERR_NO_ERROR;
256 }
257 
259  const QString& filename,
260  const SaveParameters& parameters) {
261  if (nullptr == entity) {
262  assert(false);
263  return CC_FERR_BAD_ARGUMENT;
264  }
265 
266  draco::Encoder encoder;
267  encoder.SetSpeedOptions(0, 0);
268 
269  int coordQuantization = 11;
270  int texCoordQuantization = 10;
271  int normalQuantization = 8;
272  int sfQuantization = 8;
273 
274  // we always create the dialog, even if we don't display it, to retrieve the
275  // default values
276  SaveDracoFileDlg drcDialog(parameters.parentWidget);
277  if (parameters.parentWidget && parameters.alwaysDisplaySaveDialog) {
278  if (drcDialog.exec() == 0) {
280  }
281  }
282 
283  coordQuantization = drcDialog.coordsQuantSpinBox->value();
284  // texCoordQuantization = XXX; //not available yet since we don't know how
285  // to save the texture!
286  normalQuantization = drcDialog.normQuantSpinBox->value();
287  sfQuantization = drcDialog.sfQuantSpinBox->value();
288 
289  encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION,
290  coordQuantization);
291  encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD,
292  texCoordQuantization);
293  encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL,
294  normalQuantization);
295  encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC,
296  sfQuantization);
297 
298  draco::EncoderBuffer buffer;
299  if (entity->isKindOf(CV_TYPES::MESH)) {
300  ccGenericMesh* ccMesh = static_cast<ccGenericMesh*>(entity);
301 
302  // save mesh
303  draco::Mesh dracoMesh;
304  CC_FILE_ERROR error = CCMeshToDraco(*ccMesh, dracoMesh);
305  if (error != CC_FERR_NO_ERROR) {
306  return error;
307  }
308 
309  if (!encoder.EncodeMeshToBuffer(dracoMesh, &buffer).ok()) {
311  }
312  } else if (entity->isKindOf(CV_TYPES::POINT_CLOUD)) {
313  ccGenericPointCloud* ccCloud =
314  static_cast<ccGenericPointCloud*>(entity);
315 
316  // save cloud
317  draco::PointCloud dracoCloud;
318  CC_FILE_ERROR error = CCCloudToDraco(*ccCloud, dracoCloud);
319  if (error != CC_FERR_NO_ERROR) {
320  return error;
321  }
322 
323  if (!encoder.EncodePointCloudToBuffer(dracoCloud, &buffer).ok()) {
325  }
326  } else {
328  }
329 
330  QFile file(filename);
331  if (!file.open(QFile::WriteOnly)) {
332  return CC_FERR_WRITING;
333  }
334  file.write(buffer.data(), static_cast<qint64>(buffer.size()));
335 
336  return CC_FERR_NO_ERROR;
337 }
338 
340  const draco::PointCloud& dracoCloud,
341  FileIOFilter::LoadParameters& parameters) {
342  if (dracoCloud.num_points() == 0) {
343  return CC_FERR_NO_LOAD;
344  }
345 
346  unsigned pointCount = dracoCloud.num_points();
347  if (!ccCloud.reserve(pointCount)) {
349  }
350 
351  // load vertices
352  const draco::PointAttribute* pointAttribute =
353  dracoCloud.GetNamedAttribute(draco::GeometryAttribute::POSITION);
354  if (nullptr == pointAttribute) {
356  }
357  if (pointCount != pointAttribute->size()) {
358  return CC_FERR_MALFORMED_FILE;
359  }
360  draco::DataType dt = pointAttribute->data_type();
361  if (dt == draco::DT_FLOAT32) {
362  for (draco::AttributeValueIndex i(0);
363  i < static_cast<uint32_t>(pointAttribute->size()); ++i) {
364  CCVector3f p;
365  pointAttribute->GetValue(i, p.u);
366  ccCloud.addPoint(p);
367  }
368  } else if (dt == draco::DT_FLOAT64) {
369  CCVector3d Pshift(0, 0, 0);
370  bool preserveCoordinateShift = true;
371  for (draco::AttributeValueIndex i(0);
372  i < static_cast<uint32_t>(pointAttribute->size()); ++i) {
373  CCVector3d P;
374  pointAttribute->GetValue(i, P.u);
375 
376  // first point: check for large coordinates
377  if (i == 0) {
379  P, Pshift, preserveCoordinateShift, parameters)) {
380  if (preserveCoordinateShift) {
381  ccCloud.setGlobalShift(Pshift);
382  }
384  "[DRACO] Cloud has been recentered! Translation: "
385  "(%.2f ; %.2f ; %.2f)",
386  Pshift.x, Pshift.y, Pshift.z);
387  }
388  }
389 
390  ccCloud.addPoint((P + Pshift).toPC());
391  }
392  }
393 
394  // load normals?
395  const draco::PointAttribute* normalAttribute =
396  dracoCloud.GetNamedAttribute(draco::GeometryAttribute::NORMAL);
397  if ((nullptr != normalAttribute) &&
398  (normalAttribute->data_type() == draco::DataType::DT_FLOAT32) &&
399  (pointCount == normalAttribute->size())) {
400  if (ccCloud.reserveTheNormsTable()) {
401  for (draco::AttributeValueIndex i(0);
402  i < static_cast<uint32_t>(normalAttribute->size()); ++i) {
403  draco::Vector3f n;
404  normalAttribute->GetValue(i, &n[0]);
405  ccCloud.addNorm(CCVector3f::fromArray(n.data()));
406  }
407  ccCloud.showNormals(true);
408  } else {
409  CVLog::Warning("Failed to load normals (not enough memory)");
410  }
411  }
412 
413  // load colors?
414  const draco::PointAttribute* colorAttribute =
415  dracoCloud.GetNamedAttribute(draco::GeometryAttribute::COLOR);
416  if ((nullptr != colorAttribute) &&
417  (colorAttribute->data_type() == draco::DataType::DT_UINT8) &&
418  (pointCount == colorAttribute->size())) {
419  bool rgb = (colorAttribute->num_components() == 3);
420  bool rgba = (colorAttribute->num_components() == 4);
421  if (rgb || rgba) {
422  if (ccCloud.reserveTheRGBTable()) {
423  if (rgb) {
424  std::array<uint8_t, 3> col;
425  for (draco::AttributeValueIndex i(0);
426  i < static_cast<uint32_t>(colorAttribute->size());
427  ++i) {
428  colorAttribute->GetValue(i, &col[0]);
429  ccCloud.addRGBColor(ecvColor::Rgb(col.data()));
430  }
431  } else if (rgba) {
432  std::array<uint8_t, 4> col;
433  for (draco::AttributeValueIndex i(0);
434  i < static_cast<uint32_t>(colorAttribute->size());
435  ++i) {
436  colorAttribute->GetValue(i, &col[0]);
437  ccCloud.addRGBColor(
438  ecvColor::Rgb(col[0], col[1], col[2]));
439  }
440  }
441  ccCloud.showColors(true);
442  } else {
443  CVLog::Warning("Failed to load colors (not enough memory)");
444  }
445  }
446  }
447 
448  // load SF?
449  const draco::PointAttribute* sfAttribute =
450  dracoCloud.GetNamedAttribute(draco::GeometryAttribute::GENERIC);
451  if ((nullptr != sfAttribute) &&
452  (sfAttribute->data_type() == draco::DataType::DT_FLOAT32) &&
453  (sfAttribute->size() == pointCount)) {
454  ccScalarField* sf = new ccScalarField();
455  if (sf->reserveSafe(pointCount)) {
456  for (draco::AttributeValueIndex i(0);
457  i < static_cast<uint32_t>(sfAttribute->size()); ++i) {
458  float sfValue = 0;
459  sfAttribute->GetValue(i, &sfValue);
460  sf->addElement(sfValue);
461  }
462  sf->computeMinAndMax();
463  ccCloud.addScalarField(sf);
465  ccCloud.showSF(true);
466  } else {
467  CVLog::Warning("Failed to load generic field (not enough memory)");
468  }
469  }
470 
471  return CC_FERR_NO_ERROR;
472 }
473 
475  ccHObject& container,
476  LoadParameters& parameters) {
477  draco::DecoderBuffer buffer;
478 
479  QFile file(filename);
480  if (!file.open(QFile::ReadOnly)) {
481  return CC_FERR_READING;
482  }
483 
484  QByteArray byteArray = file.readAll();
485  buffer.Init(byteArray.data(), byteArray.size());
486 
487  const auto result = draco::Decoder::GetEncodedGeometryType(&buffer);
488  if (!result.ok()) {
490  }
491 
492  const draco::EncodedGeometryType geomType = result.value();
493  if (geomType == draco::TRIANGULAR_MESH) {
494  const auto resultMesh = draco::Decoder().DecodeMeshFromBuffer(&buffer);
495  if (!resultMesh.ok()) {
497  }
498  const std::unique_ptr<draco::Mesh>& meshDraco = resultMesh.value();
499  const draco::PointAttribute* const pointAttribute =
500  meshDraco->GetNamedAttribute(
501  draco::GeometryAttribute::POSITION);
502  if (!pointAttribute) {
504  }
505  CVLog::Print(
506  "[DRACO] Mesh size: " +
507  QString::number(meshDraco->num_faces()) +
508  " / vertex count: " + QString::number(meshDraco->num_points()));
509 
510  ccPointCloud* vertices = new ccPointCloud("vertices");
511  CC_FILE_ERROR verticesError =
512  LoadCloud(*vertices, *meshDraco, parameters);
513  if (CC_FERR_NO_ERROR != verticesError) {
514  delete vertices;
515  return verticesError;
516  }
517 
518  ccMesh* meshCC = new ccMesh(vertices);
519  meshCC->addChild(vertices);
520  vertices->setVisible(false);
521  if (vertices->hasNormals()) {
522  meshCC->showNormals(true);
523  }
524  if (vertices->hasColors()) {
525  meshCC->showColors(true);
526  }
527 
528  if (!meshCC->reserve(meshDraco->num_faces())) {
529  delete meshCC;
531  }
532 
533  // load faces
534  for (draco::FaceIndex f(0); f < meshDraco->num_faces(); ++f) {
535  const draco::Mesh::Face& face = meshDraco->face(f);
536  assert(face.size() == 3);
537  uint32_t i1 = pointAttribute->mapped_index(face[0]).value();
538  uint32_t i2 = pointAttribute->mapped_index(face[1]).value();
539  uint32_t i3 = pointAttribute->mapped_index(face[2]).value();
540  meshCC->addTriangle(i1, i2, i3);
541  }
542 
543  // load texture coords if possible
544  const draco::PointAttribute* const coordAttribute =
545  meshDraco->GetNamedAttribute(
546  draco::GeometryAttribute::TEX_COORD);
547  TextureCoordsContainer* texCoords = nullptr;
548  std::size_t coord_size = meshCC->size() * 3;
549  if (coordAttribute && coordAttribute->size() == vertices->size()) {
550  texCoords = new TextureCoordsContainer();
551  texCoords->link();
552  if (!texCoords->reserveSafe(coord_size)) {
553  CVLog::Error(
554  "Not enough memory to load texture coordinates (they "
555  "will "
556  "be ignored)!");
557  CVLog::Warning("[drc] Texture coordinates ignored!");
558  texCoords->release();
559  texCoords = nullptr;
560  } else {
561  for (draco::AttributeValueIndex i(0);
562  i < static_cast<uint32_t>(coord_size); ++i) {
563  TexCoords2D T;
564  if (i < coordAttribute->size()) {
565  coordAttribute->GetValue(i, T.t);
566  } else {
567  T.tx = 0.0f;
568  T.ty = 0.0f;
569  }
570 
571  texCoords->addElement(T);
572  }
573  }
574  }
575 
576  vertices->shrinkToFit();
577  if (texCoords) {
578  texCoords->shrink_to_fit();
579  }
580 
581  if (meshCC->size() == 0) {
582  delete meshCC;
583  meshCC = nullptr;
584  return CC_FERR_NO_LOAD;
585  } else {
586  meshCC->shrinkToFit();
587  }
588 
589  if (texCoords) {
590  // materials
591  ccMaterialSet* materials = new ccMaterialSet("materials");
592  if (materials) {
593  ccMaterial::Shared material(new ccMaterial("default"));
594  material->setDiffuse(ecvColor::bright);
595  material->setSpecular(ecvColor::darker);
596  material->setAmbient(ecvColor::darker);
597  materials->push_back(material);
598  meshCC->setMaterialSet(materials);
599  meshCC->showMaterials(true);
600  }
601 
602  if (materials) {
603  meshCC->setTexCoordinatesTable(texCoords);
604  } else {
606  "[DRC] Texture coordinates were defined but no "
607  "material could be loaded!");
608  }
609  }
610 
611  container.addChild(meshCC);
612  } else if (geomType == draco::POINT_CLOUD) {
613  const auto resultCloud =
614  draco::Decoder().DecodePointCloudFromBuffer(&buffer);
615  if (!resultCloud.ok()) {
617  }
618  const std::unique_ptr<draco::PointCloud>& cloudDraco =
619  resultCloud.value();
620  CVLog::Print("[DRACO] Cloud size: " +
621  QString::number(cloudDraco->num_points()));
622 
623  ccPointCloud* cloudCC = new ccPointCloud("unnamed - Cloud");
624  CC_FILE_ERROR cloudError = LoadCloud(*cloudCC, *cloudDraco, parameters);
625  if (CC_FERR_NO_ERROR != cloudError) {
626  delete cloudCC;
627  return cloudError;
628  }
629 
630  container.addChild(cloudCC);
631  }
632 
633  return CC_FERR_NO_ERROR;
634 }
int64_t CV_CLASS_ENUM
Type of object type flags (64 bits)
Definition: CVTypes.h:97
std::string filename
static CC_FILE_ERROR CCMeshToDraco(ccGenericMesh &ccMesh, draco::Mesh &dracoMesh)
Definition: DRCFilter.cpp:192
static CC_FILE_ERROR LoadCloud(ccPointCloud &ccCloud, const draco::PointCloud &dracoCloud, FileIOFilter::LoadParameters &parameters)
Definition: DRCFilter.cpp:339
static CC_FILE_ERROR CCCloudToDraco(const ccGenericPointCloud &ccCloud, draco::PointCloud &dracoCloud)
Definition: DRCFilter.cpp:48
int size
char type
CC_FILE_ERROR
Typical I/O filter errors.
Definition: FileIOFilter.h:20
@ CC_FERR_CANCELED_BY_USER
Definition: FileIOFilter.h:30
@ CC_FERR_THIRD_PARTY_LIB_FAILURE
Definition: FileIOFilter.h:36
@ CC_FERR_NO_LOAD
Definition: FileIOFilter.h:28
@ CC_FERR_WRITING
Definition: FileIOFilter.h:25
@ CC_FERR_MALFORMED_FILE
Definition: FileIOFilter.h:32
@ CC_FERR_BAD_ARGUMENT
Definition: FileIOFilter.h:22
@ CC_FERR_NO_ERROR
Definition: FileIOFilter.h:21
@ CC_FERR_BAD_ENTITY_TYPE
Definition: FileIOFilter.h:29
@ CC_FERR_READING
Definition: FileIOFilter.h:26
@ CC_FERR_NOT_ENOUGH_MEMORY
Definition: FileIOFilter.h:31
core::Tensor result
Definition: VtkUtils.cpp:76
virtual void link()
Increase counter.
Definition: CVShareable.cpp:33
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 bool Print(const char *format,...)
Prints out a formatted message in console.
Definition: CVLog.cpp:113
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Definition: CVLog.cpp:143
CC_FILE_ERROR loadFile(const QString &filename, ccHObject &container, LoadParameters &parameters) override
Loads one or more entities from a file.
Definition: DRCFilter.cpp:474
CC_FILE_ERROR saveToFile(ccHObject *entity, const QString &filename, const SaveParameters &parameters) override
Saves an entity (or a group of) to a file.
Definition: DRCFilter.cpp:258
bool canSave(CV_CLASS_ENUM type, bool &multiple, bool &exclusive) const override
Returns whether this I/O filter can save the specified type of entity.
Definition: DRCFilter.cpp:36
Generic file I/O filter.
Definition: FileIOFilter.h:46
static bool HandleGlobalShift(const CCVector3d &P, CCVector3d &Pshift, bool &preserveCoordinateShift, LoadParameters &loadParameters, bool useInputCoordinatesShiftIfPossible=false)
Shortcut to the ecvGlobalShiftManager mechanism specific for files.
DRACO file (https://github.com/google/draco) saving dialog.
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
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
void addElement(const Type &value)
Definition: ecvArray.h:105
virtual bool hasColors() const
Returns whether colors are enabled or not.
virtual void setVisible(bool state)
Sets entity visibility.
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.
virtual bool hasScalarFields() const
Returns whether one or more scalar fields are instantiated.
Generic mesh interface.
void showNormals(bool state) override
Sets normals visibility.
virtual void showMaterials(bool state)
Sets whether textures should be displayed or not.
A 3D cloud interface with associated features (color, normals, octree, etc.)
virtual const CCVector3 & getPointNormal(unsigned pointIndex) const =0
Returns normal corresponding to a given point.
virtual const ecvColor::Rgb & getPointColor(unsigned pointIndex) const =0
Returns color corresponding to a given point.
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
Mesh (triangle) material.
Mesh (triangle) material.
Definition: ecvMaterial.h:28
QSharedPointer< ccMaterial > Shared
Shared type.
Definition: ecvMaterial.h:33
Triangular mesh.
Definition: ecvMesh.h:35
TextureCoordsContainer * getTexCoordinatesTable() const override
Returns per-triangle texture coordinates array.
Definition: ecvMesh.h:476
cloudViewer::VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex) override
Returns the indexes of the vertices of a given triangle.
void setMaterialSet(ccMaterialSet *materialSet, bool autoReleaseOldMaterialSet=true)
Sets associated material set (may be shared)
bool reserve(std::size_t n)
Reserves the memory to store the vertex indexes (3 per triangle)
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
Definition: ecvMesh.h:143
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
void setTexCoordinatesTable(TextureCoordsContainer *texCoordsTable, bool autoReleaseOldTable=true)
Sets per-triangle texture coordinates array (may be shared)
virtual unsigned size() const override
Returns the number of triangles.
void shrinkToFit()
Removes unused capacity.
Definition: ecvMesh.h:302
bool isA(CV_CLASS_ENUM type) const
Definition: ecvObject.h:131
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 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 hasNormals() const override
Returns whether normals are enabled or not.
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.
bool hasColors() const override
Returns whether colors are enabled or not.
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.
CCVector3d toGlobal3d(const Vector3Tpl< T > &Plocal) const
Returns the point back-projected into the original coordinates system.
bool isShifted() const
Returns whether the cloud is shifted or not.
virtual void setGlobalShift(double x, double y, double z)
Sets shift applied to original coordinates (information storage only)
virtual unsigned size() const =0
Returns the number of points.
virtual ScalarType getPointScalarValue(unsigned pointIndex) const =0
Returns the ith point associated scalar value.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
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.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
Definition: PointCloudTpl.h:38
A simple scalar field (to be associated to a point cloud)
Definition: ScalarField.h:25
void addElement(ScalarType value)
Definition: ScalarField.h:99
ScalarType & getValue(std::size_t index)
Definition: ScalarField.h:92
const char * getName() const
Returns scalar field name.
Definition: ScalarField.h:43
bool reserveSafe(std::size_t count)
Reserves memory (no exception thrown)
Definition: ScalarField.cpp:71
RGB color structure.
Definition: ecvColorTypes.h:49
std::vector< unsigned int > face
static void error(char *msg)
Definition: lsd.c:159
@ MESH
Definition: CVTypes.h:105
@ POINT_CLOUD
Definition: CVTypes.h:104
::ccPointCloud PointCloud
Definition: PointCloud.h:19
constexpr Rgbaf bright(1.00f, 1.00f, 1.00f, 1.00f)
constexpr Rgbaf darker(0.17f, 0.17f, 0.17f, 1.00f)
Generic loading parameters.
Definition: FileIOFilter.h:51
Generic saving parameters.
Definition: FileIOFilter.h:84
QWidget * parentWidget
Parent widget (if any)
Definition: FileIOFilter.h:93
2D texture coordinates