ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
MLSSmoothingUpsampling.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 
9 
10 // Local
11 #include <Utils/cc2sm.h>
12 #include <Utils/sm2cc.h>
13 
14 #include "PclUtils/PCLModules.h"
15 #include "dialogs/MLSDialog.h"
16 
17 // ECV_PLUGINS
18 #include <ecvMainAppInterface.h>
19 
20 // CV_DB_LIB
21 #include <ecvPointCloud.h>
22 #include <ecvScalarField.h>
23 
24 // Qt
25 #include <QMainWindow>
26 
27 #ifdef LP_PCL_PATCH_ENABLED
28 #include <Utils/copy.h>
29 #endif
30 
33  tr("MLS smoothing"),
34  tr("Smooth using MLS, optionally upsample"),
35  tr("Smooth the cloud using Moving Least Sqares algorithm, "
36  "estimate normals and optionally upsample"),
37  ":/toolbar/PclAlgorithms/icons/mls_smoothing.png")),
38  m_dialog(nullptr),
39  m_dialogHasParent(false),
40  m_parameters(new PCLModules::MLSParameters) {}
41 
43  // we must delete parent-less dialogs ourselves!
44  if (!m_dialogHasParent && m_dialog && m_dialog->parent() == nullptr) {
45  delete m_dialog;
46  }
47 
48  if (m_parameters) {
49  delete m_parameters;
50  }
51 }
52 
54  if (!m_dialog) {
55  m_dialog = new MLSDialog(m_app ? m_app->getMainWindow() : nullptr);
56  m_dialogHasParent = (m_app->getMainWindow() != nullptr);
57  }
58 
59  return m_dialog->exec() ? 1 : 0;
60 }
61 
63  // we need to read all the parameters and put them into m_parameters
64  m_parameters->search_radius_ = m_dialog->search_radius->value();
65  m_parameters->compute_normals_ = m_dialog->compute_normals->checkState();
66  m_parameters->polynomial_fit_ = m_dialog->use_polynomial->checkState();
67  m_parameters->order_ = m_dialog->polynomial_order->value();
68  m_parameters->sqr_gauss_param_ =
69  m_dialog->squared_gaussian_parameter->value();
70 
71  int index_now = m_dialog->upsampling_method->currentIndex();
72  QVariant current_status = m_dialog->upsampling_method->itemData(index_now);
73  int status = current_status.toInt();
74 
75  m_parameters->upsample_method_ =
76  (PCLModules::MLSParameters::UpsamplingMethod)status;
77 
78  m_parameters->upsampling_radius_ = m_dialog->upsampling_radius->value();
79  m_parameters->upsampling_step_ = m_dialog->upsampling_step_size->value();
80  m_parameters->step_point_density_ = m_dialog->step_point_density->value();
81  m_parameters->dilation_voxel_size_ = m_dialog->dilation_voxel_size->value();
82 }
83 
85  // pointer to selected cloud
87  if (!cloud) return -1;
88 
89  // get xyz in PCL format
90 
91  std::list<std::string> req_fields;
92  try {
93  req_fields.push_back("xyz"); // always needed
94  if (cloud->getCurrentDisplayedScalarField()) {
95  // keep the current scalar field (if any)
96  req_fields.push_back(
98  }
99  } catch (const std::bad_alloc&) {
100  // not enough memory
101  return -1;
102  }
103 
104  // take out the xyz info
105  PCLCloud::Ptr sm_cloud = cc2smReader(cloud).getAsSM(req_fields);
106  if (!sm_cloud) return -1;
107 
108  // Now change the name of the field to use to a standard name, only if in
109  // OTHER_FIELD mode
110  if (cloud->getCurrentDisplayedScalarField()) {
111  int field_index = pcl::getFieldIndex(
112  *sm_cloud,
113  cc2smReader::GetSimplifiedSFName(
115  if (field_index >= 0) sm_cloud->fields.at(field_index).name = "scalar";
116  }
117 
118  // get as pcl point cloud
119  pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud(
120  new pcl::PointCloud<pcl::PointXYZ>);
121  FROM_PCL_CLOUD(*sm_cloud, *pcl_cloud);
122 
123  // create storage for outcloud
124  pcl::PointCloud<pcl::PointNormal>::Ptr normals(
125  new pcl::PointCloud<pcl::PointNormal>);
126 #ifdef LP_PCL_PATCH_ENABLED
127  pcl::PointIndicesPtr mapping_indices;
128  PCLModules::SmoothMls<pcl::PointXYZ, pcl::PointNormal>(
129  pcl_cloud, *m_parameters, normals, mapping_indices);
130 #else
131  PCLModules::SmoothMls<pcl::PointXYZ, pcl::PointNormal>(
132  pcl_cloud, *m_parameters, normals);
133 #endif
134 
135  PCLCloud::Ptr sm_normals(new PCLCloud);
136  TO_PCL_CLOUD(*normals, *sm_normals);
137 
138  ccPointCloud* new_cloud = pcl2cc::Convert(*sm_normals);
139  if (!new_cloud) {
140  // conversion failed (not enough memory?)
141  return -1;
142  }
143 
144  new_cloud->setName(cloud->getName() +
145  QString("_smoothed")); // original name + suffix
146  // new_cloud->setDisplay(cloud->getDisplay());
147 
148 #ifdef LP_PCL_PATCH_ENABLED
149  // copy the original scalar fields here
150  copyScalarFields(cloud, new_cloud, mapping_indices, true);
151  // copy the original colors here
152  copyRGBColors(cloud, new_cloud, mapping_indices, true);
153 #endif
154 
155  // copy global shift & scale
156  new_cloud->setGlobalScale(cloud->getGlobalScale());
157  new_cloud->setGlobalShift(cloud->getGlobalShift());
158 
159  // disable original cloud
160  cloud->setEnabled(false);
161  if (cloud->getParent()) cloud->getParent()->addChild(new_cloud);
162 
163  emit newEntity(new_cloud);
164 
165  return 1;
166 }
Base abstract class for each implemented PCL filter.
Definition: BasePclModule.h:53
void newEntity(ccHObject *)
Signal emitted when a new entity is created by the filter.
ecvMainAppInterface * m_app
Associated application interface.
ccPointCloud * getSelectedEntityAsCCPointCloud() const
Returns the first selected entity as a ccPointCloud.
void getParametersFromDialog()
Collects parameters from the filter dialog (if openDialog is successful)
PCLModules::MLSParameters * m_parameters
int compute()
Performs the actual filter job.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
ccHObject * getParent() const
Returns parent object.
Definition: ecvHObject.h:245
virtual QString getName() const
Returns object name.
Definition: ecvObject.h:72
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.)
ccScalarField * getCurrentDisplayedScalarField() const
Returns the currently displayed scalar (or 0 if none)
virtual void setGlobalScale(double scale)
virtual void setGlobalShift(double x, double y, double z)
Sets shift applied to original coordinates (information storage only)
virtual const CCVector3d & getGlobalShift() const
Returns the shift applied to original coordinates.
virtual double getGlobalScale() const
Returns the scale applied to original coordinates.
const char * getName() const
Returns scalar field name.
Definition: ScalarField.h:43
virtual QMainWindow * getMainWindow()=0
Returns main window.
double normals[3]
PCL filter description.
Definition: BasePclModule.h:26