ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
RDBFilter.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 "RDBFilter.h"
9 
10 // Local
11 #include "RDBOpenDialog.h"
12 
13 // Qt
14 #include <QComboBox>
15 #include <QFile>
16 #include <QFileInfo>
17 #include <QIcon>
18 #include <QTextStream>
19 
20 // CV_CORE_LIB
21 #include <CVLog.h>
22 #include <ScalarField.h>
23 
24 // CV_DB_LIB
25 #include <ecvHObject.h>
26 #include <ecvMaterial.h>
27 #include <ecvMaterialSet.h>
28 #include <ecvMesh.h>
29 #include <ecvPlane.h>
30 #include <ecvPointCloud.h>
31 #include <ecvProgressDialog.h>
32 #include <ecvScalarField.h>
33 
34 // RDB
35 #include <riegl/rdb.hpp>
36 
37 // System
38 #include <assert.h>
39 #include <string.h>
40 
41 #include <array>
42 #include <sstream>
43 
45  : FileIOFilter({"RDB 2.0 Filter",
46  DEFAULT_PRIORITY, // priority
47  QStringList{"rdbx", "vxls", "ptch", "mtch"}, "RDB2",
48  QStringList{"RDB Pointcloud file (*.rdbx)",
49  "RDB Voxelfile (*.vxls)",
50  "RDB Plane Patch file (*.ptch)",
51  "RDB Match file (*.mtch)"},
52  QStringList(), Import}) {}
53 
54 namespace // local helper
55 {
56 
57 void updateTable(RDBOpenDialog &openDlg, riegl::rdb::Pointcloud &rdb) {
58  static const QIcon xIcon(
59  QString::fromUtf8(":/CC/images/typeXCoordinate.png"));
60  static const QIcon yIcon(
61  QString::fromUtf8(":/CC/images/typeYCoordinate.png"));
62  static const QIcon zIcon(
63  QString::fromUtf8(":/CC/images/typeZCoordinate.png"));
64  static const QIcon NormIcon(
65  QString::fromUtf8(":/CC/images/typeNormal.png"));
66  static const QIcon RGBIcon(
67  QString::fromUtf8(":/CC/images/typeRgbCcolor.png"));
68  static const QIcon GreyIcon(
69  QString::fromUtf8(":/CC/images/typeGrayColor.png"));
70  static const QIcon ScalarIcon(QString::fromUtf8(":/CC/images/typeSF.png"));
71 
72  struct SpecialAttribute {
73  const std::string name;
74  const std::string comboBoxEntry;
75  const QIcon &icon;
76  SpecialAttribute(const std::string &arg_name,
77  const std::string &arg_comboBoxEntry,
78  const QIcon &arg_icon)
79  : name(arg_name),
80  comboBoxEntry(arg_comboBoxEntry),
81  icon(arg_icon) {}
82  };
83  const std::vector<SpecialAttribute> known_special_attributes{
84  {"riegl.xyz", RDB_OPEN_DLG_TYPES_NAMES[RDB_OPEN_DLG_XYZ], xIcon},
85  {"riegl.rgba", RDB_OPEN_DLG_TYPES_NAMES[RDB_OPEN_DLG_RGB], RGBIcon},
86  {"riegl.surface_normal",
88  {"riegl.pca_axis_min", RDB_OPEN_DLG_TYPES_NAMES[RDB_OPEN_DLG_NORM],
89  NormIcon},
90  };
91  {
92  int idx = 0;
93  // Get list of point attributes
94  std::vector<std::string> attributes = rdb.pointAttribute().list();
95  openDlg.rdbTableWidget->setColumnCount(2);
96  openDlg.rdbTableWidget->setRowCount(
97  static_cast<int>(known_special_attributes.size()));
98  openDlg.rdbTableWidget->setColumnWidth(0, 200);
99  openDlg.rdbTableWidget->setEditTriggers(
100  QAbstractItemView::NoEditTriggers);
101 
102  QStringList headerLabels;
103  headerLabels << "Name"
104  << "Load as";
105  openDlg.rdbTableWidget->setHorizontalHeaderLabels(headerLabels);
106 
107  // check for existance of attribute and add it to qList
108  auto list_known_attribute = [](RDBOpenDialog &openDlg, int &idx,
109  std::vector<std::string> &attributes,
110  const std::string &att,
111  const std::string &comboBoxEntry,
112  const QIcon &icon) {
113  if (std::find(attributes.begin(), attributes.end(), att) !=
114  attributes.end()) {
115  attributes.erase(
116  std::remove(attributes.begin(), attributes.end(), att),
117  attributes.end());
118 
119  openDlg.rdbTableWidget->setItem(
120  idx, 0, new QTableWidgetItem(att.c_str()));
121  QComboBox *columnHeaderWidget = new QComboBox();
122  columnHeaderWidget->addItem(comboBoxEntry.c_str());
123  columnHeaderWidget->setMaxVisibleItems(1);
124  columnHeaderWidget->setCurrentIndex(0);
125  columnHeaderWidget->setItemIcon(0, icon);
126  openDlg.rdbTableWidget->setCellWidget(idx, 1,
127  columnHeaderWidget);
128  idx++;
129  }
130  };
131  auto add_qcombobox_scalar = [](RDBOpenDialog &openDlg, int &idx,
132  const std::string &att, bool active) {
133  openDlg.rdbTableWidget->setItem(idx, 0,
134  new QTableWidgetItem(att.c_str()));
135  // openDlg.rdbTableWidget->cellWidget(idx,0)->setEnabled(false);
136 
137  QComboBox *columnHeaderWidget = new QComboBox();
138  columnHeaderWidget->addItem(
140  columnHeaderWidget->addItem(
142  columnHeaderWidget->setMaxVisibleItems(2);
143  columnHeaderWidget->setItemIcon(1, ScalarIcon);
144  if (active)
145  columnHeaderWidget->setCurrentIndex(1);
146  else
147  columnHeaderWidget->setCurrentIndex(0);
148 
149  openDlg.rdbTableWidget->setCellWidget(idx, 1, columnHeaderWidget);
150  idx++;
151  };
152  auto add_qcombobox_known_scalar =
153  [add_qcombobox_scalar](RDBOpenDialog &openDlg, int &idx,
154  std::vector<std::string> &attributes,
155  const std::string &att, bool active) {
156  if (std::find(attributes.begin(), attributes.end(), att) !=
157  attributes.end()) {
158  attributes.erase(std::remove(attributes.begin(),
159  attributes.end(), att),
160  attributes.end());
161  add_qcombobox_scalar(openDlg, idx, att, active);
162  }
163  };
164 
165  // list non-scalar known attributes, remove them from attributes list,
166  // as they are already handled
167  for (const SpecialAttribute &att : known_special_attributes) {
168  list_known_attribute(openDlg, idx, attributes, att.name,
169  att.comboBoxEntry, att.icon);
170  }
171 
172  // some attributes have multiple entries, and each entry should have its
173  // own row to present them we need to know how many separate row entries
174  // we have, so count them
175  const size_t total_rows = std::accumulate(
176  attributes.cbegin(), attributes.cend(), size_t(idx),
177  [&rdb](const size_t running_sum,
178  const std::string &att) -> size_t {
179  uint32_t att_length = rdb.pointAttribute().get(att).length;
180  return running_sum + static_cast<size_t>(att_length);
181  });
182  // prepare adequate number of rows in the table
183  openDlg.rdbTableWidget->setRowCount(static_cast<int>(total_rows));
184 
185  // add row entry for known scalar attributes and remove them from
186  // remaining attributes list
187  add_qcombobox_known_scalar(openDlg, idx, attributes, "riegl.id", false);
188  add_qcombobox_known_scalar(openDlg, idx, attributes,
189  "riegl.reflectance", true);
190  add_qcombobox_known_scalar(openDlg, idx, attributes, "riegl.amplitude",
191  true);
192  add_qcombobox_known_scalar(openDlg, idx, attributes, "riegl.deviation",
193  true);
194 
195  CVLog::Print(QString("unknown attributes: %1").arg(attributes.size()));
196  // openDlg.rdbAttributesList->insertItem(idx, "--- unknown attributes
197  // ---");
198  for (const std::string &att : attributes) {
199  const riegl::rdb::pointcloud::PointAttribute rdb_attribute =
200  rdb.pointAttribute().get(att);
201  const uint32_t attribute_length = rdb_attribute.length;
202  if (attribute_length == 1) {
203  add_qcombobox_scalar(openDlg, idx, att, false);
204  } else {
205  // attribute with multiple entries, present as
206  // 'attribute_name[0]'
207  for (uint32_t att_idx = 0; att_idx < attribute_length;
208  att_idx++) {
209  add_qcombobox_scalar(
210  openDlg, idx,
211  att + "[" + std::to_string(att_idx) + "]", false);
212  }
213  }
214  }
215  }
216 }
217 
218 } // namespace
219 
221  ccHObject &container,
222  LoadParameters &parameters) {
223  RDBOpenDialog openDlg(nullptr);
224 
225  // New RDB library context
226  riegl::rdb::Context context;
227 
228  // check for known rdb vector attributes
229  bool rdb_hasRGBA = false;
230  bool rdb_hasNormals = false;
231  bool rdb_has_pca_axis_min = false;
232 
233  // needed for plane patch
234  // bool rdb_hasNormals = false;
235  bool rdb_has_plane_up = false;
236  bool rdb_has_plane_width = false;
237  bool rdb_has_plane_height = false;
238 
239  {
240  // Access existing database
241  riegl::rdb::Pointcloud rdb(context);
242  riegl::rdb::pointcloud::OpenSettings settings(context);
243  rdb.open(filename.toStdString(), settings);
244 
245  // Fill the table with attributes
246  updateTable(openDlg, rdb);
247 
248  // Get index graph root node
249  riegl::rdb::pointcloud::QueryStat stat = rdb.stat();
250  riegl::rdb::pointcloud::GraphNode root = stat.index();
251  openDlg.rdbPointsNumber->setText(
252  QString("%1").arg(root.pointCountTotal));
253 
254  {
255  // Get list of point attributes
256  std::vector<std::string> attributes = rdb.pointAttribute().list();
257 
258  // check for existance of specific rdb attribute
259  auto listContains = [](std::vector<std::string> &attributes,
260  const char *att) {
261  return std::find(attributes.begin(), attributes.end(), att) !=
262  attributes.end();
263  };
264 
265  rdb_hasRGBA = listContains(attributes, "riegl.rgba");
266  rdb_hasNormals = listContains(attributes, "riegl.surface_normal");
267  rdb_has_pca_axis_min =
268  listContains(attributes, "riegl.pca_axis_min");
269  rdb_has_plane_up = listContains(attributes, "riegl.plane_up");
270  rdb_has_plane_width = listContains(attributes, "riegl.plane_width");
271  rdb_has_plane_height =
272  listContains(attributes, "riegl.plane_height");
273 
274  if (rdb_hasNormals && rdb_has_pca_axis_min) {
275  // prefer plane normals
276  rdb_has_pca_axis_min = false;
277  }
278  }
279  }
280 
281  // open dialog and wait for user to configure
282  if (!openDlg.exec()) {
284  }
285 
286  // define needed parameter for scalar fields
287  struct Conversion {
288  // name of the attribute
289  std::string att;
290  // pointer to scalar field
291  ccScalarField *sf;
292  // buffer for rdb select
293  std::vector<float> buffer;
294  };
295 
296  // Load the file
297  const size_t BUFFER_SIZE = 100000;
298  size_t total = 0;
299 
300  // point cloud from CC to fill with points from rdb file
301  ccPointCloud *cloud = new ccPointCloud();
303  // if plane patch attributes are present create plane patch objects
304  bool create_planes = false;
305  ccHObject *plane_set = nullptr;
306  if (rdb_hasNormals && rdb_has_plane_up && rdb_has_plane_width &&
307  rdb_has_plane_height) {
308  create_planes = true;
309  cloud->setName("Plane Centers");
310  plane_set = new ccHObject();
311  }
312 
313  // create a list of the scalars
314  std::vector<std::string> scalars2load;
315  for (int i = 0; i < openDlg.rdbTableWidget->rowCount(); ++i) {
316  QComboBox *cbox = static_cast<QComboBox *>(
317  openDlg.rdbTableWidget->cellWidget(i, 1));
318  if (cbox->currentText() ==
320  QString att = openDlg.rdbTableWidget->item(i, 0)->text();
321  scalars2load.push_back(att.toStdString());
322  CVLog::Print(QString("load scalar: %1").arg(att));
323  }
324  }
325 
326  // initialize scalar fields and rdb buffers
327  std::vector<Conversion> conversions;
328  for (std::string &att : scalars2load) {
329  Conversion conv;
330  conv.att = att;
331  conv.sf = new ccScalarField(att.c_str());
332  conv.sf->link();
333  conv.buffer.resize(BUFFER_SIZE);
334  cloud->addScalarField(conv.sf);
335  conversions.push_back(conv);
336  }
337 
338  // if there are rgb values load and show them
339  if (rdb_hasRGBA) {
340  cloud->showColors(true);
341  }
342  // if there are surface normals load and show them
343  if (rdb_hasNormals || rdb_has_pca_axis_min) {
344  cloud->showNormals(true);
345  }
346  if (conversions.size() > 0) {
348  cloud->showSF(true);
349  }
350  {
351  // Access existing database
352  riegl::rdb::Pointcloud rdb(context);
353  riegl::rdb::pointcloud::OpenSettings settings(context);
354  rdb.open(filename.toStdString(), settings);
355  // Get index graph root node
356  riegl::rdb::pointcloud::QueryStat stat = rdb.stat();
357  riegl::rdb::pointcloud::GraphNode root = stat.index();
358 
359  // progress dialog
360  ecvProgressDialog pdlg(true, parameters.parentWidget);
362  &pdlg, root.pointCountTotal / BUFFER_SIZE);
363  {
364  std::stringstream ss;
365  ss << "Loading RDB file [" << filename.toStdString().c_str() << "]";
366  pdlg.setMethodTitle(ss.str().c_str());
367  pdlg.setInfo("Points loaded: 0");
368  pdlg.start();
369  }
370 
371  // prepare point attribute buffers
372  std::vector<std::array<float, 3>> buffer_xyz(BUFFER_SIZE);
373  std::vector<std::array<float, 3>> buffer_normals;
374  std::vector<std::array<uint8_t, 4>> buffer_rgba;
375  std::vector<std::array<float, 3>> buffer_plane_up;
376  std::vector<float> buffer_plane_width;
377  std::vector<float> buffer_plane_height;
378  // reserve memory for optional entries
379  if (rdb_hasNormals) buffer_normals.resize(BUFFER_SIZE);
380  if (rdb_hasRGBA) buffer_rgba.resize(BUFFER_SIZE);
381  if (rdb_has_plane_up) buffer_plane_up.resize(BUFFER_SIZE);
382  if (rdb_has_plane_width) buffer_plane_width.resize(BUFFER_SIZE);
383  if (rdb_has_plane_height) buffer_plane_height.resize(BUFFER_SIZE);
384 
385  // Start new select query to read all points
386  riegl::rdb::pointcloud::QuerySelect select = rdb.select();
387 
388  // Bind target data buffers to query
389  select.bind("riegl.xyz", riegl::rdb::pointcloud::DataType::SINGLE,
390  buffer_xyz.data());
391  if (rdb_hasRGBA)
392  select.bind("riegl.rgba", riegl::rdb::pointcloud::DataType::UINT8,
393  buffer_rgba.data());
394  if (rdb_hasNormals)
395  select.bind("riegl.surface_normal",
396  riegl::rdb::pointcloud::DataType::SINGLE,
397  buffer_normals.data());
398  if (rdb_has_pca_axis_min)
399  select.bind("riegl.pca_axis_min",
400  riegl::rdb::pointcloud::DataType::SINGLE,
401  buffer_normals.data());
402  if (rdb_has_plane_up)
403  select.bind("riegl.plane_up",
404  riegl::rdb::pointcloud::DataType::SINGLE,
405  buffer_plane_up.data());
406 
407  riegl::rdb::pointcloud::DataType ScalarTypeRiegl =
408  (sizeof(ScalarType) == 4
409  ? riegl::rdb::pointcloud::DataType::SINGLE
410  : riegl::rdb::pointcloud::DataType::DOUBLE);
411  if (rdb_has_plane_width)
412  select.bind("riegl.plane_width", ScalarTypeRiegl,
413  buffer_plane_width.data());
414  if (rdb_has_plane_height)
415  select.bind("riegl.plane_height", ScalarTypeRiegl,
416  buffer_plane_height.data());
417  for (Conversion &conv : conversions) {
418  select.bind(conv.att, ScalarTypeRiegl, conv.buffer.data());
419  }
420 
421  { // pre allocate memory for cloud to load
422  unsigned total_entries = 0;
423  // Start new select query to read all points
424  riegl::rdb::pointcloud::QuerySelect count_select = rdb.select();
425  while (const uint32_t count = count_select.next(BUFFER_SIZE)) {
426  total_entries += count;
427  }
428  if (cloud->reserve(total_entries)) {
429  if (rdb_hasRGBA && !cloud->reserveTheRGBTable()) {
430  CVLog::Print(QString("[RDBFilter] Not enough memory to "
431  "reserve RGB table for points. Try to "
432  "load as many as possible. Total: %1")
433  .arg(total_entries));
435  }
436  if ((rdb_hasNormals || rdb_has_pca_axis_min) &&
437  !cloud->reserveTheNormsTable()) {
438  CVLog::Print(
439  QString("[RDBFilter] Not enough memory to reserve "
440  "normal table for points. Try to load as "
441  "many as possible. Total: %1")
442  .arg(total_entries));
444  }
445  } else // not enough memory for all points
446  {
447  CVLog::Print(QString("[RDBFilter] Not enough memory to load "
448  "all points. Try to load as many as "
449  "possible. Total: %1")
450  .arg(total_entries));
452  }
453  }
454 
455  // Read and process all points block-wise
456  while (const uint32_t count = select.next(BUFFER_SIZE)) {
457  // reserve memory for next block (only if we don't have enough
458  // memory to hold the complete pointcloud)
460  if (!cloud->reserve(cloud->size() + count)) {
461  // can't load more points, exiting
463  break;
464  }
465  if (rdb_hasRGBA && !cloud->reserveTheRGBTable()) {
467  break;
468  }
469  if ((rdb_hasNormals || rdb_has_pca_axis_min) &&
470  !cloud->reserveTheNormsTable()) {
472  break;
473  }
474  }
475 
476  // buffers to hold the CC vectors
477  ecvColor::Rgb col;
478  for (uint32_t i = 0; i < count; ++i) {
479  // read XYZ
480  cloud->addPoint(CCVector3::fromArray(buffer_xyz[i].data()));
481  // read RGB
482  if (rdb_hasRGBA) {
483  col.r = static_cast<unsigned char>(buffer_rgba[i][0]);
484  col.g = static_cast<unsigned char>(buffer_rgba[i][1]);
485  col.b = static_cast<unsigned char>(buffer_rgba[i][2]);
486  cloud->addRGBColor(col);
487  }
488  // read normals
489  if (rdb_hasNormals || rdb_has_pca_axis_min) {
490  cloud->addNorm(
491  CCVector3::fromArray(buffer_normals[i].data()));
492  }
493  // read selected scalars
494  for (Conversion &conv : conversions) {
495  conv.sf->addElement(conv.buffer[i]);
496  }
497 
498  if (create_planes) {
499  // calculate tranformation matrix from norm and up vector
500  // to define the position and orientation of the plane patch
501  CCVector3 plane_norm =
502  CCVector3::fromArray(buffer_normals[i].data());
503  CCVector3 plane_up =
504  CCVector3::fromArray(buffer_plane_up[i].data());
505  CCVector3 plane_side = plane_norm.cross(-plane_up);
506  Vector3Tpl<float> X(plane_side);
507  Vector3Tpl<float> Y(plane_up);
508  Vector3Tpl<float> Z(plane_norm);
509  Vector3Tpl<float> t(static_cast<float>(buffer_xyz[i][0]),
510  static_cast<float>(buffer_xyz[i][1]),
511  static_cast<float>(buffer_xyz[i][2]));
512  ccGLMatrix mat(X, Y, Z, t);
513  // create plane patch
514  ccPlane *plane =
515  new ccPlane(static_cast<PointCoordinateType>(
516  buffer_plane_width[i]),
517  static_cast<PointCoordinateType>(
518  buffer_plane_height[i]),
519  &mat);
520  if (rdb_hasRGBA) {
521  col.r = static_cast<unsigned char>(buffer_rgba[i][0]);
522  col.g = static_cast<unsigned char>(buffer_rgba[i][1]);
523  col.b = static_cast<unsigned char>(buffer_rgba[i][2]);
524  plane->setColor(col);
525  }
526  plane->showNormalVector(
527  true); // per default show the normal vector
528  plane_set->addChild(plane);
529  }
530  }
531  total += count;
532 
533  {
534  // update the progress info
535  pdlg.setInfo(QString("Points loaded: %1").arg(total));
536  }
537 
538  if (!nprogress.oneStep()) {
539  // cancel requested
541  break;
542  }
543  }
544  }
545 
546  CVLog::Print(QString("[RDBFilter] Number of points: %1").arg(total));
547 
548  // compute min and max of scalars
549  for (Conversion &conv : conversions) {
550  conv.sf->computeMinAndMax();
551  conv.sf->release();
552  }
553  cloud->setVisible(true);
554  container.addChild(static_cast<ccHObject *>(cloud));
555  if (create_planes) {
556  container.addChild(plane_set);
557  }
558 
559  return result;
560 }
561 
563  bool &multiple,
564  bool &exclusive) const {
565  Q_UNUSED(type);
566  Q_UNUSED(multiple);
567  Q_UNUSED(exclusive);
568 
569  //... can we save this?
570  return false;
571 }
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
int64_t CV_CLASS_ENUM
Type of object type flags (64 bits)
Definition: CVTypes.h:97
std::string filename
std::string name
int count
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_NO_ERROR
Definition: FileIOFilter.h:21
@ CC_FERR_NOT_ENOUGH_MEMORY
Definition: FileIOFilter.h:31
@ RDB_OPEN_DLG_Scalar
Definition: RDBOpenDialog.h:22
@ RDB_OPEN_DLG_None
Definition: RDBOpenDialog.h:17
@ RDB_OPEN_DLG_NORM
Definition: RDBOpenDialog.h:19
@ RDB_OPEN_DLG_XYZ
Definition: RDBOpenDialog.h:18
@ RDB_OPEN_DLG_RGB
Definition: RDBOpenDialog.h:20
const char RDB_OPEN_DLG_TYPES_NAMES[RDB_OPEN_DLG_TYPES_NUMBER][24]
Definition: RDBOpenDialog.h:25
void * X
Definition: SmallVector.cpp:45
core::Tensor result
Definition: VtkUtils.cpp:76
static bool Print(const char *format,...)
Prints out a formatted message in console.
Definition: CVLog.cpp:113
Generic file I/O filter.
Definition: FileIOFilter.h:46
static constexpr float DEFAULT_PRIORITY
Definition: FileIOFilter.h:313
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: RDBFilter.cpp:562
CC_FILE_ERROR loadFile(const QString &fileName, ccHObject &container, LoadParameters &parameters) override
Loads one or more entities from a file.
Definition: RDBFilter.cpp:220
RDB Open dialog.
Definition: RDBOpenDialog.h:29
Vector3Tpl cross(const Vector3Tpl &v) const
Cross product.
Definition: CVGeom.h:412
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
Definition: CVGeom.h:268
virtual void setVisible(bool state)
Sets entity visibility.
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.
Float version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:19
virtual void setColor(const ecvColor::Rgb &col)
Sets primitive color (shortcut)
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
virtual void setName(const QString &name)
Sets object name.
Definition: ecvObject.h:75
void showNormalVector(bool state)
Show normal vector.
Plane (primitive)
Definition: ecvPlane.h:18
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 addRGBColor(const ecvColor::Rgb &C)
Pushes an RGB color on stack.
A scalar field associated to display-related parameters.
bool oneStep()
Increments total progress value of a single unit.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
Definition: PointCloudTpl.h:38
RGB color structure.
Definition: ecvColorTypes.h:49
Graphical progress indicator (thread-safe)
virtual void start() override
virtual void setInfo(const char *infoStr) override
Notifies some information about the ongoing process.
virtual void setMethodTitle(const char *methodTitle) override
Notifies the algorithm title.
ImGuiContext * context
Definition: Window.cpp:76
std::string to_string(const T &n)
Definition: Common.h:20
Generic loading parameters.
Definition: FileIOFilter.h:51
QWidget * parentWidget
Parent widget (if any)
Definition: FileIOFilter.h:78