29 #include "ui_exportCloudsDialog.h"
48 #include "rtabmap/core/Version.h"
50 #include <pcl/conversions.h>
51 #include <pcl/io/pcd_io.h>
52 #include <pcl/io/ply_io.h>
53 #include <pcl/io/vtk_io.h>
54 #include <pcl/io/obj_io.h>
55 #include <pcl/pcl_config.h>
56 #include <pcl/surface/poisson.h>
57 #include <pcl/common/common.h>
59 #include <QPushButton>
62 #include <QMessageBox>
63 #include <QFileDialog>
64 #include <QInputDialog>
68 #ifdef RTABMAP_CPUTSDF
69 #include <cpu_tsdf/tsdf_volume_octree.h>
70 #include <cpu_tsdf/marching_cubes_tsdf_octree.h>
73 #ifdef RTABMAP_OPENCHISEL
75 #include <open_chisel/ProjectionIntegrator.h>
76 #include <open_chisel/truncation/QuadraticTruncator.h>
77 #include <open_chisel/weighting/ConstantWeighter.h>
93 _ui =
new Ui_ExportCloudsDialog();
96 connect(
_ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()),
this, SLOT(
restoreDefaults()));
97 QPushButton * loadSettingsButton =
_ui->buttonBox->addButton(
"Load Settings", QDialogButtonBox::ActionRole);
98 QPushButton * saveSettingsButton =
_ui->buttonBox->addButton(
"Save Settings", QDialogButtonBox::ActionRole);
99 connect(loadSettingsButton, SIGNAL(clicked()),
this, SLOT(
loadSettings()));
100 connect(saveSettingsButton, SIGNAL(clicked()),
this, SLOT(
saveSettings()));
103 _ui->comboBox_upsamplingMethod->setItemData(1, 0, Qt::UserRole - 1);
105 connect(
_ui->checkBox_fromDepth, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
107 connect(
_ui->checkBox_binary, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
108 connect(
_ui->spinBox_normalKSearch, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
109 connect(
_ui->doubleSpinBox_normalRadiusSearch, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
110 connect(
_ui->doubleSpinBox_groundNormalsUp, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
111 connect(
_ui->comboBox_pipeline, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
113 connect(
_ui->comboBox_meshingApproach, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
116 connect(
_ui->checkBox_nodes_filtering, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
118 connect(
_ui->doubleSpinBox_nodes_filtering_xmin, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
119 connect(
_ui->doubleSpinBox_nodes_filtering_xmax, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
120 connect(
_ui->doubleSpinBox_nodes_filtering_ymin, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
121 connect(
_ui->doubleSpinBox_nodes_filtering_ymax, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
122 connect(
_ui->doubleSpinBox_nodes_filtering_zmin, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
123 connect(
_ui->doubleSpinBox_nodes_filtering_zmax, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
125 connect(
_ui->checkBox_regenerate, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
127 connect(
_ui->spinBox_decimation, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
128 connect(
_ui->doubleSpinBox_maxDepth, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
129 connect(
_ui->doubleSpinBox_minDepth, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
130 connect(
_ui->doubleSpinBox_ceilingHeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
131 connect(
_ui->doubleSpinBox_floorHeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
132 connect(
_ui->groupBox_offAxisFiltering, SIGNAL(toggled(
bool)),
this, SIGNAL(
configChanged()));
133 connect(
_ui->doubleSpinBox_offAxisFilteringAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
134 connect(
_ui->checkBox_offAxisFilteringPosX, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
135 connect(
_ui->checkBox_offAxisFilteringNegX, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
136 connect(
_ui->checkBox_offAxisFilteringPosY, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
137 connect(
_ui->checkBox_offAxisFilteringNegY, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
138 connect(
_ui->checkBox_offAxisFilteringPosZ, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
139 connect(
_ui->checkBox_offAxisFilteringNegZ, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
140 connect(
_ui->doubleSpinBox_footprintWidth, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
141 connect(
_ui->doubleSpinBox_footprintLength, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
142 connect(
_ui->doubleSpinBox_footprintHeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
143 connect(
_ui->spinBox_decimation_scan, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
144 connect(
_ui->doubleSpinBox_rangeMin, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
145 connect(
_ui->doubleSpinBox_rangeMax, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
146 connect(
_ui->spinBox_fillDepthHoles, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
147 connect(
_ui->spinBox_fillDepthHolesError, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
148 connect(
_ui->lineEdit_roiRatios, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
149 connect(
_ui->lineEdit_distortionModel, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
152 connect(
_ui->checkBox_bilateral, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
154 connect(
_ui->doubleSpinBox_bilateral_sigmaS, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
155 connect(
_ui->doubleSpinBox_bilateral_sigmaR, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
157 connect(
_ui->checkBox_filtering, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
159 connect(
_ui->doubleSpinBox_filteringRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
160 connect(
_ui->spinBox_filteringMinNeighbors, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
162 connect(
_ui->checkBox_assemble, SIGNAL(clicked(
bool)),
this, SIGNAL(
configChanged()));
164 connect(
_ui->doubleSpinBox_voxelSize_assembled, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
165 connect(
_ui->spinBox_randomSamples_assembled, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
166 connect(
_ui->comboBox_frame, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
169 connect(
_ui->checkBox_subtraction, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
171 connect(
_ui->doubleSpinBox_subtractPointFilteringRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
172 connect(
_ui->doubleSpinBox_subtractPointFilteringAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
173 connect(
_ui->spinBox_subtractFilteringMinPts, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
175 connect(
_ui->checkBox_smoothing, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
177 connect(
_ui->doubleSpinBox_mlsRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
178 connect(
_ui->spinBox_polygonialOrder, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
179 connect(
_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
180 connect(
_ui->doubleSpinBox_sampleStep, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
181 connect(
_ui->spinBox_randomPoints, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
182 connect(
_ui->doubleSpinBox_dilationVoxelSize, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
183 connect(
_ui->spinBox_dilationSteps, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
184 connect(
_ui->doubleSpinBox_mls_outputVoxelSize, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
185 _ui->stackedWidget_upsampling->setCurrentIndex(
_ui->comboBox_upsamplingMethod->currentIndex());
186 connect(
_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(
int)),
_ui->stackedWidget_upsampling, SLOT(setCurrentIndex(
int)));
189 connect(
_ui->checkBox_gainCompensation, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
191 connect(
_ui->doubleSpinBox_gainRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
192 connect(
_ui->doubleSpinBox_gainOverlap, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
193 connect(
_ui->doubleSpinBox_gainBeta, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
194 connect(
_ui->checkBox_gainRGB, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
195 connect(
_ui->checkBox_gainFull, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
196 connect(
_ui->spinBox_textureBrightnessContrastRatioLow, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
197 connect(
_ui->spinBox_textureBrightnessContrastRatioHigh, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
198 connect(
_ui->checkBox_exposureFusion, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
199 connect(
_ui->checkBox_blending, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
200 connect(
_ui->comboBox_blendingDecimation, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
202 connect(
_ui->checkBox_cameraProjection, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
204 connect(
_ui->lineEdit_camProjRoiRatios, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
205 connect(
_ui->toolButton_camProjMaskFilePath, SIGNAL(clicked()),
this, SLOT(
selectCamProjMask()));
206 connect(
_ui->lineEdit_camProjMaskFilePath, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
207 connect(
_ui->spinBox_camProjDecimation, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
208 connect(
_ui->doubleSpinBox_camProjMaxDistance, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
209 connect(
_ui->doubleSpinBox_camProjMaxAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
210 connect(
_ui->checkBox_camProjDistanceToCamPolicy, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
211 connect(
_ui->checkBox_camProjKeepPointsNotSeenByCameras, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
212 connect(
_ui->checkBox_camProjRecolorPoints, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
213 connect(
_ui->comboBox_camProjExportCamera, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
215 _ui->comboBox_camProjExportCamera->setEnabled(
false);
216 _ui->label_camProjExportCamera->setEnabled(
false);
217 _ui->label_camProjExportCamera->setText(
_ui->label_camProjExportCamera->text() +
" (PDAL dependency required)");
220 connect(
_ui->checkBox_meshing, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
222 connect(
_ui->doubleSpinBox_gp3Radius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
223 connect(
_ui->doubleSpinBox_gp3Mu, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
224 connect(
_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
226 connect(
_ui->spinBox_meshMaxPolygons, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
228 connect(
_ui->doubleSpinBox_transferColorRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
229 connect(
_ui->checkBox_cleanMesh, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
230 connect(
_ui->spinBox_mesh_minClusterSize, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
231 connect(
_ui->checkBox_textureMapping, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
233 connect(
_ui->comboBox_meshingTextureFormat, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
234 connect(
_ui->comboBox_meshingTextureSize, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
235 connect(
_ui->spinBox_mesh_maxTextures, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
236 connect(
_ui->doubleSpinBox_meshingTextureMaxDistance, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
237 connect(
_ui->doubleSpinBox_meshingTextureMaxDepthError, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
238 connect(
_ui->doubleSpinBox_meshingTextureMaxAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
239 connect(
_ui->spinBox_mesh_minTextureClusterSize, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
240 connect(
_ui->lineEdit_meshingTextureRoiRatios, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
241 connect(
_ui->checkBox_cameraFilter, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
243 connect(
_ui->doubleSpinBox_cameraFilterRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
244 connect(
_ui->doubleSpinBox_cameraFilterAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
245 connect(
_ui->doubleSpinBox_cameraFilterVel, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
246 connect(
_ui->doubleSpinBox_cameraFilterVelRad, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
247 connect(
_ui->doubleSpinBox_laplacianVariance, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
248 connect(
_ui->checkBox_multiband, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
250 connect(
_ui->spinBox_multiband_downscale, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
251 connect(
_ui->lineEdit_multiband_nbcontrib, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
252 connect(
_ui->comboBox_multiband_unwrap, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
253 connect(
_ui->checkBox_multiband_fillholes, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
254 connect(
_ui->spinBox_multiband_padding, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
255 connect(
_ui->doubleSpinBox_multiband_bestscore, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
256 connect(
_ui->doubleSpinBox_multiband_angle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
257 connect(
_ui->checkBox_multiband_forcevisible, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
259 connect(
_ui->checkBox_poisson_outputPolygons, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
260 connect(
_ui->checkBox_poisson_manifold, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
261 connect(
_ui->spinBox_poisson_depth, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
262 connect(
_ui->doubleSpinBox_poisson_targetPolygonSize, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
263 connect(
_ui->spinBox_poisson_iso, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
264 connect(
_ui->spinBox_poisson_solver, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
265 connect(
_ui->spinBox_poisson_minDepth, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
266 connect(
_ui->doubleSpinBox_poisson_samples, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
267 connect(
_ui->doubleSpinBox_poisson_pointWeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
268 connect(
_ui->doubleSpinBox_poisson_scale, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
270 connect(
_ui->doubleSpinBox_cputsdf_size, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
271 connect(
_ui->doubleSpinBox_cputsdf_resolution, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
272 connect(
_ui->doubleSpinBox_cputsdf_tuncPos, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
273 connect(
_ui->doubleSpinBox_cputsdf_tuncNeg, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
274 connect(
_ui->doubleSpinBox_cputsdf_minWeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
275 connect(
_ui->doubleSpinBox_cputsdf_flattenRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
276 connect(
_ui->spinBox_cputsdf_randomSplit, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
278 connect(
_ui->checkBox_openchisel_mergeVertices, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
279 connect(
_ui->spinBox_openchisel_chunk_size_x, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
280 connect(
_ui->spinBox_openchisel_chunk_size_y, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
281 connect(
_ui->spinBox_openchisel_chunk_size_z, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
282 connect(
_ui->doubleSpinBox_openchisel_truncation_constant, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
283 connect(
_ui->doubleSpinBox_openchisel_truncation_linear, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
284 connect(
_ui->doubleSpinBox_openchisel_truncation_quadratic, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
285 connect(
_ui->doubleSpinBox_openchisel_truncation_scale, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
286 connect(
_ui->spinBox_openchisel_integration_weight, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
287 connect(
_ui->checkBox_openchisel_use_voxel_carving, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
288 connect(
_ui->doubleSpinBox_openchisel_carving_dist_m, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
289 connect(
_ui->doubleSpinBox_openchisel_near_plane_dist, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
290 connect(
_ui->doubleSpinBox_openchisel_far_plane_dist, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
301 _ui->doubleSpinBox_meshDecimationFactor->setEnabled(
false);
302 _ui->spinBox_meshMaxPolygons->setEnabled(
false);
303 _ui->label_meshDecimation->setEnabled(
false);
304 _ui->label_meshMaxPolygons->setEnabled(
false);
307 #if CV_MAJOR_VERSION < 3
308 _ui->checkBox_exposureFusion->setEnabled(
false);
309 _ui->checkBox_exposureFusion->setChecked(
false);
310 _ui->label_exposureFusion->setEnabled(
false);
322 _ui->groupBox->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 0);
323 _ui->groupBox_2->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 1);
324 _ui->groupBox_3->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 2);
325 _ui->groupBox_4->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 3);
326 _ui->groupBox_5->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 4);
339 _ui->checkBox_assemble->setChecked(
true);
340 _ui->checkBox_assemble->setEnabled(
false);
344 _ui->checkBox_assemble->setEnabled(
true);
357 settings.beginGroup(group);
359 settings.setValue(
"pipeline",
_ui->comboBox_pipeline->currentIndex());
360 settings.setValue(
"from_depth",
_ui->checkBox_fromDepth->isChecked());
361 settings.setValue(
"binary",
_ui->checkBox_binary->isChecked());
362 settings.setValue(
"normals_k",
_ui->spinBox_normalKSearch->value());
363 settings.setValue(
"normals_radius",
_ui->doubleSpinBox_normalRadiusSearch->value());
364 settings.setValue(
"normals_ground_normals_up",
_ui->doubleSpinBox_groundNormalsUp->value());
365 settings.setValue(
"intensity_colormap",
_ui->comboBox_intensityColormap->currentIndex());
367 settings.setValue(
"nodes_filtering",
_ui->checkBox_nodes_filtering->isChecked());
368 settings.setValue(
"nodes_filtering_xmin",
_ui->doubleSpinBox_nodes_filtering_xmin->value());
369 settings.setValue(
"nodes_filtering_xmax",
_ui->doubleSpinBox_nodes_filtering_xmax->value());
370 settings.setValue(
"nodes_filtering_ymin",
_ui->doubleSpinBox_nodes_filtering_ymin->value());
371 settings.setValue(
"nodes_filtering_ymax",
_ui->doubleSpinBox_nodes_filtering_ymax->value());
372 settings.setValue(
"nodes_filtering_zmin",
_ui->doubleSpinBox_nodes_filtering_zmin->value());
373 settings.setValue(
"nodes_filtering_zmax",
_ui->doubleSpinBox_nodes_filtering_zmax->value());
375 settings.setValue(
"regenerate",
_ui->checkBox_regenerate->isChecked());
376 settings.setValue(
"regenerate_decimation",
_ui->spinBox_decimation->value());
377 settings.setValue(
"regenerate_max_depth",
_ui->doubleSpinBox_maxDepth->value());
378 settings.setValue(
"regenerate_min_depth",
_ui->doubleSpinBox_minDepth->value());
379 settings.setValue(
"regenerate_ceiling",
_ui->doubleSpinBox_ceilingHeight->value());
380 settings.setValue(
"regenerate_floor",
_ui->doubleSpinBox_floorHeight->value());
381 settings.setValue(
"regenerate_offaxis_filtering",
_ui->groupBox_offAxisFiltering->isChecked());
382 settings.setValue(
"regenerate_offaxis_filtering_angle",
_ui->doubleSpinBox_offAxisFilteringAngle->value());
383 settings.setValue(
"regenerate_offaxis_filtering_pos_x",
_ui->checkBox_offAxisFilteringPosX->isChecked());
384 settings.setValue(
"regenerate_offaxis_filtering_neg_x",
_ui->checkBox_offAxisFilteringNegX->isChecked());
385 settings.setValue(
"regenerate_offaxis_filtering_pos_y",
_ui->checkBox_offAxisFilteringPosY->isChecked());
386 settings.setValue(
"regenerate_offaxis_filtering_neg_y",
_ui->checkBox_offAxisFilteringNegY->isChecked());
387 settings.setValue(
"regenerate_offaxis_filtering_pos_z",
_ui->checkBox_offAxisFilteringPosZ->isChecked());
388 settings.setValue(
"regenerate_offaxis_filtering_neg_z",
_ui->checkBox_offAxisFilteringNegZ->isChecked());
389 settings.setValue(
"regenerate_footprint_height",
_ui->doubleSpinBox_footprintHeight->value());
390 settings.setValue(
"regenerate_footprint_width",
_ui->doubleSpinBox_footprintWidth->value());
391 settings.setValue(
"regenerate_footprint_length",
_ui->doubleSpinBox_footprintLength->value());
392 settings.setValue(
"regenerate_scan_decimation",
_ui->spinBox_decimation_scan->value());
393 settings.setValue(
"regenerate_scan_max_range",
_ui->doubleSpinBox_rangeMax->value());
394 settings.setValue(
"regenerate_scan_min_range",
_ui->doubleSpinBox_rangeMin->value());
395 settings.setValue(
"regenerate_fill_size",
_ui->spinBox_fillDepthHoles->value());
396 settings.setValue(
"regenerate_fill_error",
_ui->spinBox_fillDepthHolesError->value());
397 settings.setValue(
"regenerate_roi",
_ui->lineEdit_roiRatios->text());
398 settings.setValue(
"regenerate_distortion_model",
_ui->lineEdit_distortionModel->text());
400 settings.setValue(
"bilateral",
_ui->checkBox_bilateral->isChecked());
401 settings.setValue(
"bilateral_sigma_s",
_ui->doubleSpinBox_bilateral_sigmaS->value());
402 settings.setValue(
"bilateral_sigma_r",
_ui->doubleSpinBox_bilateral_sigmaR->value());
404 settings.setValue(
"filtering",
_ui->checkBox_filtering->isChecked());
405 settings.setValue(
"filtering_radius",
_ui->doubleSpinBox_filteringRadius->value());
406 settings.setValue(
"filtering_min_neighbors",
_ui->spinBox_filteringMinNeighbors->value());
408 settings.setValue(
"assemble",
_ui->checkBox_assemble->isChecked());
409 settings.setValue(
"assemble_voxel",
_ui->doubleSpinBox_voxelSize_assembled->value());
410 settings.setValue(
"assemble_samples",
_ui->spinBox_randomSamples_assembled->value());
411 settings.setValue(
"frame",
_ui->comboBox_frame->currentIndex());
413 settings.setValue(
"subtract",
_ui->checkBox_subtraction->isChecked());
414 settings.setValue(
"subtract_point_radius",
_ui->doubleSpinBox_subtractPointFilteringRadius->value());
415 settings.setValue(
"subtract_point_angle",
_ui->doubleSpinBox_subtractPointFilteringAngle->value());
416 settings.setValue(
"subtract_min_neighbors",
_ui->spinBox_subtractFilteringMinPts->value());
418 settings.setValue(
"mls",
_ui->checkBox_smoothing->isChecked());
419 settings.setValue(
"mls_radius",
_ui->doubleSpinBox_mlsRadius->value());
420 settings.setValue(
"mls_polygonial_order",
_ui->spinBox_polygonialOrder->value());
421 settings.setValue(
"mls_upsampling_method",
_ui->comboBox_upsamplingMethod->currentIndex());
422 settings.setValue(
"mls_upsampling_radius",
_ui->doubleSpinBox_sampleRadius->value());
423 settings.setValue(
"mls_upsampling_step",
_ui->doubleSpinBox_sampleStep->value());
424 settings.setValue(
"mls_point_density",
_ui->spinBox_randomPoints->value());
425 settings.setValue(
"mls_dilation_voxel_size",
_ui->doubleSpinBox_dilationVoxelSize->value());
426 settings.setValue(
"mls_dilation_iterations",
_ui->spinBox_dilationSteps->value());
427 settings.setValue(
"mls_output_voxel_size",
_ui->doubleSpinBox_mls_outputVoxelSize->value());
429 settings.setValue(
"gain",
_ui->checkBox_gainCompensation->isChecked());
430 settings.setValue(
"gain_radius",
_ui->doubleSpinBox_gainRadius->value());
431 settings.setValue(
"gain_overlap",
_ui->doubleSpinBox_gainOverlap->value());
432 settings.setValue(
"gain_beta",
_ui->doubleSpinBox_gainBeta->value());
433 settings.setValue(
"gain_rgb",
_ui->checkBox_gainRGB->isChecked());
434 settings.setValue(
"gain_full",
_ui->checkBox_gainFull->isChecked());
436 settings.setValue(
"cam_proj",
_ui->checkBox_cameraProjection->isChecked());
437 settings.setValue(
"cam_proj_roi_ratios",
_ui->lineEdit_camProjRoiRatios->text());
438 settings.setValue(
"cam_proj_mask",
_ui->lineEdit_camProjMaskFilePath->text());
439 settings.setValue(
"cam_proj_decimation",
_ui->spinBox_camProjDecimation->value());
440 settings.setValue(
"cam_proj_max_distance",
_ui->doubleSpinBox_camProjMaxDistance->value());
441 settings.setValue(
"cam_proj_max_angle",
_ui->doubleSpinBox_camProjMaxAngle->value());
442 settings.setValue(
"cam_proj_distance_policy",
_ui->checkBox_camProjDistanceToCamPolicy->isChecked());
443 settings.setValue(
"cam_proj_keep_points",
_ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked());
444 settings.setValue(
"cam_proj_recolor_points",
_ui->checkBox_camProjRecolorPoints->isChecked());
445 settings.setValue(
"cam_proj_export_format",
_ui->comboBox_camProjExportCamera->currentIndex());
447 settings.setValue(
"mesh",
_ui->checkBox_meshing->isChecked());
448 settings.setValue(
"mesh_radius",
_ui->doubleSpinBox_gp3Radius->value());
449 settings.setValue(
"mesh_mu",
_ui->doubleSpinBox_gp3Mu->value());
450 settings.setValue(
"mesh_decimation_factor",
_ui->doubleSpinBox_meshDecimationFactor->value());
451 settings.setValue(
"mesh_max_polygons",
_ui->spinBox_meshMaxPolygons->value());
452 settings.setValue(
"mesh_color_radius",
_ui->doubleSpinBox_transferColorRadius->value());
453 settings.setValue(
"mesh_clean",
_ui->checkBox_cleanMesh->isChecked());
454 settings.setValue(
"mesh_min_cluster_size",
_ui->spinBox_mesh_minClusterSize->value());
456 settings.setValue(
"mesh_dense_strategy",
_ui->comboBox_meshingApproach->currentIndex());
458 settings.setValue(
"mesh_texture",
_ui->checkBox_textureMapping->isChecked());
459 settings.setValue(
"mesh_textureFormat",
_ui->comboBox_meshingTextureFormat->currentIndex());
460 settings.setValue(
"mesh_textureSize",
_ui->comboBox_meshingTextureSize->currentIndex());
461 settings.setValue(
"mesh_textureMaxCount",
_ui->spinBox_mesh_maxTextures->value());
462 settings.setValue(
"mesh_textureMaxDistance",
_ui->doubleSpinBox_meshingTextureMaxDistance->value());
463 settings.setValue(
"mesh_textureMaxDepthError",
_ui->doubleSpinBox_meshingTextureMaxDepthError->value());
464 settings.setValue(
"mesh_textureMaxAngle",
_ui->doubleSpinBox_meshingTextureMaxAngle->value());
465 settings.setValue(
"mesh_textureMinCluster",
_ui->spinBox_mesh_minTextureClusterSize->value());
466 settings.setValue(
"mesh_textureRoiRatios",
_ui->lineEdit_meshingTextureRoiRatios->text());
467 settings.setValue(
"mesh_textureDistanceToCamPolicy",
_ui->checkBox_distanceToCamPolicy->isChecked());
468 settings.setValue(
"mesh_textureCameraFiltering",
_ui->checkBox_cameraFilter->isChecked());
469 settings.setValue(
"mesh_textureCameraFilteringRadius",
_ui->doubleSpinBox_cameraFilterRadius->value());
470 settings.setValue(
"mesh_textureCameraFilteringAngle",
_ui->doubleSpinBox_cameraFilterAngle->value());
471 settings.setValue(
"mesh_textureCameraFilteringVel",
_ui->doubleSpinBox_cameraFilterVel->value());
472 settings.setValue(
"mesh_textureCameraFilteringVelRad",
_ui->doubleSpinBox_cameraFilterVelRad->value());
473 settings.setValue(
"mesh_textureCameraFilteringLaplacian",
_ui->doubleSpinBox_laplacianVariance->value());
474 settings.setValue(
"mesh_textureBrightnessConstrastRatioLow",
_ui->spinBox_textureBrightnessContrastRatioLow->value());
475 settings.setValue(
"mesh_textureBrightnessConstrastRatioHigh",
_ui->spinBox_textureBrightnessContrastRatioHigh->value());
476 settings.setValue(
"mesh_textureExposureFusion",
_ui->checkBox_exposureFusion->isChecked());
477 settings.setValue(
"mesh_textureBlending",
_ui->checkBox_blending->isChecked());
478 settings.setValue(
"mesh_textureBlendingDecimation",
_ui->comboBox_blendingDecimation->currentIndex());
479 settings.setValue(
"mesh_textureMultiband",
_ui->checkBox_multiband->isChecked());
480 settings.setValue(
"mesh_textureMultibandDownScale",
_ui->spinBox_multiband_downscale->value());
481 settings.setValue(
"mesh_textureMultibandNbContrib",
_ui->lineEdit_multiband_nbcontrib->text());
482 settings.setValue(
"mesh_textureMultibandUnwrap",
_ui->comboBox_multiband_unwrap->currentIndex());
483 settings.setValue(
"mesh_textureMultibandFillHoles",
_ui->checkBox_multiband_fillholes->isChecked());
484 settings.setValue(
"mesh_textureMultibandPadding",
_ui->spinBox_multiband_padding->value());
485 settings.setValue(
"mesh_textureMultibandBestScoreThr",
_ui->doubleSpinBox_multiband_bestscore->value());
486 settings.setValue(
"mesh_textureMultibandAngleHardThr",
_ui->doubleSpinBox_multiband_angle->value());
487 settings.setValue(
"mesh_textureMultibandForceVisible",
_ui->checkBox_multiband_forcevisible->isChecked());
490 settings.setValue(
"mesh_angle_tolerance",
_ui->doubleSpinBox_mesh_angleTolerance->value());
491 settings.setValue(
"mesh_quad",
_ui->checkBox_mesh_quad->isChecked());
492 settings.setValue(
"mesh_triangle_size",
_ui->spinBox_mesh_triangleSize->value());
494 settings.setValue(
"poisson_outputPolygons",
_ui->checkBox_poisson_outputPolygons->isChecked());
495 settings.setValue(
"poisson_manifold",
_ui->checkBox_poisson_manifold->isChecked());
496 settings.setValue(
"poisson_depth",
_ui->spinBox_poisson_depth->value());
497 settings.setValue(
"poisson_polygon_size",
_ui->doubleSpinBox_poisson_targetPolygonSize->value());
498 settings.setValue(
"poisson_iso",
_ui->spinBox_poisson_iso->value());
499 settings.setValue(
"poisson_solver",
_ui->spinBox_poisson_solver->value());
500 settings.setValue(
"poisson_minDepth",
_ui->spinBox_poisson_minDepth->value());
501 settings.setValue(
"poisson_samples",
_ui->doubleSpinBox_poisson_samples->value());
502 settings.setValue(
"poisson_pointWeight",
_ui->doubleSpinBox_poisson_pointWeight->value());
503 settings.setValue(
"poisson_scale",
_ui->doubleSpinBox_poisson_scale->value());
505 settings.setValue(
"cputsdf_size",
_ui->doubleSpinBox_cputsdf_size->value());
506 settings.setValue(
"cputsdf_resolution",
_ui->doubleSpinBox_cputsdf_resolution->value());
507 settings.setValue(
"cputsdf_truncPos",
_ui->doubleSpinBox_cputsdf_tuncPos->value());
508 settings.setValue(
"cputsdf_truncNeg",
_ui->doubleSpinBox_cputsdf_tuncNeg->value());
509 settings.setValue(
"cputsdf_minWeight",
_ui->doubleSpinBox_cputsdf_minWeight->value());
510 settings.setValue(
"cputsdf_flattenRadius",
_ui->doubleSpinBox_cputsdf_flattenRadius->value());
511 settings.setValue(
"cputsdf_randomSplit",
_ui->spinBox_cputsdf_randomSplit->value());
513 settings.setValue(
"openchisel_merge_vertices",
_ui->checkBox_openchisel_mergeVertices->isChecked());
514 settings.setValue(
"openchisel_chunk_size_x",
_ui->spinBox_openchisel_chunk_size_x->value());
515 settings.setValue(
"openchisel_chunk_size_y",
_ui->spinBox_openchisel_chunk_size_y->value());
516 settings.setValue(
"openchisel_chunk_size_z",
_ui->spinBox_openchisel_chunk_size_z->value());
517 settings.setValue(
"openchisel_truncation_constant",
_ui->doubleSpinBox_openchisel_truncation_constant->value());
518 settings.setValue(
"openchisel_truncation_linear",
_ui->doubleSpinBox_openchisel_truncation_linear->value());
519 settings.setValue(
"openchisel_truncation_quadratic",
_ui->doubleSpinBox_openchisel_truncation_quadratic->value());
520 settings.setValue(
"openchisel_truncation_scale",
_ui->doubleSpinBox_openchisel_truncation_scale->value());
521 settings.setValue(
"openchisel_integration_weight",
_ui->spinBox_openchisel_integration_weight->value());
522 settings.setValue(
"openchisel_use_voxel_carving",
_ui->checkBox_openchisel_use_voxel_carving->isChecked());
523 settings.setValue(
"openchisel_carving_dist_m",
_ui->doubleSpinBox_openchisel_carving_dist_m->value());
524 settings.setValue(
"openchisel_near_plane_dist",
_ui->doubleSpinBox_openchisel_near_plane_dist->value());
525 settings.setValue(
"openchisel_far_plane_dist",
_ui->doubleSpinBox_openchisel_far_plane_dist->value());
537 settings.beginGroup(group);
540 _ui->comboBox_pipeline->setCurrentIndex(settings.value(
"pipeline",
_ui->comboBox_pipeline->currentIndex()).toInt());
541 _ui->checkBox_fromDepth->setChecked(settings.value(
"from_depth",
_ui->checkBox_fromDepth->isChecked()).toBool());
542 _ui->checkBox_binary->setChecked(settings.value(
"binary",
_ui->checkBox_binary->isChecked()).toBool());
543 _ui->spinBox_normalKSearch->setValue(settings.value(
"normals_k",
_ui->spinBox_normalKSearch->value()).toInt());
544 _ui->doubleSpinBox_normalRadiusSearch->setValue(settings.value(
"normals_radius",
_ui->doubleSpinBox_normalRadiusSearch->value()).toDouble());
545 _ui->doubleSpinBox_groundNormalsUp->setValue(settings.value(
"normals_ground_normals_up",
_ui->doubleSpinBox_groundNormalsUp->value()).toDouble());
546 _ui->comboBox_intensityColormap->setCurrentIndex(settings.value(
"intensity_colormap",
_ui->comboBox_intensityColormap->currentIndex()).toInt());
548 _ui->checkBox_nodes_filtering->setChecked(settings.value(
"nodes_filtering",
_ui->checkBox_nodes_filtering->isChecked()).toBool());
549 _ui->doubleSpinBox_nodes_filtering_xmin->setValue(settings.value(
"nodes_filtering_xmin",
_ui->doubleSpinBox_nodes_filtering_xmin->value()).toInt());
550 _ui->doubleSpinBox_nodes_filtering_xmax->setValue(settings.value(
"nodes_filtering_xmax",
_ui->doubleSpinBox_nodes_filtering_xmax->value()).toInt());
551 _ui->doubleSpinBox_nodes_filtering_ymin->setValue(settings.value(
"nodes_filtering_ymin",
_ui->doubleSpinBox_nodes_filtering_ymin->value()).toInt());
552 _ui->doubleSpinBox_nodes_filtering_ymax->setValue(settings.value(
"nodes_filtering_ymax",
_ui->doubleSpinBox_nodes_filtering_ymax->value()).toInt());
553 _ui->doubleSpinBox_nodes_filtering_zmin->setValue(settings.value(
"nodes_filtering_zmin",
_ui->doubleSpinBox_nodes_filtering_zmin->value()).toInt());
554 _ui->doubleSpinBox_nodes_filtering_zmax->setValue(settings.value(
"nodes_filtering_zmax",
_ui->doubleSpinBox_nodes_filtering_zmax->value()).toInt());
556 _ui->checkBox_regenerate->setChecked(settings.value(
"regenerate",
_ui->checkBox_regenerate->isChecked()).toBool());
557 _ui->spinBox_decimation->setValue(settings.value(
"regenerate_decimation",
_ui->spinBox_decimation->value()).toInt());
558 _ui->doubleSpinBox_maxDepth->setValue(settings.value(
"regenerate_max_depth",
_ui->doubleSpinBox_maxDepth->value()).toDouble());
559 _ui->doubleSpinBox_minDepth->setValue(settings.value(
"regenerate_min_depth",
_ui->doubleSpinBox_minDepth->value()).toDouble());
560 _ui->doubleSpinBox_ceilingHeight->setValue(settings.value(
"regenerate_ceiling",
_ui->doubleSpinBox_ceilingHeight->value()).toDouble());
561 _ui->doubleSpinBox_floorHeight->setValue(settings.value(
"regenerate_floor",
_ui->doubleSpinBox_floorHeight->value()).toDouble());
562 _ui->groupBox_offAxisFiltering->setChecked(settings.value(
"regenerate_offaxis_filtering",
_ui->groupBox_offAxisFiltering->isChecked()).toBool());
563 _ui->doubleSpinBox_offAxisFilteringAngle->setValue(settings.value(
"regenerate_offaxis_filtering_angle",
_ui->doubleSpinBox_offAxisFilteringAngle->value()).toDouble());
564 _ui->checkBox_offAxisFilteringPosX->setChecked(settings.value(
"regenerate_offaxis_filtering_pos_x",
_ui->checkBox_offAxisFilteringPosX->isChecked()).toBool());
565 _ui->checkBox_offAxisFilteringNegX->setChecked(settings.value(
"regenerate_offaxis_filtering_neg_x",
_ui->checkBox_offAxisFilteringNegX->isChecked()).toBool());
566 _ui->checkBox_offAxisFilteringPosY->setChecked(settings.value(
"regenerate_offaxis_filtering_pos_y",
_ui->checkBox_offAxisFilteringPosY->isChecked()).toBool());
567 _ui->checkBox_offAxisFilteringNegY->setChecked(settings.value(
"regenerate_offaxis_filtering_neg_y",
_ui->checkBox_offAxisFilteringNegY->isChecked()).toBool());
568 _ui->checkBox_offAxisFilteringPosZ->setChecked(settings.value(
"regenerate_offaxis_filtering_pos_z",
_ui->checkBox_offAxisFilteringPosZ->isChecked()).toBool());
569 _ui->checkBox_offAxisFilteringNegZ->setChecked(settings.value(
"regenerate_offaxis_filtering_neg_z",
_ui->checkBox_offAxisFilteringNegZ->isChecked()).toBool());
570 _ui->doubleSpinBox_footprintHeight->setValue(settings.value(
"regenerate_footprint_height",
_ui->doubleSpinBox_footprintHeight->value()).toDouble());
571 _ui->doubleSpinBox_footprintWidth->setValue(settings.value(
"regenerate_footprint_width",
_ui->doubleSpinBox_footprintWidth->value()).toDouble());
572 _ui->doubleSpinBox_footprintLength->setValue(settings.value(
"regenerate_footprint_length",
_ui->doubleSpinBox_footprintLength->value()).toDouble());
573 _ui->spinBox_decimation_scan->setValue(settings.value(
"regenerate_scan_decimation",
_ui->spinBox_decimation_scan->value()).toInt());
574 _ui->doubleSpinBox_rangeMax->setValue(settings.value(
"regenerate_scan_max_range",
_ui->doubleSpinBox_rangeMax->value()).toDouble());
575 _ui->doubleSpinBox_rangeMin->setValue(settings.value(
"regenerate_scan_min_range",
_ui->doubleSpinBox_rangeMin->value()).toDouble());
576 _ui->spinBox_fillDepthHoles->setValue(settings.value(
"regenerate_fill_size",
_ui->spinBox_fillDepthHoles->value()).toInt());
577 _ui->spinBox_fillDepthHolesError->setValue(settings.value(
"regenerate_fill_error",
_ui->spinBox_fillDepthHolesError->value()).toInt());
578 _ui->lineEdit_roiRatios->setText(settings.value(
"regenerate_roi",
_ui->lineEdit_roiRatios->text()).toString());
579 _ui->lineEdit_distortionModel->setText(settings.value(
"regenerate_distortion_model",
_ui->lineEdit_distortionModel->text()).toString());
581 _ui->checkBox_bilateral->setChecked(settings.value(
"bilateral",
_ui->checkBox_bilateral->isChecked()).toBool());
582 _ui->doubleSpinBox_bilateral_sigmaS->setValue(settings.value(
"bilateral_sigma_s",
_ui->doubleSpinBox_bilateral_sigmaS->value()).toDouble());
583 _ui->doubleSpinBox_bilateral_sigmaR->setValue(settings.value(
"bilateral_sigma_r",
_ui->doubleSpinBox_bilateral_sigmaR->value()).toDouble());
585 _ui->checkBox_filtering->setChecked(settings.value(
"filtering",
_ui->checkBox_filtering->isChecked()).toBool());
586 _ui->doubleSpinBox_filteringRadius->setValue(settings.value(
"filtering_radius",
_ui->doubleSpinBox_filteringRadius->value()).toDouble());
587 _ui->spinBox_filteringMinNeighbors->setValue(settings.value(
"filtering_min_neighbors",
_ui->spinBox_filteringMinNeighbors->value()).toInt());
589 if(
_ui->checkBox_assemble->isEnabled())
591 _ui->checkBox_assemble->setChecked(settings.value(
"assemble",
_ui->checkBox_assemble->isChecked()).toBool());
593 _ui->doubleSpinBox_voxelSize_assembled->setValue(settings.value(
"assemble_voxel",
_ui->doubleSpinBox_voxelSize_assembled->value()).toDouble());
594 _ui->spinBox_randomSamples_assembled->setValue(settings.value(
"assemble_samples",
_ui->spinBox_randomSamples_assembled->value()).toInt());
595 _ui->comboBox_frame->setCurrentIndex(settings.value(
"frame",
_ui->comboBox_frame->currentIndex()).toInt());
597 _ui->checkBox_subtraction->setChecked(settings.value(
"subtract",
_ui->checkBox_subtraction->isChecked()).toBool());
598 _ui->doubleSpinBox_subtractPointFilteringRadius->setValue(settings.value(
"subtract_point_radius",
_ui->doubleSpinBox_subtractPointFilteringRadius->value()).toDouble());
599 _ui->doubleSpinBox_subtractPointFilteringAngle->setValue(settings.value(
"subtract_point_angle",
_ui->doubleSpinBox_subtractPointFilteringAngle->value()).toDouble());
600 _ui->spinBox_subtractFilteringMinPts->setValue(settings.value(
"subtract_min_neighbors",
_ui->spinBox_subtractFilteringMinPts->value()).toInt());
602 _ui->checkBox_smoothing->setChecked(settings.value(
"mls",
_ui->checkBox_smoothing->isChecked()).toBool());
603 _ui->doubleSpinBox_mlsRadius->setValue(settings.value(
"mls_radius",
_ui->doubleSpinBox_mlsRadius->value()).toDouble());
604 _ui->spinBox_polygonialOrder->setValue(settings.value(
"mls_polygonial_order",
_ui->spinBox_polygonialOrder->value()).toInt());
605 _ui->comboBox_upsamplingMethod->setCurrentIndex(settings.value(
"mls_upsampling_method",
_ui->comboBox_upsamplingMethod->currentIndex()).toInt());
606 _ui->doubleSpinBox_sampleRadius->setValue(settings.value(
"mls_upsampling_radius",
_ui->doubleSpinBox_sampleRadius->value()).toDouble());
607 _ui->doubleSpinBox_sampleStep->setValue(settings.value(
"mls_upsampling_step",
_ui->doubleSpinBox_sampleStep->value()).toDouble());
608 _ui->spinBox_randomPoints->setValue(settings.value(
"mls_point_density",
_ui->spinBox_randomPoints->value()).toInt());
609 _ui->doubleSpinBox_dilationVoxelSize->setValue(settings.value(
"mls_dilation_voxel_size",
_ui->doubleSpinBox_dilationVoxelSize->value()).toDouble());
610 _ui->spinBox_dilationSteps->setValue(settings.value(
"mls_dilation_iterations",
_ui->spinBox_dilationSteps->value()).toInt());
611 _ui->doubleSpinBox_mls_outputVoxelSize->setValue(settings.value(
"mls_output_voxel_size",
_ui->doubleSpinBox_mls_outputVoxelSize->value()).toInt());
613 _ui->checkBox_gainCompensation->setChecked(settings.value(
"gain",
_ui->checkBox_gainCompensation->isChecked()).toBool());
614 _ui->doubleSpinBox_gainRadius->setValue(settings.value(
"gain_radius",
_ui->doubleSpinBox_gainRadius->value()).toDouble());
615 _ui->doubleSpinBox_gainOverlap->setValue(settings.value(
"gain_overlap",
_ui->doubleSpinBox_gainOverlap->value()).toDouble());
616 _ui->doubleSpinBox_gainBeta->setValue(settings.value(
"gain_beta",
_ui->doubleSpinBox_gainBeta->value()).toDouble());
617 _ui->checkBox_gainRGB->setChecked(settings.value(
"gain_rgb",
_ui->checkBox_gainRGB->isChecked()).toBool());
618 _ui->checkBox_gainFull->setChecked(settings.value(
"gain_full",
_ui->checkBox_gainFull->isChecked()).toBool());
620 _ui->checkBox_cameraProjection->setChecked(settings.value(
"cam_proj",
_ui->checkBox_cameraProjection->isChecked()).toBool());
621 _ui->lineEdit_camProjRoiRatios->setText(settings.value(
"cam_proj_roi_ratios",
_ui->lineEdit_camProjRoiRatios->text()).toString());
622 _ui->lineEdit_camProjMaskFilePath->setText(settings.value(
"cam_proj_mask",
_ui->lineEdit_camProjMaskFilePath->text()).toString());
623 _ui->spinBox_camProjDecimation->setValue(settings.value(
"cam_proj_decimation",
_ui->spinBox_camProjDecimation->value()).toInt());
624 _ui->doubleSpinBox_camProjMaxDistance->setValue(settings.value(
"cam_proj_max_distance",
_ui->doubleSpinBox_camProjMaxDistance->value()).toDouble());
625 _ui->doubleSpinBox_camProjMaxAngle->setValue(settings.value(
"cam_proj_max_angle",
_ui->doubleSpinBox_camProjMaxAngle->value()).toDouble());
626 _ui->checkBox_camProjDistanceToCamPolicy->setChecked(settings.value(
"cam_proj_distance_policy",
_ui->checkBox_camProjDistanceToCamPolicy->isChecked()).toBool());
627 _ui->checkBox_camProjKeepPointsNotSeenByCameras->setChecked(settings.value(
"cam_proj_keep_points",
_ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked()).toBool());
628 _ui->checkBox_camProjRecolorPoints->setChecked(settings.value(
"cam_proj_recolor_points",
_ui->checkBox_camProjRecolorPoints->isChecked()).toBool());
629 _ui->comboBox_camProjExportCamera->setCurrentIndex(settings.value(
"cam_proj_export_format",
_ui->comboBox_camProjExportCamera->currentIndex()).toInt());
631 _ui->checkBox_meshing->setChecked(settings.value(
"mesh",
_ui->checkBox_meshing->isChecked()).toBool());
632 _ui->doubleSpinBox_gp3Radius->setValue(settings.value(
"mesh_radius",
_ui->doubleSpinBox_gp3Radius->value()).toDouble());
633 _ui->doubleSpinBox_gp3Mu->setValue(settings.value(
"mesh_mu",
_ui->doubleSpinBox_gp3Mu->value()).toDouble());
634 _ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value(
"mesh_decimation_factor",
_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble());
635 _ui->spinBox_meshMaxPolygons->setValue(settings.value(
"mesh_max_polygons",
_ui->spinBox_meshMaxPolygons->value()).toDouble());
636 _ui->doubleSpinBox_transferColorRadius->setValue(settings.value(
"mesh_color_radius",
_ui->doubleSpinBox_transferColorRadius->value()).toDouble());
637 _ui->checkBox_cleanMesh->setChecked(settings.value(
"mesh_clean",
_ui->checkBox_cleanMesh->isChecked()).toBool());
638 _ui->spinBox_mesh_minClusterSize->setValue(settings.value(
"mesh_min_cluster_size",
_ui->spinBox_mesh_minClusterSize->value()).toInt());
640 _ui->comboBox_meshingApproach->setCurrentIndex(settings.value(
"mesh_dense_strategy",
_ui->comboBox_meshingApproach->currentIndex()).toInt());
642 _ui->checkBox_textureMapping->setChecked(settings.value(
"mesh_texture",
_ui->checkBox_textureMapping->isChecked()).toBool());
643 _ui->comboBox_meshingTextureFormat->setCurrentIndex(settings.value(
"mesh_textureFormat",
_ui->comboBox_meshingTextureFormat->currentIndex()).toInt());
644 _ui->comboBox_meshingTextureSize->setCurrentIndex(settings.value(
"mesh_textureSize",
_ui->comboBox_meshingTextureSize->currentIndex()).toInt());
645 _ui->spinBox_mesh_maxTextures->setValue(settings.value(
"mesh_textureMaxCount",
_ui->spinBox_mesh_maxTextures->value()).toInt());
646 _ui->doubleSpinBox_meshingTextureMaxDistance->setValue(settings.value(
"mesh_textureMaxDistance",
_ui->doubleSpinBox_meshingTextureMaxDistance->value()).toDouble());
647 _ui->doubleSpinBox_meshingTextureMaxDepthError->setValue(settings.value(
"mesh_textureMaxDepthError",
_ui->doubleSpinBox_meshingTextureMaxDepthError->value()).toDouble());
648 _ui->doubleSpinBox_meshingTextureMaxAngle->setValue(settings.value(
"mesh_textureMaxAngle",
_ui->doubleSpinBox_meshingTextureMaxAngle->value()).toDouble());
649 _ui->spinBox_mesh_minTextureClusterSize->setValue(settings.value(
"mesh_textureMinCluster",
_ui->spinBox_mesh_minTextureClusterSize->value()).toDouble());
650 _ui->lineEdit_meshingTextureRoiRatios->setText(settings.value(
"mesh_textureRoiRatios",
_ui->lineEdit_meshingTextureRoiRatios->text()).toString());
651 _ui->checkBox_distanceToCamPolicy->setChecked(settings.value(
"mesh_textureDistanceToCamPolicy",
_ui->checkBox_distanceToCamPolicy->isChecked()).toBool());
652 _ui->checkBox_cameraFilter->setChecked(settings.value(
"mesh_textureCameraFiltering",
_ui->checkBox_cameraFilter->isChecked()).toBool());
653 _ui->doubleSpinBox_cameraFilterRadius->setValue(settings.value(
"mesh_textureCameraFilteringRadius",
_ui->doubleSpinBox_cameraFilterRadius->value()).toDouble());
654 _ui->doubleSpinBox_cameraFilterAngle->setValue(settings.value(
"mesh_textureCameraFilteringAngle",
_ui->doubleSpinBox_cameraFilterAngle->value()).toDouble());
655 _ui->doubleSpinBox_cameraFilterVel->setValue(settings.value(
"mesh_textureCameraFilteringVel",
_ui->doubleSpinBox_cameraFilterVel->value()).toDouble());
656 _ui->doubleSpinBox_cameraFilterVelRad->setValue(settings.value(
"mesh_textureCameraFilteringVelRad",
_ui->doubleSpinBox_cameraFilterVelRad->value()).toDouble());
657 _ui->doubleSpinBox_laplacianVariance->setValue(settings.value(
"mesh_textureCameraFilteringLaplacian",
_ui->doubleSpinBox_laplacianVariance->value()).toDouble());
658 _ui->spinBox_textureBrightnessContrastRatioLow->setValue(settings.value(
"mesh_textureBrightnessConstrastRatioLow",
_ui->spinBox_textureBrightnessContrastRatioLow->value()).toDouble());
659 _ui->spinBox_textureBrightnessContrastRatioHigh->setValue(settings.value(
"mesh_textureBrightnessConstrastRatioHigh",
_ui->spinBox_textureBrightnessContrastRatioHigh->value()).toDouble());
660 if(
_ui->checkBox_exposureFusion->isEnabled())
662 _ui->checkBox_exposureFusion->setChecked(settings.value(
"mesh_textureExposureFusion",
_ui->checkBox_exposureFusion->isChecked()).toBool());
664 _ui->checkBox_blending->setChecked(settings.value(
"mesh_textureBlending",
_ui->checkBox_blending->isChecked()).toBool());
665 _ui->comboBox_blendingDecimation->setCurrentIndex(settings.value(
"mesh_textureBlendingDecimation",
_ui->comboBox_blendingDecimation->currentIndex()).toInt());
666 _ui->checkBox_multiband->setChecked(settings.value(
"mesh_textureMultiband",
_ui->checkBox_multiband->isChecked()).toBool());
667 _ui->spinBox_multiband_downscale->setValue(settings.value(
"mesh_textureMultibandDownScale",
_ui->spinBox_multiband_downscale->value()).toInt());
668 _ui->lineEdit_multiband_nbcontrib->setText(settings.value(
"mesh_textureMultibandNbContrib",
_ui->lineEdit_multiband_nbcontrib->text()).toString());
669 _ui->comboBox_multiband_unwrap->setCurrentIndex(settings.value(
"mesh_textureMultibandUnwrap",
_ui->comboBox_multiband_unwrap->currentIndex()).toInt());
670 _ui->checkBox_multiband_fillholes->setChecked(settings.value(
"mesh_textureMultibandFillHoles",
_ui->checkBox_multiband_fillholes->isChecked()).toBool());
671 _ui->spinBox_multiband_padding->setValue(settings.value(
"mesh_textureMultibandPadding",
_ui->spinBox_multiband_padding->value()).toInt());
672 _ui->doubleSpinBox_multiband_bestscore->setValue(settings.value(
"mesh_textureMultibandBestScoreThr",
_ui->doubleSpinBox_multiband_bestscore->value()).toDouble());
673 _ui->doubleSpinBox_multiband_angle->setValue(settings.value(
"mesh_textureMultibandAngleHardThr",
_ui->doubleSpinBox_multiband_angle->value()).toDouble());
674 _ui->checkBox_multiband_forcevisible->setChecked(settings.value(
"mesh_textureMultibandForceVisible",
_ui->checkBox_multiband_forcevisible->isChecked()).toBool());
676 _ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value(
"mesh_angle_tolerance",
_ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble());
677 _ui->checkBox_mesh_quad->setChecked(settings.value(
"mesh_quad",
_ui->checkBox_mesh_quad->isChecked()).toBool());
678 _ui->spinBox_mesh_triangleSize->setValue(settings.value(
"mesh_triangle_size",
_ui->spinBox_mesh_triangleSize->value()).toInt());
680 _ui->checkBox_poisson_outputPolygons->setChecked(settings.value(
"poisson_outputPolygons",
_ui->checkBox_poisson_outputPolygons->isChecked()).toBool());
681 _ui->checkBox_poisson_manifold->setChecked(settings.value(
"poisson_manifold",
_ui->checkBox_poisson_manifold->isChecked()).toBool());
682 _ui->spinBox_poisson_depth->setValue(settings.value(
"poisson_depth",
_ui->spinBox_poisson_depth->value()).toInt());
683 _ui->doubleSpinBox_poisson_targetPolygonSize->setValue(settings.value(
"poisson_polygon_size",
_ui->doubleSpinBox_poisson_targetPolygonSize->value()).toDouble());
684 _ui->spinBox_poisson_iso->setValue(settings.value(
"poisson_iso",
_ui->spinBox_poisson_iso->value()).toInt());
685 _ui->spinBox_poisson_solver->setValue(settings.value(
"poisson_solver",
_ui->spinBox_poisson_solver->value()).toInt());
686 _ui->spinBox_poisson_minDepth->setValue(settings.value(
"poisson_minDepth",
_ui->spinBox_poisson_minDepth->value()).toInt());
687 _ui->doubleSpinBox_poisson_samples->setValue(settings.value(
"poisson_samples",
_ui->doubleSpinBox_poisson_samples->value()).toDouble());
688 _ui->doubleSpinBox_poisson_pointWeight->setValue(settings.value(
"poisson_pointWeight",
_ui->doubleSpinBox_poisson_pointWeight->value()).toDouble());
689 _ui->doubleSpinBox_poisson_scale->setValue(settings.value(
"poisson_scale",
_ui->doubleSpinBox_poisson_scale->value()).toDouble());
691 _ui->doubleSpinBox_cputsdf_size->setValue(settings.value(
"cputsdf_size",
_ui->doubleSpinBox_cputsdf_size->value()).toDouble());
692 _ui->doubleSpinBox_cputsdf_resolution->setValue(settings.value(
"cputsdf_resolution",
_ui->doubleSpinBox_cputsdf_resolution->value()).toDouble());
693 _ui->doubleSpinBox_cputsdf_tuncPos->setValue(settings.value(
"cputsdf_truncPos",
_ui->doubleSpinBox_cputsdf_tuncPos->value()).toDouble());
694 _ui->doubleSpinBox_cputsdf_tuncNeg->setValue(settings.value(
"cputsdf_truncNeg",
_ui->doubleSpinBox_cputsdf_tuncNeg->value()).toDouble());
695 _ui->doubleSpinBox_cputsdf_minWeight->setValue(settings.value(
"cputsdf_minWeight",
_ui->doubleSpinBox_cputsdf_minWeight->value()).toDouble());
696 _ui->doubleSpinBox_cputsdf_flattenRadius->setValue(settings.value(
"cputsdf_flattenRadius",
_ui->doubleSpinBox_cputsdf_flattenRadius->value()).toDouble());
697 _ui->spinBox_cputsdf_randomSplit->setValue(settings.value(
"cputsdf_randomSplit",
_ui->spinBox_cputsdf_randomSplit->value()).toInt());
699 _ui->checkBox_openchisel_mergeVertices->setChecked(settings.value(
"openchisel_merge_vertices",
_ui->checkBox_openchisel_mergeVertices->isChecked()).toBool());
700 _ui->spinBox_openchisel_chunk_size_x->setValue(settings.value(
"openchisel_chunk_size_x",
_ui->spinBox_openchisel_chunk_size_x->value()).toInt());
701 _ui->spinBox_openchisel_chunk_size_y->setValue(settings.value(
"openchisel_chunk_size_y",
_ui->spinBox_openchisel_chunk_size_y->value()).toInt());
702 _ui->spinBox_openchisel_chunk_size_z->setValue(settings.value(
"openchisel_chunk_size_z",
_ui->spinBox_openchisel_chunk_size_z->value()).toInt());
703 _ui->doubleSpinBox_openchisel_truncation_constant->setValue(settings.value(
"openchisel_truncation_constant",
_ui->doubleSpinBox_openchisel_truncation_constant->value()).toDouble());
704 _ui->doubleSpinBox_openchisel_truncation_linear->setValue(settings.value(
"openchisel_truncation_linear",
_ui->doubleSpinBox_openchisel_truncation_linear->value()).toDouble());
705 _ui->doubleSpinBox_openchisel_truncation_quadratic->setValue(settings.value(
"openchisel_truncation_quadratic",
_ui->doubleSpinBox_openchisel_truncation_quadratic->value()).toDouble());
706 _ui->doubleSpinBox_openchisel_truncation_scale->setValue(settings.value(
"openchisel_truncation_scale",
_ui->doubleSpinBox_openchisel_truncation_scale->value()).toDouble());
707 _ui->spinBox_openchisel_integration_weight->setValue(settings.value(
"openchisel_integration_weight",
_ui->spinBox_openchisel_integration_weight->value()).toInt());
708 _ui->checkBox_openchisel_use_voxel_carving->setChecked(settings.value(
"openchisel_use_voxel_carving",
_ui->checkBox_openchisel_use_voxel_carving->isChecked()).toBool());
709 _ui->doubleSpinBox_openchisel_carving_dist_m->setValue(settings.value(
"openchisel_carving_dist_m",
_ui->doubleSpinBox_openchisel_carving_dist_m->value()).toDouble());
710 _ui->doubleSpinBox_openchisel_near_plane_dist->setValue(settings.value(
"openchisel_near_plane_dist",
_ui->doubleSpinBox_openchisel_near_plane_dist->value()).toDouble());
711 _ui->doubleSpinBox_openchisel_far_plane_dist->setValue(settings.value(
"openchisel_far_plane_dist",
_ui->doubleSpinBox_openchisel_far_plane_dist->value()).toDouble());
724 _ui->comboBox_pipeline->setCurrentIndex(1);
725 _ui->checkBox_fromDepth->setChecked(
true);
726 _ui->checkBox_binary->setChecked(
true);
727 _ui->spinBox_normalKSearch->setValue(20);
728 _ui->doubleSpinBox_normalRadiusSearch->setValue(0.0);
729 _ui->doubleSpinBox_groundNormalsUp->setValue(0.0);
730 _ui->comboBox_intensityColormap->setCurrentIndex(0);
732 _ui->checkBox_nodes_filtering->setChecked(
false);
733 _ui->doubleSpinBox_nodes_filtering_xmin->setValue(0);
734 _ui->doubleSpinBox_nodes_filtering_xmax->setValue(0);
735 _ui->doubleSpinBox_nodes_filtering_ymin->setValue(0);
736 _ui->doubleSpinBox_nodes_filtering_ymax->setValue(0);
737 _ui->doubleSpinBox_nodes_filtering_zmin->setValue(0);
738 _ui->doubleSpinBox_nodes_filtering_zmax->setValue(0);
740 _ui->checkBox_regenerate->setChecked(
_dbDriver!=0?
true:
false);
741 _ui->spinBox_decimation->setValue(1);
742 _ui->doubleSpinBox_maxDepth->setValue(4);
743 _ui->doubleSpinBox_minDepth->setValue(0);
744 _ui->doubleSpinBox_ceilingHeight->setValue(0);
745 _ui->doubleSpinBox_floorHeight->setValue(0);
746 _ui->groupBox_offAxisFiltering->setChecked(
false);
747 _ui->doubleSpinBox_offAxisFilteringAngle->setValue(10);
748 _ui->checkBox_offAxisFilteringPosX->setChecked(
true);
749 _ui->checkBox_offAxisFilteringNegX->setChecked(
true);
750 _ui->checkBox_offAxisFilteringPosY->setChecked(
true);
751 _ui->checkBox_offAxisFilteringNegY->setChecked(
true);
752 _ui->checkBox_offAxisFilteringPosZ->setChecked(
true);
753 _ui->checkBox_offAxisFilteringNegZ->setChecked(
true);
754 _ui->doubleSpinBox_footprintHeight->setValue(0);
755 _ui->doubleSpinBox_footprintLength->setValue(0);
756 _ui->doubleSpinBox_footprintWidth->setValue(0);
757 _ui->spinBox_decimation_scan->setValue(1);
758 _ui->doubleSpinBox_rangeMax->setValue(0);
759 _ui->doubleSpinBox_rangeMin->setValue(0);
760 _ui->spinBox_fillDepthHoles->setValue(0);
761 _ui->spinBox_fillDepthHolesError->setValue(2);
762 _ui->lineEdit_roiRatios->setText(
"0.0 0.0 0.0 0.0");
763 _ui->lineEdit_distortionModel->setText(
"");
765 _ui->checkBox_bilateral->setChecked(
false);
766 _ui->doubleSpinBox_bilateral_sigmaS->setValue(10.0);
767 _ui->doubleSpinBox_bilateral_sigmaR->setValue(0.1);
769 _ui->checkBox_filtering->setChecked(
false);
770 _ui->doubleSpinBox_filteringRadius->setValue(0.00);
771 _ui->spinBox_filteringMinNeighbors->setValue(5);
773 _ui->checkBox_assemble->setChecked(
true);
774 _ui->doubleSpinBox_voxelSize_assembled->setValue(0.01);
775 _ui->spinBox_randomSamples_assembled->setValue(0);
776 _ui->comboBox_frame->setCurrentIndex(0);
778 _ui->checkBox_subtraction->setChecked(
false);
779 _ui->doubleSpinBox_subtractPointFilteringRadius->setValue(0.02);
780 _ui->doubleSpinBox_subtractPointFilteringAngle->setValue(0);
781 _ui->spinBox_subtractFilteringMinPts->setValue(5);
783 _ui->checkBox_smoothing->setChecked(
false);
784 _ui->doubleSpinBox_mlsRadius->setValue(0.04);
785 _ui->spinBox_polygonialOrder->setValue(2);
786 _ui->comboBox_upsamplingMethod->setCurrentIndex(0);
787 _ui->doubleSpinBox_sampleRadius->setValue(0.01);
788 _ui->doubleSpinBox_sampleStep->setValue(0.005);
789 _ui->spinBox_randomPoints->setValue(10);
790 _ui->doubleSpinBox_dilationVoxelSize->setValue(0.005);
791 _ui->spinBox_dilationSteps->setValue(1);
792 _ui->doubleSpinBox_mls_outputVoxelSize->setValue(0);
794 _ui->checkBox_gainCompensation->setChecked(
false);
795 _ui->doubleSpinBox_gainRadius->setValue(0.02);
796 _ui->doubleSpinBox_gainOverlap->setValue(0.0);
797 _ui->doubleSpinBox_gainBeta->setValue(10);
798 _ui->checkBox_gainRGB->setChecked(
true);
799 _ui->checkBox_gainFull->setChecked(
false);
801 _ui->checkBox_cameraProjection->setChecked(
false);
802 _ui->lineEdit_camProjRoiRatios->setText(
"0.0 0.0 0.0 0.0");
803 _ui->lineEdit_camProjMaskFilePath->setText(
"");
804 _ui->spinBox_camProjDecimation->setValue(1);
805 _ui->doubleSpinBox_camProjMaxDistance->setValue(0);
806 _ui->doubleSpinBox_camProjMaxAngle->setValue(0);
807 _ui->checkBox_camProjDistanceToCamPolicy->setChecked(
true);
808 _ui->checkBox_camProjKeepPointsNotSeenByCameras->setChecked(
false);
809 _ui->checkBox_camProjRecolorPoints->setChecked(
true);
810 _ui->comboBox_camProjExportCamera->setCurrentIndex(0);
812 _ui->checkBox_meshing->setChecked(
false);
813 _ui->doubleSpinBox_gp3Radius->setValue(0.2);
814 _ui->doubleSpinBox_gp3Mu->setValue(2.5);
815 _ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
816 _ui->spinBox_meshMaxPolygons->setValue(0);
817 _ui->doubleSpinBox_transferColorRadius->setValue(0.025);
818 _ui->checkBox_cleanMesh->setChecked(
true);
819 _ui->spinBox_mesh_minClusterSize->setValue(0);
821 _ui->comboBox_meshingApproach->setCurrentIndex(1);
823 _ui->checkBox_textureMapping->setChecked(
false);
824 _ui->comboBox_meshingTextureFormat->setCurrentIndex(0);
825 _ui->comboBox_meshingTextureSize->setCurrentIndex(6);
826 _ui->spinBox_mesh_maxTextures->setValue(1);
827 _ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0);
828 _ui->doubleSpinBox_meshingTextureMaxDepthError->setValue(0.0);
829 _ui->doubleSpinBox_meshingTextureMaxAngle->setValue(0.0);
830 _ui->spinBox_mesh_minTextureClusterSize->setValue(50);
831 _ui->lineEdit_meshingTextureRoiRatios->setText(
"0.0 0.0 0.0 0.0");
832 _ui->checkBox_distanceToCamPolicy->setChecked(
false);
833 _ui->checkBox_cameraFilter->setChecked(
false);
834 _ui->doubleSpinBox_cameraFilterRadius->setValue(0);
835 _ui->doubleSpinBox_cameraFilterAngle->setValue(30);
836 _ui->doubleSpinBox_cameraFilterVel->setValue(0);
837 _ui->doubleSpinBox_cameraFilterVelRad->setValue(0);
838 _ui->doubleSpinBox_laplacianVariance->setValue(0);
839 _ui->spinBox_textureBrightnessContrastRatioLow->setValue(0);
840 _ui->spinBox_textureBrightnessContrastRatioHigh->setValue(5);
841 _ui->checkBox_exposureFusion->setChecked(
false);
842 _ui->checkBox_blending->setChecked(
true);
843 _ui->comboBox_blendingDecimation->setCurrentIndex(0);
844 _ui->checkBox_multiband->setChecked(
false);
845 _ui->spinBox_multiband_downscale->setValue(2);
846 _ui->lineEdit_multiband_nbcontrib->setText(
"1 5 10 0");
847 _ui->comboBox_multiband_unwrap->setCurrentIndex(0);
848 _ui->checkBox_multiband_fillholes->setChecked(
false);
849 _ui->spinBox_multiband_padding->setValue(5);
850 _ui->doubleSpinBox_multiband_bestscore->setValue(0.1);
851 _ui->doubleSpinBox_multiband_angle->setValue(90.0);
852 _ui->checkBox_multiband_forcevisible->setChecked(
false);
855 _ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0);
856 _ui->checkBox_mesh_quad->setChecked(
false);
857 _ui->spinBox_mesh_triangleSize->setValue(1);
859 _ui->checkBox_poisson_outputPolygons->setChecked(
false);
860 _ui->checkBox_poisson_manifold->setChecked(
true);
861 _ui->spinBox_poisson_depth->setValue(0);
862 _ui->doubleSpinBox_poisson_targetPolygonSize->setValue(0.03);
863 _ui->spinBox_poisson_iso->setValue(8);
864 _ui->spinBox_poisson_solver->setValue(8);
865 _ui->spinBox_poisson_minDepth->setValue(5);
866 _ui->doubleSpinBox_poisson_samples->setValue(1.0);
867 _ui->doubleSpinBox_poisson_pointWeight->setValue(4.0);
868 _ui->doubleSpinBox_poisson_scale->setValue(1.1);
870 _ui->doubleSpinBox_cputsdf_size->setValue(12.0);
871 _ui->doubleSpinBox_cputsdf_resolution->setValue(0.01);
872 _ui->doubleSpinBox_cputsdf_tuncPos->setValue(0.03);
873 _ui->doubleSpinBox_cputsdf_tuncNeg->setValue(0.03);
874 _ui->doubleSpinBox_cputsdf_minWeight->setValue(0);
875 _ui->doubleSpinBox_cputsdf_flattenRadius->setValue(0.005);
876 _ui->spinBox_cputsdf_randomSplit->setValue(1);
878 _ui->checkBox_openchisel_mergeVertices->setChecked(
true);
879 _ui->spinBox_openchisel_chunk_size_x->setValue(16);
880 _ui->spinBox_openchisel_chunk_size_y->setValue(16);
881 _ui->spinBox_openchisel_chunk_size_z->setValue(16);
882 _ui->doubleSpinBox_openchisel_truncation_constant->setValue(0.001504);
883 _ui->doubleSpinBox_openchisel_truncation_linear->setValue(0.00152);
884 _ui->doubleSpinBox_openchisel_truncation_quadratic->setValue(0.0019);
885 _ui->doubleSpinBox_openchisel_truncation_scale->setValue(10.0);
886 _ui->spinBox_openchisel_integration_weight->setValue(1);
887 _ui->checkBox_openchisel_use_voxel_carving->setChecked(
false);
888 _ui->doubleSpinBox_openchisel_carving_dist_m->setValue(0.05);
889 _ui->doubleSpinBox_openchisel_near_plane_dist->setValue(0.05);
890 _ui->doubleSpinBox_openchisel_far_plane_dist->setValue(1.1);
901 QString
path = QFileDialog::getOpenFileName(
this, tr(
"Load Settings"),
_workingDirectory, tr(
"Config (*.ini)"));
904 QSettings settings(
path, QSettings::IniFormat);
905 settings.beginGroup(
"Gui");
906 settings.beginGroup(this->objectName());
915 QString
path = QFileDialog::getSaveFileName(
this, tr(
"Save Settings"),
_workingDirectory, tr(
"Config (*.ini)"));
918 QSettings settings(
path, QSettings::IniFormat);
919 settings.beginGroup(
"Gui");
920 settings.beginGroup(this->objectName());
929 if(!
_ui->checkBox_fromDepth->isChecked())
931 _ui->comboBox_pipeline->setCurrentIndex(1);
932 _ui->comboBox_pipeline->setEnabled(
false);
933 _ui->comboBox_frame->setItemData(2, 0,Qt::UserRole - 1);
934 _ui->comboBox_frame->setItemData(3, 1|32,Qt::UserRole - 1);
935 if(
_ui->comboBox_frame->currentIndex() == 2)
937 _ui->comboBox_frame->setCurrentIndex(0);
942 _ui->comboBox_pipeline->setEnabled(
true);
943 _ui->comboBox_frame->setItemData(2, 1|32,Qt::UserRole - 1);
944 _ui->comboBox_frame->setItemData(3, 0,Qt::UserRole - 1);
945 if(
_ui->comboBox_frame->currentIndex() == 3)
947 _ui->comboBox_frame->setCurrentIndex(0);
950 _ui->comboBox_intensityColormap->setVisible(!
_ui->checkBox_fromDepth->isChecked() && !
_ui->checkBox_binary->isEnabled());
951 _ui->comboBox_intensityColormap->setEnabled(!
_ui->checkBox_fromDepth->isChecked() && !
_ui->checkBox_binary->isEnabled());
952 _ui->label_intensityColormap->setVisible(!
_ui->checkBox_fromDepth->isChecked() && !
_ui->checkBox_binary->isEnabled());
954 _ui->checkBox_smoothing->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1);
955 _ui->checkBox_smoothing->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
956 _ui->label_smoothing->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1);
958 _ui->comboBox_frame->setEnabled(!
_ui->checkBox_assemble->isChecked() &&
_ui->checkBox_binary->isEnabled());
959 _ui->comboBox_frame->setVisible(
_ui->comboBox_frame->isEnabled());
960 _ui->label_frame->setVisible(
_ui->comboBox_frame->isEnabled());
961 _ui->checkBox_gainCompensation->setEnabled(!(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex() == 2));
962 _ui->checkBox_gainCompensation->setVisible(
_ui->checkBox_gainCompensation->isEnabled());
963 _ui->label_gainCompensation->setVisible(
_ui->checkBox_gainCompensation->isEnabled());
965 _ui->checkBox_cameraProjection->setEnabled(
_ui->checkBox_assemble->isChecked() && !
_ui->checkBox_meshing->isChecked());
966 _ui->label_cameraProjection->setEnabled(
_ui->checkBox_cameraProjection->isEnabled());
968 _ui->groupBox_nodes_filtering->setVisible(
_ui->checkBox_nodes_filtering->isChecked());
969 _ui->groupBox_regenerate->setVisible(
_ui->checkBox_regenerate->isChecked() &&
_ui->checkBox_fromDepth->isChecked());
970 _ui->groupBox_regenerateScans->setVisible(
_ui->checkBox_regenerate->isChecked() && !
_ui->checkBox_fromDepth->isChecked());
971 _ui->groupBox_bilateral->setVisible(
_ui->checkBox_bilateral->isChecked());
972 _ui->groupBox_filtering->setVisible(
_ui->checkBox_filtering->isChecked());
973 _ui->groupBox_gain->setVisible(
_ui->checkBox_gainCompensation->isEnabled() &&
_ui->checkBox_gainCompensation->isChecked());
974 _ui->groupBox_cameraProjection->setVisible(
_ui->checkBox_cameraProjection->isEnabled() &&
_ui->checkBox_cameraProjection->isChecked());
975 _ui->groupBox_mls->setVisible(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked());
976 _ui->groupBox_meshing->setVisible(
_ui->checkBox_meshing->isChecked());
977 _ui->groupBox_subtraction->setVisible(
_ui->checkBox_subtraction->isChecked());
978 _ui->groupBox_textureMapping->setVisible(
_ui->checkBox_textureMapping->isChecked());
979 _ui->groupBox_cameraFilter->setVisible(
_ui->checkBox_cameraFilter->isChecked());
980 _ui->groupBox_multiband->setVisible(
_ui->checkBox_multiband->isChecked());
983 if(
_ui->checkBox_meshing->isChecked())
986 _ui->comboBox_meshingApproach->setItemData(0,
_ui->comboBox_pipeline->currentIndex() == 1?1 | 32:0,Qt::UserRole - 1);
989 _ui->comboBox_meshingApproach->setItemData(1,
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
992 #ifdef RTABMAP_CPUTSDF
993 _ui->comboBox_meshingApproach->setItemData(2,
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
995 _ui->comboBox_meshingApproach->setItemData(2, 0, Qt::UserRole - 1);
999 _ui->comboBox_meshingApproach->setItemData(3,
_ui->comboBox_pipeline->currentIndex() == 0?1 | 32:0,Qt::UserRole - 1);
1002 #ifdef RTABMAP_OPENCHISEL
1003 _ui->comboBox_meshingApproach->setItemData(4,
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
1005 _ui->comboBox_meshingApproach->setItemData(4, 0, Qt::UserRole - 1);
1008 if(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()<2)
1010 _ui->comboBox_meshingApproach->setCurrentIndex(3);
1012 if(
_ui->comboBox_pipeline->currentIndex() == 1 && (
_ui->comboBox_meshingApproach->currentIndex()==2 ||
_ui->comboBox_meshingApproach->currentIndex()==3))
1014 _ui->comboBox_meshingApproach->setCurrentIndex(1);
1016 if(!
_ui->checkBox_assemble->isChecked())
1018 _ui->comboBox_meshingApproach->setCurrentIndex(
_ui->comboBox_pipeline->currentIndex() == 1?0:3);
1021 _ui->checkBox_poisson_outputPolygons->setDisabled(
1022 _ui->checkBox_binary->isEnabled() ||
1023 _ui->doubleSpinBox_meshDecimationFactor->value()!=0.0 ||
1024 _ui->spinBox_meshMaxPolygons->value()!=0 ||
1025 _ui->checkBox_textureMapping->isChecked());
1026 _ui->label_outputPolygons->setEnabled(
_ui->checkBox_poisson_outputPolygons->isEnabled());
1028 _ui->checkBox_cleanMesh->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
1029 _ui->label_meshClean->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
1031 _ui->groupBox_gp3->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->comboBox_meshingApproach->currentIndex()==0);
1032 _ui->groupBox_poisson->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->comboBox_meshingApproach->currentIndex()==1);
1033 _ui->groupBox_cputsdf->setVisible(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()==2);
1034 _ui->groupBox_organized->setVisible(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()==3);
1035 _ui->groupBox_openchisel->setVisible(
_ui->comboBox_meshingApproach->currentIndex()==4);
1038 _ui->doubleSpinBox_meshDecimationFactor->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
1039 _ui->label_meshDecimation->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
1040 _ui->spinBox_meshMaxPolygons->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
1041 _ui->label_meshMaxPolygons->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
1044 #ifndef RTABMAP_ALICE_VISION
1045 _ui->checkBox_multiband->setEnabled(
false);
1047 _ui->checkBox_multiband->setEnabled(
_ui->checkBox_binary->isEnabled());
1049 _ui->label_multiband->setEnabled(
_ui->checkBox_multiband->isEnabled());
1055 QString dir =
_ui->lineEdit_distortionModel->text();
1060 QString
path = QFileDialog::getOpenFileName(
this, tr(
"Select file"), dir, tr(
"Distortion model (*.bin *.txt)"));
1063 _ui->lineEdit_distortionModel->setText(
path);
1069 QString dir =
_ui->lineEdit_camProjMaskFilePath->text();
1074 QString
path = QFileDialog::getOpenFileName(
this, tr(
"Select file"), dir, tr(
"Mask (grayscale) (*.png *.pgm *bmp)"));
1077 _ui->lineEdit_camProjMaskFilePath->setText(
path);
1083 _ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
false);
1084 _ui->buttonBox->button(QDialogButtonBox::Save)->setVisible(
true);
1085 _ui->checkBox_binary->setVisible(
true);
1086 _ui->checkBox_binary->setEnabled(
true);
1087 _ui->label_binaryFile->setVisible(
true);
1088 _ui->checkBox_mesh_quad->setVisible(
false);
1089 _ui->checkBox_mesh_quad->setEnabled(
false);
1090 _ui->label_quad->setVisible(
false);
1096 _ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
true);
1097 _ui->buttonBox->button(QDialogButtonBox::Save)->setVisible(
false);
1098 _ui->checkBox_binary->setVisible(
false);
1099 _ui->checkBox_binary->setEnabled(
false);
1100 _ui->label_binaryFile->setVisible(
false);
1101 _ui->checkBox_mesh_quad->setVisible(
true);
1102 _ui->checkBox_mesh_quad->setEnabled(
true);
1103 _ui->label_quad->setVisible(
true);
1109 if(
_ui->checkBox_nodes_filtering->isChecked())
1111 std::map<int, Transform> posesFiltered;
1112 for(std::map<int, Transform>::const_iterator
iter=poses.begin();
iter!=poses.end(); ++
iter)
1114 bool ignore =
false;
1115 if(
_ui->doubleSpinBox_nodes_filtering_xmin->value() !=
_ui->doubleSpinBox_nodes_filtering_xmax->value() &&
1116 (
iter->second.x() <
_ui->doubleSpinBox_nodes_filtering_xmin->value() ||
1117 iter->second.x() >
_ui->doubleSpinBox_nodes_filtering_xmax->value()))
1121 if(
_ui->doubleSpinBox_nodes_filtering_ymin->value() !=
_ui->doubleSpinBox_nodes_filtering_ymax->value() &&
1122 (
iter->second.y() <
_ui->doubleSpinBox_nodes_filtering_ymin->value() ||
1123 iter->second.y() >
_ui->doubleSpinBox_nodes_filtering_ymax->value()))
1127 if(
_ui->doubleSpinBox_nodes_filtering_zmin->value() !=
_ui->doubleSpinBox_nodes_filtering_zmax->value() &&
1128 (
iter->second.z() <
_ui->doubleSpinBox_nodes_filtering_zmin->value() ||
1129 iter->second.z() >
_ui->doubleSpinBox_nodes_filtering_zmax->value()))
1135 posesFiltered.insert(*
iter);
1138 return posesFiltered;
1144 const std::map<int, Transform> & poses,
1145 const std::multimap<int, Link> & links,
1146 const std::map<int, int> & mapIds,
1147 const QMap<int, Signature> & cachedSignatures,
1148 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
1149 const std::map<int, LaserScan> & cachedScans,
1150 const QString & workingDirectory,
1153 std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> clouds;
1154 std::map<int, pcl::PolygonMesh::Ptr> meshes;
1155 std::map<int, pcl::TextureMesh::Ptr> textureMeshes;
1156 std::vector<std::map<int, pcl::PointXY> > textureVertexToPixels;
1172 textureVertexToPixels))
1174 if(textureMeshes.size())
1176 saveTextureMeshes(workingDirectory, poses, textureMeshes, cachedSignatures, textureVertexToPixels);
1178 else if(meshes.size())
1180 bool exportMeshes =
true;
1181 if(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked())
1183 QMessageBox::StandardButton r = QMessageBox::warning(
this, tr(
"Exporting Texture Mesh"),
1184 tr(
"No texture mesh could be created, do you want to continue with saving only the meshes (%1)?").
arg(meshes.size()),
1185 QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
1186 exportMeshes = r == QMessageBox::Yes;
1190 saveMeshes(workingDirectory, poses, meshes,
_ui->checkBox_binary->isChecked());
1195 saveClouds(workingDirectory, poses, clouds,
_ui->checkBox_binary->isChecked(), textureVertexToPixels);
1206 const std::map<int, Transform> & poses,
1207 const std::multimap<int, Link> & links,
1208 const std::map<int, int> & mapIds,
1209 const QMap<int, Signature> & cachedSignatures,
1210 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
1211 const std::map<int, LaserScan> & cachedScans,
1212 const QString & workingDirectory,
1215 std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> clouds;
1216 std::map<int, pcl::PolygonMesh::Ptr> meshes;
1217 std::map<int, pcl::TextureMesh::Ptr> textureMeshes;
1218 std::vector<std::map<int, pcl::PointXY> > textureVertexToPixels;
1234 textureVertexToPixels))
1236 QDialog * window =
new QDialog(this->parentWidget()?this->parentWidget():
this, Qt::Window);
1237 window->setAttribute(Qt::WA_DeleteOnClose,
true);
1240 window->setWindowTitle(tr(
"Meshes (%1 nodes)").
arg(meshes.size()));
1244 window->setWindowTitle(tr(
"Clouds (%1 nodes)").
arg(clouds.size()));
1246 window->setMinimumWidth(120);
1247 window->setMinimumHeight(90);
1248 window->resize(this->window()->windowHandle()->screen()->availableGeometry().
size() * 0.7);
1251 if(
_ui->comboBox_pipeline->currentIndex() == 0)
1258 if(
_ui->comboBox_intensityColormap->currentIndex()==1)
1262 else if(
_ui->comboBox_intensityColormap->currentIndex() == 2)
1267 QVBoxLayout *layout =
new QVBoxLayout();
1268 layout->addWidget(viewer);
1269 layout->setContentsMargins(0,0,0,0);
1270 window->setLayout(layout);
1271 connect(window, SIGNAL(finished(
int)), viewer, SLOT(clear()));
1276 QApplication::processEvents();
1278 QApplication::processEvents();
1280 if(textureMeshes.size())
1283 std::map<int, cv::Mat> images;
1284 std::map<int, std::vector<CameraModel> > calibrations;
1285 for(QMap<int, Signature>::const_iterator
iter=cachedSignatures.constBegin();
iter!=cachedSignatures.constEnd(); ++
iter)
1287 std::vector<CameraModel> models;
1288 if(
iter->sensorData().cameraModels().size())
1290 models =
iter->sensorData().cameraModels();
1292 else if(
iter->sensorData().stereoCameraModels().size())
1294 for(
size_t i=0;
i<
iter->sensorData().stereoCameraModels().
size(); ++
i)
1296 models.push_back(
iter->sensorData().stereoCameraModels()[
i].left());
1302 if(!
iter->sensorData().imageRaw().empty())
1304 calibrations.insert(std::make_pair(
iter.key(), models));
1305 images.insert(std::make_pair(
iter.key(),
iter->sensorData().imageRaw()));
1307 else if(!
iter->sensorData().imageCompressed().empty())
1309 calibrations.insert(std::make_pair(
iter.key(), models));
1310 images.insert(std::make_pair(
iter.key(),
iter->sensorData().imageCompressed()));
1314 int textureSize = 1024;
1315 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
1317 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
1319 int blendingDecimation = 0;
1320 if(
_ui->checkBox_blending->isChecked())
1322 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
1324 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
1328 for (std::map<int, pcl::TextureMesh::Ptr>::iterator
iter = textureMeshes.begin();
iter != textureMeshes.end(); ++
iter)
1330 pcl::TextureMesh::Ptr mesh =
iter->second;
1333 cv::Mat globalTexture;
1334 if (mesh->tex_materials.size() > 1)
1336 cv::Mat globalTextures;
1345 textureVertexToPixels,
1346 _ui->checkBox_gainCompensation->isChecked(),
1347 _ui->doubleSpinBox_gainBeta->value(),
1348 _ui->checkBox_gainRGB->isChecked(),
1349 _ui->checkBox_blending->isChecked(),
1351 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
1352 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
1353 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked());
1354 if(globalTextures.rows == globalTextures.cols)
1356 globalTexture = globalTextures;
1367 for (
unsigned int t = 0;
t < mesh->tex_coordinates.size(); ++
t)
1369 if(mesh->tex_polygons[
t].size())
1372 pcl::PointCloud<pcl::PointXYZ>::Ptr originalCloud(
new pcl::PointCloud<pcl::PointXYZ>);
1373 pcl::fromPCLPointCloud2(mesh->cloud, *originalCloud);
1376 unsigned int nPoints = mesh->tex_coordinates[
t].size();
1377 UASSERT(nPoints == mesh->tex_polygons[
t].size()*mesh->tex_polygons[
t][0].vertices.size());
1379 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
1380 cloud->resize(nPoints);
1382 unsigned int oi = 0;
1383 for (
unsigned int i = 0;
i < mesh->tex_polygons[
t].size(); ++
i)
1385 pcl::Vertices &
vertices = mesh->tex_polygons[
t][
i];
1387 for(
unsigned int j=0;
j<
vertices.vertices.size(); ++
j)
1391 cloud->at(oi) = originalCloud->at(
vertices.vertices[
j]);
1396 pcl::toPCLPointCloud2(*cloud, mesh->cloud);
1400 UWARN(
"No polygons for texture %d of mesh %d?!",
t,
iter->first);
1404 if (globalTexture.empty())
1406 if(mesh->tex_materials.size()==1 &&
1407 !mesh->tex_materials[0].tex_file.empty() &&
1408 uIsInteger(mesh->tex_materials[0].tex_file,
false))
1410 int textureId =
uStr2Int(mesh->tex_materials[0].tex_file);
1412 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
1414 data = cachedSignatures.value(textureId).sensorData();
1421 data.uncompressDataConst(&globalTexture, 0);
1422 UASSERT(!globalTexture.empty());
1437 QApplication::processEvents();
1440 else if(meshes.size())
1443 viewer->
setLighting(
_ui->doubleSpinBox_transferColorRadius->value() < 0.0);
1444 for(std::map<int, pcl::PolygonMesh::Ptr>::iterator
iter = meshes.begin();
iter!=meshes.end(); ++
iter)
1449 for(
unsigned int i=0;
i<
iter->second->cloud.fields.size(); ++
i)
1451 if(
iter->second->cloud.fields[
i].name.compare(
"rgb") == 0)
1459 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
1460 pcl::fromPCLPointCloud2(
iter->second->cloud, *cloud);
1465 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
1466 pcl::fromPCLPointCloud2(
iter->second->cloud, *cloud);
1470 QApplication::processEvents();
1473 else if(clouds.size())
1475 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::
iterator iter = clouds.begin();
iter!=clouds.end(); ++
iter)
1481 !(
_ui->checkBox_cameraProjection->isEnabled() &&
1482 _ui->checkBox_cameraProjection->isChecked() &&
1483 _ui->checkBox_camProjRecolorPoints->isChecked() &&
1484 clouds.size()==1 && clouds.begin()->first==0))
1487 if(
_ui->spinBox_normalKSearch->value()<=0 &&
_ui->doubleSpinBox_normalRadiusSearch->value()<=0.0)
1490 pcl::PointCloud<pcl::PointXYZI>::Ptr cloudIWithoutNormals(
new pcl::PointCloud<pcl::PointXYZI>);
1491 cloudIWithoutNormals->resize(
iter->second->size());
1492 for(
unsigned int i=0;
i<cloudIWithoutNormals->size(); ++
i)
1494 cloudIWithoutNormals->points[
i].x =
iter->second->points[
i].x;
1495 cloudIWithoutNormals->points[
i].y =
iter->second->points[
i].y;
1496 cloudIWithoutNormals->points[
i].z =
iter->second->points[
i].z;
1497 int * intensity = (
int *)&cloudIWithoutNormals->points[
i].intensity;
1499 int(
iter->second->points[
i].r) |
1500 int(
iter->second->points[
i].g) << 8 |
1501 int(
iter->second->points[
i].b) << 16 |
1502 int(
iter->second->points[
i].a) << 24;
1508 pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloudI(
new pcl::PointCloud<pcl::PointXYZINormal>);
1509 cloudI->resize(
iter->second->size());
1510 for(
unsigned int i=0;
i<cloudI->size(); ++
i)
1512 cloudI->points[
i].x =
iter->second->points[
i].x;
1513 cloudI->points[
i].y =
iter->second->points[
i].y;
1514 cloudI->points[
i].z =
iter->second->points[
i].z;
1515 cloudI->points[
i].normal_x =
iter->second->points[
i].normal_x;
1516 cloudI->points[
i].normal_y =
iter->second->points[
i].normal_y;
1517 cloudI->points[
i].normal_z =
iter->second->points[
i].normal_z;
1518 cloudI->points[
i].curvature =
iter->second->points[
i].curvature;
1519 int * intensity = (
int *)&cloudI->points[
i].intensity;
1521 int(
iter->second->points[
i].r) |
1522 int(
iter->second->points[
i].g) << 8 |
1523 int(
iter->second->points[
i].b) << 16 |
1524 int(
iter->second->points[
i].a) << 24;
1539 window->activateWindow();
1550 int textureSize = 1024;
1551 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
1553 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
1559 return _ui->spinBox_mesh_maxTextures->value();
1563 return _ui->checkBox_gainCompensation->isChecked();
1567 return _ui->doubleSpinBox_gainBeta->value();
1571 return _ui->checkBox_gainRGB->isChecked();
1575 return _ui->checkBox_blending->isChecked();
1579 int blendingDecimation = 0;
1580 if(
_ui->checkBox_blending->isChecked())
1582 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
1584 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
1587 return blendingDecimation;
1591 return _ui->spinBox_textureBrightnessContrastRatioLow->value();
1595 return _ui->spinBox_textureBrightnessContrastRatioHigh->value();
1599 return _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked();
1607 if (dir.exists(dirName)) {
1608 Q_FOREACH(QFileInfo
info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
1613 result = QFile::remove(
info.absoluteFilePath());
1620 result = dir.rmdir(dirName);
1626 const std::map<int, Transform> & posesIn,
1627 const std::multimap<int, Link> & links,
1628 const std::map<int, int> & mapIds,
1629 const QMap<int, Signature> & cachedSignatures,
1630 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
1631 const std::map<int, LaserScan> & cachedScans,
1632 const QString & workingDirectory,
1634 std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & cloudsWithNormals,
1635 std::map<int, pcl::PolygonMesh::Ptr> & meshes,
1636 std::map<int, pcl::TextureMesh::Ptr> & textureMeshes,
1637 std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels)
1641 _ui->checkBox_regenerate->setEnabled(
true);
1642 if(cachedSignatures.empty() &&
_dbDriver)
1644 _ui->checkBox_regenerate->setChecked(
true);
1645 _ui->checkBox_regenerate->setEnabled(
false);
1652 if(this->
exec() == QDialog::Accepted)
1654 std::map<int, Transform> poses =
filterNodes(posesIn);
1658 QMessageBox::critical(
this, tr(
"Creating clouds..."), tr(
"Poses are empty! Cannot export/view clouds."));
1664 if(
_ui->checkBox_meshing->isChecked())
1668 if(
_ui->checkBox_assemble->isChecked())
1673 if(
_ui->checkBox_subtraction->isChecked())
1677 if(
_ui->checkBox_textureMapping->isChecked())
1681 if(
_ui->checkBox_gainCompensation->isChecked())
1685 if(
_ui->checkBox_mesh_quad->isEnabled())
1691 bool loadClouds =
true;
1692 #ifdef RTABMAP_OPENCHISEL
1693 if(
_ui->comboBox_meshingApproach->currentIndex()==4 &&
_ui->checkBox_assemble->isChecked())
1695 loadClouds = !
_ui->checkBox_fromDepth->isChecked();
1699 bool has2dScans =
false;
1700 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
1715 for(std::map<int, Transform>::const_iterator
iter=poses.begin();
iter!=poses.end(); ++
iter)
1717 clouds.insert(std::make_pair(
iter->first,
1719 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr(
new pcl::PointCloud<pcl::PointXYZRGBNormal>),
1720 pcl::IndicesPtr(
new std::vector<int>))));
1725 std::set<int> validCameras =
uKeysSet(clouds);
1736 if(
_ui->checkBox_regenerate->isEnabled() && !
_ui->checkBox_regenerate->isChecked())
1738 QMessageBox::warning(
this, tr(
"Creating clouds..."), tr(
"Could create clouds for %1 node(s). You "
1739 "may want to activate clouds regeneration option.").
arg(poses.size()));
1743 QMessageBox::warning(
this, tr(
"Creating clouds..."), tr(
"Could not create clouds for %1 "
1744 "node(s). The cache may not contain point cloud data. Try re-downloading the map.").
arg(poses.size()));
1750 if(
_ui->checkBox_gainCompensation->isChecked() &&
_ui->checkBox_fromDepth->isChecked() && clouds.size() > 1 &&
1752 !(
_ui->checkBox_meshing->isChecked() &&
1753 _ui->checkBox_textureMapping->isEnabled() &&
1754 _ui->checkBox_textureMapping->isChecked() &&
1755 _ui->comboBox_pipeline->currentIndex()==1 &&
1756 _ui->checkBox_assemble->isChecked() &&
1757 _ui->comboBox_meshingTextureSize->isEnabled() &&
1758 _ui->comboBox_meshingTextureSize->currentIndex() > 0) &&
1760 !(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==2))
1765 if(
_ui->checkBox_gainFull->isChecked())
1773 QApplication::processEvents();
1775 QApplication::processEvents();
1777 if(
_ui->checkBox_gainFull->isChecked())
1779 std::multimap<int, Link> allLinks;
1780 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::const_iterator
iter=clouds.begin();
iter!=clouds.end(); ++
iter)
1782 int from =
iter->first;
1783 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::const_iterator jter =
iter;
1785 for(;jter!=clouds.end(); ++jter)
1787 int to = jter->first;
1788 allLinks.insert(std::make_pair(from,
Link(from, to,
Link::kUserClosure, poses.at(from).inverse()*poses.at(to))));
1799 if(!(
_ui->checkBox_meshing->isChecked() &&
1800 _ui->checkBox_textureMapping->isEnabled() &&
1801 _ui->checkBox_textureMapping->isChecked()))
1804 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::
iterator jter=clouds.begin();jter!=clouds.end(); ++jter)
1806 if(jter!=clouds.end())
1809 _compensator->
apply(jter->first, jter->second.first, jter->second.second,
_ui->checkBox_gainRGB->isChecked());
1813 QApplication::processEvents();
1824 std::map<int, Transform> normalViewpoints = poses;
1825 if(
_ui->checkBox_assemble->isChecked())
1828 for(std::map<int, Transform>::iterator
iter= normalViewpoints.begin();
iter!=normalViewpoints.end(); ++
iter)
1830 if(
_ui->checkBox_fromDepth->isChecked())
1832 std::vector<CameraModel> models;
1833 std::vector<StereoCameraModel> stereoModels;
1834 if(cachedSignatures.contains(
iter->first))
1837 models =
data.cameraModels();
1838 stereoModels =
data.stereoCameraModels();
1845 if(models.size() && !models[0].localTransform().isNull())
1847 iter->second *= models[0].localTransform();
1849 else if(stereoModels.size() && !stereoModels[0].localTransform().isNull())
1851 iter->second *= stereoModels[0].localTransform();
1858 iter->second *= cachedScans.at(
iter->first).localTransform();
1860 else if(cachedSignatures.contains(
iter->first))
1863 if(!
data.laserScanCompressed().isEmpty())
1865 iter->second *=
data.laserScanCompressed().localTransform();
1867 else if(!
data.laserScanRaw().isEmpty())
1869 iter->second *=
data.laserScanRaw().localTransform();
1883 pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(
new pcl::PointCloud<pcl::PointXYZ>);
1884 std::vector<int> rawCameraIndices;
1885 if(
_ui->checkBox_assemble->isChecked() &&
1886 !((
_ui->comboBox_pipeline->currentIndex()==0 ||
_ui->comboBox_meshingApproach->currentIndex()==4) &&
_ui->checkBox_meshing->isChecked()))
1889 QApplication::processEvents();
1892 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
1893 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::
iterator iter=clouds.begin();
1894 iter!= clouds.end();
1897 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformed(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
1898 if(
iter->second.first->isOrganized())
1900 pcl::copyPointCloud(*
iter->second.first, *
iter->second.second, *transformed);
1907 pcl::copyPointCloud(*
iter->second.first, *
iter->second.second, *transformed);
1911 *assembledCloud += *transformed;
1912 rawCameraIndices.resize(assembledCloud->size(),
iter->first);
1916 QApplication::processEvents();
1923 assembledCloud->is_dense =
true;
1924 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
1926 pcl::copyPointCloud(*assembledCloud, *rawAssembledCloud);
1929 if(
_ui->doubleSpinBox_voxelSize_assembled->value())
1932 .
arg(assembledCloud->size())
1933 .
arg(
_ui->doubleSpinBox_voxelSize_assembled->value()));
1934 QApplication::processEvents();
1935 unsigned int before = assembledCloud->size();
1938 _ui->doubleSpinBox_voxelSize_assembled->value());
1941 .
arg(
_ui->doubleSpinBox_voxelSize_assembled->value())
1942 .
arg(assembledCloud->size()));
1946 pcl::IndicesPtr
indices(
new std::vector<int>);
1947 indices->resize(assembledCloud->size());
1948 for(
unsigned int i=0;
i<
indices->size(); ++
i)
1953 if(!
_ui->checkBox_fromDepth->isChecked() && !has2dScans &&
1954 (
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0))
1957 .
arg(assembledCloud->size())
1958 .
arg(
_ui->spinBox_normalKSearch->value())
1959 .arg(
_ui->doubleSpinBox_normalRadiusSearch->value()));
1962 pcl::PointCloud<pcl::PointXYZ>::Ptr cloudWithoutNormals(
new pcl::PointCloud<pcl::PointXYZ>);
1963 pcl::copyPointCloud(*assembledCloud, *cloudWithoutNormals);
1964 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals,
indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value());
1966 UASSERT(assembledCloud->size() == normals->size());
1967 for(
unsigned int i=0;
i<normals->size(); ++
i)
1969 assembledCloud->points[
i].normal_x = normals->points[
i].normal_x;
1970 assembledCloud->points[
i].normal_y = normals->points[
i].normal_y;
1971 assembledCloud->points[
i].normal_z = normals->points[
i].normal_z;
1981 _ui->doubleSpinBox_groundNormalsUp->value());
1984 if(
_ui->spinBox_randomSamples_assembled->value()>0 &&
1985 (
int)assembledCloud->size() >
_ui->spinBox_randomSamples_assembled->value())
1988 .
arg(assembledCloud->size())
1989 .
arg(
_ui->spinBox_randomSamples_assembled->value()));
1992 .
arg(assembledCloud->size())
1993 .
arg(
_ui->spinBox_randomSamples_assembled->value()));
1996 clouds.insert(std::make_pair(0, std::make_pair(assembledCloud,
indices)));
2005 if(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked() && !has2dScans)
2008 "[search radius=%1m voxel=%2m]").
arg(
_ui->doubleSpinBox_mlsRadius->value()).
arg(
_ui->doubleSpinBox_voxelSize_assembled->value()));
2009 QApplication::processEvents();
2011 QApplication::processEvents();
2015 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::
iterator iter=clouds.begin();
2016 iter!= clouds.end();)
2018 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals =
iter->second.first;
2020 if(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked() && !has2dScans)
2022 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals(
new pcl::PointCloud<pcl::PointXYZRGB>);
2023 if(
iter->second.second->size())
2025 pcl::copyPointCloud(*cloudWithNormals, *
iter->second.second, *cloudWithoutNormals);
2029 pcl::copyPointCloud(*cloudWithNormals, *cloudWithoutNormals);
2033 QApplication::processEvents();
2035 QApplication::processEvents();
2042 cloudWithoutNormals,
2043 (
float)
_ui->doubleSpinBox_mlsRadius->value(),
2044 _ui->spinBox_polygonialOrder->value(),
2045 _ui->comboBox_upsamplingMethod->currentIndex(),
2046 (
float)
_ui->doubleSpinBox_sampleRadius->value(),
2047 (
float)
_ui->doubleSpinBox_sampleStep->value(),
2048 _ui->spinBox_randomPoints->value(),
2049 (
float)
_ui->doubleSpinBox_dilationVoxelSize->value(),
2050 _ui->spinBox_dilationSteps->value());
2053 UDEBUG(
"NaNs filtering... size before = %d", cloudWithNormals->size());
2055 UDEBUG(
"NaNs filtering... size after = %d", cloudWithNormals->size());
2057 if(
_ui->checkBox_assemble->isChecked())
2060 if(
_ui->doubleSpinBox_mls_outputVoxelSize->value())
2063 .
arg(cloudWithNormals->size())
2064 .
arg(
_ui->doubleSpinBox_mls_outputVoxelSize->value()));
2065 QApplication::processEvents();
2069 _ui->doubleSpinBox_mls_outputVoxelSize->value());
2081 else if(
iter->second.first->isOrganized() &&
_ui->checkBox_filtering->isChecked())
2086 cloudsWithNormals.insert(std::make_pair(
iter->first, cloudWithNormals));
2089 clouds.erase(
iter++);
2092 QApplication::processEvents();
2100 #ifdef RTABMAP_CPUTSDF
2101 cpu_tsdf::TSDFVolumeOctree::Ptr tsdf;
2103 #ifdef RTABMAP_OPENCHISEL
2104 chisel::ChiselPtr chiselMap;
2105 chisel::ProjectionIntegrator projectionIntegrator;
2109 std::map<int, std::vector<int> > organizedIndices;
2110 std::map<int, cv::Size> organizedCloudSizes;
2113 UDEBUG(
"Meshing=%d",
_ui->checkBox_meshing->isChecked()?1:0);
2114 if(
_ui->checkBox_meshing->isChecked() && !has2dScans)
2117 #ifdef RTABMAP_OPENCHISEL
2118 if(
_ui->comboBox_meshingApproach->currentIndex()==4 &&
_ui->checkBox_assemble->isChecked())
2122 QApplication::processEvents();
2124 QApplication::processEvents();
2126 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2127 std::vector<pcl::Vertices> mergedPolygons;
2129 int cloudsAdded = 1;
2130 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::
iterator iter=cloudsWithNormals.begin();
2131 iter!= cloudsWithNormals.end();
2132 ++
iter,++cloudsAdded)
2134 std::vector<CameraModel> models;
2136 bool cacheHasCompressedImage =
false;
2138 if(cachedSignatures.contains(
iter->first))
2141 models =
data.cameraModels();
2142 cacheHasCompressedImage = !
data.imageCompressed().empty();
2143 scanInfo = !
data.laserScanRaw().isEmpty()?
data.laserScanRaw():
data.laserScanCompressed();
2151 if(chiselMap.get() == 0)
2154 int chunkSizeX =
_ui->spinBox_openchisel_chunk_size_x->value();
2155 int chunkSizeY =
_ui->spinBox_openchisel_chunk_size_y->value();
2156 int chunkSizeZ =
_ui->spinBox_openchisel_chunk_size_z->value();
2157 float voxelResolution =
_ui->doubleSpinBox_voxelSize_assembled->value();
2158 if(voxelResolution <=0.0
f)
2164 bool useColor =
_ui->checkBox_fromDepth->isChecked();
2165 chiselMap.reset(
new chisel::Chisel(Eigen::Vector3i(chunkSizeX, chunkSizeY, chunkSizeZ), voxelResolution, useColor));
2166 double truncationDistConst =
_ui->doubleSpinBox_openchisel_truncation_constant->value();
2167 double truncationDistLinear =
_ui->doubleSpinBox_openchisel_truncation_linear->value();
2168 double truncationDistQuad =
_ui->doubleSpinBox_openchisel_truncation_quadratic->value();
2169 double truncationDistScale =
_ui->doubleSpinBox_openchisel_truncation_scale->value();
2170 int weight =
_ui->spinBox_openchisel_integration_weight->value();
2171 bool useCarving =
_ui->checkBox_openchisel_use_voxel_carving->isChecked();
2172 double carvingDist =
_ui->doubleSpinBox_openchisel_carving_dist_m->value();
2173 chisel::Vec4 truncation(truncationDistQuad, truncationDistLinear, truncationDistConst, truncationDistScale);
2174 UDEBUG(
"If crashing just after this message, make sure PCL and OpenChisel are built both with -march=native or both without -march=native");
2175 projectionIntegrator.SetCentroids(chiselMap->GetChunkManager().GetCentroids());
2176 projectionIntegrator.SetTruncator(chisel::TruncatorPtr(
new chisel::QuadraticTruncator(truncation(0), truncation(1), truncation(2), truncation(3))));
2177 projectionIntegrator.SetWeighter(chisel::WeighterPtr(
new chisel::ConstantWeighter(weight)));
2178 projectionIntegrator.SetCarvingDist(carvingDist);
2179 projectionIntegrator.SetCarvingEnabled(useCarving);
2183 double nearPlaneDist =
_ui->doubleSpinBox_openchisel_near_plane_dist->value();
2184 double farPlaneDist =
_ui->doubleSpinBox_openchisel_far_plane_dist->value();
2185 if(
_ui->checkBox_fromDepth->isChecked())
2187 if(models.size() == 1 && !models[0].localTransform().isNull())
2192 if(cacheHasCompressedImage)
2194 cachedSignatures.find(
iter->first)->sensorData().uncompressDataConst(&rgb, &depth);
2200 data.uncompressDataConst(&rgb, &depth);
2202 if(!rgb.empty() && !depth.empty())
2206 if(rgb.cols > depth.cols)
2208 UASSERT(rgb.cols % depth.cols == 0);
2209 depthModel = depthModel.
scaled(
double(depth.cols)/
double(rgb.cols));
2212 if(depth.type() == CV_16UC1)
2217 std::shared_ptr<chisel::ColorImage<unsigned char> > colorChisel =
colorImageToChisel(rgb);
2222 cameraColor.SetNearPlane(nearPlaneDist);
2223 cameraColor.SetFarPlane(farPlaneDist);
2224 cameraDepth.SetNearPlane(nearPlaneDist);
2225 cameraDepth.SetFarPlane(farPlaneDist);
2227 chisel::Transform pose_rel_to_first_frame = (poses.at(
iter->first)*models[0].localTransform()).toEigen3f();
2228 chiselMap->IntegrateDepthScanColor<
float,
unsigned char>(projectionIntegrator, depthChisel, pose_rel_to_first_frame, cameraDepth, colorChisel, pose_rel_to_first_frame, cameraColor);
2246 chisel::Transform pose_rel_to_first_frame = (poses.at(
iter->first)*scanInfo.
localTransform()).toEigen3f();
2247 chiselMap->IntegratePointCloud(projectionIntegrator, *chiselCloud, pose_rel_to_first_frame, farPlaneDist);
2256 chiselMap->UpdateMeshes();
2261 QApplication::processEvents();
2271 if(
_ui->comboBox_pipeline->currentIndex() == 0)
2273 if(
_ui->comboBox_meshingApproach->currentIndex()==2)
2281 QApplication::processEvents();
2283 QApplication::processEvents();
2285 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2286 std::vector<pcl::Vertices> mergedPolygons;
2288 int cloudsAdded = 1;
2289 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::
iterator iter=cloudsWithNormals.begin();
2290 iter!= cloudsWithNormals.end();
2291 ++
iter,++cloudsAdded)
2293 if(
iter->second->isOrganized())
2295 if(
iter->second->size())
2297 Eigen::Vector3f viewpoint(0.0
f,0.0
f,0.0
f);
2299 std::vector<CameraModel> models;
2300 std::vector<StereoCameraModel> stereoModels;
2301 if(cachedSignatures.contains(
iter->first))
2304 models =
data.cameraModels();
2305 stereoModels =
data.stereoCameraModels();
2312 #ifdef RTABMAP_CPUTSDF
2313 if(
_ui->comboBox_meshingApproach->currentIndex()==2 &&
_ui->checkBox_assemble->isChecked())
2317 if(models.size()==1 && models[0].isValidForProjection() && models[0].imageHeight()>0 && models[0].imageWidth()>0)
2319 float tsdf_size =
_ui->doubleSpinBox_cputsdf_size->value();
2320 float cell_size =
_ui->doubleSpinBox_cputsdf_resolution->value();
2321 int num_random_splits =
_ui->spinBox_cputsdf_randomSplit->value();
2323 int desired_res = tsdf_size / cell_size;
2326 while (desired_res >
n)
2332 tsdf.reset (
new cpu_tsdf::TSDFVolumeOctree);
2333 tsdf->setGridSize (tsdf_size, tsdf_size, tsdf_size);
2334 tsdf->setResolution (tsdf_res, tsdf_res, tsdf_res);
2335 float decimation =
float(models[0].imageWidth()) /
float(
iter->second->width);
2336 tsdf->setImageSize (models[0].imageWidth()/decimation, models[0].imageHeight()/decimation);
2337 tsdf->setCameraIntrinsics (models[0].
fx()/decimation, models[0].
fy()/decimation, models[0].
cx()/decimation, models[0].
cy()/decimation);
2338 tsdf->setNumRandomSplts (num_random_splits);
2339 tsdf->setSensorDistanceBounds (0, 9999);
2340 tsdf->setIntegrateColor(
true);
2341 tsdf->setDepthTruncationLimits (
_ui->doubleSpinBox_cputsdf_tuncPos->value(),
_ui->doubleSpinBox_cputsdf_tuncNeg->value());
2354 if(tsdf.get() && models.size() == 1 && !models[0].localTransform().isNull())
2356 Eigen::Affine3d pose_rel_to_first_frame = ((poses.begin()->second.inverse() * poses.at(
iter->first))*models[0].localTransform()).toEigen3d();
2357 if(!tsdf->integrateCloud(*
util3d::transformPointCloud(
iter->second, models[0].localTransform().inverse()), pcl::PointCloud<pcl::Normal>(), pose_rel_to_first_frame))
2359 _progressDialog->
appendText(tr(
"CPU-TSDF: Failed integrating cloud %1 (%2/%3) to TSDF volume").arg(
iter->first).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2363 _progressDialog->
appendText(tr(
"CPU-TSDF: Integrated cloud %1 (%2/%3) to TSDF volume").arg(
iter->first).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2371 if((
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex() != 2) ||
2372 !
iter->second->isOrganized())
2374 if(models.size() && !models[0].localTransform().isNull())
2376 viewpoint[0] = models[0].localTransform().x();
2377 viewpoint[1] = models[0].localTransform().y();
2378 viewpoint[2] = models[0].localTransform().z();
2380 else if(stereoModels.size() && !stereoModels[0].localTransform().isNull())
2382 viewpoint[0] = stereoModels[0].localTransform().x();
2383 viewpoint[1] = stereoModels[0].localTransform().y();
2384 viewpoint[2] = stereoModels[0].localTransform().z();
2390 _ui->doubleSpinBox_mesh_angleTolerance->value()*
M_PI/180.0,
2391 _ui->checkBox_mesh_quad->isEnabled() &&
_ui->checkBox_mesh_quad->isChecked(),
2392 _ui->spinBox_mesh_triangleSize->value(),
2395 if(
_ui->spinBox_mesh_minClusterSize->value() != 0)
2398 QApplication::processEvents();
2401 std::vector<std::set<int> > neighbors;
2402 std::vector<std::set<int> > vertexToPolygons;
2404 (
int)
iter->second->size(),
2409 _ui->spinBox_mesh_minClusterSize->value()<0?0:
_ui->spinBox_mesh_minClusterSize->value());
2411 std::vector<pcl::Vertices> filteredPolygons(polygons.size());
2412 if(
_ui->spinBox_mesh_minClusterSize->value() < 0)
2415 std::list<std::list<int> >
::iterator biggestClusterIndex = clusters.end();
2416 unsigned int biggestClusterSize = 0;
2419 if(
iter->size() > biggestClusterSize)
2421 biggestClusterIndex =
iter;
2422 biggestClusterSize =
iter->size();
2425 if(biggestClusterIndex != clusters.end())
2428 for(std::list<int>::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter)
2430 filteredPolygons[oi++] = polygons.at(*jter);
2432 filteredPolygons.resize(oi);
2440 for(std::list<int>::iterator jter=
iter->begin(); jter!=
iter->end(); ++jter)
2442 filteredPolygons[oi++] = polygons.at(*jter);
2445 filteredPolygons.resize(oi);
2447 int before = (
int)polygons.size();
2448 polygons = filteredPolygons;
2450 if(polygons.size() == 0)
2452 std::string
msg =
uFormat(
"All %d polygons filtered after polygon cluster filtering. Cluster minimum size is %d.", before,
_ui->spinBox_mesh_minClusterSize->value());
2458 QApplication::processEvents();
2463 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr denseCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2464 std::vector<pcl::Vertices> densePolygons;
2467 if(!
_ui->checkBox_assemble->isChecked() ||
2468 (
_ui->checkBox_textureMapping->isEnabled() &&
2469 _ui->checkBox_textureMapping->isChecked() &&
2470 _ui->doubleSpinBox_voxelSize_assembled->value() == 0.0))
2472 if(
_ui->checkBox_assemble->isChecked())
2477 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2478 pcl::toPCLPointCloud2(*denseCloud, mesh->cloud);
2479 mesh->polygons = densePolygons;
2481 organizedIndices.insert(std::make_pair(
iter->first, denseToOrganizedIndices));
2482 organizedCloudSizes.insert(std::make_pair(
iter->first, cv::Size(
iter->second->width,
iter->second->height)));
2484 meshes.insert(std::make_pair(
iter->first, mesh));
2489 if(mergedClouds->size() == 0)
2491 *mergedClouds = *denseCloud;
2492 mergedPolygons = densePolygons;
2509 if(cachedSignatures.contains(
iter->first))
2511 const Signature &
s = cachedSignatures.find(
iter->first).value();
2512 weight =
s.getWeight();
2520 _progressDialog->
appendText(tr(
"Mesh %1 not created (cloud is not organized). You may want to check cloud regeneration option (%2/%3).").
arg(
iter->first).
arg(cloudsAdded).arg(cloudsWithNormals.size()));
2525 QApplication::processEvents();
2532 if(
_ui->checkBox_assemble->isChecked() && mergedClouds->size())
2534 if(
_ui->doubleSpinBox_voxelSize_assembled->value())
2536 _progressDialog->
appendText(tr(
"Filtering assembled mesh for close vertices (points=%1, polygons=%2)...").
arg(mergedClouds->size()).
arg(mergedPolygons.size()));
2537 QApplication::processEvents();
2542 _ui->doubleSpinBox_voxelSize_assembled->value(),
2547 unsigned int count = mergedPolygons.size();
2550 QApplication::processEvents();
2553 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr filteredCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2554 std::vector<pcl::Vertices> filteredPolygons;
2556 mergedClouds = filteredCloud;
2557 mergedPolygons = filteredPolygons;
2560 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2561 pcl::toPCLPointCloud2(*mergedClouds, mesh->cloud);
2562 mesh->polygons = mergedPolygons;
2564 meshes.insert(std::make_pair(0, mesh));
2567 QApplication::processEvents();
2572 if(
_ui->comboBox_meshingApproach->currentIndex() == 0)
2580 QApplication::processEvents();
2582 QApplication::processEvents();
2585 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::
iterator iter=cloudsWithNormals.begin();
2586 iter!= cloudsWithNormals.end();
2587 ++
iter,++cloudsAdded)
2589 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2590 if(
_ui->comboBox_meshingApproach->currentIndex() == 0)
2594 _ui->doubleSpinBox_gp3Radius->value(),
2595 _ui->doubleSpinBox_gp3Mu->value());
2599 pcl::Poisson<pcl::PointXYZRGBNormal> poisson;
2600 poisson.setOutputPolygons(
_ui->checkBox_poisson_outputPolygons->isEnabled()?
_ui->checkBox_poisson_outputPolygons->isChecked():
false);
2601 poisson.setManifold(
_ui->checkBox_poisson_manifold->isChecked());
2602 poisson.setSamplesPerNode(
_ui->doubleSpinBox_poisson_samples->value());
2603 int depth =
_ui->spinBox_poisson_depth->value();
2610 for(
int i=6;
i<12; ++
i)
2612 if(mapLength/
float(1<<
i) <
_ui->doubleSpinBox_poisson_targetPolygonSize->value())
2623 QApplication::processEvents();
2625 QApplication::processEvents();
2627 poisson.setDepth(depth);
2628 poisson.setIsoDivide(
_ui->spinBox_poisson_iso->value());
2629 poisson.setSolverDivide(
_ui->spinBox_poisson_solver->value());
2630 poisson.setMinDepth(
_ui->spinBox_poisson_minDepth->value());
2631 poisson.setPointWeight(
_ui->doubleSpinBox_poisson_pointWeight->value());
2632 poisson.setScale(
_ui->doubleSpinBox_poisson_scale->value());
2633 poisson.setInputCloud(
iter->second);
2634 poisson.reconstruct(*mesh);
2638 QApplication::processEvents();
2640 if(mesh->polygons.size()>0)
2647 int maxIntensity = 1;
2649 for(
size_t i=0;
i<
iter->second->size(); ++
i)
2653 int(
iter->second->points[
i].g) << 8 |
2654 int(
iter->second->points[
i].b) << 16 |
2655 int(
iter->second->points[
i].a) << 24;
2656 if(intensity > maxIntensity)
2658 maxIntensity = intensity;
2662 for(
size_t i=0;
i<
iter->second->size(); ++
i)
2666 int(
iter->second->points[
i].g) << 8 |
2667 int(
iter->second->points[
i].b) << 16 |
2668 int(
iter->second->points[
i].a) << 24;
2669 intensity = intensity*255/maxIntensity;
2670 iter->second->points[
i].r = (
unsigned char)intensity;
2671 iter->second->points[
i].g = (
unsigned char)intensity;
2672 iter->second->points[
i].b = (
unsigned char)intensity;
2673 iter->second->points[
i].a = (
unsigned char)255;
2677 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
2679 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(
float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
2680 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
2682 (
float)
_ui->doubleSpinBox_transferColorRadius->value(),
2683 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
2684 _ui->checkBox_cleanMesh->isChecked(),
2685 _ui->spinBox_mesh_minClusterSize->value(),
2687 meshes.insert(std::make_pair(
iter->first, mesh));
2696 QApplication::processEvents();
2704 else if(
_ui->checkBox_meshing->isChecked())
2706 std::string
msg =
uFormat(
"Some clouds are 2D laser scans. Meshing can be done only from RGB-D clouds or 3D laser scans.");
2710 else if(
_ui->checkBox_cameraProjection->isEnabled() &&
2711 _ui->checkBox_cameraProjection->isChecked() &&
2712 cloudsWithNormals.size()==1 && cloudsWithNormals.begin()->first==0)
2715 QApplication::processEvents();
2717 QApplication::processEvents();
2719 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloud = cloudsWithNormals.begin()->second;
2721 std::map<int, Transform> cameraPoses;
2722 std::map<int, std::vector<CameraModel> > cameraModels;
2723 for(std::map<int, Transform>::const_iterator
iter=poses.lower_bound(0);
iter!=poses.end(); ++
iter)
2725 std::vector<CameraModel> models;
2726 std::vector<StereoCameraModel> stereoModels;
2727 if(cachedSignatures.contains(
iter->first))
2730 models =
data.cameraModels();
2731 stereoModels =
data.stereoCameraModels();
2738 if(stereoModels.size())
2741 for(
size_t i=0;
i<stereoModels.size(); ++
i)
2743 models.push_back(stereoModels[
i].left());
2747 if(models.size() == 0 || !models[0].isValidForProjection())
2752 if(!models.empty() && models[0].imageWidth() != 0 && models[0].imageHeight() != 0)
2754 cameraPoses.insert(std::make_pair(
iter->first,
iter->second));
2755 cameraModels.insert(std::make_pair(
iter->first, models));
2759 UWARN(
"%d node has invalid camera models, ignoring it.",
iter->first);
2762 if(!cameraPoses.empty())
2766 std::vector<float> roiRatios;
2767 QStringList strings =
_ui->lineEdit_camProjRoiRatios->text().split(
' ');
2768 if(!
_ui->lineEdit_meshingTextureRoiRatios->text().isEmpty())
2770 if(strings.size()==4)
2772 roiRatios.resize(4);
2773 roiRatios[0]=strings[0].toDouble();
2774 roiRatios[1]=strings[1].toDouble();
2775 roiRatios[2]=strings[2].toDouble();
2776 roiRatios[3]=strings[3].toDouble();
2777 if(!(roiRatios[0]>=0.0
f && roiRatios[0]<=1.0
f &&
2778 roiRatios[1]>=0.0
f && roiRatios[1]<=1.0
f &&
2779 roiRatios[2]>=0.0
f && roiRatios[2]<=1.0
f &&
2780 roiRatios[3]>=0.0
f && roiRatios[3]<=1.0
f))
2785 if(roiRatios.empty())
2787 QString
msg = tr(
"Wrong ROI format. Region of Interest (ROI) must "
2788 "have 4 values [left right top bottom] between 0 and 1 "
2789 "separated by space (%1), ignoring it for projecting cameras...")
2790 .arg(
_ui->lineEdit_camProjRoiRatios->text());
2797 std::map<int, std::vector<rtabmap::CameraModel> > cameraModelsProj;
2798 if(
_ui->spinBox_camProjDecimation->value()>1)
2800 for(std::map<
int, std::vector<rtabmap::CameraModel> >::
iterator iter=cameraModels.begin();
2801 iter!=cameraModels.end();
2804 std::vector<rtabmap::CameraModel> models;
2805 for(
size_t i=0;
i<
iter->second.size(); ++
i)
2807 models.push_back(
iter->second[
i].scaled(1.0/
double(
_ui->spinBox_camProjDecimation->value())));
2809 cameraModelsProj.insert(std::make_pair(
iter->first, models));
2814 cameraModelsProj = cameraModels;
2818 if(!
_ui->lineEdit_camProjMaskFilePath->text().isEmpty())
2820 projMask = cv::imread(
_ui->lineEdit_camProjMaskFilePath->text().toStdString(), cv::IMREAD_GRAYSCALE);
2821 if(
_ui->spinBox_camProjDecimation->value()>1)
2823 cv::Mat
out = projMask;
2824 cv::resize(projMask,
out, cv::Size(), 1.0
f/
float(
_ui->spinBox_camProjDecimation->value()), 1.0f/
float(
_ui->spinBox_camProjDecimation->value()), cv::INTER_NEAREST);
2829 std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > pointToPixel;
2834 _ui->doubleSpinBox_camProjMaxDistance->value(),
2835 _ui->doubleSpinBox_camProjMaxAngle->value()*
M_PI/180.0,
2838 _ui->checkBox_camProjDistanceToCamPolicy->isChecked(),
2847 UASSERT(pointToPixel.empty() || pointToPixel.size() == assembledCloud->size());
2848 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloudValidPoints;
2849 if(!
_ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked())
2851 assembledCloudValidPoints.reset(
new pcl::PointCloud<pcl::PointXYZRGBNormal>());
2852 assembledCloudValidPoints->resize(assembledCloud->size());
2854 if(
_ui->comboBox_camProjExportCamera->isEnabled() &&
2855 _ui->comboBox_camProjExportCamera->currentIndex()>0)
2857 textureVertexToPixels.resize(assembledCloud->size());
2860 if(
_ui->checkBox_camProjRecolorPoints->isChecked())
2863 for(std::map<int, rtabmap::Transform>::iterator
iter=cameraPoses.begin();
iter!=cameraPoses.end() && !
_canceled; ++
iter)
2865 int nodeID =
iter->first;
2868 if(cachedSignatures.contains(nodeID) && !cachedSignatures.value(nodeID).sensorData().imageCompressed().empty())
2870 cachedSignatures.value(nodeID).sensorData().uncompressDataConst(&image, 0);
2876 data.uncompressDataConst(&image, 0);
2881 if(
_ui->spinBox_camProjDecimation->value()>1)
2886 UASSERT(cameraModelsProj.find(nodeID) != cameraModelsProj.end());
2887 int modelsSize = cameraModelsProj.at(nodeID).size();
2888 for(
size_t i=0;
i<pointToPixel.size(); ++
i)
2890 int cameraIndex = pointToPixel[
i].first.second;
2891 if(nodeID == pointToPixel[
i].
first.first && cameraIndex>=0)
2893 int subImageWidth = image.cols / modelsSize;
2894 cv::Mat subImage = image(
cv::Range::all(), cv::Range(cameraIndex*subImageWidth, (cameraIndex+1)*subImageWidth));
2896 int x = pointToPixel[
i].second.x * (
float)subImage.cols;
2897 int y = pointToPixel[
i].second.y * (
float)subImage.rows;
2901 pcl::PointXYZRGBNormal & pt = assembledCloud->at(
i);
2902 if(subImage.type()==CV_8UC3)
2904 cv::Vec3b bgr = subImage.at<cv::Vec3b>(
y,
x);
2911 UASSERT(subImage.type()==CV_8UC1);
2912 pt.r = pt.g = pt.b = subImage.at<
unsigned char>(pointToPixel[
i].second.y * subImage.rows, pointToPixel[
i].second.x * subImage.cols);
2917 QString
msg = tr(
"Processed %1/%2 images").arg(imagesDone++).arg(cameraPoses.size());
2920 QApplication::processEvents();
2924 pcl::IndicesPtr validIndices(
new std::vector<int>(pointToPixel.size()));
2926 for(
size_t i=0;
i<pointToPixel.size() && !
_canceled; ++
i)
2928 pcl::PointXYZRGBNormal & pt = assembledCloud->at(
i);
2929 if(pointToPixel[
i].
first.first <=0)
2931 if(
_ui->checkBox_camProjRecolorPoints->isChecked() && !
_ui->checkBox_fromDepth->isChecked() && !
_scansHaveRGB)
2941 int nodeID = pointToPixel[
i].first.first;
2942 int cameraIndex = pointToPixel[
i].first.second;
2943 int exportedId = nodeID;
2944 if(
_ui->comboBox_camProjExportCamera->currentIndex() == 2)
2946 exportedId = cameraIndex+1;
2948 else if(
_ui->comboBox_camProjExportCamera->currentIndex() == 3)
2950 UASSERT_MSG(cameraIndex<10,
"Exporting cam id as NodeId+CamIndex is only supported when the number of cameras per node < 10.");
2951 exportedId = nodeID*10 + cameraIndex;
2954 if(assembledCloudValidPoints.get())
2956 if(!textureVertexToPixels.empty())
2958 textureVertexToPixels[oi].insert(std::make_pair(exportedId, pointToPixel[
i].
second));
2960 assembledCloudValidPoints->at(oi++) = pt;
2962 else if(!textureVertexToPixels.empty())
2964 textureVertexToPixels[
i].insert(std::make_pair(exportedId, pointToPixel[
i].
second));
2969 if(assembledCloudValidPoints.get())
2971 assembledCloudValidPoints->resize(oi);
2972 cloudsWithNormals.begin()->second = assembledCloudValidPoints;
2974 if(!textureVertexToPixels.empty())
2976 textureVertexToPixels.resize(oi);
2988 #ifdef RTABMAP_CPUTSDF
2992 QApplication::processEvents();
2994 QApplication::processEvents();
2996 cpu_tsdf::MarchingCubesTSDFOctree mc;
2997 mc.setMinWeight (
_ui->doubleSpinBox_cputsdf_minWeight->value());
2998 mc.setInputTSDF (tsdf);
2999 mc.setColorByRGB (
true);
3000 pcl::PolygonMesh::Ptr mesh (
new pcl::PolygonMesh);
3001 mc.reconstruct (*mesh);
3005 if(mesh->polygons.size()>0)
3008 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr
vertices (
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3009 pcl::fromPCLPointCloud2 (mesh->cloud, *
vertices);
3011 if(
_ui->doubleSpinBox_cputsdf_flattenRadius->value()>0.0)
3014 QApplication::processEvents();
3016 QApplication::processEvents();
3018 float min_dist =
_ui->doubleSpinBox_cputsdf_flattenRadius->value();
3019 pcl::search::KdTree<pcl::PointXYZRGBNormal> vert_tree (
true);
3020 vert_tree.setInputCloud (
vertices);
3022 std::vector<int> vertex_remap (
vertices->size (), -1);
3024 std::vector<int> neighbors;
3025 std::vector<float> dists;
3026 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr vertices_new(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3027 vertices_new->resize(
vertices->size ());
3030 if (vertex_remap[
i] >= 0)
3032 vertex_remap[
i] = idx;
3033 vert_tree.radiusSearch (
i, min_dist, neighbors, dists);
3034 for (
size_t j = 1;
j < neighbors.size ();
j++)
3036 if (dists[
j] < min_dist)
3037 vertex_remap[neighbors[
j]] = idx;
3039 vertices_new->at(idx++) =
vertices->at (
i);
3041 vertices_new->resize(idx);
3042 std::vector<size_t> faces_to_remove;
3043 size_t face_idx = 0;
3044 for (
size_t i = 0;
i < mesh->polygons.size ();
i++)
3046 pcl::Vertices &
v = mesh->polygons[
i];
3047 for (
size_t j = 0;
j <
v.vertices.size ();
j++)
3049 v.vertices[
j] = vertex_remap[
v.vertices[
j]];
3051 if (!(
v.vertices[0] ==
v.vertices[1] ||
v.vertices[1] ==
v.vertices[2] ||
v.vertices[2] ==
v.vertices[0]))
3053 mesh->polygons[face_idx++] = mesh->polygons[
i];
3056 mesh->polygons.resize (face_idx);
3057 pcl::toPCLPointCloud2 (*vertices_new, mesh->cloud);
3061 pcl::fromPCLPointCloud2(mesh->cloud, *
vertices);
3063 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
3065 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(
float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
3066 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
3068 (
float)
_ui->doubleSpinBox_transferColorRadius->value(),
3069 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
3070 _ui->checkBox_cleanMesh->isChecked(),
3071 _ui->spinBox_mesh_minClusterSize->value(),
3073 meshes.insert(std::make_pair(0, mesh));
3082 #ifdef RTABMAP_OPENCHISEL
3086 QApplication::processEvents();
3088 QApplication::processEvents();
3090 const chisel::MeshMap& meshMap = chiselMap->GetChunkManager().GetAllMeshes();
3101 if(mesh->polygons.size()>0)
3103 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3104 pcl::fromPCLPointCloud2(mesh->cloud, *mergedClouds);
3105 if(
_ui->checkBox_openchisel_mergeVertices->isChecked())
3107 _progressDialog->
appendText(tr(
"Filtering assembled mesh for close vertices (points=%1, polygons=%2)...").
arg(mergedClouds->size()).
arg(mesh->polygons.size()));
3108 QApplication::processEvents();
3113 _ui->doubleSpinBox_voxelSize_assembled->value()/2.0,
3118 unsigned int count = mesh->polygons.size();
3121 QApplication::processEvents();
3124 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr filteredCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3125 std::vector<pcl::Vertices> filteredPolygons;
3126 count = mergedClouds->size();
3128 mergedClouds = filteredCloud;
3129 pcl::toPCLPointCloud2(*mergedClouds, mesh->cloud);
3130 mesh->polygons = filteredPolygons;
3132 QApplication::processEvents();
3135 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
3137 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(
float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
3138 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
3140 (
float)
_ui->doubleSpinBox_transferColorRadius->value(),
3141 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
3142 _ui->checkBox_cleanMesh->isChecked(),
3143 _ui->spinBox_mesh_minClusterSize->value(),
3145 meshes.insert(std::make_pair(0, mesh));
3162 UDEBUG(
"texture mapping=%d",
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()?1:0);
3163 if(!has2dScans && !meshes.empty() &&
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked())
3166 QApplication::processEvents();
3168 QApplication::processEvents();
3171 for(std::map<int, pcl::PolygonMesh::Ptr>::iterator
iter=meshes.begin();
3172 iter!= meshes.end();
3175 std::map<int, Transform> cameras;
3176 if(
iter->first == 0)
3185 std::map<int, Transform> cameraPoses;
3186 std::map<int, std::vector<CameraModel> > cameraModels;
3187 std::map<int, cv::Mat > cameraDepths;
3188 int ignoredCameras = 0;
3189 for(std::map<int, Transform>::iterator jter=cameras.begin(); jter!=cameras.end(); ++jter)
3191 if(validCameras.find(jter->first) != validCameras.end())
3193 std::vector<CameraModel> models;
3194 std::vector<StereoCameraModel> stereoModels;
3195 bool cacheHasCompressedImage =
false;
3196 if(cachedSignatures.contains(jter->first))
3198 const SensorData &
data = cachedSignatures.find(jter->first)->sensorData();
3199 models =
data.cameraModels();
3200 stereoModels =
data.stereoCameraModels();
3201 cacheHasCompressedImage = !
data.imageCompressed().empty();
3209 if(stereoModels.size())
3213 for(
size_t i=0;
i<stereoModels.size(); ++
i)
3215 models.push_back(stereoModels[
i].left());
3219 if(models.size() == 0 || !models[0].isValidForProjection())
3224 if(!jter->second.isNull() && models.size())
3227 bool blurryImage =
false;
3228 bool getDepth = !stereo &&
_ui->doubleSpinBox_meshingTextureMaxDepthError->value() >= 0.0f;
3231 if(models[0].imageWidth() == 0 || models[0].imageHeight() == 0)
3235 if(cacheHasCompressedImage)
3237 cachedSignatures.find(jter->first)->sensorData().uncompressDataConst(&
img,
getDepth?&depth:0);
3238 velocity = cachedSignatures.find(jter->first)->getVelocity();
3246 if(
_ui->checkBox_cameraFilter->isChecked() &&
3247 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
3258 cv::Size imageSize =
img.size();
3259 imageSize.width /= models.size();
3260 for(
unsigned int i=0;
i<models.size(); ++
i)
3262 models[
i].setImageSize(imageSize);
3267 bool getImg =
_ui->checkBox_cameraFilter->isChecked() &&
_ui->doubleSpinBox_laplacianVariance->value()>0.0;
3269 if(cacheHasCompressedImage)
3271 cachedSignatures.find(jter->first)->sensorData().uncompressDataConst(getImg?&
img:0,
getDepth?&depth:0);
3272 velocity = cachedSignatures.find(jter->first)->getVelocity();
3280 if(
_ui->checkBox_cameraFilter->isChecked() &&
3281 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
3293 if(
_ui->checkBox_cameraFilter->isChecked())
3297 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
3303 if(
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 && transVel >
_ui->doubleSpinBox_cameraFilterVel->value())
3305 msg =
uFormat(
"Fast motion detected for camera %d (speed=%f m/s > thr=%f m/s), camera is ignored for texturing.", jter->first, transVel,
_ui->doubleSpinBox_cameraFilterVel->value());
3308 else if(
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0 && rotVel >
_ui->doubleSpinBox_cameraFilterVelRad->value())
3310 msg =
uFormat(
"Fast motion detected for camera %d (speed=%f rad/s > thr=%f rad/s), camera is ignored for texturing.", jter->first, rotVel,
_ui->doubleSpinBox_cameraFilterVelRad->value());
3316 UWARN(
"Camera motion filtering is set, but velocity of camera %d is not available.", jter->first);
3320 if(!blurryImage && !
img.empty() &&
_ui->doubleSpinBox_laplacianVariance->value()>0.0)
3322 cv::Mat imgLaplacian;
3323 cv::Laplacian(
img, imgLaplacian, CV_16S);
3325 cv::meanStdDev(imgLaplacian,
m,
s);
3326 double stddev_pxl =
s.at<
double>(0);
3327 double var = stddev_pxl*stddev_pxl;
3328 if(var < _ui->doubleSpinBox_laplacianVariance->value())
3331 msg =
uFormat(
"Camera's image %d is detected as blurry (var=%f, thr=%f), camera is ignored for texturing.", jter->first, var,
_ui->doubleSpinBox_laplacianVariance->value());
3337 QApplication::processEvents();
3342 if(!blurryImage && models[0].imageWidth() != 0 && models[0].imageHeight() != 0)
3344 cameraPoses.insert(std::make_pair(jter->first, jter->second));
3345 cameraModels.insert(std::make_pair(jter->first, models));
3348 cameraDepths.insert(std::make_pair(jter->first, depth));
3354 if(ignoredCameras > (
int)validCameras.size()/2)
3356 std::string
msg =
uFormat(
"More than 50%% of the cameras (%d/%d) have been filtered for "
3357 "too fast motion and/or blur level. You may adjust the corresponding thresholds.",
3358 ignoredCameras, (
int)validCameras.size());
3362 QApplication::processEvents();
3365 if(cameraPoses.size() &&
iter->second->polygons.size())
3367 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
3368 std::map<int, std::vector<int> >
::iterator oter = organizedIndices.find(
iter->first);
3369 std::map<int, cv::Size>::iterator ster = organizedCloudSizes.find(
iter->first);
3370 if(
iter->first != 0 && oter != organizedIndices.end())
3372 UASSERT(ster!=organizedCloudSizes.end()&&ster->first == oter->first);
3373 UDEBUG(
"Texture by pixels");
3374 textureMesh->cloud =
iter->second->cloud;
3375 textureMesh->tex_polygons.push_back(
iter->second->polygons);
3376 int w = ster->second.width;
3377 int h = ster->second.height;
3379 if(textureMesh->tex_polygons.size() && textureMesh->tex_polygons[0].size())
3381 textureMesh->tex_coordinates.resize(1);
3384 int polygonSize = (
int)textureMesh->tex_polygons[0][0].vertices.size();
3385 textureMesh->tex_coordinates[0].resize(polygonSize*textureMesh->tex_polygons[0].size());
3386 for(
unsigned int i=0;
i<textureMesh->tex_polygons[0].size(); ++
i)
3388 const pcl::Vertices &
vertices = textureMesh->tex_polygons[0][
i];
3390 for(
int k=0; k<polygonSize; ++k)
3394 int originalVertex = oter->second[
vertices.vertices[k]];
3395 textureMesh->tex_coordinates[0][
i*polygonSize+k] = Eigen::Vector2f(
3396 float(originalVertex %
w) /
float(
w),
3397 float(
h - originalVertex /
w) /
float(
h));
3401 pcl::TexMaterial mesh_material;
3402 mesh_material.tex_d = 1.0f;
3403 mesh_material.tex_Ns = 75.0f;
3404 mesh_material.tex_illum = 1;
3406 std::stringstream tex_name;
3407 tex_name <<
"material_" <<
iter->first;
3408 tex_name >> mesh_material.tex_name;
3410 mesh_material.tex_file =
uFormat(
"%d",
iter->first);
3411 textureMesh->tex_materials.push_back(mesh_material);
3415 UWARN(
"No polygons for mesh %d!?",
iter->first);
3420 UDEBUG(
"Texture by projection");
3422 if(cameraPoses.size() &&
_ui->checkBox_cameraFilter->isChecked())
3424 int before = (
int)cameraPoses.size();
3426 _ui->doubleSpinBox_cameraFilterRadius->value(),
3427 _ui->doubleSpinBox_cameraFilterAngle->value());
3428 for(std::map<
int, std::vector<CameraModel> >::
iterator modelIter = cameraModels.begin(); modelIter!=cameraModels.end();)
3430 if(cameraPoses.find(modelIter->first)==cameraPoses.end())
3432 cameraModels.erase(modelIter++);
3433 cameraDepths.erase(modelIter->first);
3440 _progressDialog->
appendText(tr(
"Camera filtering: keeping %1/%2/%3 cameras for texturing.").
arg(cameraPoses.size()).
arg(before).arg(validCameras.size()));
3441 QApplication::processEvents();
3443 QApplication::processEvents();
3453 if(cameraModels.size() && cameraModels.begin()->second.size()>1)
3458 std::vector<float> roiRatios;
3459 QStringList strings =
_ui->lineEdit_meshingTextureRoiRatios->text().split(
' ');
3460 if(!
_ui->lineEdit_meshingTextureRoiRatios->text().isEmpty())
3462 if(strings.size()==4)
3464 roiRatios.resize(4);
3465 roiRatios[0]=strings[0].toDouble();
3466 roiRatios[1]=strings[1].toDouble();
3467 roiRatios[2]=strings[2].toDouble();
3468 roiRatios[3]=strings[3].toDouble();
3469 if(!(roiRatios[0]>=0.0
f && roiRatios[0]<=1.0
f &&
3470 roiRatios[1]>=0.0
f && roiRatios[1]<=1.0
f &&
3471 roiRatios[2]>=0.0
f && roiRatios[2]<=1.0
f &&
3472 roiRatios[3]>=0.0
f && roiRatios[3]<=1.0
f))
3477 if(roiRatios.empty())
3479 QString
msg = tr(
"Wrong ROI format. Region of Interest (ROI) must have 4 "
3480 "values [left right top bottom] between 0 and 1 "
3481 "separated by space (%1), ignoring it for texturing...")
3482 .arg(
_ui->lineEdit_meshingTextureRoiRatios->text());
3494 _ui->doubleSpinBox_meshingTextureMaxDistance->value(),
3495 _ui->doubleSpinBox_meshingTextureMaxDepthError->value(),
3496 _ui->doubleSpinBox_meshingTextureMaxAngle->value()*
M_PI/180.0,
3497 _ui->spinBox_mesh_minTextureClusterSize->value(),
3500 cameraPoses.size()>1?&textureVertexToPixels:0,
3501 _ui->checkBox_distanceToCamPolicy->isChecked());
3509 if(
_ui->checkBox_cleanMesh->isChecked())
3511 unsigned int totalSize = 0;
3512 for(
unsigned int t=0;
t<textureMesh->tex_polygons.size(); ++
t)
3514 totalSize+=textureMesh->tex_polygons[
t].size();
3519 unsigned int totalSizeAfter = 0;
3520 for(
unsigned int t=0;
t<textureMesh->tex_polygons.size(); ++
t)
3522 totalSizeAfter+=textureMesh->tex_polygons[
t].size();
3528 textureMeshes.insert(std::make_pair(
iter->first, textureMesh));
3530 else if(cameraPoses.size() == 0)
3534 UWARN(
"No camera poses!?");
3540 UWARN(
"No polygons!");
3545 QApplication::processEvents();
3552 if(textureMeshes.size() > 1 &&
_ui->checkBox_assemble->isChecked())
3554 UDEBUG(
"Concatenate texture meshes");
3556 QApplication::processEvents();
3558 QApplication::processEvents();
3561 textureMeshes.clear();
3562 textureMeshes.insert(std::make_pair(0, assembledMesh));
3573 const std::map<int, Transform> & poses,
3574 const QMap<int, Signature> & cachedSignatures,
3575 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
3576 const std::map<int, LaserScan> & cachedScans,
3579 bool & scansHaveRGB)
const
3581 scansHaveRGB =
false;
3583 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
3585 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr previousCloud;
3586 pcl::IndicesPtr previousIndices;
3588 for(std::map<int, Transform>::const_iterator
iter = poses.lower_bound(1);
iter!=poses.end() && !
_canceled; ++
iter, ++index)
3591 int totalIndices = 0;
3592 if(!
iter->second.isNull())
3594 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3595 pcl::IndicesPtr
indices(
new std::vector<int>);
3597 if(
_ui->checkBox_regenerate->isChecked())
3601 if(cachedSignatures.contains(
iter->first))
3603 const Signature &
s = cachedSignatures.find(
iter->first).value();
3604 data =
s.sensorData();
3605 cv::Mat image,depth;
3606 data.uncompressData(
3607 _ui->checkBox_fromDepth->isChecked()?&image:0,
3608 _ui->checkBox_fromDepth->isChecked()?&depth:0,
3609 !
_ui->checkBox_fromDepth->isChecked()?&scan:0);
3613 cv::Mat image,depth;
3615 data.uncompressData(
3616 _ui->checkBox_fromDepth->isChecked()?&image:0,
3617 _ui->checkBox_fromDepth->isChecked()?&depth:0,
3618 !
_ui->checkBox_fromDepth->isChecked()?&scan:0);
3621 if(
_ui->checkBox_fromDepth->isChecked() && !
data.imageRaw().empty() && !
data.depthOrRightRaw().empty())
3623 cv::Mat depth =
data.depthRaw();
3624 if(!depth.empty() &&
_ui->spinBox_fillDepthHoles->value() > 0)
3629 if(!depth.empty() &&
3630 !
_ui->lineEdit_distortionModel->text().isEmpty() &&
3631 QFileInfo(
_ui->lineEdit_distortionModel->text()).exists())
3634 model.load(
_ui->lineEdit_distortionModel->text().toStdString());
3635 depth = depth.clone();
3636 model.undistort(depth);
3640 if(!depth.empty() &&
_ui->checkBox_bilateral->isChecked())
3643 _ui->doubleSpinBox_bilateral_sigmaS->value(),
3644 _ui->doubleSpinBox_bilateral_sigmaR->value());
3649 data.setRGBDImage(
data.imageRaw(), depth,
data.cameraModels());
3653 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
3654 std::vector<float> roiRatios;
3655 if(!
_ui->lineEdit_roiRatios->text().isEmpty())
3657 QStringList
values =
_ui->lineEdit_roiRatios->text().split(
' ');
3660 roiRatios.resize(4);
3669 _ui->spinBox_decimation->value() == 0?1:
_ui->spinBox_decimation->value(),
3670 _ui->doubleSpinBox_maxDepth->value(),
3671 _ui->doubleSpinBox_minDepth->value(),
3676 if(cloudWithoutNormals->size())
3679 if(!(
_ui->comboBox_pipeline->currentIndex()==0 &&
_ui->checkBox_meshing->isChecked()) &&
_ui->doubleSpinBox_voxelSize_assembled->value()>0.0)
3682 indices->resize(cloudWithoutNormals->size());
3683 for(
unsigned int i=0;
i<
indices->size(); ++
i)
3690 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3691 if(
data.cameraModels().size() && !
data.cameraModels()[0].localTransform().isNull())
3693 localTransform =
data.cameraModels()[0].localTransform();
3694 viewPoint[0] =
data.cameraModels()[0].localTransform().x();
3695 viewPoint[1] =
data.cameraModels()[0].localTransform().y();
3696 viewPoint[2] =
data.cameraModels()[0].localTransform().z();
3698 else if(
data.stereoCameraModels().size() && !
data.stereoCameraModels()[0].localTransform().isNull())
3700 localTransform =
data.stereoCameraModels()[0].localTransform();
3701 viewPoint[0] =
data.stereoCameraModels()[0].localTransform().x();
3702 viewPoint[1] =
data.stereoCameraModels()[0].localTransform().y();
3703 viewPoint[2] =
data.stereoCameraModels()[0].localTransform().z();
3706 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
3708 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals,
indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
3709 pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
3710 if(
_ui->doubleSpinBox_groundNormalsUp->value() > 0.0)
3717 pcl::copyPointCloud(*cloudWithoutNormals, *cloud);
3720 if(
_ui->checkBox_subtraction->isChecked() &&
3721 _ui->doubleSpinBox_subtractPointFilteringRadius->value() > 0.0)
3723 pcl::IndicesPtr beforeSubtractionIndices =
indices;
3724 if( cloud->size() &&
3725 previousCloud.get() != 0 &&
3726 previousIndices.get() != 0 &&
3727 previousIndices->size() &&
3737 _ui->doubleSpinBox_subtractPointFilteringRadius->value(),
3738 _ui->doubleSpinBox_subtractPointFilteringAngle->value(),
3739 _ui->spinBox_subtractFilteringMinPts->value());
3741 previousCloud = cloud;
3742 previousIndices = beforeSubtractionIndices;
3743 previousPose =
iter->second;
3747 else if(!
_ui->checkBox_fromDepth->isChecked() && !scan.
isEmpty())
3750 _ui->spinBox_decimation_scan->value(),
3751 _ui->doubleSpinBox_rangeMin->value(),
3752 _ui->doubleSpinBox_rangeMax->value(),
3753 _ui->doubleSpinBox_voxelSize_assembled->value(),
3754 _ui->spinBox_normalKSearch->value(),
3755 _ui->doubleSpinBox_normalRadiusSearch->value());
3759 scansHaveRGB = scan.
hasRGB();
3763 indices->resize(cloud->size());
3764 for(
unsigned int i=0;
i<
indices->size(); ++
i)
3772 if(cachedSignatures.contains(
iter->first))
3774 const Signature &
s = cachedSignatures.find(
iter->first).value();
3775 weight =
s.getWeight();
3783 UERROR(
"Cloud %d not found in cache!",
iter->first);
3787 else if(
_ui->checkBox_fromDepth->isChecked() &&
uContains(cachedClouds,
iter->first))
3789 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
3790 if(!
_ui->checkBox_meshing->isChecked() &&
3791 _ui->doubleSpinBox_voxelSize_assembled->value() > 0.0)
3794 cachedClouds.at(
iter->first).first,
3795 cachedClouds.at(
iter->first).second,
3796 _ui->doubleSpinBox_voxelSize_assembled->value());
3799 indices->resize(cloudWithoutNormals->size());
3800 for(
unsigned int i=0;
i<cloudWithoutNormals->size(); ++
i)
3807 cloudWithoutNormals = cachedClouds.at(
iter->first).first;
3812 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3813 std::vector<CameraModel> models;
3814 std::vector<StereoCameraModel> stereoModels;
3815 if(cachedSignatures.contains(
iter->first))
3817 const Signature &
s = cachedSignatures.find(
iter->first).value();
3818 models =
s.sensorData().cameraModels();
3819 stereoModels =
s.sensorData().stereoCameraModels();
3826 if(models.size() && !models[0].localTransform().isNull())
3828 localTransform = models[0].localTransform();
3829 viewPoint[0] = models[0].localTransform().
x();
3830 viewPoint[1] = models[0].localTransform().y();
3831 viewPoint[2] = models[0].localTransform().z();
3833 else if(stereoModels.size() && !stereoModels[0].localTransform().isNull())
3835 localTransform = stereoModels[0].localTransform();
3836 viewPoint[0] = stereoModels[0].localTransform().
x();
3837 viewPoint[1] = stereoModels[0].localTransform().y();
3838 viewPoint[2] = stereoModels[0].localTransform().z();
3842 _progressDialog->
appendText(tr(
"Cached cloud %1 is not found in cached data, the view point for normal computation will not be set (%2/%3).").
arg(
iter->first).
arg(index).arg(poses.size()), Qt::darkYellow);
3845 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
3847 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals,
indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
3848 pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
3849 if(
_ui->doubleSpinBox_groundNormalsUp->value() > 0.0)
3856 pcl::copyPointCloud(*cloudWithoutNormals, *cloud);
3859 else if(!
_ui->checkBox_fromDepth->isChecked() &&
uContains(cachedScans,
iter->first))
3862 _ui->spinBox_decimation_scan->value(),
3863 _ui->doubleSpinBox_rangeMin->value(),
3864 _ui->doubleSpinBox_rangeMax->value(),
3865 _ui->doubleSpinBox_voxelSize_assembled->value(),
3866 _ui->spinBox_normalKSearch->value(),
3867 _ui->doubleSpinBox_normalRadiusSearch->value());
3871 scansHaveRGB = scan.
hasRGB();
3875 indices->resize(cloud->size());
3876 for(
unsigned int i=0;
i<
indices->size(); ++
i)
3884 if(cachedSignatures.contains(
iter->first))
3886 const Signature &
s = cachedSignatures.find(
iter->first).value();
3887 weight =
s.getWeight();
3895 _progressDialog->
appendText(tr(
"Cached cloud %1 not found. You may want to regenerate the clouds (%2/%3).").
arg(
iter->first).
arg(index).arg(poses.size()), Qt::darkYellow);
3899 if(
_ui->checkBox_filtering->isChecked())
3902 (
_ui->doubleSpinBox_ceilingHeight->value() != 0.0 ||
3903 _ui->doubleSpinBox_floorHeight->value() != 0.0))
3905 float min =
_ui->doubleSpinBox_floorHeight->value();
3906 float max =
_ui->doubleSpinBox_ceilingHeight->value();
3915 (
_ui->doubleSpinBox_footprintHeight->value() != 0.0 &&
3916 _ui->doubleSpinBox_footprintWidth->value() != 0.0 &&
3917 _ui->doubleSpinBox_footprintLength->value() != 0.0))
3920 float h =
_ui->doubleSpinBox_footprintHeight->value();
3921 float w =
_ui->doubleSpinBox_footprintWidth->value();
3922 float l =
_ui->doubleSpinBox_footprintLength->value();
3941 _ui->doubleSpinBox_filteringRadius->value() > 0.0f &&
3942 _ui->spinBox_filteringMinNeighbors->value() > 0)
3947 UWARN(
"Point cloud %d doesn't have anymore points (had %d points) after radius filtering.",
iter->first, (
int)cloud->size());
3950 if( !
indices->empty() &&
_ui->groupBox_offAxisFiltering->isChecked() &&
3951 (
_ui->checkBox_offAxisFilteringPosX->isChecked() ||
3952 _ui->checkBox_offAxisFilteringNegX->isChecked() ||
3953 _ui->checkBox_offAxisFilteringPosY->isChecked() ||
3954 _ui->checkBox_offAxisFilteringNegY->isChecked() ||
3955 _ui->checkBox_offAxisFilteringPosZ->isChecked() ||
3956 _ui->checkBox_offAxisFilteringNegZ->isChecked()))
3959 std::vector<pcl::IndicesPtr> indicesVector;
3960 double maxDeltaAngle =
_ui->doubleSpinBox_offAxisFilteringAngle->value()*
M_PI/180.0;
3961 Eigen::Vector4f viewpoint(
iter->second.x(),
iter->second.y(),
iter->second.z(), 0);
3962 if(
_ui->checkBox_offAxisFilteringPosX->isChecked())
3964 if(
_ui->checkBox_offAxisFilteringPosY->isChecked())
3966 if(
_ui->checkBox_offAxisFilteringPosZ->isChecked())
3968 if(
_ui->checkBox_offAxisFilteringNegX->isChecked())
3970 if(
_ui->checkBox_offAxisFilteringNegY->isChecked())
3972 if(
_ui->checkBox_offAxisFilteringNegZ->isChecked())
3977 UWARN(
"Point cloud %d doesn't have anymore points (had %d points) after offaxis filtering.",
iter->first, (
int)cloud->size());
3984 if((
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==2) && cloud->isOrganized())
3988 else if(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==3)
3993 clouds.insert(std::make_pair(
iter->first, std::make_pair(cloud,
indices)));
3994 points = (
int)cloud->size();
4000 UERROR(
"transform is null!?");
4005 if(
_ui->checkBox_regenerate->isChecked())
4008 .
arg(
iter->first).
arg(points).arg(totalIndices).arg(index).arg(poses.size()));
4013 .
arg(
iter->first).
arg(points).arg(totalIndices).arg(index).arg(poses.size()));
4021 QApplication::processEvents();
4029 const QString & workingDirectory,
4030 const std::map<int, Transform> & poses,
4031 const std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds,
4033 const std::vector<std::map<int, pcl::PointXY> > & pointToPixels)
4035 if(clouds.size() == 1)
4038 QString
extensions = tr(
"Point cloud data (*.ply *.pcd");
4040 for(std::list<std::string>::iterator
iter=pdalFormats.begin();
iter!=pdalFormats.end(); ++
iter)
4042 if(
iter->compare(
"ply") == 0 ||
iter->compare(
"pcd") == 0)
4050 QString
extensions = tr(
"Point cloud data (*.ply *.pcd)");
4052 QString
path = QFileDialog::getSaveFileName(
this, tr(
"Save cloud to ..."), workingDirectory+QDir::separator()+
"cloud.ply",
extensions);
4056 if(QFileInfo(
path).suffix().isEmpty())
4062 if(clouds.begin()->second->size())
4064 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudRGBWithoutNormals;
4065 pcl::PointCloud<pcl::PointXYZI>::Ptr cloudIWithoutNormals;
4066 pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloudIWithNormals;
4068 !(
_ui->checkBox_cameraProjection->isEnabled() &&
4069 _ui->checkBox_cameraProjection->isChecked() &&
4070 _ui->checkBox_camProjRecolorPoints->isChecked() &&
4071 clouds.size()==1 && clouds.begin()->first==0))
4074 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
4076 cloudIWithNormals.reset(
new pcl::PointCloud<pcl::PointXYZINormal>);
4077 cloudIWithNormals->resize(clouds.begin()->second->size());
4078 for(
unsigned int i=0;
i<cloudIWithNormals->size(); ++
i)
4080 cloudIWithNormals->points[
i].x = clouds.begin()->second->points[
i].x;
4081 cloudIWithNormals->points[
i].y = clouds.begin()->second->points[
i].y;
4082 cloudIWithNormals->points[
i].z = clouds.begin()->second->points[
i].z;
4083 cloudIWithNormals->points[
i].normal_x = clouds.begin()->second->points[
i].normal_x;
4084 cloudIWithNormals->points[
i].normal_y = clouds.begin()->second->points[
i].normal_y;
4085 cloudIWithNormals->points[
i].normal_z = clouds.begin()->second->points[
i].normal_z;
4086 cloudIWithNormals->points[
i].curvature = clouds.begin()->second->points[
i].curvature;
4087 int * intensity = (
int *)&cloudIWithNormals->points[
i].intensity;
4089 int(clouds.begin()->second->points[
i].r) |
4090 int(clouds.begin()->second->points[
i].g) << 8 |
4091 int(clouds.begin()->second->points[
i].b) << 16 |
4092 int(clouds.begin()->second->points[
i].a) << 24;
4097 cloudIWithoutNormals.reset(
new pcl::PointCloud<pcl::PointXYZI>);
4098 cloudIWithoutNormals->resize(clouds.begin()->second->size());
4099 for(
unsigned int i=0;
i<cloudIWithoutNormals->size(); ++
i)
4101 cloudIWithoutNormals->points[
i].x = clouds.begin()->second->points[
i].x;
4102 cloudIWithoutNormals->points[
i].y = clouds.begin()->second->points[
i].y;
4103 cloudIWithoutNormals->points[
i].z = clouds.begin()->second->points[
i].z;
4104 int * intensity = (
int *)&cloudIWithoutNormals->points[
i].intensity;
4106 int(clouds.begin()->second->points[
i].r) |
4107 int(clouds.begin()->second->points[
i].g) << 8 |
4108 int(clouds.begin()->second->points[
i].b) << 16 |
4109 int(clouds.begin()->second->points[
i].a) << 24;
4113 else if(
_ui->spinBox_normalKSearch->value()<=0 &&
_ui->doubleSpinBox_normalRadiusSearch->value()<=0.0)
4115 cloudRGBWithoutNormals.reset(
new pcl::PointCloud<pcl::PointXYZRGB>);
4116 pcl::copyPointCloud(*clouds.begin()->second, *cloudRGBWithoutNormals);
4121 bool success =
false;
4122 if(QFileInfo(
path).suffix() ==
"pcd")
4124 if(cloudIWithNormals.get())
4126 success = pcl::io::savePCDFile(
path.toStdString(), *cloudIWithNormals, binaryMode) == 0;
4128 else if(cloudIWithoutNormals.get())
4130 success = pcl::io::savePCDFile(
path.toStdString(), *cloudIWithoutNormals, binaryMode) == 0;
4132 else if(cloudRGBWithoutNormals.get())
4134 success = pcl::io::savePCDFile(
path.toStdString(), *cloudRGBWithoutNormals, binaryMode) == 0;
4138 success = pcl::io::savePCDFile(
path.toStdString(), *clouds.begin()->second, binaryMode) == 0;
4142 else if(QFileInfo(
path).suffix() ==
"ply" && pointToPixels.empty()) {
4144 else if(QFileInfo(
path).suffix() ==
"ply") {
4146 if(cloudIWithNormals.get())
4148 success = pcl::io::savePLYFile(
path.toStdString(), *cloudIWithNormals, binaryMode) == 0;
4150 else if(cloudIWithoutNormals.get())
4152 success = pcl::io::savePLYFile(
path.toStdString(), *cloudIWithoutNormals, binaryMode) == 0;
4154 else if(cloudRGBWithoutNormals.get())
4156 success = pcl::io::savePLYFile(
path.toStdString(), *cloudRGBWithoutNormals, binaryMode) == 0;
4160 success = pcl::io::savePLYFile(
path.toStdString(), *clouds.begin()->second, binaryMode) == 0;
4164 else if(!QFileInfo(
path).suffix().isEmpty())
4166 std::vector<int> cameraIds(pointToPixels.size(), 0);
4167 for(
size_t i=0;
i<pointToPixels.size(); ++
i)
4169 if(!pointToPixels[
i].
empty())
4171 cameraIds[
i] = pointToPixels[
i].begin()->first;
4174 if(cloudIWithNormals.get())
4176 success =
savePDALFile(
path.toStdString(), *cloudIWithNormals, cameraIds, binaryMode) == 0;
4178 else if(cloudIWithoutNormals.get())
4180 success =
savePDALFile(
path.toStdString(), *cloudIWithoutNormals, cameraIds, binaryMode) == 0;
4182 else if(cloudRGBWithoutNormals.get())
4184 success =
savePDALFile(
path.toStdString(), *cloudRGBWithoutNormals, cameraIds, binaryMode) == 0;
4188 success =
savePDALFile(
path.toStdString(), *clouds.begin()->second, cameraIds, binaryMode) == 0;
4194 UERROR(
"Extension not recognized! (%s) Should be one of (*.ply *.pcd *.las).", QFileInfo(
path).suffix().toStdString().
c_str());
4201 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Cloud saved to \"%1\"").
arg(
path));
4205 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").
arg(
path));
4210 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Cloud is empty..."));
4214 else if(clouds.size())
4217 items.push_back(
"ply");
4218 items.push_back(
"pcd");
4220 QString
extensions = tr(
"Save clouds to (*.ply *.pcd");
4222 for(std::list<std::string>::iterator
iter=pdalFormats.begin();
iter!=pdalFormats.end(); ++
iter)
4224 if(
iter->compare(
"ply") == 0 ||
iter->compare(
"pcd") == 0)
4230 items.push_back(
iter->c_str());
4234 QString
extensions = tr(
"Save clouds to (*.ply *.pcd)...");
4236 QString
path = QFileDialog::getExistingDirectory(
this,
extensions, workingDirectory, QFileDialog::ShowDirsOnly);
4240 QString suffix = QInputDialog::getItem(
this, tr(
"File format"), tr(
"Which format?"), items, 0,
false, &ok);
4244 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"cloud", &ok);
4248 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::const_iterator
iter=clouds.begin();
iter!=clouds.end(); ++
iter)
4250 if(
iter->second->size())
4252 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformedCloud;
4255 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudRGBWithoutNormals;
4256 pcl::PointCloud<pcl::PointXYZI>::Ptr cloudIWithoutNormals;
4257 pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloudIWithNormals;
4261 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
4263 cloudIWithNormals.reset(
new pcl::PointCloud<pcl::PointXYZINormal>);
4264 cloudIWithNormals->resize(transformedCloud->size());
4265 for(
unsigned int i=0;
i<cloudIWithNormals->size(); ++
i)
4267 cloudIWithNormals->points[
i].x = transformedCloud->points[
i].x;
4268 cloudIWithNormals->points[
i].y = transformedCloud->points[
i].y;
4269 cloudIWithNormals->points[
i].z = transformedCloud->points[
i].z;
4270 cloudIWithNormals->points[
i].normal_x = transformedCloud->points[
i].normal_x;
4271 cloudIWithNormals->points[
i].normal_y = transformedCloud->points[
i].normal_y;
4272 cloudIWithNormals->points[
i].normal_z = transformedCloud->points[
i].normal_z;
4273 cloudIWithNormals->points[
i].curvature = transformedCloud->points[
i].curvature;
4274 int * intensity = (
int *)&cloudIWithNormals->points[
i].intensity;
4276 int(transformedCloud->points[
i].r) |
4277 int(transformedCloud->points[
i].g) << 8 |
4278 int(transformedCloud->points[
i].b) << 16 |
4279 int(transformedCloud->points[
i].a) << 24;
4284 cloudIWithoutNormals.reset(
new pcl::PointCloud<pcl::PointXYZI>);
4285 cloudIWithoutNormals->resize(transformedCloud->size());
4286 for(
unsigned int i=0;
i<cloudIWithoutNormals->size(); ++
i)
4288 cloudIWithoutNormals->points[
i].x = transformedCloud->points[
i].x;
4289 cloudIWithoutNormals->points[
i].y = transformedCloud->points[
i].y;
4290 cloudIWithoutNormals->points[
i].z = transformedCloud->points[
i].z;
4291 int * intensity = (
int *)&cloudIWithoutNormals->points[
i].intensity;
4293 int(transformedCloud->points[
i].r) |
4294 int(transformedCloud->points[
i].g) << 8 |
4295 int(transformedCloud->points[
i].b) << 16 |
4296 int(transformedCloud->points[
i].a) << 24;
4300 else if(
_ui->spinBox_normalKSearch->value()<=0 &&
_ui->doubleSpinBox_normalRadiusSearch->value()<=0.0)
4302 cloudRGBWithoutNormals.reset(
new pcl::PointCloud<pcl::PointXYZRGB>);
4303 pcl::copyPointCloud(*transformedCloud, *cloudRGBWithoutNormals);
4306 QString pathFile =
path+QDir::separator()+QString(
"%1%2.%3").arg(prefix).arg(
iter->first).arg(suffix);
4307 bool success =
false;
4310 if(cloudIWithNormals.get())
4312 success = pcl::io::savePCDFile(pathFile.toStdString(), *cloudIWithNormals, binaryMode) == 0;
4314 else if(cloudIWithoutNormals.get())
4316 success = pcl::io::savePCDFile(pathFile.toStdString(), *cloudIWithoutNormals, binaryMode) == 0;
4318 else if(cloudRGBWithoutNormals.get())
4320 success = pcl::io::savePCDFile(pathFile.toStdString(), *cloudRGBWithoutNormals, binaryMode) == 0;
4324 success = pcl::io::savePCDFile(pathFile.toStdString(), *transformedCloud, binaryMode) == 0;
4327 else if(suffix ==
"ply")
4329 if(cloudIWithNormals.get())
4331 success = pcl::io::savePLYFile(pathFile.toStdString(), *cloudIWithNormals, binaryMode) == 0;
4333 else if(cloudIWithoutNormals.get())
4335 success = pcl::io::savePLYFile(pathFile.toStdString(), *cloudIWithoutNormals, binaryMode) == 0;
4337 else if(cloudRGBWithoutNormals.get())
4339 success = pcl::io::savePLYFile(pathFile.toStdString(), *cloudRGBWithoutNormals, binaryMode) == 0;
4343 success = pcl::io::savePLYFile(pathFile.toStdString(), *transformedCloud, binaryMode) == 0;
4347 else if(!suffix.isEmpty())
4349 if(cloudIWithNormals.get())
4351 success =
savePDALFile(pathFile.toStdString(), *cloudIWithNormals) == 0;
4353 else if(cloudIWithoutNormals.get())
4355 success =
savePDALFile(pathFile.toStdString(), *cloudIWithoutNormals) == 0;
4357 else if(cloudRGBWithoutNormals.get())
4359 success =
savePDALFile(pathFile.toStdString(), *cloudRGBWithoutNormals) == 0;
4363 success =
savePDALFile(pathFile.toStdString(), *transformedCloud) == 0;
4369 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
4386 QApplication::processEvents();
4399 const QString & workingDirectory,
4400 const std::map<int, Transform> & poses,
4401 const std::map<int, pcl::PolygonMesh::Ptr> & meshes,
4404 if(meshes.size() == 1)
4406 QString
path = QFileDialog::getSaveFileName(
this, tr(
"Save mesh to ..."), workingDirectory+QDir::separator()+
"mesh.ply", tr(
"Mesh (*.ply)"));
4409 if(meshes.begin()->second->polygons.size())
4412 QApplication::processEvents();
4414 QApplication::processEvents();
4416 bool success =
false;
4417 if(QFileInfo(
path).suffix() ==
"")
4422 if(QFileInfo(
path).suffix() ==
"ply")
4426 success = pcl::io::savePLYFileBinary(
path.toStdString(), *meshes.begin()->second) == 0;
4430 success = pcl::io::savePLYFile(
path.toStdString(), *meshes.begin()->second) == 0;
4433 else if(QFileInfo(
path).suffix() ==
"obj")
4439 UERROR(
"Extension not recognized! (%s) Should be (*.ply) or (*.obj).", QFileInfo(
path).suffix().toStdString().
c_str());
4446 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Mesh saved to \"%1\"").
arg(
path));
4450 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").
arg(
path));
4455 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Cloud is empty..."));
4459 else if(meshes.size())
4461 QString
path = QFileDialog::getExistingDirectory(
this, tr(
"Save meshes to (*.ply *.obj)..."), workingDirectory, QFileDialog::ShowDirsOnly);
4466 items.push_back(
"ply");
4467 items.push_back(
"obj");
4468 QString suffix = QInputDialog::getItem(
this, tr(
"File format"), tr(
"Which format?"), items, 0,
false, &ok);
4472 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"mesh", &ok);
4476 for(std::map<int, pcl::PolygonMesh::Ptr>::const_iterator
iter=meshes.begin();
iter!=meshes.end(); ++
iter)
4478 if(
iter->second->polygons.size())
4480 pcl::PolygonMesh mesh;
4481 mesh.polygons =
iter->second->polygons;
4483 for(
unsigned int i=0;
i<
iter->second->cloud.fields.size(); ++
i)
4485 if(
iter->second->cloud.fields[
i].name.compare(
"rgb") == 0)
4493 pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp(
new pcl::PointCloud<pcl::PointXYZRGB>);
4494 pcl::fromPCLPointCloud2(
iter->second->cloud, *tmp);
4496 pcl::toPCLPointCloud2(*tmp, mesh.cloud);
4500 pcl::PointCloud<pcl::PointXYZ>::Ptr tmp(
new pcl::PointCloud<pcl::PointXYZ>);
4501 pcl::fromPCLPointCloud2(
iter->second->cloud, *tmp);
4503 pcl::toPCLPointCloud2(*tmp, mesh.cloud);
4506 QString pathFile =
path+QDir::separator()+QString(
"%1%2.%3").arg(prefix).arg(
iter->first).arg(suffix);
4507 bool success =
false;
4512 success = pcl::io::savePLYFileBinary(pathFile.toStdString(), mesh) == 0;
4516 success = pcl::io::savePLYFile(pathFile.toStdString(), mesh) == 0;
4519 else if(suffix ==
"obj")
4525 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
4530 .
arg(
iter->first).
arg(
iter->second->polygons.size()).arg(pathFile));
4535 .
arg(
iter->first).
arg(
iter->second->polygons.size()).arg(pathFile), Qt::darkRed);
4544 QApplication::processEvents();
4557 const QString & workingDirectory,
4558 const std::map<int, Transform> & poses,
4559 std::map<int, pcl::TextureMesh::Ptr> & meshes,
4560 const QMap<int, Signature> & cachedSignatures,
4561 const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels)
4563 std::map<int, cv::Mat> images;
4564 std::map<int, std::vector<CameraModel> > calibrations;
4565 for(QMap<int, Signature>::const_iterator
iter=cachedSignatures.constBegin();
iter!=cachedSignatures.constEnd(); ++
iter)
4567 std::vector<CameraModel> models;
4568 if(
iter->sensorData().cameraModels().size())
4570 models =
iter->sensorData().cameraModels();
4572 else if(
iter->sensorData().stereoCameraModels().size())
4574 for(
size_t i=0;
i<
iter->sensorData().stereoCameraModels().
size(); ++
i)
4576 models.push_back(
iter->sensorData().stereoCameraModels()[
i].left());
4582 if(!
iter->sensorData().imageRaw().empty())
4584 calibrations.insert(std::make_pair(
iter.key(), models));
4585 images.insert(std::make_pair(
iter.key(),
iter->sensorData().imageRaw()));
4587 else if(!
iter->sensorData().imageCompressed().empty())
4589 calibrations.insert(std::make_pair(
iter.key(), models));
4590 images.insert(std::make_pair(
iter.key(),
iter->sensorData().imageCompressed()));
4594 int textureSize = 1024;
4595 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
4597 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
4599 int blendingDecimation = 0;
4600 if(
_ui->checkBox_blending->isChecked())
4602 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
4604 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
4608 if(meshes.size() == 1)
4610 QString
path = QFileDialog::getSaveFileName(
this, tr(
"Save texture mesh to ..."), workingDirectory+QDir::separator()+
"mesh.obj", tr(
"Mesh (*.obj)"));
4613 if(meshes.begin()->second->tex_materials.size())
4616 QApplication::processEvents();
4618 QApplication::processEvents();
4620 bool success =
false;
4621 if(QFileInfo(
path).suffix() ==
"")
4626 pcl::TextureMesh::Ptr mesh = meshes.begin()->second;
4628 cv::Mat globalTextures;
4629 bool texturesMerged =
_ui->comboBox_meshingTextureSize->isEnabled() &&
_ui->comboBox_meshingTextureSize->currentIndex() > 0;
4630 if(texturesMerged && mesh->tex_materials.size()>1)
4633 QApplication::processEvents();
4635 QApplication::processEvents();
4637 std::map<int, std::map<int, cv::Vec4d> > gains;
4638 std::map<int, std::map<int, cv::Mat> > blendingGains;
4639 std::pair<float, float> contrastValues(0,0);
4647 _ui->checkBox_multiband->isEnabled() &&
_ui->checkBox_multiband->isChecked()?1:
_ui->spinBox_mesh_maxTextures->value(),
4648 textureVertexToPixels,
4649 _ui->checkBox_gainCompensation->isChecked(),
4650 _ui->doubleSpinBox_gainBeta->value(),
4651 _ui->checkBox_gainRGB->isChecked(),
4652 _ui->checkBox_blending->isChecked(),
4654 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
4655 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
4656 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked(),
4664 QApplication::processEvents();
4666 QApplication::processEvents();
4668 if(
_ui->checkBox_multiband->isEnabled() &&
_ui->checkBox_multiband->isChecked() && mesh->tex_polygons.size() == 1)
4671 QApplication::processEvents();
4673 QApplication::processEvents();
4678 mesh->tex_polygons[0],
4680 textureVertexToPixels,
4686 _ui->spinBox_multiband_downscale->value(),
4687 _ui->lineEdit_multiband_nbcontrib->text().toStdString(),
4688 _ui->comboBox_meshingTextureFormat->currentText().toStdString(),
4693 _ui->comboBox_multiband_unwrap->currentIndex(),
4694 _ui->checkBox_multiband_fillholes->isChecked(),
4695 _ui->spinBox_multiband_padding->value(),
4696 _ui->doubleSpinBox_multiband_bestscore->value(),
4697 _ui->doubleSpinBox_multiband_angle->value(),
4698 _ui->checkBox_multiband_forcevisible->isChecked());
4704 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Mesh saved to \"%1\"").
arg(
path));
4708 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").
arg(
path));
4714 bool singleTexture = mesh->tex_materials.size() == 1;
4718 QDir(QFileInfo(
path).absoluteDir().absolutePath()).mkdir(QFileInfo(
path).baseName());
4722 cv::Mat previousImage;
4723 int previousTextureId = 0;
4724 std::vector<CameraModel> previousCameraModels;
4727 for(
unsigned int i=0;
i<mesh->tex_materials.size(); ++
i)
4729 if(!mesh->tex_materials[
i].tex_file.empty())
4735 fullPath = QFileInfo(
path).absoluteDir().absolutePath()+QDir::separator()+QFileInfo(
path).baseName()+
_ui->comboBox_meshingTextureFormat->currentText();
4739 fullPath = QFileInfo(
path).absoluteDir().absolutePath()+QDir::separator()+QFileInfo(
path).baseName()+QDir::separator()+QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText();
4741 UDEBUG(
"Saving %s...", fullPath.toStdString().c_str());
4742 if(singleTexture || !QFileInfo(fullPath).exists())
4744 std::list<std::string> texFileSplit =
uSplit(mesh->tex_materials[
i].tex_file,
'_');
4745 if(texFileSplit.size() &&
uIsInteger(texFileSplit.front(),
false))
4747 int textureId =
uStr2Int(texFileSplit.front());
4748 int textureSubCamera = -1;
4749 if(texFileSplit.size() == 2 &&
4752 textureSubCamera =
uStr2Int(texFileSplit.back());
4755 std::vector<CameraModel> cameraModels;
4757 if(textureId == previousTextureId)
4759 image = previousImage;
4760 cameraModels = previousCameraModels;
4764 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
4766 cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
4767 cameraModels = cachedSignatures.value(textureId).sensorData().cameraModels();
4773 data.uncompressDataConst(&image, 0);
4774 std::vector<StereoCameraModel> stereoModels;
4776 if(cameraModels.empty())
4778 for(
size_t i=0;
i<stereoModels.size(); ++
i)
4780 cameraModels.push_back(stereoModels[
i].left());
4785 previousImage = image;
4786 previousCameraModels = cameraModels;
4787 previousTextureId = textureId;
4790 imageSize = image.size();
4791 if(textureSubCamera>=0)
4794 imageSize.width/=cameraModels.size();
4795 image = image.colRange(imageSize.width*textureSubCamera, imageSize.width*(textureSubCamera+1));
4802 if(!cv::imwrite(fullPath.toStdString(), image))
4805 .
arg(mesh->tex_materials[
i].tex_file.c_str()).
arg(fullPath), Qt::darkRed);
4809 else if(imageSize.height && imageSize.width)
4812 cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
4813 cv::imwrite(fullPath.toStdString(), image);
4815 else if(!globalTextures.empty())
4817 if(!cv::imwrite(fullPath.toStdString(), globalTextures(
cv::Range::all(), cv::Range(
i*globalTextures.rows, (
i+1)*globalTextures.rows))))
4820 .
arg(mesh->tex_materials[
i].tex_file.c_str()).
arg(fullPath), Qt::darkRed);
4826 UWARN(
"Ignored texture %s (no image size set yet)", mesh->tex_materials[
i].tex_file.c_str());
4831 UWARN(
"File %s already exists!", fullPath.toStdString().c_str());
4836 mesh->tex_materials[
i].tex_file=QFileInfo(
path).baseName().toStdString()+
_ui->comboBox_meshingTextureFormat->currentText().toStdString();
4840 mesh->tex_materials[
i].tex_file=(QFileInfo(
path).baseName()+QDir::separator()+QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
4850 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Mesh saved to \"%1\"").
arg(
path));
4854 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").
arg(
path));
4859 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"No textures..."));
4863 else if(meshes.size())
4865 QString
path = QFileDialog::getExistingDirectory(
this, tr(
"Save texture meshes to (*.obj)..."), workingDirectory, QFileDialog::ShowDirsOnly);
4869 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"mesh", &ok);
4870 QString suffix =
"obj";
4874 for(std::map<int, pcl::TextureMesh::Ptr>::iterator
iter=meshes.begin();
iter!=meshes.end(); ++
iter)
4876 QString currentPrefix=prefix+QString::number(
iter->first);
4877 if(
iter->second->tex_materials.size())
4879 pcl::TextureMesh::Ptr mesh =
iter->second;
4880 cv::Mat globalTextures;
4881 bool texturesMerged =
_ui->comboBox_meshingTextureSize->isEnabled() &&
_ui->comboBox_meshingTextureSize->currentIndex() > 0;
4882 if(texturesMerged && mesh->tex_materials.size()>1)
4891 _ui->spinBox_mesh_maxTextures->value(),
4892 textureVertexToPixels,
4893 _ui->checkBox_gainCompensation->isChecked(),
4894 _ui->doubleSpinBox_gainBeta->value(),
4895 _ui->checkBox_gainRGB->isChecked(),
4896 _ui->checkBox_blending->isChecked(),
4898 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
4899 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
4900 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked());
4902 bool singleTexture = mesh->tex_materials.size() == 1;
4906 QDir(
path).mkdir(currentPrefix);
4910 cv::Mat previousImage;
4911 int previousTextureId = 0;
4912 std::vector<CameraModel> previousCameraModels;
4915 for(
unsigned int i=0;
i<mesh->tex_materials.size(); ++
i)
4917 if(!mesh->tex_materials[
i].tex_file.empty())
4919 std::list<std::string> texFileSplit =
uSplit(mesh->tex_materials[
i].tex_file,
'_');
4921 int textureSubCamera = -1;
4922 if(texFileSplit.size() &&
uIsInteger(texFileSplit.front(),
false))
4924 textureId =
uStr2Int(texFileSplit.front());
4925 if(texFileSplit.size() == 2 &&
4928 textureSubCamera =
uStr2Int(texFileSplit.back());
4937 fullPath =
path+QDir::separator()+prefix + QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText();
4941 fullPath =
path+QDir::separator()+currentPrefix+QDir::separator()+QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText();
4946 std::vector<CameraModel> cameraModels;
4948 if(textureId == previousTextureId)
4950 image = previousImage;
4951 cameraModels = previousCameraModels;
4955 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
4957 cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
4958 cameraModels = cachedSignatures.value(textureId).sensorData().cameraModels();
4964 data.uncompressDataConst(&image, 0);
4965 std::vector<StereoCameraModel> stereoModels;
4967 if(cameraModels.empty())
4969 for(
size_t i=0;
i<stereoModels.size(); ++
i)
4971 cameraModels.push_back(stereoModels[
i].left());
4976 previousImage = image;
4977 previousCameraModels = cameraModels;
4978 previousTextureId = textureId;
4983 imageSize = image.size();
4984 if(textureSubCamera>=0)
4987 imageSize.width/=cameraModels.size();
4988 image = image.colRange(imageSize.width*textureSubCamera, imageSize.width*(textureSubCamera+1));
4995 if(!cv::imwrite(fullPath.toStdString(), image))
4998 .
arg(mesh->tex_materials[
i].tex_file.c_str()).
arg(fullPath), Qt::darkRed);
5002 else if(imageSize.height && imageSize.width)
5005 cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
5006 cv::imwrite(fullPath.toStdString(), image);
5008 else if(!globalTextures.empty())
5010 if(!cv::imwrite(fullPath.toStdString(), globalTextures(
cv::Range::all(), cv::Range(
i*globalTextures.rows, (
i+1)*globalTextures.rows))))
5013 .
arg(mesh->tex_materials[
i].tex_file.c_str()).
arg(fullPath), Qt::darkRed);
5019 UWARN(
"Ignored texture %s (no image size set yet)", mesh->tex_materials[
i].tex_file.c_str());
5024 mesh->tex_materials[
i].tex_file=(prefix+ QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
5028 mesh->tex_materials[
i].tex_file=(currentPrefix+QDir::separator()+QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
5032 pcl::PointCloud<pcl::PointNormal>::Ptr tmp(
new pcl::PointCloud<pcl::PointNormal>);
5033 pcl::fromPCLPointCloud2(mesh->cloud, *tmp);
5035 pcl::toPCLPointCloud2(*tmp, mesh->cloud);
5037 QString pathFile =
path+QDir::separator()+QString(
"%1.%3").arg(currentPrefix).arg(suffix);
5038 bool success =
false;
5045 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
5050 .
arg(
iter->first).
arg(mesh->tex_materials.size()).arg(pathFile));
5055 .
arg(
iter->first).
arg(mesh->tex_materials.size()).arg(pathFile), Qt::darkRed);
5064 QApplication::processEvents();
5076 #if PCL_VERSION_COMPARE(>=, 1, 13, 0)
5077 mesh->tex_coord_indices = std::vector<std::vector<pcl::Vertices>>();
5078 auto nr_meshes =
static_cast<unsigned>(mesh->tex_polygons.size());
5080 for (
unsigned m = 0;
m < nr_meshes;
m++) {
5081 std::vector<pcl::Vertices> ci = mesh->tex_polygons[
m];
5082 for(std::size_t
i = 0;
i < ci.size();
i++) {
5083 for (std::size_t
j = 0;
j < ci[
i].vertices.size();
j++) {
5084 ci[
i].vertices[
j] = ci[
i].vertices.size() * (
i + f_idx) +
j;
5087 mesh->tex_coord_indices.push_back(ci);
5088 f_idx +=
static_cast<unsigned>(mesh->tex_polygons[
m].size());
5091 return pcl::io::saveOBJFile(
path.toStdString(), *mesh) == 0;
5095 return pcl::io::saveOBJFile(
path.toStdString(), mesh) == 0;