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>
82 #elif defined(RTABMAP_LIBLAS)
95 _ui =
new Ui_ExportCloudsDialog();
98 connect(
_ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()),
this, SLOT(
restoreDefaults()));
99 QPushButton * loadSettingsButton =
_ui->buttonBox->addButton(
"Load Settings", QDialogButtonBox::ActionRole);
100 QPushButton * saveSettingsButton =
_ui->buttonBox->addButton(
"Save Settings", QDialogButtonBox::ActionRole);
101 connect(loadSettingsButton, SIGNAL(clicked()),
this, SLOT(
loadSettings()));
102 connect(saveSettingsButton, SIGNAL(clicked()),
this, SLOT(
saveSettings()));
105 _ui->comboBox_upsamplingMethod->setItemData(1, 0, Qt::UserRole - 1);
107 connect(
_ui->checkBox_fromDepth, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
109 connect(
_ui->checkBox_binary, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
110 connect(
_ui->spinBox_normalKSearch, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
111 connect(
_ui->doubleSpinBox_normalRadiusSearch, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
112 connect(
_ui->doubleSpinBox_groundNormalsUp, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
113 connect(
_ui->comboBox_pipeline, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
115 connect(
_ui->comboBox_meshingApproach, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
118 connect(
_ui->checkBox_nodes_filtering, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
120 connect(
_ui->doubleSpinBox_nodes_filtering_xmin, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
121 connect(
_ui->doubleSpinBox_nodes_filtering_xmax, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
122 connect(
_ui->doubleSpinBox_nodes_filtering_ymin, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
123 connect(
_ui->doubleSpinBox_nodes_filtering_ymax, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
124 connect(
_ui->doubleSpinBox_nodes_filtering_zmin, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
125 connect(
_ui->doubleSpinBox_nodes_filtering_zmax, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
127 connect(
_ui->checkBox_regenerate, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
129 connect(
_ui->spinBox_decimation, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
130 connect(
_ui->doubleSpinBox_maxDepth, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
131 connect(
_ui->doubleSpinBox_minDepth, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
132 connect(
_ui->doubleSpinBox_ceilingHeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
133 connect(
_ui->doubleSpinBox_floorHeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
134 connect(
_ui->groupBox_offAxisFiltering, SIGNAL(toggled(
bool)),
this, SIGNAL(
configChanged()));
135 connect(
_ui->doubleSpinBox_offAxisFilteringAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
136 connect(
_ui->checkBox_offAxisFilteringPosX, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
137 connect(
_ui->checkBox_offAxisFilteringNegX, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
138 connect(
_ui->checkBox_offAxisFilteringPosY, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
139 connect(
_ui->checkBox_offAxisFilteringNegY, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
140 connect(
_ui->checkBox_offAxisFilteringPosZ, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
141 connect(
_ui->checkBox_offAxisFilteringNegZ, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
142 connect(
_ui->doubleSpinBox_footprintWidth, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
143 connect(
_ui->doubleSpinBox_footprintLength, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
144 connect(
_ui->doubleSpinBox_footprintHeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
145 connect(
_ui->spinBox_decimation_scan, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
146 connect(
_ui->doubleSpinBox_rangeMin, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
147 connect(
_ui->doubleSpinBox_rangeMax, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
148 connect(
_ui->spinBox_fillDepthHoles, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
149 connect(
_ui->spinBox_fillDepthHolesError, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
150 connect(
_ui->lineEdit_roiRatios, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
151 connect(
_ui->lineEdit_distortionModel, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
154 connect(
_ui->checkBox_bilateral, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
156 connect(
_ui->doubleSpinBox_bilateral_sigmaS, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
157 connect(
_ui->doubleSpinBox_bilateral_sigmaR, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
159 connect(
_ui->checkBox_filtering, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
161 connect(
_ui->doubleSpinBox_filteringRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
162 connect(
_ui->spinBox_filteringMinNeighbors, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
164 connect(
_ui->checkBox_assemble, SIGNAL(clicked(
bool)),
this, SIGNAL(
configChanged()));
166 connect(
_ui->doubleSpinBox_voxelSize_assembled, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
167 connect(
_ui->spinBox_randomSamples_assembled, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
168 connect(
_ui->comboBox_frame, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
171 connect(
_ui->checkBox_subtraction, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
173 connect(
_ui->doubleSpinBox_subtractPointFilteringRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
174 connect(
_ui->doubleSpinBox_subtractPointFilteringAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
175 connect(
_ui->spinBox_subtractFilteringMinPts, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
177 connect(
_ui->checkBox_smoothing, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
179 connect(
_ui->doubleSpinBox_mlsRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
180 connect(
_ui->spinBox_polygonialOrder, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
181 connect(
_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
182 connect(
_ui->doubleSpinBox_sampleStep, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
183 connect(
_ui->spinBox_randomPoints, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
184 connect(
_ui->doubleSpinBox_dilationVoxelSize, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
185 connect(
_ui->spinBox_dilationSteps, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
186 connect(
_ui->doubleSpinBox_mls_outputVoxelSize, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
187 _ui->stackedWidget_upsampling->setCurrentIndex(
_ui->comboBox_upsamplingMethod->currentIndex());
188 connect(
_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(
int)),
_ui->stackedWidget_upsampling, SLOT(setCurrentIndex(
int)));
191 connect(
_ui->checkBox_gainCompensation, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
193 connect(
_ui->doubleSpinBox_gainRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
194 connect(
_ui->doubleSpinBox_gainOverlap, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
195 connect(
_ui->doubleSpinBox_gainBeta, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
196 connect(
_ui->checkBox_gainRGB, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
197 connect(
_ui->checkBox_gainFull, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
198 connect(
_ui->spinBox_textureBrightnessContrastRatioLow, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
199 connect(
_ui->spinBox_textureBrightnessContrastRatioHigh, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
200 connect(
_ui->checkBox_exposureFusion, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
201 connect(
_ui->checkBox_blending, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
202 connect(
_ui->comboBox_blendingDecimation, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
204 connect(
_ui->checkBox_cameraProjection, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
206 connect(
_ui->lineEdit_camProjRoiRatios, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
207 connect(
_ui->toolButton_camProjMaskFilePath, SIGNAL(clicked()),
this, SLOT(
selectCamProjMask()));
208 connect(
_ui->lineEdit_camProjMaskFilePath, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
209 connect(
_ui->spinBox_camProjDecimation, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
210 connect(
_ui->doubleSpinBox_camProjMaxDistance, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
211 connect(
_ui->doubleSpinBox_camProjMaxAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
212 connect(
_ui->checkBox_camProjDistanceToCamPolicy, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
213 connect(
_ui->checkBox_camProjKeepPointsNotSeenByCameras, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
214 connect(
_ui->checkBox_camProjRecolorPoints, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
215 connect(
_ui->comboBox_camProjExportCamera, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
216 #if !defined(RTABMAP_PDAL) && !defined(RTABMAP_LIBLAS)
217 _ui->comboBox_camProjExportCamera->setEnabled(
false);
218 _ui->label_camProjExportCamera->setEnabled(
false);
219 _ui->label_camProjExportCamera->setText(
_ui->label_camProjExportCamera->text() +
" (PDAL dependency required)");
222 connect(
_ui->checkBox_meshing, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
224 connect(
_ui->doubleSpinBox_gp3Radius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
225 connect(
_ui->doubleSpinBox_gp3Mu, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
226 connect(
_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
228 connect(
_ui->spinBox_meshMaxPolygons, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
230 connect(
_ui->doubleSpinBox_transferColorRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
231 connect(
_ui->checkBox_cleanMesh, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
232 connect(
_ui->spinBox_mesh_minClusterSize, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
233 connect(
_ui->checkBox_textureMapping, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
235 connect(
_ui->comboBox_meshingTextureFormat, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
236 connect(
_ui->comboBox_meshingTextureSize, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
237 connect(
_ui->spinBox_mesh_maxTextures, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
238 connect(
_ui->doubleSpinBox_meshingTextureMaxDistance, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
239 connect(
_ui->doubleSpinBox_meshingTextureMaxDepthError, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
240 connect(
_ui->doubleSpinBox_meshingTextureMaxAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
241 connect(
_ui->spinBox_mesh_minTextureClusterSize, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
242 connect(
_ui->lineEdit_meshingTextureRoiRatios, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
243 connect(
_ui->checkBox_cameraFilter, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
245 connect(
_ui->doubleSpinBox_cameraFilterRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
246 connect(
_ui->doubleSpinBox_cameraFilterAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
247 connect(
_ui->doubleSpinBox_cameraFilterVel, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
248 connect(
_ui->doubleSpinBox_cameraFilterVelRad, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
249 connect(
_ui->doubleSpinBox_laplacianVariance, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
250 connect(
_ui->checkBox_multiband, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
252 connect(
_ui->spinBox_multiband_downscale, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
253 connect(
_ui->lineEdit_multiband_nbcontrib, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
254 connect(
_ui->comboBox_multiband_unwrap, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
255 connect(
_ui->checkBox_multiband_fillholes, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
256 connect(
_ui->spinBox_multiband_padding, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
257 connect(
_ui->doubleSpinBox_multiband_bestscore, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
258 connect(
_ui->doubleSpinBox_multiband_angle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
259 connect(
_ui->checkBox_multiband_forcevisible, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
261 connect(
_ui->checkBox_poisson_outputPolygons, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
262 connect(
_ui->checkBox_poisson_manifold, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
263 connect(
_ui->spinBox_poisson_depth, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
264 connect(
_ui->doubleSpinBox_poisson_targetPolygonSize, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
265 connect(
_ui->spinBox_poisson_iso, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
266 connect(
_ui->spinBox_poisson_solver, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
267 connect(
_ui->spinBox_poisson_minDepth, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
268 connect(
_ui->doubleSpinBox_poisson_samples, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
269 connect(
_ui->doubleSpinBox_poisson_pointWeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
270 connect(
_ui->doubleSpinBox_poisson_scale, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
272 connect(
_ui->doubleSpinBox_cputsdf_size, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
273 connect(
_ui->doubleSpinBox_cputsdf_resolution, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
274 connect(
_ui->doubleSpinBox_cputsdf_tuncPos, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
275 connect(
_ui->doubleSpinBox_cputsdf_tuncNeg, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
276 connect(
_ui->doubleSpinBox_cputsdf_minWeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
277 connect(
_ui->doubleSpinBox_cputsdf_flattenRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
278 connect(
_ui->spinBox_cputsdf_randomSplit, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
280 connect(
_ui->checkBox_openchisel_mergeVertices, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
281 connect(
_ui->spinBox_openchisel_chunk_size_x, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
282 connect(
_ui->spinBox_openchisel_chunk_size_y, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
283 connect(
_ui->spinBox_openchisel_chunk_size_z, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
284 connect(
_ui->doubleSpinBox_openchisel_truncation_constant, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
285 connect(
_ui->doubleSpinBox_openchisel_truncation_linear, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
286 connect(
_ui->doubleSpinBox_openchisel_truncation_quadratic, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
287 connect(
_ui->doubleSpinBox_openchisel_truncation_scale, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
288 connect(
_ui->spinBox_openchisel_integration_weight, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
289 connect(
_ui->checkBox_openchisel_use_voxel_carving, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
290 connect(
_ui->doubleSpinBox_openchisel_carving_dist_m, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
291 connect(
_ui->doubleSpinBox_openchisel_near_plane_dist, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
292 connect(
_ui->doubleSpinBox_openchisel_far_plane_dist, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
303 _ui->doubleSpinBox_meshDecimationFactor->setEnabled(
false);
304 _ui->spinBox_meshMaxPolygons->setEnabled(
false);
305 _ui->label_meshDecimation->setEnabled(
false);
306 _ui->label_meshMaxPolygons->setEnabled(
false);
309 #if CV_MAJOR_VERSION < 3
310 _ui->checkBox_exposureFusion->setEnabled(
false);
311 _ui->checkBox_exposureFusion->setChecked(
false);
312 _ui->label_exposureFusion->setEnabled(
false);
324 _ui->groupBox->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 0);
325 _ui->groupBox_2->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 1);
326 _ui->groupBox_3->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 2);
327 _ui->groupBox_4->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 3);
328 _ui->groupBox_5->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 4);
341 _ui->checkBox_assemble->setChecked(
true);
342 _ui->checkBox_assemble->setEnabled(
false);
346 _ui->checkBox_assemble->setEnabled(
true);
359 settings.beginGroup(group);
361 settings.setValue(
"pipeline",
_ui->comboBox_pipeline->currentIndex());
362 settings.setValue(
"from_depth",
_ui->checkBox_fromDepth->isChecked());
363 settings.setValue(
"binary",
_ui->checkBox_binary->isChecked());
364 settings.setValue(
"normals_k",
_ui->spinBox_normalKSearch->value());
365 settings.setValue(
"normals_radius",
_ui->doubleSpinBox_normalRadiusSearch->value());
366 settings.setValue(
"normals_ground_normals_up",
_ui->doubleSpinBox_groundNormalsUp->value());
367 settings.setValue(
"intensity_colormap",
_ui->comboBox_intensityColormap->currentIndex());
369 settings.setValue(
"nodes_filtering",
_ui->checkBox_nodes_filtering->isChecked());
370 settings.setValue(
"nodes_filtering_xmin",
_ui->doubleSpinBox_nodes_filtering_xmin->value());
371 settings.setValue(
"nodes_filtering_xmax",
_ui->doubleSpinBox_nodes_filtering_xmax->value());
372 settings.setValue(
"nodes_filtering_ymin",
_ui->doubleSpinBox_nodes_filtering_ymin->value());
373 settings.setValue(
"nodes_filtering_ymax",
_ui->doubleSpinBox_nodes_filtering_ymax->value());
374 settings.setValue(
"nodes_filtering_zmin",
_ui->doubleSpinBox_nodes_filtering_zmin->value());
375 settings.setValue(
"nodes_filtering_zmax",
_ui->doubleSpinBox_nodes_filtering_zmax->value());
377 settings.setValue(
"regenerate",
_ui->checkBox_regenerate->isChecked());
378 settings.setValue(
"regenerate_decimation",
_ui->spinBox_decimation->value());
379 settings.setValue(
"regenerate_max_depth",
_ui->doubleSpinBox_maxDepth->value());
380 settings.setValue(
"regenerate_min_depth",
_ui->doubleSpinBox_minDepth->value());
381 settings.setValue(
"regenerate_ceiling",
_ui->doubleSpinBox_ceilingHeight->value());
382 settings.setValue(
"regenerate_floor",
_ui->doubleSpinBox_floorHeight->value());
383 settings.setValue(
"regenerate_offaxis_filtering",
_ui->groupBox_offAxisFiltering->isChecked());
384 settings.setValue(
"regenerate_offaxis_filtering_angle",
_ui->doubleSpinBox_offAxisFilteringAngle->value());
385 settings.setValue(
"regenerate_offaxis_filtering_pos_x",
_ui->checkBox_offAxisFilteringPosX->isChecked());
386 settings.setValue(
"regenerate_offaxis_filtering_neg_x",
_ui->checkBox_offAxisFilteringNegX->isChecked());
387 settings.setValue(
"regenerate_offaxis_filtering_pos_y",
_ui->checkBox_offAxisFilteringPosY->isChecked());
388 settings.setValue(
"regenerate_offaxis_filtering_neg_y",
_ui->checkBox_offAxisFilteringNegY->isChecked());
389 settings.setValue(
"regenerate_offaxis_filtering_pos_z",
_ui->checkBox_offAxisFilteringPosZ->isChecked());
390 settings.setValue(
"regenerate_offaxis_filtering_neg_z",
_ui->checkBox_offAxisFilteringNegZ->isChecked());
391 settings.setValue(
"regenerate_footprint_height",
_ui->doubleSpinBox_footprintHeight->value());
392 settings.setValue(
"regenerate_footprint_width",
_ui->doubleSpinBox_footprintWidth->value());
393 settings.setValue(
"regenerate_footprint_length",
_ui->doubleSpinBox_footprintLength->value());
394 settings.setValue(
"regenerate_scan_decimation",
_ui->spinBox_decimation_scan->value());
395 settings.setValue(
"regenerate_scan_max_range",
_ui->doubleSpinBox_rangeMax->value());
396 settings.setValue(
"regenerate_scan_min_range",
_ui->doubleSpinBox_rangeMin->value());
397 settings.setValue(
"regenerate_fill_size",
_ui->spinBox_fillDepthHoles->value());
398 settings.setValue(
"regenerate_fill_error",
_ui->spinBox_fillDepthHolesError->value());
399 settings.setValue(
"regenerate_roi",
_ui->lineEdit_roiRatios->text());
400 settings.setValue(
"regenerate_distortion_model",
_ui->lineEdit_distortionModel->text());
402 settings.setValue(
"bilateral",
_ui->checkBox_bilateral->isChecked());
403 settings.setValue(
"bilateral_sigma_s",
_ui->doubleSpinBox_bilateral_sigmaS->value());
404 settings.setValue(
"bilateral_sigma_r",
_ui->doubleSpinBox_bilateral_sigmaR->value());
406 settings.setValue(
"filtering",
_ui->checkBox_filtering->isChecked());
407 settings.setValue(
"filtering_radius",
_ui->doubleSpinBox_filteringRadius->value());
408 settings.setValue(
"filtering_min_neighbors",
_ui->spinBox_filteringMinNeighbors->value());
410 settings.setValue(
"assemble",
_ui->checkBox_assemble->isChecked());
411 settings.setValue(
"assemble_voxel",
_ui->doubleSpinBox_voxelSize_assembled->value());
412 settings.setValue(
"assemble_samples",
_ui->spinBox_randomSamples_assembled->value());
413 settings.setValue(
"frame",
_ui->comboBox_frame->currentIndex());
415 settings.setValue(
"subtract",
_ui->checkBox_subtraction->isChecked());
416 settings.setValue(
"subtract_point_radius",
_ui->doubleSpinBox_subtractPointFilteringRadius->value());
417 settings.setValue(
"subtract_point_angle",
_ui->doubleSpinBox_subtractPointFilteringAngle->value());
418 settings.setValue(
"subtract_min_neighbors",
_ui->spinBox_subtractFilteringMinPts->value());
420 settings.setValue(
"mls",
_ui->checkBox_smoothing->isChecked());
421 settings.setValue(
"mls_radius",
_ui->doubleSpinBox_mlsRadius->value());
422 settings.setValue(
"mls_polygonial_order",
_ui->spinBox_polygonialOrder->value());
423 settings.setValue(
"mls_upsampling_method",
_ui->comboBox_upsamplingMethod->currentIndex());
424 settings.setValue(
"mls_upsampling_radius",
_ui->doubleSpinBox_sampleRadius->value());
425 settings.setValue(
"mls_upsampling_step",
_ui->doubleSpinBox_sampleStep->value());
426 settings.setValue(
"mls_point_density",
_ui->spinBox_randomPoints->value());
427 settings.setValue(
"mls_dilation_voxel_size",
_ui->doubleSpinBox_dilationVoxelSize->value());
428 settings.setValue(
"mls_dilation_iterations",
_ui->spinBox_dilationSteps->value());
429 settings.setValue(
"mls_output_voxel_size",
_ui->doubleSpinBox_mls_outputVoxelSize->value());
431 settings.setValue(
"gain",
_ui->checkBox_gainCompensation->isChecked());
432 settings.setValue(
"gain_radius",
_ui->doubleSpinBox_gainRadius->value());
433 settings.setValue(
"gain_overlap",
_ui->doubleSpinBox_gainOverlap->value());
434 settings.setValue(
"gain_beta",
_ui->doubleSpinBox_gainBeta->value());
435 settings.setValue(
"gain_rgb",
_ui->checkBox_gainRGB->isChecked());
436 settings.setValue(
"gain_full",
_ui->checkBox_gainFull->isChecked());
438 settings.setValue(
"cam_proj",
_ui->checkBox_cameraProjection->isChecked());
439 settings.setValue(
"cam_proj_roi_ratios",
_ui->lineEdit_camProjRoiRatios->text());
440 settings.setValue(
"cam_proj_mask",
_ui->lineEdit_camProjMaskFilePath->text());
441 settings.setValue(
"cam_proj_decimation",
_ui->spinBox_camProjDecimation->value());
442 settings.setValue(
"cam_proj_max_distance",
_ui->doubleSpinBox_camProjMaxDistance->value());
443 settings.setValue(
"cam_proj_max_angle",
_ui->doubleSpinBox_camProjMaxAngle->value());
444 settings.setValue(
"cam_proj_distance_policy",
_ui->checkBox_camProjDistanceToCamPolicy->isChecked());
445 settings.setValue(
"cam_proj_keep_points",
_ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked());
446 settings.setValue(
"cam_proj_recolor_points",
_ui->checkBox_camProjRecolorPoints->isChecked());
447 settings.setValue(
"cam_proj_export_format",
_ui->comboBox_camProjExportCamera->currentIndex());
449 settings.setValue(
"mesh",
_ui->checkBox_meshing->isChecked());
450 settings.setValue(
"mesh_radius",
_ui->doubleSpinBox_gp3Radius->value());
451 settings.setValue(
"mesh_mu",
_ui->doubleSpinBox_gp3Mu->value());
452 settings.setValue(
"mesh_decimation_factor",
_ui->doubleSpinBox_meshDecimationFactor->value());
453 settings.setValue(
"mesh_max_polygons",
_ui->spinBox_meshMaxPolygons->value());
454 settings.setValue(
"mesh_color_radius",
_ui->doubleSpinBox_transferColorRadius->value());
455 settings.setValue(
"mesh_clean",
_ui->checkBox_cleanMesh->isChecked());
456 settings.setValue(
"mesh_min_cluster_size",
_ui->spinBox_mesh_minClusterSize->value());
458 settings.setValue(
"mesh_dense_strategy",
_ui->comboBox_meshingApproach->currentIndex());
460 settings.setValue(
"mesh_texture",
_ui->checkBox_textureMapping->isChecked());
461 settings.setValue(
"mesh_textureFormat",
_ui->comboBox_meshingTextureFormat->currentIndex());
462 settings.setValue(
"mesh_textureSize",
_ui->comboBox_meshingTextureSize->currentIndex());
463 settings.setValue(
"mesh_textureMaxCount",
_ui->spinBox_mesh_maxTextures->value());
464 settings.setValue(
"mesh_textureMaxDistance",
_ui->doubleSpinBox_meshingTextureMaxDistance->value());
465 settings.setValue(
"mesh_textureMaxDepthError",
_ui->doubleSpinBox_meshingTextureMaxDepthError->value());
466 settings.setValue(
"mesh_textureMaxAngle",
_ui->doubleSpinBox_meshingTextureMaxAngle->value());
467 settings.setValue(
"mesh_textureMinCluster",
_ui->spinBox_mesh_minTextureClusterSize->value());
468 settings.setValue(
"mesh_textureRoiRatios",
_ui->lineEdit_meshingTextureRoiRatios->text());
469 settings.setValue(
"mesh_textureDistanceToCamPolicy",
_ui->checkBox_distanceToCamPolicy->isChecked());
470 settings.setValue(
"mesh_textureCameraFiltering",
_ui->checkBox_cameraFilter->isChecked());
471 settings.setValue(
"mesh_textureCameraFilteringRadius",
_ui->doubleSpinBox_cameraFilterRadius->value());
472 settings.setValue(
"mesh_textureCameraFilteringAngle",
_ui->doubleSpinBox_cameraFilterAngle->value());
473 settings.setValue(
"mesh_textureCameraFilteringVel",
_ui->doubleSpinBox_cameraFilterVel->value());
474 settings.setValue(
"mesh_textureCameraFilteringVelRad",
_ui->doubleSpinBox_cameraFilterVelRad->value());
475 settings.setValue(
"mesh_textureCameraFilteringLaplacian",
_ui->doubleSpinBox_laplacianVariance->value());
476 settings.setValue(
"mesh_textureBrightnessConstrastRatioLow",
_ui->spinBox_textureBrightnessContrastRatioLow->value());
477 settings.setValue(
"mesh_textureBrightnessConstrastRatioHigh",
_ui->spinBox_textureBrightnessContrastRatioHigh->value());
478 settings.setValue(
"mesh_textureExposureFusion",
_ui->checkBox_exposureFusion->isChecked());
479 settings.setValue(
"mesh_textureBlending",
_ui->checkBox_blending->isChecked());
480 settings.setValue(
"mesh_textureBlendingDecimation",
_ui->comboBox_blendingDecimation->currentIndex());
481 settings.setValue(
"mesh_textureMultiband",
_ui->checkBox_multiband->isChecked());
482 settings.setValue(
"mesh_textureMultibandDownScale",
_ui->spinBox_multiband_downscale->value());
483 settings.setValue(
"mesh_textureMultibandNbContrib",
_ui->lineEdit_multiband_nbcontrib->text());
484 settings.setValue(
"mesh_textureMultibandUnwrap",
_ui->comboBox_multiband_unwrap->currentIndex());
485 settings.setValue(
"mesh_textureMultibandFillHoles",
_ui->checkBox_multiband_fillholes->isChecked());
486 settings.setValue(
"mesh_textureMultibandPadding",
_ui->spinBox_multiband_padding->value());
487 settings.setValue(
"mesh_textureMultibandBestScoreThr",
_ui->doubleSpinBox_multiband_bestscore->value());
488 settings.setValue(
"mesh_textureMultibandAngleHardThr",
_ui->doubleSpinBox_multiband_angle->value());
489 settings.setValue(
"mesh_textureMultibandForceVisible",
_ui->checkBox_multiband_forcevisible->isChecked());
492 settings.setValue(
"mesh_angle_tolerance",
_ui->doubleSpinBox_mesh_angleTolerance->value());
493 settings.setValue(
"mesh_quad",
_ui->checkBox_mesh_quad->isChecked());
494 settings.setValue(
"mesh_triangle_size",
_ui->spinBox_mesh_triangleSize->value());
496 settings.setValue(
"poisson_outputPolygons",
_ui->checkBox_poisson_outputPolygons->isChecked());
497 settings.setValue(
"poisson_manifold",
_ui->checkBox_poisson_manifold->isChecked());
498 settings.setValue(
"poisson_depth",
_ui->spinBox_poisson_depth->value());
499 settings.setValue(
"poisson_polygon_size",
_ui->doubleSpinBox_poisson_targetPolygonSize->value());
500 settings.setValue(
"poisson_iso",
_ui->spinBox_poisson_iso->value());
501 settings.setValue(
"poisson_solver",
_ui->spinBox_poisson_solver->value());
502 settings.setValue(
"poisson_minDepth",
_ui->spinBox_poisson_minDepth->value());
503 settings.setValue(
"poisson_samples",
_ui->doubleSpinBox_poisson_samples->value());
504 settings.setValue(
"poisson_pointWeight",
_ui->doubleSpinBox_poisson_pointWeight->value());
505 settings.setValue(
"poisson_scale",
_ui->doubleSpinBox_poisson_scale->value());
507 settings.setValue(
"cputsdf_size",
_ui->doubleSpinBox_cputsdf_size->value());
508 settings.setValue(
"cputsdf_resolution",
_ui->doubleSpinBox_cputsdf_resolution->value());
509 settings.setValue(
"cputsdf_truncPos",
_ui->doubleSpinBox_cputsdf_tuncPos->value());
510 settings.setValue(
"cputsdf_truncNeg",
_ui->doubleSpinBox_cputsdf_tuncNeg->value());
511 settings.setValue(
"cputsdf_minWeight",
_ui->doubleSpinBox_cputsdf_minWeight->value());
512 settings.setValue(
"cputsdf_flattenRadius",
_ui->doubleSpinBox_cputsdf_flattenRadius->value());
513 settings.setValue(
"cputsdf_randomSplit",
_ui->spinBox_cputsdf_randomSplit->value());
515 settings.setValue(
"openchisel_merge_vertices",
_ui->checkBox_openchisel_mergeVertices->isChecked());
516 settings.setValue(
"openchisel_chunk_size_x",
_ui->spinBox_openchisel_chunk_size_x->value());
517 settings.setValue(
"openchisel_chunk_size_y",
_ui->spinBox_openchisel_chunk_size_y->value());
518 settings.setValue(
"openchisel_chunk_size_z",
_ui->spinBox_openchisel_chunk_size_z->value());
519 settings.setValue(
"openchisel_truncation_constant",
_ui->doubleSpinBox_openchisel_truncation_constant->value());
520 settings.setValue(
"openchisel_truncation_linear",
_ui->doubleSpinBox_openchisel_truncation_linear->value());
521 settings.setValue(
"openchisel_truncation_quadratic",
_ui->doubleSpinBox_openchisel_truncation_quadratic->value());
522 settings.setValue(
"openchisel_truncation_scale",
_ui->doubleSpinBox_openchisel_truncation_scale->value());
523 settings.setValue(
"openchisel_integration_weight",
_ui->spinBox_openchisel_integration_weight->value());
524 settings.setValue(
"openchisel_use_voxel_carving",
_ui->checkBox_openchisel_use_voxel_carving->isChecked());
525 settings.setValue(
"openchisel_carving_dist_m",
_ui->doubleSpinBox_openchisel_carving_dist_m->value());
526 settings.setValue(
"openchisel_near_plane_dist",
_ui->doubleSpinBox_openchisel_near_plane_dist->value());
527 settings.setValue(
"openchisel_far_plane_dist",
_ui->doubleSpinBox_openchisel_far_plane_dist->value());
539 settings.beginGroup(group);
542 _ui->comboBox_pipeline->setCurrentIndex(settings.value(
"pipeline",
_ui->comboBox_pipeline->currentIndex()).toInt());
543 _ui->checkBox_fromDepth->setChecked(settings.value(
"from_depth",
_ui->checkBox_fromDepth->isChecked()).toBool());
544 _ui->checkBox_binary->setChecked(settings.value(
"binary",
_ui->checkBox_binary->isChecked()).toBool());
545 _ui->spinBox_normalKSearch->setValue(settings.value(
"normals_k",
_ui->spinBox_normalKSearch->value()).toInt());
546 _ui->doubleSpinBox_normalRadiusSearch->setValue(settings.value(
"normals_radius",
_ui->doubleSpinBox_normalRadiusSearch->value()).toDouble());
547 _ui->doubleSpinBox_groundNormalsUp->setValue(settings.value(
"normals_ground_normals_up",
_ui->doubleSpinBox_groundNormalsUp->value()).toDouble());
548 _ui->comboBox_intensityColormap->setCurrentIndex(settings.value(
"intensity_colormap",
_ui->comboBox_intensityColormap->currentIndex()).toInt());
550 _ui->checkBox_nodes_filtering->setChecked(settings.value(
"nodes_filtering",
_ui->checkBox_nodes_filtering->isChecked()).toBool());
551 _ui->doubleSpinBox_nodes_filtering_xmin->setValue(settings.value(
"nodes_filtering_xmin",
_ui->doubleSpinBox_nodes_filtering_xmin->value()).toInt());
552 _ui->doubleSpinBox_nodes_filtering_xmax->setValue(settings.value(
"nodes_filtering_xmax",
_ui->doubleSpinBox_nodes_filtering_xmax->value()).toInt());
553 _ui->doubleSpinBox_nodes_filtering_ymin->setValue(settings.value(
"nodes_filtering_ymin",
_ui->doubleSpinBox_nodes_filtering_ymin->value()).toInt());
554 _ui->doubleSpinBox_nodes_filtering_ymax->setValue(settings.value(
"nodes_filtering_ymax",
_ui->doubleSpinBox_nodes_filtering_ymax->value()).toInt());
555 _ui->doubleSpinBox_nodes_filtering_zmin->setValue(settings.value(
"nodes_filtering_zmin",
_ui->doubleSpinBox_nodes_filtering_zmin->value()).toInt());
556 _ui->doubleSpinBox_nodes_filtering_zmax->setValue(settings.value(
"nodes_filtering_zmax",
_ui->doubleSpinBox_nodes_filtering_zmax->value()).toInt());
558 _ui->checkBox_regenerate->setChecked(settings.value(
"regenerate",
_ui->checkBox_regenerate->isChecked()).toBool());
559 _ui->spinBox_decimation->setValue(settings.value(
"regenerate_decimation",
_ui->spinBox_decimation->value()).toInt());
560 _ui->doubleSpinBox_maxDepth->setValue(settings.value(
"regenerate_max_depth",
_ui->doubleSpinBox_maxDepth->value()).toDouble());
561 _ui->doubleSpinBox_minDepth->setValue(settings.value(
"regenerate_min_depth",
_ui->doubleSpinBox_minDepth->value()).toDouble());
562 _ui->doubleSpinBox_ceilingHeight->setValue(settings.value(
"regenerate_ceiling",
_ui->doubleSpinBox_ceilingHeight->value()).toDouble());
563 _ui->doubleSpinBox_floorHeight->setValue(settings.value(
"regenerate_floor",
_ui->doubleSpinBox_floorHeight->value()).toDouble());
564 _ui->groupBox_offAxisFiltering->setChecked(settings.value(
"regenerate_offaxis_filtering",
_ui->groupBox_offAxisFiltering->isChecked()).toBool());
565 _ui->doubleSpinBox_offAxisFilteringAngle->setValue(settings.value(
"regenerate_offaxis_filtering_angle",
_ui->doubleSpinBox_offAxisFilteringAngle->value()).toDouble());
566 _ui->checkBox_offAxisFilteringPosX->setChecked(settings.value(
"regenerate_offaxis_filtering_pos_x",
_ui->checkBox_offAxisFilteringPosX->isChecked()).toBool());
567 _ui->checkBox_offAxisFilteringNegX->setChecked(settings.value(
"regenerate_offaxis_filtering_neg_x",
_ui->checkBox_offAxisFilteringNegX->isChecked()).toBool());
568 _ui->checkBox_offAxisFilteringPosY->setChecked(settings.value(
"regenerate_offaxis_filtering_pos_y",
_ui->checkBox_offAxisFilteringPosY->isChecked()).toBool());
569 _ui->checkBox_offAxisFilteringNegY->setChecked(settings.value(
"regenerate_offaxis_filtering_neg_y",
_ui->checkBox_offAxisFilteringNegY->isChecked()).toBool());
570 _ui->checkBox_offAxisFilteringPosZ->setChecked(settings.value(
"regenerate_offaxis_filtering_pos_z",
_ui->checkBox_offAxisFilteringPosZ->isChecked()).toBool());
571 _ui->checkBox_offAxisFilteringNegZ->setChecked(settings.value(
"regenerate_offaxis_filtering_neg_z",
_ui->checkBox_offAxisFilteringNegZ->isChecked()).toBool());
572 _ui->doubleSpinBox_footprintHeight->setValue(settings.value(
"regenerate_footprint_height",
_ui->doubleSpinBox_footprintHeight->value()).toDouble());
573 _ui->doubleSpinBox_footprintWidth->setValue(settings.value(
"regenerate_footprint_width",
_ui->doubleSpinBox_footprintWidth->value()).toDouble());
574 _ui->doubleSpinBox_footprintLength->setValue(settings.value(
"regenerate_footprint_length",
_ui->doubleSpinBox_footprintLength->value()).toDouble());
575 _ui->spinBox_decimation_scan->setValue(settings.value(
"regenerate_scan_decimation",
_ui->spinBox_decimation_scan->value()).toInt());
576 _ui->doubleSpinBox_rangeMax->setValue(settings.value(
"regenerate_scan_max_range",
_ui->doubleSpinBox_rangeMax->value()).toDouble());
577 _ui->doubleSpinBox_rangeMin->setValue(settings.value(
"regenerate_scan_min_range",
_ui->doubleSpinBox_rangeMin->value()).toDouble());
578 _ui->spinBox_fillDepthHoles->setValue(settings.value(
"regenerate_fill_size",
_ui->spinBox_fillDepthHoles->value()).toInt());
579 _ui->spinBox_fillDepthHolesError->setValue(settings.value(
"regenerate_fill_error",
_ui->spinBox_fillDepthHolesError->value()).toInt());
580 _ui->lineEdit_roiRatios->setText(settings.value(
"regenerate_roi",
_ui->lineEdit_roiRatios->text()).toString());
581 _ui->lineEdit_distortionModel->setText(settings.value(
"regenerate_distortion_model",
_ui->lineEdit_distortionModel->text()).toString());
583 _ui->checkBox_bilateral->setChecked(settings.value(
"bilateral",
_ui->checkBox_bilateral->isChecked()).toBool());
584 _ui->doubleSpinBox_bilateral_sigmaS->setValue(settings.value(
"bilateral_sigma_s",
_ui->doubleSpinBox_bilateral_sigmaS->value()).toDouble());
585 _ui->doubleSpinBox_bilateral_sigmaR->setValue(settings.value(
"bilateral_sigma_r",
_ui->doubleSpinBox_bilateral_sigmaR->value()).toDouble());
587 _ui->checkBox_filtering->setChecked(settings.value(
"filtering",
_ui->checkBox_filtering->isChecked()).toBool());
588 _ui->doubleSpinBox_filteringRadius->setValue(settings.value(
"filtering_radius",
_ui->doubleSpinBox_filteringRadius->value()).toDouble());
589 _ui->spinBox_filteringMinNeighbors->setValue(settings.value(
"filtering_min_neighbors",
_ui->spinBox_filteringMinNeighbors->value()).toInt());
591 if(
_ui->checkBox_assemble->isEnabled())
593 _ui->checkBox_assemble->setChecked(settings.value(
"assemble",
_ui->checkBox_assemble->isChecked()).toBool());
595 _ui->doubleSpinBox_voxelSize_assembled->setValue(settings.value(
"assemble_voxel",
_ui->doubleSpinBox_voxelSize_assembled->value()).toDouble());
596 _ui->spinBox_randomSamples_assembled->setValue(settings.value(
"assemble_samples",
_ui->spinBox_randomSamples_assembled->value()).toInt());
597 _ui->comboBox_frame->setCurrentIndex(settings.value(
"frame",
_ui->comboBox_frame->currentIndex()).toInt());
599 _ui->checkBox_subtraction->setChecked(settings.value(
"subtract",
_ui->checkBox_subtraction->isChecked()).toBool());
600 _ui->doubleSpinBox_subtractPointFilteringRadius->setValue(settings.value(
"subtract_point_radius",
_ui->doubleSpinBox_subtractPointFilteringRadius->value()).toDouble());
601 _ui->doubleSpinBox_subtractPointFilteringAngle->setValue(settings.value(
"subtract_point_angle",
_ui->doubleSpinBox_subtractPointFilteringAngle->value()).toDouble());
602 _ui->spinBox_subtractFilteringMinPts->setValue(settings.value(
"subtract_min_neighbors",
_ui->spinBox_subtractFilteringMinPts->value()).toInt());
604 _ui->checkBox_smoothing->setChecked(settings.value(
"mls",
_ui->checkBox_smoothing->isChecked()).toBool());
605 _ui->doubleSpinBox_mlsRadius->setValue(settings.value(
"mls_radius",
_ui->doubleSpinBox_mlsRadius->value()).toDouble());
606 _ui->spinBox_polygonialOrder->setValue(settings.value(
"mls_polygonial_order",
_ui->spinBox_polygonialOrder->value()).toInt());
607 _ui->comboBox_upsamplingMethod->setCurrentIndex(settings.value(
"mls_upsampling_method",
_ui->comboBox_upsamplingMethod->currentIndex()).toInt());
608 _ui->doubleSpinBox_sampleRadius->setValue(settings.value(
"mls_upsampling_radius",
_ui->doubleSpinBox_sampleRadius->value()).toDouble());
609 _ui->doubleSpinBox_sampleStep->setValue(settings.value(
"mls_upsampling_step",
_ui->doubleSpinBox_sampleStep->value()).toDouble());
610 _ui->spinBox_randomPoints->setValue(settings.value(
"mls_point_density",
_ui->spinBox_randomPoints->value()).toInt());
611 _ui->doubleSpinBox_dilationVoxelSize->setValue(settings.value(
"mls_dilation_voxel_size",
_ui->doubleSpinBox_dilationVoxelSize->value()).toDouble());
612 _ui->spinBox_dilationSteps->setValue(settings.value(
"mls_dilation_iterations",
_ui->spinBox_dilationSteps->value()).toInt());
613 _ui->doubleSpinBox_mls_outputVoxelSize->setValue(settings.value(
"mls_output_voxel_size",
_ui->doubleSpinBox_mls_outputVoxelSize->value()).toInt());
615 _ui->checkBox_gainCompensation->setChecked(settings.value(
"gain",
_ui->checkBox_gainCompensation->isChecked()).toBool());
616 _ui->doubleSpinBox_gainRadius->setValue(settings.value(
"gain_radius",
_ui->doubleSpinBox_gainRadius->value()).toDouble());
617 _ui->doubleSpinBox_gainOverlap->setValue(settings.value(
"gain_overlap",
_ui->doubleSpinBox_gainOverlap->value()).toDouble());
618 _ui->doubleSpinBox_gainBeta->setValue(settings.value(
"gain_beta",
_ui->doubleSpinBox_gainBeta->value()).toDouble());
619 _ui->checkBox_gainRGB->setChecked(settings.value(
"gain_rgb",
_ui->checkBox_gainRGB->isChecked()).toBool());
620 _ui->checkBox_gainFull->setChecked(settings.value(
"gain_full",
_ui->checkBox_gainFull->isChecked()).toBool());
622 _ui->checkBox_cameraProjection->setChecked(settings.value(
"cam_proj",
_ui->checkBox_cameraProjection->isChecked()).toBool());
623 _ui->lineEdit_camProjRoiRatios->setText(settings.value(
"cam_proj_roi_ratios",
_ui->lineEdit_camProjRoiRatios->text()).toString());
624 _ui->lineEdit_camProjMaskFilePath->setText(settings.value(
"cam_proj_mask",
_ui->lineEdit_camProjMaskFilePath->text()).toString());
625 _ui->spinBox_camProjDecimation->setValue(settings.value(
"cam_proj_decimation",
_ui->spinBox_camProjDecimation->value()).toInt());
626 _ui->doubleSpinBox_camProjMaxDistance->setValue(settings.value(
"cam_proj_max_distance",
_ui->doubleSpinBox_camProjMaxDistance->value()).toDouble());
627 _ui->doubleSpinBox_camProjMaxAngle->setValue(settings.value(
"cam_proj_max_angle",
_ui->doubleSpinBox_camProjMaxAngle->value()).toDouble());
628 _ui->checkBox_camProjDistanceToCamPolicy->setChecked(settings.value(
"cam_proj_distance_policy",
_ui->checkBox_camProjDistanceToCamPolicy->isChecked()).toBool());
629 _ui->checkBox_camProjKeepPointsNotSeenByCameras->setChecked(settings.value(
"cam_proj_keep_points",
_ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked()).toBool());
630 _ui->checkBox_camProjRecolorPoints->setChecked(settings.value(
"cam_proj_recolor_points",
_ui->checkBox_camProjRecolorPoints->isChecked()).toBool());
631 _ui->comboBox_camProjExportCamera->setCurrentIndex(settings.value(
"cam_proj_export_format",
_ui->comboBox_camProjExportCamera->currentIndex()).toInt());
633 _ui->checkBox_meshing->setChecked(settings.value(
"mesh",
_ui->checkBox_meshing->isChecked()).toBool());
634 _ui->doubleSpinBox_gp3Radius->setValue(settings.value(
"mesh_radius",
_ui->doubleSpinBox_gp3Radius->value()).toDouble());
635 _ui->doubleSpinBox_gp3Mu->setValue(settings.value(
"mesh_mu",
_ui->doubleSpinBox_gp3Mu->value()).toDouble());
636 _ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value(
"mesh_decimation_factor",
_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble());
637 _ui->spinBox_meshMaxPolygons->setValue(settings.value(
"mesh_max_polygons",
_ui->spinBox_meshMaxPolygons->value()).toDouble());
638 _ui->doubleSpinBox_transferColorRadius->setValue(settings.value(
"mesh_color_radius",
_ui->doubleSpinBox_transferColorRadius->value()).toDouble());
639 _ui->checkBox_cleanMesh->setChecked(settings.value(
"mesh_clean",
_ui->checkBox_cleanMesh->isChecked()).toBool());
640 _ui->spinBox_mesh_minClusterSize->setValue(settings.value(
"mesh_min_cluster_size",
_ui->spinBox_mesh_minClusterSize->value()).toInt());
642 _ui->comboBox_meshingApproach->setCurrentIndex(settings.value(
"mesh_dense_strategy",
_ui->comboBox_meshingApproach->currentIndex()).toInt());
644 _ui->checkBox_textureMapping->setChecked(settings.value(
"mesh_texture",
_ui->checkBox_textureMapping->isChecked()).toBool());
645 _ui->comboBox_meshingTextureFormat->setCurrentIndex(settings.value(
"mesh_textureFormat",
_ui->comboBox_meshingTextureFormat->currentIndex()).toInt());
646 _ui->comboBox_meshingTextureSize->setCurrentIndex(settings.value(
"mesh_textureSize",
_ui->comboBox_meshingTextureSize->currentIndex()).toInt());
647 _ui->spinBox_mesh_maxTextures->setValue(settings.value(
"mesh_textureMaxCount",
_ui->spinBox_mesh_maxTextures->value()).toInt());
648 _ui->doubleSpinBox_meshingTextureMaxDistance->setValue(settings.value(
"mesh_textureMaxDistance",
_ui->doubleSpinBox_meshingTextureMaxDistance->value()).toDouble());
649 _ui->doubleSpinBox_meshingTextureMaxDepthError->setValue(settings.value(
"mesh_textureMaxDepthError",
_ui->doubleSpinBox_meshingTextureMaxDepthError->value()).toDouble());
650 _ui->doubleSpinBox_meshingTextureMaxAngle->setValue(settings.value(
"mesh_textureMaxAngle",
_ui->doubleSpinBox_meshingTextureMaxAngle->value()).toDouble());
651 _ui->spinBox_mesh_minTextureClusterSize->setValue(settings.value(
"mesh_textureMinCluster",
_ui->spinBox_mesh_minTextureClusterSize->value()).toDouble());
652 _ui->lineEdit_meshingTextureRoiRatios->setText(settings.value(
"mesh_textureRoiRatios",
_ui->lineEdit_meshingTextureRoiRatios->text()).toString());
653 _ui->checkBox_distanceToCamPolicy->setChecked(settings.value(
"mesh_textureDistanceToCamPolicy",
_ui->checkBox_distanceToCamPolicy->isChecked()).toBool());
654 _ui->checkBox_cameraFilter->setChecked(settings.value(
"mesh_textureCameraFiltering",
_ui->checkBox_cameraFilter->isChecked()).toBool());
655 _ui->doubleSpinBox_cameraFilterRadius->setValue(settings.value(
"mesh_textureCameraFilteringRadius",
_ui->doubleSpinBox_cameraFilterRadius->value()).toDouble());
656 _ui->doubleSpinBox_cameraFilterAngle->setValue(settings.value(
"mesh_textureCameraFilteringAngle",
_ui->doubleSpinBox_cameraFilterAngle->value()).toDouble());
657 _ui->doubleSpinBox_cameraFilterVel->setValue(settings.value(
"mesh_textureCameraFilteringVel",
_ui->doubleSpinBox_cameraFilterVel->value()).toDouble());
658 _ui->doubleSpinBox_cameraFilterVelRad->setValue(settings.value(
"mesh_textureCameraFilteringVelRad",
_ui->doubleSpinBox_cameraFilterVelRad->value()).toDouble());
659 _ui->doubleSpinBox_laplacianVariance->setValue(settings.value(
"mesh_textureCameraFilteringLaplacian",
_ui->doubleSpinBox_laplacianVariance->value()).toDouble());
660 _ui->spinBox_textureBrightnessContrastRatioLow->setValue(settings.value(
"mesh_textureBrightnessConstrastRatioLow",
_ui->spinBox_textureBrightnessContrastRatioLow->value()).toDouble());
661 _ui->spinBox_textureBrightnessContrastRatioHigh->setValue(settings.value(
"mesh_textureBrightnessConstrastRatioHigh",
_ui->spinBox_textureBrightnessContrastRatioHigh->value()).toDouble());
662 if(
_ui->checkBox_exposureFusion->isEnabled())
664 _ui->checkBox_exposureFusion->setChecked(settings.value(
"mesh_textureExposureFusion",
_ui->checkBox_exposureFusion->isChecked()).toBool());
666 _ui->checkBox_blending->setChecked(settings.value(
"mesh_textureBlending",
_ui->checkBox_blending->isChecked()).toBool());
667 _ui->comboBox_blendingDecimation->setCurrentIndex(settings.value(
"mesh_textureBlendingDecimation",
_ui->comboBox_blendingDecimation->currentIndex()).toInt());
668 _ui->checkBox_multiband->setChecked(settings.value(
"mesh_textureMultiband",
_ui->checkBox_multiband->isChecked()).toBool());
669 _ui->spinBox_multiband_downscale->setValue(settings.value(
"mesh_textureMultibandDownScale",
_ui->spinBox_multiband_downscale->value()).toInt());
670 _ui->lineEdit_multiband_nbcontrib->setText(settings.value(
"mesh_textureMultibandNbContrib",
_ui->lineEdit_multiband_nbcontrib->text()).toString());
671 _ui->comboBox_multiband_unwrap->setCurrentIndex(settings.value(
"mesh_textureMultibandUnwrap",
_ui->comboBox_multiband_unwrap->currentIndex()).toInt());
672 _ui->checkBox_multiband_fillholes->setChecked(settings.value(
"mesh_textureMultibandFillHoles",
_ui->checkBox_multiband_fillholes->isChecked()).toBool());
673 _ui->spinBox_multiband_padding->setValue(settings.value(
"mesh_textureMultibandPadding",
_ui->spinBox_multiband_padding->value()).toInt());
674 _ui->doubleSpinBox_multiband_bestscore->setValue(settings.value(
"mesh_textureMultibandBestScoreThr",
_ui->doubleSpinBox_multiband_bestscore->value()).toDouble());
675 _ui->doubleSpinBox_multiband_angle->setValue(settings.value(
"mesh_textureMultibandAngleHardThr",
_ui->doubleSpinBox_multiband_angle->value()).toDouble());
676 _ui->checkBox_multiband_forcevisible->setChecked(settings.value(
"mesh_textureMultibandForceVisible",
_ui->checkBox_multiband_forcevisible->isChecked()).toBool());
678 _ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value(
"mesh_angle_tolerance",
_ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble());
679 _ui->checkBox_mesh_quad->setChecked(settings.value(
"mesh_quad",
_ui->checkBox_mesh_quad->isChecked()).toBool());
680 _ui->spinBox_mesh_triangleSize->setValue(settings.value(
"mesh_triangle_size",
_ui->spinBox_mesh_triangleSize->value()).toInt());
682 _ui->checkBox_poisson_outputPolygons->setChecked(settings.value(
"poisson_outputPolygons",
_ui->checkBox_poisson_outputPolygons->isChecked()).toBool());
683 _ui->checkBox_poisson_manifold->setChecked(settings.value(
"poisson_manifold",
_ui->checkBox_poisson_manifold->isChecked()).toBool());
684 _ui->spinBox_poisson_depth->setValue(settings.value(
"poisson_depth",
_ui->spinBox_poisson_depth->value()).toInt());
685 _ui->doubleSpinBox_poisson_targetPolygonSize->setValue(settings.value(
"poisson_polygon_size",
_ui->doubleSpinBox_poisson_targetPolygonSize->value()).toDouble());
686 _ui->spinBox_poisson_iso->setValue(settings.value(
"poisson_iso",
_ui->spinBox_poisson_iso->value()).toInt());
687 _ui->spinBox_poisson_solver->setValue(settings.value(
"poisson_solver",
_ui->spinBox_poisson_solver->value()).toInt());
688 _ui->spinBox_poisson_minDepth->setValue(settings.value(
"poisson_minDepth",
_ui->spinBox_poisson_minDepth->value()).toInt());
689 _ui->doubleSpinBox_poisson_samples->setValue(settings.value(
"poisson_samples",
_ui->doubleSpinBox_poisson_samples->value()).toDouble());
690 _ui->doubleSpinBox_poisson_pointWeight->setValue(settings.value(
"poisson_pointWeight",
_ui->doubleSpinBox_poisson_pointWeight->value()).toDouble());
691 _ui->doubleSpinBox_poisson_scale->setValue(settings.value(
"poisson_scale",
_ui->doubleSpinBox_poisson_scale->value()).toDouble());
693 _ui->doubleSpinBox_cputsdf_size->setValue(settings.value(
"cputsdf_size",
_ui->doubleSpinBox_cputsdf_size->value()).toDouble());
694 _ui->doubleSpinBox_cputsdf_resolution->setValue(settings.value(
"cputsdf_resolution",
_ui->doubleSpinBox_cputsdf_resolution->value()).toDouble());
695 _ui->doubleSpinBox_cputsdf_tuncPos->setValue(settings.value(
"cputsdf_truncPos",
_ui->doubleSpinBox_cputsdf_tuncPos->value()).toDouble());
696 _ui->doubleSpinBox_cputsdf_tuncNeg->setValue(settings.value(
"cputsdf_truncNeg",
_ui->doubleSpinBox_cputsdf_tuncNeg->value()).toDouble());
697 _ui->doubleSpinBox_cputsdf_minWeight->setValue(settings.value(
"cputsdf_minWeight",
_ui->doubleSpinBox_cputsdf_minWeight->value()).toDouble());
698 _ui->doubleSpinBox_cputsdf_flattenRadius->setValue(settings.value(
"cputsdf_flattenRadius",
_ui->doubleSpinBox_cputsdf_flattenRadius->value()).toDouble());
699 _ui->spinBox_cputsdf_randomSplit->setValue(settings.value(
"cputsdf_randomSplit",
_ui->spinBox_cputsdf_randomSplit->value()).toInt());
701 _ui->checkBox_openchisel_mergeVertices->setChecked(settings.value(
"openchisel_merge_vertices",
_ui->checkBox_openchisel_mergeVertices->isChecked()).toBool());
702 _ui->spinBox_openchisel_chunk_size_x->setValue(settings.value(
"openchisel_chunk_size_x",
_ui->spinBox_openchisel_chunk_size_x->value()).toInt());
703 _ui->spinBox_openchisel_chunk_size_y->setValue(settings.value(
"openchisel_chunk_size_y",
_ui->spinBox_openchisel_chunk_size_y->value()).toInt());
704 _ui->spinBox_openchisel_chunk_size_z->setValue(settings.value(
"openchisel_chunk_size_z",
_ui->spinBox_openchisel_chunk_size_z->value()).toInt());
705 _ui->doubleSpinBox_openchisel_truncation_constant->setValue(settings.value(
"openchisel_truncation_constant",
_ui->doubleSpinBox_openchisel_truncation_constant->value()).toDouble());
706 _ui->doubleSpinBox_openchisel_truncation_linear->setValue(settings.value(
"openchisel_truncation_linear",
_ui->doubleSpinBox_openchisel_truncation_linear->value()).toDouble());
707 _ui->doubleSpinBox_openchisel_truncation_quadratic->setValue(settings.value(
"openchisel_truncation_quadratic",
_ui->doubleSpinBox_openchisel_truncation_quadratic->value()).toDouble());
708 _ui->doubleSpinBox_openchisel_truncation_scale->setValue(settings.value(
"openchisel_truncation_scale",
_ui->doubleSpinBox_openchisel_truncation_scale->value()).toDouble());
709 _ui->spinBox_openchisel_integration_weight->setValue(settings.value(
"openchisel_integration_weight",
_ui->spinBox_openchisel_integration_weight->value()).toInt());
710 _ui->checkBox_openchisel_use_voxel_carving->setChecked(settings.value(
"openchisel_use_voxel_carving",
_ui->checkBox_openchisel_use_voxel_carving->isChecked()).toBool());
711 _ui->doubleSpinBox_openchisel_carving_dist_m->setValue(settings.value(
"openchisel_carving_dist_m",
_ui->doubleSpinBox_openchisel_carving_dist_m->value()).toDouble());
712 _ui->doubleSpinBox_openchisel_near_plane_dist->setValue(settings.value(
"openchisel_near_plane_dist",
_ui->doubleSpinBox_openchisel_near_plane_dist->value()).toDouble());
713 _ui->doubleSpinBox_openchisel_far_plane_dist->setValue(settings.value(
"openchisel_far_plane_dist",
_ui->doubleSpinBox_openchisel_far_plane_dist->value()).toDouble());
726 _ui->comboBox_pipeline->setCurrentIndex(1);
727 _ui->checkBox_fromDepth->setChecked(
true);
728 _ui->checkBox_binary->setChecked(
true);
729 _ui->spinBox_normalKSearch->setValue(20);
730 _ui->doubleSpinBox_normalRadiusSearch->setValue(0.0);
731 _ui->doubleSpinBox_groundNormalsUp->setValue(0.0);
732 _ui->comboBox_intensityColormap->setCurrentIndex(0);
734 _ui->checkBox_nodes_filtering->setChecked(
false);
735 _ui->doubleSpinBox_nodes_filtering_xmin->setValue(0);
736 _ui->doubleSpinBox_nodes_filtering_xmax->setValue(0);
737 _ui->doubleSpinBox_nodes_filtering_ymin->setValue(0);
738 _ui->doubleSpinBox_nodes_filtering_ymax->setValue(0);
739 _ui->doubleSpinBox_nodes_filtering_zmin->setValue(0);
740 _ui->doubleSpinBox_nodes_filtering_zmax->setValue(0);
742 _ui->checkBox_regenerate->setChecked(
_dbDriver!=0?
true:
false);
743 _ui->spinBox_decimation->setValue(1);
744 _ui->doubleSpinBox_maxDepth->setValue(4);
745 _ui->doubleSpinBox_minDepth->setValue(0);
746 _ui->doubleSpinBox_ceilingHeight->setValue(0);
747 _ui->doubleSpinBox_floorHeight->setValue(0);
748 _ui->groupBox_offAxisFiltering->setChecked(
false);
749 _ui->doubleSpinBox_offAxisFilteringAngle->setValue(10);
750 _ui->checkBox_offAxisFilteringPosX->setChecked(
true);
751 _ui->checkBox_offAxisFilteringNegX->setChecked(
true);
752 _ui->checkBox_offAxisFilteringPosY->setChecked(
true);
753 _ui->checkBox_offAxisFilteringNegY->setChecked(
true);
754 _ui->checkBox_offAxisFilteringPosZ->setChecked(
true);
755 _ui->checkBox_offAxisFilteringNegZ->setChecked(
true);
756 _ui->doubleSpinBox_footprintHeight->setValue(0);
757 _ui->doubleSpinBox_footprintLength->setValue(0);
758 _ui->doubleSpinBox_footprintWidth->setValue(0);
759 _ui->spinBox_decimation_scan->setValue(1);
760 _ui->doubleSpinBox_rangeMax->setValue(0);
761 _ui->doubleSpinBox_rangeMin->setValue(0);
762 _ui->spinBox_fillDepthHoles->setValue(0);
763 _ui->spinBox_fillDepthHolesError->setValue(2);
764 _ui->lineEdit_roiRatios->setText(
"0.0 0.0 0.0 0.0");
765 _ui->lineEdit_distortionModel->setText(
"");
767 _ui->checkBox_bilateral->setChecked(
false);
768 _ui->doubleSpinBox_bilateral_sigmaS->setValue(10.0);
769 _ui->doubleSpinBox_bilateral_sigmaR->setValue(0.1);
771 _ui->checkBox_filtering->setChecked(
false);
772 _ui->doubleSpinBox_filteringRadius->setValue(0.00);
773 _ui->spinBox_filteringMinNeighbors->setValue(5);
775 _ui->checkBox_assemble->setChecked(
true);
776 _ui->doubleSpinBox_voxelSize_assembled->setValue(0.01);
777 _ui->spinBox_randomSamples_assembled->setValue(0);
778 _ui->comboBox_frame->setCurrentIndex(0);
780 _ui->checkBox_subtraction->setChecked(
false);
781 _ui->doubleSpinBox_subtractPointFilteringRadius->setValue(0.02);
782 _ui->doubleSpinBox_subtractPointFilteringAngle->setValue(0);
783 _ui->spinBox_subtractFilteringMinPts->setValue(5);
785 _ui->checkBox_smoothing->setChecked(
false);
786 _ui->doubleSpinBox_mlsRadius->setValue(0.04);
787 _ui->spinBox_polygonialOrder->setValue(2);
788 _ui->comboBox_upsamplingMethod->setCurrentIndex(0);
789 _ui->doubleSpinBox_sampleRadius->setValue(0.01);
790 _ui->doubleSpinBox_sampleStep->setValue(0.005);
791 _ui->spinBox_randomPoints->setValue(10);
792 _ui->doubleSpinBox_dilationVoxelSize->setValue(0.005);
793 _ui->spinBox_dilationSteps->setValue(1);
794 _ui->doubleSpinBox_mls_outputVoxelSize->setValue(0);
796 _ui->checkBox_gainCompensation->setChecked(
false);
797 _ui->doubleSpinBox_gainRadius->setValue(0.02);
798 _ui->doubleSpinBox_gainOverlap->setValue(0.0);
799 _ui->doubleSpinBox_gainBeta->setValue(10);
800 _ui->checkBox_gainRGB->setChecked(
true);
801 _ui->checkBox_gainFull->setChecked(
false);
803 _ui->checkBox_cameraProjection->setChecked(
false);
804 _ui->lineEdit_camProjRoiRatios->setText(
"0.0 0.0 0.0 0.0");
805 _ui->lineEdit_camProjMaskFilePath->setText(
"");
806 _ui->spinBox_camProjDecimation->setValue(1);
807 _ui->doubleSpinBox_camProjMaxDistance->setValue(0);
808 _ui->doubleSpinBox_camProjMaxAngle->setValue(0);
809 _ui->checkBox_camProjDistanceToCamPolicy->setChecked(
true);
810 _ui->checkBox_camProjKeepPointsNotSeenByCameras->setChecked(
false);
811 _ui->checkBox_camProjRecolorPoints->setChecked(
true);
812 _ui->comboBox_camProjExportCamera->setCurrentIndex(0);
814 _ui->checkBox_meshing->setChecked(
false);
815 _ui->doubleSpinBox_gp3Radius->setValue(0.2);
816 _ui->doubleSpinBox_gp3Mu->setValue(2.5);
817 _ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
818 _ui->spinBox_meshMaxPolygons->setValue(0);
819 _ui->doubleSpinBox_transferColorRadius->setValue(0.025);
820 _ui->checkBox_cleanMesh->setChecked(
true);
821 _ui->spinBox_mesh_minClusterSize->setValue(0);
823 _ui->comboBox_meshingApproach->setCurrentIndex(1);
825 _ui->checkBox_textureMapping->setChecked(
false);
826 _ui->comboBox_meshingTextureFormat->setCurrentIndex(0);
827 _ui->comboBox_meshingTextureSize->setCurrentIndex(6);
828 _ui->spinBox_mesh_maxTextures->setValue(1);
829 _ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0);
830 _ui->doubleSpinBox_meshingTextureMaxDepthError->setValue(0.0);
831 _ui->doubleSpinBox_meshingTextureMaxAngle->setValue(0.0);
832 _ui->spinBox_mesh_minTextureClusterSize->setValue(50);
833 _ui->lineEdit_meshingTextureRoiRatios->setText(
"0.0 0.0 0.0 0.0");
834 _ui->checkBox_distanceToCamPolicy->setChecked(
false);
835 _ui->checkBox_cameraFilter->setChecked(
false);
836 _ui->doubleSpinBox_cameraFilterRadius->setValue(0);
837 _ui->doubleSpinBox_cameraFilterAngle->setValue(30);
838 _ui->doubleSpinBox_cameraFilterVel->setValue(0);
839 _ui->doubleSpinBox_cameraFilterVelRad->setValue(0);
840 _ui->doubleSpinBox_laplacianVariance->setValue(0);
841 _ui->spinBox_textureBrightnessContrastRatioLow->setValue(0);
842 _ui->spinBox_textureBrightnessContrastRatioHigh->setValue(5);
843 _ui->checkBox_exposureFusion->setChecked(
false);
844 _ui->checkBox_blending->setChecked(
true);
845 _ui->comboBox_blendingDecimation->setCurrentIndex(0);
846 _ui->checkBox_multiband->setChecked(
false);
847 _ui->spinBox_multiband_downscale->setValue(2);
848 _ui->lineEdit_multiband_nbcontrib->setText(
"1 5 10 0");
849 _ui->comboBox_multiband_unwrap->setCurrentIndex(0);
850 _ui->checkBox_multiband_fillholes->setChecked(
false);
851 _ui->spinBox_multiband_padding->setValue(5);
852 _ui->doubleSpinBox_multiband_bestscore->setValue(0.1);
853 _ui->doubleSpinBox_multiband_angle->setValue(90.0);
854 _ui->checkBox_multiband_forcevisible->setChecked(
false);
857 _ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0);
858 _ui->checkBox_mesh_quad->setChecked(
false);
859 _ui->spinBox_mesh_triangleSize->setValue(1);
861 _ui->checkBox_poisson_outputPolygons->setChecked(
false);
862 _ui->checkBox_poisson_manifold->setChecked(
true);
863 _ui->spinBox_poisson_depth->setValue(0);
864 _ui->doubleSpinBox_poisson_targetPolygonSize->setValue(0.03);
865 _ui->spinBox_poisson_iso->setValue(8);
866 _ui->spinBox_poisson_solver->setValue(8);
867 _ui->spinBox_poisson_minDepth->setValue(5);
868 _ui->doubleSpinBox_poisson_samples->setValue(1.0);
869 _ui->doubleSpinBox_poisson_pointWeight->setValue(4.0);
870 _ui->doubleSpinBox_poisson_scale->setValue(1.1);
872 _ui->doubleSpinBox_cputsdf_size->setValue(12.0);
873 _ui->doubleSpinBox_cputsdf_resolution->setValue(0.01);
874 _ui->doubleSpinBox_cputsdf_tuncPos->setValue(0.03);
875 _ui->doubleSpinBox_cputsdf_tuncNeg->setValue(0.03);
876 _ui->doubleSpinBox_cputsdf_minWeight->setValue(0);
877 _ui->doubleSpinBox_cputsdf_flattenRadius->setValue(0.005);
878 _ui->spinBox_cputsdf_randomSplit->setValue(1);
880 _ui->checkBox_openchisel_mergeVertices->setChecked(
true);
881 _ui->spinBox_openchisel_chunk_size_x->setValue(16);
882 _ui->spinBox_openchisel_chunk_size_y->setValue(16);
883 _ui->spinBox_openchisel_chunk_size_z->setValue(16);
884 _ui->doubleSpinBox_openchisel_truncation_constant->setValue(0.001504);
885 _ui->doubleSpinBox_openchisel_truncation_linear->setValue(0.00152);
886 _ui->doubleSpinBox_openchisel_truncation_quadratic->setValue(0.0019);
887 _ui->doubleSpinBox_openchisel_truncation_scale->setValue(10.0);
888 _ui->spinBox_openchisel_integration_weight->setValue(1);
889 _ui->checkBox_openchisel_use_voxel_carving->setChecked(
false);
890 _ui->doubleSpinBox_openchisel_carving_dist_m->setValue(0.05);
891 _ui->doubleSpinBox_openchisel_near_plane_dist->setValue(0.05);
892 _ui->doubleSpinBox_openchisel_far_plane_dist->setValue(1.1);
903 QString
path = QFileDialog::getOpenFileName(
this, tr(
"Load Settings"),
_workingDirectory, tr(
"Config (*.ini)"));
906 QSettings settings(
path, QSettings::IniFormat);
907 settings.beginGroup(
"Gui");
908 settings.beginGroup(this->objectName());
917 QString
path = QFileDialog::getSaveFileName(
this, tr(
"Save Settings"),
_workingDirectory, tr(
"Config (*.ini)"));
920 QSettings settings(
path, QSettings::IniFormat);
921 settings.beginGroup(
"Gui");
922 settings.beginGroup(this->objectName());
931 if(!
_ui->checkBox_fromDepth->isChecked())
933 _ui->comboBox_pipeline->setCurrentIndex(1);
934 _ui->comboBox_pipeline->setEnabled(
false);
935 _ui->comboBox_frame->setItemData(2, 0,Qt::UserRole - 1);
936 _ui->comboBox_frame->setItemData(3, 1|32,Qt::UserRole - 1);
937 if(
_ui->comboBox_frame->currentIndex() == 2)
939 _ui->comboBox_frame->setCurrentIndex(0);
944 _ui->comboBox_pipeline->setEnabled(
true);
945 _ui->comboBox_frame->setItemData(2, 1|32,Qt::UserRole - 1);
946 _ui->comboBox_frame->setItemData(3, 0,Qt::UserRole - 1);
947 if(
_ui->comboBox_frame->currentIndex() == 3)
949 _ui->comboBox_frame->setCurrentIndex(0);
952 _ui->comboBox_intensityColormap->setVisible(!
_ui->checkBox_fromDepth->isChecked() && !
_ui->checkBox_binary->isEnabled());
953 _ui->comboBox_intensityColormap->setEnabled(!
_ui->checkBox_fromDepth->isChecked() && !
_ui->checkBox_binary->isEnabled());
954 _ui->label_intensityColormap->setVisible(!
_ui->checkBox_fromDepth->isChecked() && !
_ui->checkBox_binary->isEnabled());
956 _ui->checkBox_smoothing->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1);
957 _ui->checkBox_smoothing->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
958 _ui->label_smoothing->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1);
960 _ui->comboBox_frame->setEnabled(!
_ui->checkBox_assemble->isChecked() &&
_ui->checkBox_binary->isEnabled());
961 _ui->comboBox_frame->setVisible(
_ui->comboBox_frame->isEnabled());
962 _ui->label_frame->setVisible(
_ui->comboBox_frame->isEnabled());
963 _ui->checkBox_gainCompensation->setEnabled(!(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex() == 2));
964 _ui->checkBox_gainCompensation->setVisible(
_ui->checkBox_gainCompensation->isEnabled());
965 _ui->label_gainCompensation->setVisible(
_ui->checkBox_gainCompensation->isEnabled());
967 _ui->checkBox_cameraProjection->setEnabled(
_ui->checkBox_assemble->isChecked() && !
_ui->checkBox_meshing->isChecked());
968 _ui->label_cameraProjection->setEnabled(
_ui->checkBox_cameraProjection->isEnabled());
970 _ui->groupBox_nodes_filtering->setVisible(
_ui->checkBox_nodes_filtering->isChecked());
971 _ui->groupBox_regenerate->setVisible(
_ui->checkBox_regenerate->isChecked() &&
_ui->checkBox_fromDepth->isChecked());
972 _ui->groupBox_regenerateScans->setVisible(
_ui->checkBox_regenerate->isChecked() && !
_ui->checkBox_fromDepth->isChecked());
973 _ui->groupBox_bilateral->setVisible(
_ui->checkBox_bilateral->isChecked());
974 _ui->groupBox_filtering->setVisible(
_ui->checkBox_filtering->isChecked());
975 _ui->groupBox_gain->setVisible(
_ui->checkBox_gainCompensation->isEnabled() &&
_ui->checkBox_gainCompensation->isChecked());
976 _ui->groupBox_cameraProjection->setVisible(
_ui->checkBox_cameraProjection->isEnabled() &&
_ui->checkBox_cameraProjection->isChecked());
977 _ui->groupBox_mls->setVisible(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked());
978 _ui->groupBox_meshing->setVisible(
_ui->checkBox_meshing->isChecked());
979 _ui->groupBox_subtraction->setVisible(
_ui->checkBox_subtraction->isChecked());
980 _ui->groupBox_textureMapping->setVisible(
_ui->checkBox_textureMapping->isChecked());
981 _ui->groupBox_cameraFilter->setVisible(
_ui->checkBox_cameraFilter->isChecked());
982 _ui->groupBox_multiband->setVisible(
_ui->checkBox_multiband->isChecked());
985 if(
_ui->checkBox_meshing->isChecked())
988 _ui->comboBox_meshingApproach->setItemData(0,
_ui->comboBox_pipeline->currentIndex() == 1?1 | 32:0,Qt::UserRole - 1);
991 _ui->comboBox_meshingApproach->setItemData(1,
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
994 #ifdef RTABMAP_CPUTSDF
995 _ui->comboBox_meshingApproach->setItemData(2,
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
997 _ui->comboBox_meshingApproach->setItemData(2, 0, Qt::UserRole - 1);
1001 _ui->comboBox_meshingApproach->setItemData(3,
_ui->comboBox_pipeline->currentIndex() == 0?1 | 32:0,Qt::UserRole - 1);
1004 #ifdef RTABMAP_OPENCHISEL
1005 _ui->comboBox_meshingApproach->setItemData(4,
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
1007 _ui->comboBox_meshingApproach->setItemData(4, 0, Qt::UserRole - 1);
1010 if(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()<2)
1012 _ui->comboBox_meshingApproach->setCurrentIndex(3);
1014 if(
_ui->comboBox_pipeline->currentIndex() == 1 && (
_ui->comboBox_meshingApproach->currentIndex()==2 ||
_ui->comboBox_meshingApproach->currentIndex()==3))
1016 _ui->comboBox_meshingApproach->setCurrentIndex(1);
1018 if(!
_ui->checkBox_assemble->isChecked())
1020 _ui->comboBox_meshingApproach->setCurrentIndex(
_ui->comboBox_pipeline->currentIndex() == 1?0:3);
1023 _ui->checkBox_poisson_outputPolygons->setDisabled(
1024 _ui->checkBox_binary->isEnabled() ||
1025 _ui->doubleSpinBox_meshDecimationFactor->value()!=0.0 ||
1026 _ui->spinBox_meshMaxPolygons->value()!=0 ||
1027 _ui->checkBox_textureMapping->isChecked());
1028 _ui->label_outputPolygons->setEnabled(
_ui->checkBox_poisson_outputPolygons->isEnabled());
1030 _ui->checkBox_cleanMesh->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
1031 _ui->label_meshClean->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
1033 _ui->groupBox_gp3->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->comboBox_meshingApproach->currentIndex()==0);
1034 _ui->groupBox_poisson->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->comboBox_meshingApproach->currentIndex()==1);
1035 _ui->groupBox_cputsdf->setVisible(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()==2);
1036 _ui->groupBox_organized->setVisible(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()==3);
1037 _ui->groupBox_openchisel->setVisible(
_ui->comboBox_meshingApproach->currentIndex()==4);
1040 _ui->doubleSpinBox_meshDecimationFactor->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
1041 _ui->label_meshDecimation->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
1042 _ui->spinBox_meshMaxPolygons->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
1043 _ui->label_meshMaxPolygons->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
1046 #ifndef RTABMAP_ALICE_VISION
1047 _ui->checkBox_multiband->setEnabled(
false);
1049 _ui->checkBox_multiband->setEnabled(
_ui->checkBox_binary->isEnabled());
1051 _ui->label_multiband->setEnabled(
_ui->checkBox_multiband->isEnabled());
1057 QString dir =
_ui->lineEdit_distortionModel->text();
1062 QString
path = QFileDialog::getOpenFileName(
this, tr(
"Select file"), dir, tr(
"Distortion model (*.bin *.txt)"));
1065 _ui->lineEdit_distortionModel->setText(
path);
1071 QString dir =
_ui->lineEdit_camProjMaskFilePath->text();
1076 QString
path = QFileDialog::getOpenFileName(
this, tr(
"Select file"), dir, tr(
"Mask (grayscale) (*.png *.pgm *bmp)"));
1079 _ui->lineEdit_camProjMaskFilePath->setText(
path);
1085 _ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
false);
1086 _ui->buttonBox->button(QDialogButtonBox::Save)->setVisible(
true);
1087 _ui->checkBox_binary->setVisible(
true);
1088 _ui->checkBox_binary->setEnabled(
true);
1089 _ui->label_binaryFile->setVisible(
true);
1090 _ui->checkBox_mesh_quad->setVisible(
false);
1091 _ui->checkBox_mesh_quad->setEnabled(
false);
1092 _ui->label_quad->setVisible(
false);
1098 _ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
true);
1099 _ui->buttonBox->button(QDialogButtonBox::Save)->setVisible(
false);
1100 _ui->checkBox_binary->setVisible(
false);
1101 _ui->checkBox_binary->setEnabled(
false);
1102 _ui->label_binaryFile->setVisible(
false);
1103 _ui->checkBox_mesh_quad->setVisible(
true);
1104 _ui->checkBox_mesh_quad->setEnabled(
true);
1105 _ui->label_quad->setVisible(
true);
1111 if(
_ui->checkBox_nodes_filtering->isChecked())
1113 std::map<int, Transform> posesFiltered;
1114 for(std::map<int, Transform>::const_iterator
iter=poses.begin();
iter!=poses.end(); ++
iter)
1116 bool ignore =
false;
1117 if(
_ui->doubleSpinBox_nodes_filtering_xmin->value() !=
_ui->doubleSpinBox_nodes_filtering_xmax->value() &&
1118 (
iter->second.x() <
_ui->doubleSpinBox_nodes_filtering_xmin->value() ||
1119 iter->second.x() >
_ui->doubleSpinBox_nodes_filtering_xmax->value()))
1123 if(
_ui->doubleSpinBox_nodes_filtering_ymin->value() !=
_ui->doubleSpinBox_nodes_filtering_ymax->value() &&
1124 (
iter->second.y() <
_ui->doubleSpinBox_nodes_filtering_ymin->value() ||
1125 iter->second.y() >
_ui->doubleSpinBox_nodes_filtering_ymax->value()))
1129 if(
_ui->doubleSpinBox_nodes_filtering_zmin->value() !=
_ui->doubleSpinBox_nodes_filtering_zmax->value() &&
1130 (
iter->second.z() <
_ui->doubleSpinBox_nodes_filtering_zmin->value() ||
1131 iter->second.z() >
_ui->doubleSpinBox_nodes_filtering_zmax->value()))
1137 posesFiltered.insert(*
iter);
1140 return posesFiltered;
1146 const std::map<int, Transform> & poses,
1147 const std::multimap<int, Link> & links,
1148 const std::map<int, int> & mapIds,
1149 const QMap<int, Signature> & cachedSignatures,
1150 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
1151 const std::map<int, LaserScan> & cachedScans,
1152 const QString & workingDirectory,
1155 std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> clouds;
1156 std::map<int, pcl::PolygonMesh::Ptr> meshes;
1157 std::map<int, pcl::TextureMesh::Ptr> textureMeshes;
1158 std::vector<std::map<int, pcl::PointXY> > textureVertexToPixels;
1174 textureVertexToPixels))
1176 if(textureMeshes.size())
1178 saveTextureMeshes(workingDirectory, poses, textureMeshes, cachedSignatures, textureVertexToPixels);
1180 else if(meshes.size())
1182 bool exportMeshes =
true;
1183 if(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked())
1185 QMessageBox::StandardButton r = QMessageBox::warning(
this, tr(
"Exporting Texture Mesh"),
1186 tr(
"No texture mesh could be created, do you want to continue with saving only the meshes (%1)?").
arg(meshes.size()),
1187 QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
1188 exportMeshes = r == QMessageBox::Yes;
1192 saveMeshes(workingDirectory, poses, meshes,
_ui->checkBox_binary->isChecked());
1197 saveClouds(workingDirectory, poses, clouds,
_ui->checkBox_binary->isChecked(), textureVertexToPixels);
1208 const std::map<int, Transform> & poses,
1209 const std::multimap<int, Link> & links,
1210 const std::map<int, int> & mapIds,
1211 const QMap<int, Signature> & cachedSignatures,
1212 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
1213 const std::map<int, LaserScan> & cachedScans,
1214 const QString & workingDirectory,
1217 std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> clouds;
1218 std::map<int, pcl::PolygonMesh::Ptr> meshes;
1219 std::map<int, pcl::TextureMesh::Ptr> textureMeshes;
1220 std::vector<std::map<int, pcl::PointXY> > textureVertexToPixels;
1236 textureVertexToPixels))
1238 QDialog * window =
new QDialog(this->parentWidget()?this->parentWidget():
this, Qt::Window);
1239 window->setAttribute(Qt::WA_DeleteOnClose,
true);
1242 window->setWindowTitle(tr(
"Meshes (%1 nodes)").
arg(meshes.size()));
1246 window->setWindowTitle(tr(
"Clouds (%1 nodes)").
arg(clouds.size()));
1248 window->setMinimumWidth(120);
1249 window->setMinimumHeight(90);
1250 window->resize(this->window()->windowHandle()->screen()->availableGeometry().
size() * 0.7);
1253 if(
_ui->comboBox_pipeline->currentIndex() == 0)
1260 if(
_ui->comboBox_intensityColormap->currentIndex()==1)
1264 else if(
_ui->comboBox_intensityColormap->currentIndex() == 2)
1269 QVBoxLayout *layout =
new QVBoxLayout();
1270 layout->addWidget(viewer);
1271 layout->setContentsMargins(0,0,0,0);
1272 window->setLayout(layout);
1273 connect(window, SIGNAL(finished(
int)), viewer, SLOT(clear()));
1278 QApplication::processEvents();
1280 QApplication::processEvents();
1282 if(textureMeshes.size())
1285 std::map<int, cv::Mat> images;
1286 std::map<int, std::vector<CameraModel> > calibrations;
1287 for(QMap<int, Signature>::const_iterator
iter=cachedSignatures.constBegin();
iter!=cachedSignatures.constEnd(); ++
iter)
1289 std::vector<CameraModel> models;
1290 if(
iter->sensorData().cameraModels().size())
1292 models =
iter->sensorData().cameraModels();
1294 else if(
iter->sensorData().stereoCameraModels().size())
1296 for(
size_t i=0;
i<
iter->sensorData().stereoCameraModels().
size(); ++
i)
1298 models.push_back(
iter->sensorData().stereoCameraModels()[
i].left());
1304 if(!
iter->sensorData().imageRaw().empty())
1306 calibrations.insert(std::make_pair(
iter.key(), models));
1307 images.insert(std::make_pair(
iter.key(),
iter->sensorData().imageRaw()));
1309 else if(!
iter->sensorData().imageCompressed().empty())
1311 calibrations.insert(std::make_pair(
iter.key(), models));
1312 images.insert(std::make_pair(
iter.key(),
iter->sensorData().imageCompressed()));
1316 int textureSize = 1024;
1317 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
1319 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
1321 int blendingDecimation = 0;
1322 if(
_ui->checkBox_blending->isChecked())
1324 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
1326 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
1330 for (std::map<int, pcl::TextureMesh::Ptr>::iterator
iter = textureMeshes.begin();
iter != textureMeshes.end(); ++
iter)
1332 pcl::TextureMesh::Ptr mesh =
iter->second;
1335 cv::Mat globalTexture;
1336 if (mesh->tex_materials.size() > 1)
1338 cv::Mat globalTextures;
1347 textureVertexToPixels,
1348 _ui->checkBox_gainCompensation->isChecked(),
1349 _ui->doubleSpinBox_gainBeta->value(),
1350 _ui->checkBox_gainRGB->isChecked(),
1351 _ui->checkBox_blending->isChecked(),
1353 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
1354 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
1355 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked());
1356 if(globalTextures.rows == globalTextures.cols)
1358 globalTexture = globalTextures;
1369 for (
unsigned int t = 0;
t < mesh->tex_coordinates.size(); ++
t)
1371 if(mesh->tex_polygons[
t].size())
1374 pcl::PointCloud<pcl::PointXYZ>::Ptr originalCloud(
new pcl::PointCloud<pcl::PointXYZ>);
1375 pcl::fromPCLPointCloud2(mesh->cloud, *originalCloud);
1378 unsigned int nPoints = mesh->tex_coordinates[
t].size();
1379 UASSERT(nPoints == mesh->tex_polygons[
t].size()*mesh->tex_polygons[
t][0].vertices.size());
1381 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
1382 cloud->resize(nPoints);
1384 unsigned int oi = 0;
1385 for (
unsigned int i = 0;
i < mesh->tex_polygons[
t].size(); ++
i)
1387 pcl::Vertices &
vertices = mesh->tex_polygons[
t][
i];
1389 for(
unsigned int j=0;
j<
vertices.vertices.size(); ++
j)
1393 cloud->at(oi) = originalCloud->at(
vertices.vertices[
j]);
1398 pcl::toPCLPointCloud2(*cloud, mesh->cloud);
1402 UWARN(
"No polygons for texture %d of mesh %d?!",
t,
iter->first);
1406 if (globalTexture.empty())
1408 if(mesh->tex_materials.size()==1 &&
1409 !mesh->tex_materials[0].tex_file.empty() &&
1410 uIsInteger(mesh->tex_materials[0].tex_file,
false))
1412 int textureId =
uStr2Int(mesh->tex_materials[0].tex_file);
1414 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
1416 data = cachedSignatures.value(textureId).sensorData();
1423 data.uncompressDataConst(&globalTexture, 0);
1424 UASSERT(!globalTexture.empty());
1439 QApplication::processEvents();
1442 else if(meshes.size())
1445 viewer->
setLighting(
_ui->doubleSpinBox_transferColorRadius->value() < 0.0);
1446 for(std::map<int, pcl::PolygonMesh::Ptr>::iterator
iter = meshes.begin();
iter!=meshes.end(); ++
iter)
1451 for(
unsigned int i=0;
i<
iter->second->cloud.fields.size(); ++
i)
1453 if(
iter->second->cloud.fields[
i].name.compare(
"rgb") == 0)
1461 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
1462 pcl::fromPCLPointCloud2(
iter->second->cloud, *cloud);
1467 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
1468 pcl::fromPCLPointCloud2(
iter->second->cloud, *cloud);
1472 QApplication::processEvents();
1475 else if(clouds.size())
1477 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::
iterator iter = clouds.begin();
iter!=clouds.end(); ++
iter)
1483 !(
_ui->checkBox_cameraProjection->isEnabled() &&
1484 _ui->checkBox_cameraProjection->isChecked() &&
1485 _ui->checkBox_camProjRecolorPoints->isChecked() &&
1486 clouds.size()==1 && clouds.begin()->first==0))
1489 if(
_ui->spinBox_normalKSearch->value()<=0 &&
_ui->doubleSpinBox_normalRadiusSearch->value()<=0.0)
1492 pcl::PointCloud<pcl::PointXYZI>::Ptr cloudIWithoutNormals(
new pcl::PointCloud<pcl::PointXYZI>);
1493 cloudIWithoutNormals->resize(
iter->second->size());
1494 for(
unsigned int i=0;
i<cloudIWithoutNormals->size(); ++
i)
1496 cloudIWithoutNormals->points[
i].x =
iter->second->points[
i].x;
1497 cloudIWithoutNormals->points[
i].y =
iter->second->points[
i].y;
1498 cloudIWithoutNormals->points[
i].z =
iter->second->points[
i].z;
1499 int * intensity = (
int *)&cloudIWithoutNormals->points[
i].intensity;
1501 int(
iter->second->points[
i].r) |
1502 int(
iter->second->points[
i].g) << 8 |
1503 int(
iter->second->points[
i].b) << 16 |
1504 int(
iter->second->points[
i].a) << 24;
1510 pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloudI(
new pcl::PointCloud<pcl::PointXYZINormal>);
1511 cloudI->resize(
iter->second->size());
1512 for(
unsigned int i=0;
i<cloudI->size(); ++
i)
1514 cloudI->points[
i].x =
iter->second->points[
i].x;
1515 cloudI->points[
i].y =
iter->second->points[
i].y;
1516 cloudI->points[
i].z =
iter->second->points[
i].z;
1517 cloudI->points[
i].normal_x =
iter->second->points[
i].normal_x;
1518 cloudI->points[
i].normal_y =
iter->second->points[
i].normal_y;
1519 cloudI->points[
i].normal_z =
iter->second->points[
i].normal_z;
1520 cloudI->points[
i].curvature =
iter->second->points[
i].curvature;
1521 int * intensity = (
int *)&cloudI->points[
i].intensity;
1523 int(
iter->second->points[
i].r) |
1524 int(
iter->second->points[
i].g) << 8 |
1525 int(
iter->second->points[
i].b) << 16 |
1526 int(
iter->second->points[
i].a) << 24;
1541 window->activateWindow();
1552 int textureSize = 1024;
1553 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
1555 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
1561 return _ui->spinBox_mesh_maxTextures->value();
1565 return _ui->checkBox_gainCompensation->isChecked();
1569 return _ui->doubleSpinBox_gainBeta->value();
1573 return _ui->checkBox_gainRGB->isChecked();
1577 return _ui->checkBox_blending->isChecked();
1581 int blendingDecimation = 0;
1582 if(
_ui->checkBox_blending->isChecked())
1584 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
1586 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
1589 return blendingDecimation;
1593 return _ui->spinBox_textureBrightnessContrastRatioLow->value();
1597 return _ui->spinBox_textureBrightnessContrastRatioHigh->value();
1601 return _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked();
1609 if (dir.exists(dirName)) {
1610 Q_FOREACH(QFileInfo
info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
1615 result = QFile::remove(
info.absoluteFilePath());
1622 result = dir.rmdir(dirName);
1628 const std::map<int, Transform> & posesIn,
1629 const std::multimap<int, Link> & links,
1630 const std::map<int, int> & mapIds,
1631 const QMap<int, Signature> & cachedSignatures,
1632 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
1633 const std::map<int, LaserScan> & cachedScans,
1634 const QString & workingDirectory,
1636 std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & cloudsWithNormals,
1637 std::map<int, pcl::PolygonMesh::Ptr> & meshes,
1638 std::map<int, pcl::TextureMesh::Ptr> & textureMeshes,
1639 std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels)
1643 _ui->checkBox_regenerate->setEnabled(
true);
1644 if(cachedSignatures.empty() &&
_dbDriver)
1646 _ui->checkBox_regenerate->setChecked(
true);
1647 _ui->checkBox_regenerate->setEnabled(
false);
1654 if(this->
exec() == QDialog::Accepted)
1656 std::map<int, Transform> poses =
filterNodes(posesIn);
1660 QMessageBox::critical(
this, tr(
"Creating clouds..."), tr(
"Poses are empty! Cannot export/view clouds."));
1666 if(
_ui->checkBox_meshing->isChecked())
1670 if(
_ui->checkBox_assemble->isChecked())
1675 if(
_ui->checkBox_subtraction->isChecked())
1679 if(
_ui->checkBox_textureMapping->isChecked())
1683 if(
_ui->checkBox_gainCompensation->isChecked())
1687 if(
_ui->checkBox_mesh_quad->isEnabled())
1693 bool loadClouds =
true;
1694 #ifdef RTABMAP_OPENCHISEL
1695 if(
_ui->comboBox_meshingApproach->currentIndex()==4 &&
_ui->checkBox_assemble->isChecked())
1697 loadClouds = !
_ui->checkBox_fromDepth->isChecked();
1701 bool has2dScans =
false;
1702 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
1717 for(std::map<int, Transform>::const_iterator
iter=poses.begin();
iter!=poses.end(); ++
iter)
1719 clouds.insert(std::make_pair(
iter->first,
1721 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr(
new pcl::PointCloud<pcl::PointXYZRGBNormal>),
1722 pcl::IndicesPtr(
new std::vector<int>))));
1727 std::set<int> validCameras =
uKeysSet(clouds);
1738 if(
_ui->checkBox_regenerate->isEnabled() && !
_ui->checkBox_regenerate->isChecked())
1740 QMessageBox::warning(
this, tr(
"Creating clouds..."), tr(
"Could create clouds for %1 node(s). You "
1741 "may want to activate clouds regeneration option.").
arg(poses.size()));
1745 QMessageBox::warning(
this, tr(
"Creating clouds..."), tr(
"Could not create clouds for %1 "
1746 "node(s). The cache may not contain point cloud data. Try re-downloading the map.").
arg(poses.size()));
1752 if(
_ui->checkBox_gainCompensation->isChecked() &&
_ui->checkBox_fromDepth->isChecked() && clouds.size() > 1 &&
1754 !(
_ui->checkBox_meshing->isChecked() &&
1755 _ui->checkBox_textureMapping->isEnabled() &&
1756 _ui->checkBox_textureMapping->isChecked() &&
1757 _ui->comboBox_pipeline->currentIndex()==1 &&
1758 _ui->checkBox_assemble->isChecked() &&
1759 _ui->comboBox_meshingTextureSize->isEnabled() &&
1760 _ui->comboBox_meshingTextureSize->currentIndex() > 0) &&
1762 !(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==2))
1767 if(
_ui->checkBox_gainFull->isChecked())
1775 QApplication::processEvents();
1777 QApplication::processEvents();
1779 if(
_ui->checkBox_gainFull->isChecked())
1781 std::multimap<int, Link> allLinks;
1782 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::const_iterator
iter=clouds.begin();
iter!=clouds.end(); ++
iter)
1784 int from =
iter->first;
1785 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::const_iterator jter =
iter;
1787 for(;jter!=clouds.end(); ++jter)
1789 int to = jter->first;
1790 allLinks.insert(std::make_pair(from,
Link(from, to,
Link::kUserClosure, poses.at(from).inverse()*poses.at(to))));
1801 if(!(
_ui->checkBox_meshing->isChecked() &&
1802 _ui->checkBox_textureMapping->isEnabled() &&
1803 _ui->checkBox_textureMapping->isChecked()))
1806 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::
iterator jter=clouds.begin();jter!=clouds.end(); ++jter)
1808 if(jter!=clouds.end())
1811 _compensator->
apply(jter->first, jter->second.first, jter->second.second,
_ui->checkBox_gainRGB->isChecked());
1815 QApplication::processEvents();
1826 std::map<int, Transform> normalViewpoints = poses;
1827 if(
_ui->checkBox_assemble->isChecked())
1830 for(std::map<int, Transform>::iterator
iter= normalViewpoints.begin();
iter!=normalViewpoints.end(); ++
iter)
1832 if(
_ui->checkBox_fromDepth->isChecked())
1834 std::vector<CameraModel> models;
1835 std::vector<StereoCameraModel> stereoModels;
1836 if(cachedSignatures.contains(
iter->first))
1839 models =
data.cameraModels();
1840 stereoModels =
data.stereoCameraModels();
1847 if(models.size() && !models[0].localTransform().isNull())
1849 iter->second *= models[0].localTransform();
1851 else if(stereoModels.size() && !stereoModels[0].localTransform().isNull())
1853 iter->second *= stereoModels[0].localTransform();
1860 iter->second *= cachedScans.at(
iter->first).localTransform();
1862 else if(cachedSignatures.contains(
iter->first))
1865 if(!
data.laserScanCompressed().isEmpty())
1867 iter->second *=
data.laserScanCompressed().localTransform();
1869 else if(!
data.laserScanRaw().isEmpty())
1871 iter->second *=
data.laserScanRaw().localTransform();
1885 pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(
new pcl::PointCloud<pcl::PointXYZ>);
1886 std::vector<int> rawCameraIndices;
1887 if(
_ui->checkBox_assemble->isChecked() &&
1888 !((
_ui->comboBox_pipeline->currentIndex()==0 ||
_ui->comboBox_meshingApproach->currentIndex()==4) &&
_ui->checkBox_meshing->isChecked()))
1891 QApplication::processEvents();
1894 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
1895 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::
iterator iter=clouds.begin();
1896 iter!= clouds.end();
1899 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformed(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
1900 if(
iter->second.first->isOrganized())
1902 pcl::copyPointCloud(*
iter->second.first, *
iter->second.second, *transformed);
1909 pcl::copyPointCloud(*
iter->second.first, *
iter->second.second, *transformed);
1913 *assembledCloud += *transformed;
1914 rawCameraIndices.resize(assembledCloud->size(),
iter->first);
1918 QApplication::processEvents();
1925 assembledCloud->is_dense =
true;
1926 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
1928 pcl::copyPointCloud(*assembledCloud, *rawAssembledCloud);
1931 if(
_ui->doubleSpinBox_voxelSize_assembled->value())
1934 .
arg(assembledCloud->size())
1935 .
arg(
_ui->doubleSpinBox_voxelSize_assembled->value()));
1936 QApplication::processEvents();
1937 unsigned int before = assembledCloud->size();
1940 _ui->doubleSpinBox_voxelSize_assembled->value());
1943 .
arg(
_ui->doubleSpinBox_voxelSize_assembled->value())
1944 .
arg(assembledCloud->size()));
1948 pcl::IndicesPtr
indices(
new std::vector<int>);
1949 indices->resize(assembledCloud->size());
1950 for(
unsigned int i=0;
i<
indices->size(); ++
i)
1955 if(!
_ui->checkBox_fromDepth->isChecked() && !has2dScans &&
1956 (
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0))
1959 .
arg(assembledCloud->size())
1960 .
arg(
_ui->spinBox_normalKSearch->value())
1961 .arg(
_ui->doubleSpinBox_normalRadiusSearch->value()));
1964 pcl::PointCloud<pcl::PointXYZ>::Ptr cloudWithoutNormals(
new pcl::PointCloud<pcl::PointXYZ>);
1965 pcl::copyPointCloud(*assembledCloud, *cloudWithoutNormals);
1966 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals,
indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value());
1968 UASSERT(assembledCloud->size() == normals->size());
1969 for(
unsigned int i=0;
i<normals->size(); ++
i)
1971 assembledCloud->points[
i].normal_x = normals->points[
i].normal_x;
1972 assembledCloud->points[
i].normal_y = normals->points[
i].normal_y;
1973 assembledCloud->points[
i].normal_z = normals->points[
i].normal_z;
1983 _ui->doubleSpinBox_groundNormalsUp->value());
1986 if(
_ui->spinBox_randomSamples_assembled->value()>0 &&
1987 (
int)assembledCloud->size() >
_ui->spinBox_randomSamples_assembled->value())
1990 .
arg(assembledCloud->size())
1991 .
arg(
_ui->spinBox_randomSamples_assembled->value()));
1994 .
arg(assembledCloud->size())
1995 .
arg(
_ui->spinBox_randomSamples_assembled->value()));
1998 clouds.insert(std::make_pair(0, std::make_pair(assembledCloud,
indices)));
2007 if(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked() && !has2dScans)
2010 "[search radius=%1m voxel=%2m]").
arg(
_ui->doubleSpinBox_mlsRadius->value()).
arg(
_ui->doubleSpinBox_voxelSize_assembled->value()));
2011 QApplication::processEvents();
2013 QApplication::processEvents();
2017 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::
iterator iter=clouds.begin();
2018 iter!= clouds.end();)
2020 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals =
iter->second.first;
2022 if(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked() && !has2dScans)
2024 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals(
new pcl::PointCloud<pcl::PointXYZRGB>);
2025 if(
iter->second.second->size())
2027 pcl::copyPointCloud(*cloudWithNormals, *
iter->second.second, *cloudWithoutNormals);
2031 pcl::copyPointCloud(*cloudWithNormals, *cloudWithoutNormals);
2035 QApplication::processEvents();
2037 QApplication::processEvents();
2044 cloudWithoutNormals,
2045 (
float)
_ui->doubleSpinBox_mlsRadius->value(),
2046 _ui->spinBox_polygonialOrder->value(),
2047 _ui->comboBox_upsamplingMethod->currentIndex(),
2048 (
float)
_ui->doubleSpinBox_sampleRadius->value(),
2049 (
float)
_ui->doubleSpinBox_sampleStep->value(),
2050 _ui->spinBox_randomPoints->value(),
2051 (
float)
_ui->doubleSpinBox_dilationVoxelSize->value(),
2052 _ui->spinBox_dilationSteps->value());
2055 UDEBUG(
"NaNs filtering... size before = %d", cloudWithNormals->size());
2057 UDEBUG(
"NaNs filtering... size after = %d", cloudWithNormals->size());
2059 if(
_ui->checkBox_assemble->isChecked())
2062 if(
_ui->doubleSpinBox_mls_outputVoxelSize->value())
2065 .
arg(cloudWithNormals->size())
2066 .
arg(
_ui->doubleSpinBox_mls_outputVoxelSize->value()));
2067 QApplication::processEvents();
2071 _ui->doubleSpinBox_mls_outputVoxelSize->value());
2083 else if(
iter->second.first->isOrganized() &&
_ui->checkBox_filtering->isChecked())
2088 cloudsWithNormals.insert(std::make_pair(
iter->first, cloudWithNormals));
2091 clouds.erase(
iter++);
2094 QApplication::processEvents();
2102 #ifdef RTABMAP_CPUTSDF
2103 cpu_tsdf::TSDFVolumeOctree::Ptr tsdf;
2105 #ifdef RTABMAP_OPENCHISEL
2106 chisel::ChiselPtr chiselMap;
2107 chisel::ProjectionIntegrator projectionIntegrator;
2111 std::map<int, std::vector<int> > organizedIndices;
2112 std::map<int, cv::Size> organizedCloudSizes;
2115 UDEBUG(
"Meshing=%d",
_ui->checkBox_meshing->isChecked()?1:0);
2116 if(
_ui->checkBox_meshing->isChecked() && !has2dScans)
2119 #ifdef RTABMAP_OPENCHISEL
2120 if(
_ui->comboBox_meshingApproach->currentIndex()==4 &&
_ui->checkBox_assemble->isChecked())
2124 QApplication::processEvents();
2126 QApplication::processEvents();
2128 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2129 std::vector<pcl::Vertices> mergedPolygons;
2131 int cloudsAdded = 1;
2132 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::
iterator iter=cloudsWithNormals.begin();
2133 iter!= cloudsWithNormals.end();
2134 ++
iter,++cloudsAdded)
2136 std::vector<CameraModel> models;
2138 bool cacheHasCompressedImage =
false;
2140 if(cachedSignatures.contains(
iter->first))
2143 models =
data.cameraModels();
2144 cacheHasCompressedImage = !
data.imageCompressed().empty();
2145 scanInfo = !
data.laserScanRaw().isEmpty()?
data.laserScanRaw():
data.laserScanCompressed();
2153 if(chiselMap.get() == 0)
2156 int chunkSizeX =
_ui->spinBox_openchisel_chunk_size_x->value();
2157 int chunkSizeY =
_ui->spinBox_openchisel_chunk_size_y->value();
2158 int chunkSizeZ =
_ui->spinBox_openchisel_chunk_size_z->value();
2159 float voxelResolution =
_ui->doubleSpinBox_voxelSize_assembled->value();
2160 if(voxelResolution <=0.0
f)
2166 bool useColor =
_ui->checkBox_fromDepth->isChecked();
2167 chiselMap.reset(
new chisel::Chisel(Eigen::Vector3i(chunkSizeX, chunkSizeY, chunkSizeZ), voxelResolution, useColor));
2168 double truncationDistConst =
_ui->doubleSpinBox_openchisel_truncation_constant->value();
2169 double truncationDistLinear =
_ui->doubleSpinBox_openchisel_truncation_linear->value();
2170 double truncationDistQuad =
_ui->doubleSpinBox_openchisel_truncation_quadratic->value();
2171 double truncationDistScale =
_ui->doubleSpinBox_openchisel_truncation_scale->value();
2172 int weight =
_ui->spinBox_openchisel_integration_weight->value();
2173 bool useCarving =
_ui->checkBox_openchisel_use_voxel_carving->isChecked();
2174 double carvingDist =
_ui->doubleSpinBox_openchisel_carving_dist_m->value();
2175 chisel::Vec4 truncation(truncationDistQuad, truncationDistLinear, truncationDistConst, truncationDistScale);
2176 UDEBUG(
"If crashing just after this message, make sure PCL and OpenChisel are built both with -march=native or both without -march=native");
2177 projectionIntegrator.SetCentroids(chiselMap->GetChunkManager().GetCentroids());
2178 projectionIntegrator.SetTruncator(chisel::TruncatorPtr(
new chisel::QuadraticTruncator(truncation(0), truncation(1), truncation(2), truncation(3))));
2179 projectionIntegrator.SetWeighter(chisel::WeighterPtr(
new chisel::ConstantWeighter(weight)));
2180 projectionIntegrator.SetCarvingDist(carvingDist);
2181 projectionIntegrator.SetCarvingEnabled(useCarving);
2185 double nearPlaneDist =
_ui->doubleSpinBox_openchisel_near_plane_dist->value();
2186 double farPlaneDist =
_ui->doubleSpinBox_openchisel_far_plane_dist->value();
2187 if(
_ui->checkBox_fromDepth->isChecked())
2189 if(models.size() == 1 && !models[0].localTransform().isNull())
2194 if(cacheHasCompressedImage)
2196 cachedSignatures.find(
iter->first)->sensorData().uncompressDataConst(&rgb, &depth);
2202 data.uncompressDataConst(&rgb, &depth);
2204 if(!rgb.empty() && !depth.empty())
2208 if(rgb.cols > depth.cols)
2210 UASSERT(rgb.cols % depth.cols == 0);
2211 depthModel = depthModel.
scaled(
double(depth.cols)/
double(rgb.cols));
2214 if(depth.type() == CV_16UC1)
2219 std::shared_ptr<chisel::ColorImage<unsigned char> > colorChisel =
colorImageToChisel(rgb);
2224 cameraColor.SetNearPlane(nearPlaneDist);
2225 cameraColor.SetFarPlane(farPlaneDist);
2226 cameraDepth.SetNearPlane(nearPlaneDist);
2227 cameraDepth.SetFarPlane(farPlaneDist);
2229 chisel::Transform pose_rel_to_first_frame = (poses.at(
iter->first)*models[0].localTransform()).toEigen3f();
2230 chiselMap->IntegrateDepthScanColor<
float,
unsigned char>(projectionIntegrator, depthChisel, pose_rel_to_first_frame, cameraDepth, colorChisel, pose_rel_to_first_frame, cameraColor);
2248 chisel::Transform pose_rel_to_first_frame = (poses.at(
iter->first)*scanInfo.
localTransform()).toEigen3f();
2249 chiselMap->IntegratePointCloud(projectionIntegrator, *chiselCloud, pose_rel_to_first_frame, farPlaneDist);
2258 chiselMap->UpdateMeshes();
2263 QApplication::processEvents();
2273 if(
_ui->comboBox_pipeline->currentIndex() == 0)
2275 if(
_ui->comboBox_meshingApproach->currentIndex()==2)
2283 QApplication::processEvents();
2285 QApplication::processEvents();
2287 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2288 std::vector<pcl::Vertices> mergedPolygons;
2290 int cloudsAdded = 1;
2291 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::
iterator iter=cloudsWithNormals.begin();
2292 iter!= cloudsWithNormals.end();
2293 ++
iter,++cloudsAdded)
2295 if(
iter->second->isOrganized())
2297 if(
iter->second->size())
2299 Eigen::Vector3f viewpoint(0.0
f,0.0
f,0.0
f);
2301 std::vector<CameraModel> models;
2302 std::vector<StereoCameraModel> stereoModels;
2303 if(cachedSignatures.contains(
iter->first))
2306 models =
data.cameraModels();
2307 stereoModels =
data.stereoCameraModels();
2314 #ifdef RTABMAP_CPUTSDF
2315 if(
_ui->comboBox_meshingApproach->currentIndex()==2 &&
_ui->checkBox_assemble->isChecked())
2319 if(models.size()==1 && models[0].isValidForProjection() && models[0].imageHeight()>0 && models[0].imageWidth()>0)
2321 float tsdf_size =
_ui->doubleSpinBox_cputsdf_size->value();
2322 float cell_size =
_ui->doubleSpinBox_cputsdf_resolution->value();
2323 int num_random_splits =
_ui->spinBox_cputsdf_randomSplit->value();
2325 int desired_res = tsdf_size / cell_size;
2328 while (desired_res >
n)
2334 tsdf.reset (
new cpu_tsdf::TSDFVolumeOctree);
2335 tsdf->setGridSize (tsdf_size, tsdf_size, tsdf_size);
2336 tsdf->setResolution (tsdf_res, tsdf_res, tsdf_res);
2337 float decimation =
float(models[0].imageWidth()) /
float(
iter->second->width);
2338 tsdf->setImageSize (models[0].imageWidth()/decimation, models[0].imageHeight()/decimation);
2339 tsdf->setCameraIntrinsics (models[0].
fx()/decimation, models[0].
fy()/decimation, models[0].
cx()/decimation, models[0].
cy()/decimation);
2340 tsdf->setNumRandomSplts (num_random_splits);
2341 tsdf->setSensorDistanceBounds (0, 9999);
2342 tsdf->setIntegrateColor(
true);
2343 tsdf->setDepthTruncationLimits (
_ui->doubleSpinBox_cputsdf_tuncPos->value(),
_ui->doubleSpinBox_cputsdf_tuncNeg->value());
2356 if(tsdf.get() && models.size() == 1 && !models[0].localTransform().isNull())
2358 Eigen::Affine3d pose_rel_to_first_frame = ((poses.begin()->second.inverse() * poses.at(
iter->first))*models[0].localTransform()).toEigen3d();
2359 if(!tsdf->integrateCloud(*
util3d::transformPointCloud(
iter->second, models[0].localTransform().inverse()), pcl::PointCloud<pcl::Normal>(), pose_rel_to_first_frame))
2361 _progressDialog->
appendText(tr(
"CPU-TSDF: Failed integrating cloud %1 (%2/%3) to TSDF volume").arg(
iter->first).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2365 _progressDialog->
appendText(tr(
"CPU-TSDF: Integrated cloud %1 (%2/%3) to TSDF volume").arg(
iter->first).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2373 if((
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex() != 2) ||
2374 !
iter->second->isOrganized())
2376 if(models.size() && !models[0].localTransform().isNull())
2378 viewpoint[0] = models[0].localTransform().x();
2379 viewpoint[1] = models[0].localTransform().y();
2380 viewpoint[2] = models[0].localTransform().z();
2382 else if(stereoModels.size() && !stereoModels[0].localTransform().isNull())
2384 viewpoint[0] = stereoModels[0].localTransform().x();
2385 viewpoint[1] = stereoModels[0].localTransform().y();
2386 viewpoint[2] = stereoModels[0].localTransform().z();
2392 _ui->doubleSpinBox_mesh_angleTolerance->value()*
M_PI/180.0,
2393 _ui->checkBox_mesh_quad->isEnabled() &&
_ui->checkBox_mesh_quad->isChecked(),
2394 _ui->spinBox_mesh_triangleSize->value(),
2397 if(
_ui->spinBox_mesh_minClusterSize->value() != 0)
2400 QApplication::processEvents();
2403 std::vector<std::set<int> > neighbors;
2404 std::vector<std::set<int> > vertexToPolygons;
2406 (
int)
iter->second->size(),
2411 _ui->spinBox_mesh_minClusterSize->value()<0?0:
_ui->spinBox_mesh_minClusterSize->value());
2413 std::vector<pcl::Vertices> filteredPolygons(polygons.size());
2414 if(
_ui->spinBox_mesh_minClusterSize->value() < 0)
2417 std::list<std::list<int> >
::iterator biggestClusterIndex = clusters.end();
2418 unsigned int biggestClusterSize = 0;
2421 if(
iter->size() > biggestClusterSize)
2423 biggestClusterIndex =
iter;
2424 biggestClusterSize =
iter->size();
2427 if(biggestClusterIndex != clusters.end())
2430 for(std::list<int>::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter)
2432 filteredPolygons[oi++] = polygons.at(*jter);
2434 filteredPolygons.resize(oi);
2442 for(std::list<int>::iterator jter=
iter->begin(); jter!=
iter->end(); ++jter)
2444 filteredPolygons[oi++] = polygons.at(*jter);
2447 filteredPolygons.resize(oi);
2449 int before = (
int)polygons.size();
2450 polygons = filteredPolygons;
2452 if(polygons.size() == 0)
2454 std::string
msg =
uFormat(
"All %d polygons filtered after polygon cluster filtering. Cluster minimum size is %d.", before,
_ui->spinBox_mesh_minClusterSize->value());
2460 QApplication::processEvents();
2465 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr denseCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2466 std::vector<pcl::Vertices> densePolygons;
2469 if(!
_ui->checkBox_assemble->isChecked() ||
2470 (
_ui->checkBox_textureMapping->isEnabled() &&
2471 _ui->checkBox_textureMapping->isChecked() &&
2472 _ui->doubleSpinBox_voxelSize_assembled->value() == 0.0))
2474 if(
_ui->checkBox_assemble->isChecked())
2479 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2480 pcl::toPCLPointCloud2(*denseCloud, mesh->cloud);
2481 mesh->polygons = densePolygons;
2483 organizedIndices.insert(std::make_pair(
iter->first, denseToOrganizedIndices));
2484 organizedCloudSizes.insert(std::make_pair(
iter->first, cv::Size(
iter->second->width,
iter->second->height)));
2486 meshes.insert(std::make_pair(
iter->first, mesh));
2491 if(mergedClouds->size() == 0)
2493 *mergedClouds = *denseCloud;
2494 mergedPolygons = densePolygons;
2511 if(cachedSignatures.contains(
iter->first))
2513 const Signature &
s = cachedSignatures.find(
iter->first).value();
2514 weight =
s.getWeight();
2522 _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()));
2527 QApplication::processEvents();
2534 if(
_ui->checkBox_assemble->isChecked() && mergedClouds->size())
2536 if(
_ui->doubleSpinBox_voxelSize_assembled->value())
2538 _progressDialog->
appendText(tr(
"Filtering assembled mesh for close vertices (points=%1, polygons=%2)...").
arg(mergedClouds->size()).
arg(mergedPolygons.size()));
2539 QApplication::processEvents();
2544 _ui->doubleSpinBox_voxelSize_assembled->value(),
2549 unsigned int count = mergedPolygons.size();
2552 QApplication::processEvents();
2555 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr filteredCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2556 std::vector<pcl::Vertices> filteredPolygons;
2558 mergedClouds = filteredCloud;
2559 mergedPolygons = filteredPolygons;
2562 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2563 pcl::toPCLPointCloud2(*mergedClouds, mesh->cloud);
2564 mesh->polygons = mergedPolygons;
2566 meshes.insert(std::make_pair(0, mesh));
2569 QApplication::processEvents();
2574 if(
_ui->comboBox_meshingApproach->currentIndex() == 0)
2582 QApplication::processEvents();
2584 QApplication::processEvents();
2587 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::
iterator iter=cloudsWithNormals.begin();
2588 iter!= cloudsWithNormals.end();
2589 ++
iter,++cloudsAdded)
2591 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2592 if(
_ui->comboBox_meshingApproach->currentIndex() == 0)
2596 _ui->doubleSpinBox_gp3Radius->value(),
2597 _ui->doubleSpinBox_gp3Mu->value());
2601 pcl::Poisson<pcl::PointXYZRGBNormal> poisson;
2602 poisson.setOutputPolygons(
_ui->checkBox_poisson_outputPolygons->isEnabled()?
_ui->checkBox_poisson_outputPolygons->isChecked():
false);
2603 poisson.setManifold(
_ui->checkBox_poisson_manifold->isChecked());
2604 poisson.setSamplesPerNode(
_ui->doubleSpinBox_poisson_samples->value());
2605 int depth =
_ui->spinBox_poisson_depth->value();
2612 for(
int i=6;
i<12; ++
i)
2614 if(mapLength/
float(1<<
i) <
_ui->doubleSpinBox_poisson_targetPolygonSize->value())
2625 QApplication::processEvents();
2627 QApplication::processEvents();
2629 poisson.setDepth(depth);
2630 poisson.setIsoDivide(
_ui->spinBox_poisson_iso->value());
2631 poisson.setSolverDivide(
_ui->spinBox_poisson_solver->value());
2632 poisson.setMinDepth(
_ui->spinBox_poisson_minDepth->value());
2633 poisson.setPointWeight(
_ui->doubleSpinBox_poisson_pointWeight->value());
2634 poisson.setScale(
_ui->doubleSpinBox_poisson_scale->value());
2635 poisson.setInputCloud(
iter->second);
2636 poisson.reconstruct(*mesh);
2640 QApplication::processEvents();
2642 if(mesh->polygons.size()>0)
2649 int maxIntensity = 1;
2651 for(
size_t i=0;
i<
iter->second->size(); ++
i)
2655 int(
iter->second->points[
i].g) << 8 |
2656 int(
iter->second->points[
i].b) << 16 |
2657 int(
iter->second->points[
i].a) << 24;
2658 if(intensity > maxIntensity)
2660 maxIntensity = intensity;
2664 for(
size_t i=0;
i<
iter->second->size(); ++
i)
2668 int(
iter->second->points[
i].g) << 8 |
2669 int(
iter->second->points[
i].b) << 16 |
2670 int(
iter->second->points[
i].a) << 24;
2671 intensity = intensity*255/maxIntensity;
2672 iter->second->points[
i].r = (
unsigned char)intensity;
2673 iter->second->points[
i].g = (
unsigned char)intensity;
2674 iter->second->points[
i].b = (
unsigned char)intensity;
2675 iter->second->points[
i].a = (
unsigned char)255;
2679 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
2681 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(
float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
2682 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
2684 (
float)
_ui->doubleSpinBox_transferColorRadius->value(),
2685 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
2686 _ui->checkBox_cleanMesh->isChecked(),
2687 _ui->spinBox_mesh_minClusterSize->value(),
2689 meshes.insert(std::make_pair(
iter->first, mesh));
2698 QApplication::processEvents();
2706 else if(
_ui->checkBox_meshing->isChecked())
2708 std::string
msg =
uFormat(
"Some clouds are 2D laser scans. Meshing can be done only from RGB-D clouds or 3D laser scans.");
2712 else if(
_ui->checkBox_cameraProjection->isEnabled() &&
2713 _ui->checkBox_cameraProjection->isChecked() &&
2714 cloudsWithNormals.size()==1 && cloudsWithNormals.begin()->first==0)
2717 QApplication::processEvents();
2719 QApplication::processEvents();
2721 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloud = cloudsWithNormals.begin()->second;
2724 std::map<int, std::vector<CameraModel> > cameraModels;
2725 for(std::map<int, Transform>::const_iterator
iter=poses.lower_bound(0);
iter!=poses.end(); ++
iter)
2727 std::vector<CameraModel> models;
2728 std::vector<StereoCameraModel> stereoModels;
2729 if(cachedSignatures.contains(
iter->first))
2732 models =
data.cameraModels();
2733 stereoModels =
data.stereoCameraModels();
2740 if(stereoModels.size())
2743 for(
size_t i=0;
i<stereoModels.size(); ++
i)
2745 models.push_back(stereoModels[
i].left());
2749 if(models.size() == 0 || !models[0].isValidForProjection())
2754 if(!models.empty() && models[0].imageWidth() != 0 && models[0].imageHeight() != 0)
2757 cameraModels.insert(std::make_pair(
iter->first, models));
2761 UWARN(
"%d node has invalid camera models, ignoring it.",
iter->first);
2768 std::vector<float> roiRatios;
2769 QStringList strings =
_ui->lineEdit_camProjRoiRatios->text().split(
' ');
2770 if(!
_ui->lineEdit_meshingTextureRoiRatios->text().isEmpty())
2772 if(strings.size()==4)
2774 roiRatios.resize(4);
2775 roiRatios[0]=strings[0].toDouble();
2776 roiRatios[1]=strings[1].toDouble();
2777 roiRatios[2]=strings[2].toDouble();
2778 roiRatios[3]=strings[3].toDouble();
2779 if(!(roiRatios[0]>=0.0
f && roiRatios[0]<=1.0
f &&
2780 roiRatios[1]>=0.0
f && roiRatios[1]<=1.0
f &&
2781 roiRatios[2]>=0.0
f && roiRatios[2]<=1.0
f &&
2782 roiRatios[3]>=0.0
f && roiRatios[3]<=1.0
f))
2787 if(roiRatios.empty())
2789 QString
msg = tr(
"Wrong ROI format. Region of Interest (ROI) must "
2790 "have 4 values [left right top bottom] between 0 and 1 "
2791 "separated by space (%1), ignoring it for projecting cameras...")
2792 .arg(
_ui->lineEdit_camProjRoiRatios->text());
2799 std::map<int, std::vector<rtabmap::CameraModel> > cameraModelsProj;
2800 if(
_ui->spinBox_camProjDecimation->value()>1)
2802 for(std::map<
int, std::vector<rtabmap::CameraModel> >::
iterator iter=cameraModels.begin();
2803 iter!=cameraModels.end();
2806 std::vector<rtabmap::CameraModel> models;
2807 for(
size_t i=0;
i<
iter->second.size(); ++
i)
2809 models.push_back(
iter->second[
i].scaled(1.0/
double(
_ui->spinBox_camProjDecimation->value())));
2811 cameraModelsProj.insert(std::make_pair(
iter->first, models));
2816 cameraModelsProj = cameraModels;
2820 if(!
_ui->lineEdit_camProjMaskFilePath->text().isEmpty())
2822 projMask = cv::imread(
_ui->lineEdit_camProjMaskFilePath->text().toStdString(), cv::IMREAD_GRAYSCALE);
2823 if(
_ui->spinBox_camProjDecimation->value()>1)
2825 cv::Mat
out = projMask;
2826 cv::resize(projMask,
out, cv::Size(), 1.0
f/
float(
_ui->spinBox_camProjDecimation->value()), 1.0f/
float(
_ui->spinBox_camProjDecimation->value()), cv::INTER_NEAREST);
2831 std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > pointToPixel;
2836 _ui->doubleSpinBox_camProjMaxDistance->value(),
2837 _ui->doubleSpinBox_camProjMaxAngle->value()*
M_PI/180.0,
2840 _ui->checkBox_camProjDistanceToCamPolicy->isChecked(),
2849 UASSERT(pointToPixel.empty() || pointToPixel.size() == assembledCloud->size());
2850 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloudValidPoints;
2851 if(!
_ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked())
2853 assembledCloudValidPoints.reset(
new pcl::PointCloud<pcl::PointXYZRGBNormal>());
2854 assembledCloudValidPoints->resize(assembledCloud->size());
2856 if(
_ui->comboBox_camProjExportCamera->isEnabled() &&
2857 _ui->comboBox_camProjExportCamera->currentIndex()>0)
2859 textureVertexToPixels.resize(assembledCloud->size());
2862 if(
_ui->checkBox_camProjRecolorPoints->isChecked())
2867 int nodeID =
iter->first;
2870 if(cachedSignatures.contains(nodeID) && !cachedSignatures.value(nodeID).sensorData().imageCompressed().empty())
2872 cachedSignatures.value(nodeID).sensorData().uncompressDataConst(&image, 0);
2878 data.uncompressDataConst(&image, 0);
2883 if(
_ui->spinBox_camProjDecimation->value()>1)
2888 UASSERT(cameraModelsProj.find(nodeID) != cameraModelsProj.end());
2889 int modelsSize = cameraModelsProj.at(nodeID).size();
2890 for(
size_t i=0;
i<pointToPixel.size(); ++
i)
2892 int cameraIndex = pointToPixel[
i].first.second;
2893 if(nodeID == pointToPixel[
i].
first.first && cameraIndex>=0)
2895 int subImageWidth = image.cols / modelsSize;
2896 cv::Mat subImage = image(
cv::Range::all(), cv::Range(cameraIndex*subImageWidth, (cameraIndex+1)*subImageWidth));
2898 int x = pointToPixel[
i].second.x * (
float)subImage.cols;
2899 int y = pointToPixel[
i].second.y * (
float)subImage.rows;
2903 pcl::PointXYZRGBNormal & pt = assembledCloud->at(
i);
2904 if(subImage.type()==CV_8UC3)
2906 cv::Vec3b bgr = subImage.at<cv::Vec3b>(
y,
x);
2913 UASSERT(subImage.type()==CV_8UC1);
2914 pt.r = pt.g = pt.b = subImage.at<
unsigned char>(pointToPixel[
i].second.y * subImage.rows, pointToPixel[
i].second.x * subImage.cols);
2919 QString
msg = tr(
"Processed %1/%2 images").arg(imagesDone++).arg(
cameraPoses.size());
2922 QApplication::processEvents();
2926 pcl::IndicesPtr validIndices(
new std::vector<int>(pointToPixel.size()));
2928 for(
size_t i=0;
i<pointToPixel.size() && !
_canceled; ++
i)
2930 pcl::PointXYZRGBNormal & pt = assembledCloud->at(
i);
2931 if(pointToPixel[
i].
first.first <=0)
2933 if(
_ui->checkBox_camProjRecolorPoints->isChecked() && !
_ui->checkBox_fromDepth->isChecked() && !
_scansHaveRGB)
2943 int nodeID = pointToPixel[
i].first.first;
2944 int cameraIndex = pointToPixel[
i].first.second;
2945 int exportedId = nodeID;
2946 if(
_ui->comboBox_camProjExportCamera->currentIndex() == 2)
2948 exportedId = cameraIndex+1;
2950 else if(
_ui->comboBox_camProjExportCamera->currentIndex() == 3)
2952 UASSERT_MSG(cameraIndex<10,
"Exporting cam id as NodeId+CamIndex is only supported when the number of cameras per node < 10.");
2953 exportedId = nodeID*10 + cameraIndex;
2956 if(assembledCloudValidPoints.get())
2958 if(!textureVertexToPixels.empty())
2960 textureVertexToPixels[oi].insert(std::make_pair(exportedId, pointToPixel[
i].
second));
2962 assembledCloudValidPoints->at(oi++) = pt;
2964 else if(!textureVertexToPixels.empty())
2966 textureVertexToPixels[
i].insert(std::make_pair(exportedId, pointToPixel[
i].
second));
2971 if(assembledCloudValidPoints.get())
2973 assembledCloudValidPoints->resize(oi);
2974 cloudsWithNormals.begin()->second = assembledCloudValidPoints;
2976 if(!textureVertexToPixels.empty())
2978 textureVertexToPixels.resize(oi);
2990 #ifdef RTABMAP_CPUTSDF
2994 QApplication::processEvents();
2996 QApplication::processEvents();
2998 cpu_tsdf::MarchingCubesTSDFOctree mc;
2999 mc.setMinWeight (
_ui->doubleSpinBox_cputsdf_minWeight->value());
3000 mc.setInputTSDF (tsdf);
3001 mc.setColorByRGB (
true);
3002 pcl::PolygonMesh::Ptr mesh (
new pcl::PolygonMesh);
3003 mc.reconstruct (*mesh);
3007 if(mesh->polygons.size()>0)
3010 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr
vertices (
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3011 pcl::fromPCLPointCloud2 (mesh->cloud, *
vertices);
3013 if(
_ui->doubleSpinBox_cputsdf_flattenRadius->value()>0.0)
3016 QApplication::processEvents();
3018 QApplication::processEvents();
3020 float min_dist =
_ui->doubleSpinBox_cputsdf_flattenRadius->value();
3021 pcl::search::KdTree<pcl::PointXYZRGBNormal> vert_tree (
true);
3022 vert_tree.setInputCloud (
vertices);
3024 std::vector<int> vertex_remap (
vertices->size (), -1);
3026 std::vector<int> neighbors;
3027 std::vector<float> dists;
3028 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr vertices_new(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3029 vertices_new->resize(
vertices->size ());
3032 if (vertex_remap[
i] >= 0)
3034 vertex_remap[
i] = idx;
3035 vert_tree.radiusSearch (
i, min_dist, neighbors, dists);
3036 for (
size_t j = 1;
j < neighbors.size ();
j++)
3038 if (dists[
j] < min_dist)
3039 vertex_remap[neighbors[
j]] = idx;
3041 vertices_new->at(idx++) =
vertices->at (
i);
3043 vertices_new->resize(idx);
3044 std::vector<size_t> faces_to_remove;
3045 size_t face_idx = 0;
3046 for (
size_t i = 0;
i < mesh->polygons.size ();
i++)
3048 pcl::Vertices &
v = mesh->polygons[
i];
3049 for (
size_t j = 0;
j <
v.vertices.size ();
j++)
3051 v.vertices[
j] = vertex_remap[
v.vertices[
j]];
3053 if (!(
v.vertices[0] ==
v.vertices[1] ||
v.vertices[1] ==
v.vertices[2] ||
v.vertices[2] ==
v.vertices[0]))
3055 mesh->polygons[face_idx++] = mesh->polygons[
i];
3058 mesh->polygons.resize (face_idx);
3059 pcl::toPCLPointCloud2 (*vertices_new, mesh->cloud);
3063 pcl::fromPCLPointCloud2(mesh->cloud, *
vertices);
3065 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
3067 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(
float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
3068 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
3070 (
float)
_ui->doubleSpinBox_transferColorRadius->value(),
3071 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
3072 _ui->checkBox_cleanMesh->isChecked(),
3073 _ui->spinBox_mesh_minClusterSize->value(),
3075 meshes.insert(std::make_pair(0, mesh));
3084 #ifdef RTABMAP_OPENCHISEL
3088 QApplication::processEvents();
3090 QApplication::processEvents();
3092 const chisel::MeshMap& meshMap = chiselMap->GetChunkManager().GetAllMeshes();
3103 if(mesh->polygons.size()>0)
3105 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3106 pcl::fromPCLPointCloud2(mesh->cloud, *mergedClouds);
3107 if(
_ui->checkBox_openchisel_mergeVertices->isChecked())
3109 _progressDialog->
appendText(tr(
"Filtering assembled mesh for close vertices (points=%1, polygons=%2)...").
arg(mergedClouds->size()).
arg(mesh->polygons.size()));
3110 QApplication::processEvents();
3115 _ui->doubleSpinBox_voxelSize_assembled->value()/2.0,
3120 unsigned int count = mesh->polygons.size();
3123 QApplication::processEvents();
3126 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr filteredCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3127 std::vector<pcl::Vertices> filteredPolygons;
3128 count = mergedClouds->size();
3130 mergedClouds = filteredCloud;
3131 pcl::toPCLPointCloud2(*mergedClouds, mesh->cloud);
3132 mesh->polygons = filteredPolygons;
3134 QApplication::processEvents();
3137 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
3139 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(
float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
3140 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
3142 (
float)
_ui->doubleSpinBox_transferColorRadius->value(),
3143 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
3144 _ui->checkBox_cleanMesh->isChecked(),
3145 _ui->spinBox_mesh_minClusterSize->value(),
3147 meshes.insert(std::make_pair(0, mesh));
3164 UDEBUG(
"texture mapping=%d",
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()?1:0);
3165 if(!has2dScans && !meshes.empty() &&
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked())
3168 QApplication::processEvents();
3170 QApplication::processEvents();
3173 for(std::map<int, pcl::PolygonMesh::Ptr>::iterator
iter=meshes.begin();
3174 iter!= meshes.end();
3177 std::map<int, Transform>
cameras;
3178 if(
iter->first == 0)
3188 std::map<int, std::vector<CameraModel> > cameraModels;
3189 std::map<int, cv::Mat > cameraDepths;
3190 int ignoredCameras = 0;
3191 for(std::map<int, Transform>::iterator jter=
cameras.begin(); jter!=
cameras.end(); ++jter)
3193 if(validCameras.find(jter->first) != validCameras.end())
3195 std::vector<CameraModel> models;
3196 std::vector<StereoCameraModel> stereoModels;
3197 bool cacheHasCompressedImage =
false;
3198 if(cachedSignatures.contains(jter->first))
3200 const SensorData &
data = cachedSignatures.find(jter->first)->sensorData();
3201 models =
data.cameraModels();
3202 stereoModels =
data.stereoCameraModels();
3203 cacheHasCompressedImage = !
data.imageCompressed().empty();
3211 if(stereoModels.size())
3215 for(
size_t i=0;
i<stereoModels.size(); ++
i)
3217 models.push_back(stereoModels[
i].left());
3221 if(models.size() == 0 || !models[0].isValidForProjection())
3226 if(!jter->second.isNull() && models.size())
3229 bool blurryImage =
false;
3230 bool getDepth = !stereo &&
_ui->doubleSpinBox_meshingTextureMaxDepthError->value() >= 0.0f;
3233 if(models[0].imageWidth() == 0 || models[0].imageHeight() == 0)
3237 if(cacheHasCompressedImage)
3239 cachedSignatures.find(jter->first)->sensorData().uncompressDataConst(&
img,
getDepth?&depth:0);
3240 velocity = cachedSignatures.find(jter->first)->getVelocity();
3248 if(
_ui->checkBox_cameraFilter->isChecked() &&
3249 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
3260 cv::Size imageSize =
img.size();
3261 imageSize.width /= models.size();
3262 for(
unsigned int i=0;
i<models.size(); ++
i)
3264 models[
i].setImageSize(imageSize);
3269 bool getImg =
_ui->checkBox_cameraFilter->isChecked() &&
_ui->doubleSpinBox_laplacianVariance->value()>0.0;
3271 if(cacheHasCompressedImage)
3273 cachedSignatures.find(jter->first)->sensorData().uncompressDataConst(getImg?&
img:0,
getDepth?&depth:0);
3274 velocity = cachedSignatures.find(jter->first)->getVelocity();
3282 if(
_ui->checkBox_cameraFilter->isChecked() &&
3283 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
3295 if(
_ui->checkBox_cameraFilter->isChecked())
3299 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
3305 if(
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 && transVel >
_ui->doubleSpinBox_cameraFilterVel->value())
3307 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());
3310 else if(
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0 && rotVel >
_ui->doubleSpinBox_cameraFilterVelRad->value())
3312 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());
3318 UWARN(
"Camera motion filtering is set, but velocity of camera %d is not available.", jter->first);
3322 if(!blurryImage && !
img.empty() &&
_ui->doubleSpinBox_laplacianVariance->value()>0.0)
3324 cv::Mat imgLaplacian;
3325 cv::Laplacian(
img, imgLaplacian, CV_16S);
3327 cv::meanStdDev(imgLaplacian,
m,
s);
3328 double stddev_pxl =
s.at<
double>(0);
3329 double var = stddev_pxl*stddev_pxl;
3330 if(var < _ui->doubleSpinBox_laplacianVariance->value())
3333 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());
3339 QApplication::processEvents();
3344 if(!blurryImage && models[0].imageWidth() != 0 && models[0].imageHeight() != 0)
3346 cameraPoses.insert(std::make_pair(jter->first, jter->second));
3347 cameraModels.insert(std::make_pair(jter->first, models));
3350 cameraDepths.insert(std::make_pair(jter->first, depth));
3356 if(ignoredCameras > (
int)validCameras.size()/2)
3358 std::string
msg =
uFormat(
"More than 50%% of the cameras (%d/%d) have been filtered for "
3359 "too fast motion and/or blur level. You may adjust the corresponding thresholds.",
3360 ignoredCameras, (
int)validCameras.size());
3364 QApplication::processEvents();
3369 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
3370 std::map<int, std::vector<int> >
::iterator oter = organizedIndices.find(
iter->first);
3371 std::map<int, cv::Size>::iterator ster = organizedCloudSizes.find(
iter->first);
3372 if(
iter->first != 0 && oter != organizedIndices.end())
3374 UASSERT(ster!=organizedCloudSizes.end()&&ster->first == oter->first);
3375 UDEBUG(
"Texture by pixels");
3376 textureMesh->cloud =
iter->second->cloud;
3377 textureMesh->tex_polygons.push_back(
iter->second->polygons);
3378 int w = ster->second.width;
3379 int h = ster->second.height;
3381 if(textureMesh->tex_polygons.size() && textureMesh->tex_polygons[0].size())
3383 textureMesh->tex_coordinates.resize(1);
3386 int polygonSize = (
int)textureMesh->tex_polygons[0][0].vertices.size();
3387 textureMesh->tex_coordinates[0].resize(polygonSize*textureMesh->tex_polygons[0].size());
3388 for(
unsigned int i=0;
i<textureMesh->tex_polygons[0].size(); ++
i)
3390 const pcl::Vertices &
vertices = textureMesh->tex_polygons[0][
i];
3392 for(
int k=0; k<polygonSize; ++k)
3396 int originalVertex = oter->second[
vertices.vertices[k]];
3397 textureMesh->tex_coordinates[0][
i*polygonSize+k] = Eigen::Vector2f(
3398 float(originalVertex %
w) /
float(
w),
3399 float(
h - originalVertex /
w) /
float(
h));
3403 pcl::TexMaterial mesh_material;
3404 mesh_material.tex_d = 1.0f;
3405 mesh_material.tex_Ns = 75.0f;
3406 mesh_material.tex_illum = 1;
3408 std::stringstream tex_name;
3409 tex_name <<
"material_" <<
iter->first;
3410 tex_name >> mesh_material.tex_name;
3412 mesh_material.tex_file =
uFormat(
"%d",
iter->first);
3413 textureMesh->tex_materials.push_back(mesh_material);
3417 UWARN(
"No polygons for mesh %d!?",
iter->first);
3422 UDEBUG(
"Texture by projection");
3424 if(
cameraPoses.size() &&
_ui->checkBox_cameraFilter->isChecked())
3428 _ui->doubleSpinBox_cameraFilterRadius->value(),
3429 _ui->doubleSpinBox_cameraFilterAngle->value());
3430 for(std::map<
int, std::vector<CameraModel> >::
iterator modelIter = cameraModels.begin(); modelIter!=cameraModels.end();)
3434 cameraModels.erase(modelIter++);
3435 cameraDepths.erase(modelIter->first);
3443 QApplication::processEvents();
3445 QApplication::processEvents();
3455 if(cameraModels.size() && cameraModels.begin()->second.size()>1)
3460 std::vector<float> roiRatios;
3461 QStringList strings =
_ui->lineEdit_meshingTextureRoiRatios->text().split(
' ');
3462 if(!
_ui->lineEdit_meshingTextureRoiRatios->text().isEmpty())
3464 if(strings.size()==4)
3466 roiRatios.resize(4);
3467 roiRatios[0]=strings[0].toDouble();
3468 roiRatios[1]=strings[1].toDouble();
3469 roiRatios[2]=strings[2].toDouble();
3470 roiRatios[3]=strings[3].toDouble();
3471 if(!(roiRatios[0]>=0.0
f && roiRatios[0]<=1.0
f &&
3472 roiRatios[1]>=0.0
f && roiRatios[1]<=1.0
f &&
3473 roiRatios[2]>=0.0
f && roiRatios[2]<=1.0
f &&
3474 roiRatios[3]>=0.0
f && roiRatios[3]<=1.0
f))
3479 if(roiRatios.empty())
3481 QString
msg = tr(
"Wrong ROI format. Region of Interest (ROI) must have 4 "
3482 "values [left right top bottom] between 0 and 1 "
3483 "separated by space (%1), ignoring it for texturing...")
3484 .arg(
_ui->lineEdit_meshingTextureRoiRatios->text());
3496 _ui->doubleSpinBox_meshingTextureMaxDistance->value(),
3497 _ui->doubleSpinBox_meshingTextureMaxDepthError->value(),
3498 _ui->doubleSpinBox_meshingTextureMaxAngle->value()*
M_PI/180.0,
3499 _ui->spinBox_mesh_minTextureClusterSize->value(),
3503 _ui->checkBox_distanceToCamPolicy->isChecked());
3511 if(
_ui->checkBox_cleanMesh->isChecked())
3513 unsigned int totalSize = 0;
3514 for(
unsigned int t=0;
t<textureMesh->tex_polygons.size(); ++
t)
3516 totalSize+=textureMesh->tex_polygons[
t].size();
3521 unsigned int totalSizeAfter = 0;
3522 for(
unsigned int t=0;
t<textureMesh->tex_polygons.size(); ++
t)
3524 totalSizeAfter+=textureMesh->tex_polygons[
t].size();
3530 textureMeshes.insert(std::make_pair(
iter->first, textureMesh));
3536 UWARN(
"No camera poses!?");
3542 UWARN(
"No polygons!");
3547 QApplication::processEvents();
3554 if(textureMeshes.size() > 1 &&
_ui->checkBox_assemble->isChecked())
3556 UDEBUG(
"Concatenate texture meshes");
3558 QApplication::processEvents();
3560 QApplication::processEvents();
3563 textureMeshes.clear();
3564 textureMeshes.insert(std::make_pair(0, assembledMesh));
3575 const std::map<int, Transform> & poses,
3576 const QMap<int, Signature> & cachedSignatures,
3577 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
3578 const std::map<int, LaserScan> & cachedScans,
3581 bool & scansHaveRGB)
const
3583 scansHaveRGB =
false;
3585 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
3587 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr previousCloud;
3588 pcl::IndicesPtr previousIndices;
3590 for(std::map<int, Transform>::const_iterator
iter = poses.lower_bound(1);
iter!=poses.end() && !
_canceled; ++
iter, ++index)
3593 int totalIndices = 0;
3594 if(!
iter->second.isNull())
3596 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3597 pcl::IndicesPtr
indices(
new std::vector<int>);
3599 if(
_ui->checkBox_regenerate->isChecked())
3603 if(cachedSignatures.contains(
iter->first))
3605 const Signature &
s = cachedSignatures.find(
iter->first).value();
3606 data =
s.sensorData();
3607 cv::Mat image,depth;
3608 data.uncompressData(
3609 _ui->checkBox_fromDepth->isChecked()?&image:0,
3610 _ui->checkBox_fromDepth->isChecked()?&depth:0,
3611 !
_ui->checkBox_fromDepth->isChecked()?&scan:0);
3615 cv::Mat image,depth;
3617 data.uncompressData(
3618 _ui->checkBox_fromDepth->isChecked()?&image:0,
3619 _ui->checkBox_fromDepth->isChecked()?&depth:0,
3620 !
_ui->checkBox_fromDepth->isChecked()?&scan:0);
3623 if(
_ui->checkBox_fromDepth->isChecked() && !
data.imageRaw().empty() && !
data.depthOrRightRaw().empty())
3625 cv::Mat depth =
data.depthRaw();
3626 if(!depth.empty() &&
_ui->spinBox_fillDepthHoles->value() > 0)
3631 if(!depth.empty() &&
3632 !
_ui->lineEdit_distortionModel->text().isEmpty() &&
3633 QFileInfo(
_ui->lineEdit_distortionModel->text()).exists())
3636 model.load(
_ui->lineEdit_distortionModel->text().toStdString());
3637 depth = depth.clone();
3638 model.undistort(depth);
3642 if(!depth.empty() &&
_ui->checkBox_bilateral->isChecked())
3645 _ui->doubleSpinBox_bilateral_sigmaS->value(),
3646 _ui->doubleSpinBox_bilateral_sigmaR->value());
3651 data.setRGBDImage(
data.imageRaw(), depth,
data.cameraModels());
3655 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
3656 std::vector<float> roiRatios;
3657 if(!
_ui->lineEdit_roiRatios->text().isEmpty())
3659 QStringList
values =
_ui->lineEdit_roiRatios->text().split(
' ');
3662 roiRatios.resize(4);
3671 _ui->spinBox_decimation->value() == 0?1:
_ui->spinBox_decimation->value(),
3672 _ui->doubleSpinBox_maxDepth->value(),
3673 _ui->doubleSpinBox_minDepth->value(),
3678 if(cloudWithoutNormals->size())
3681 if(!(
_ui->comboBox_pipeline->currentIndex()==0 &&
_ui->checkBox_meshing->isChecked()) &&
_ui->doubleSpinBox_voxelSize_assembled->value()>0.0)
3684 indices->resize(cloudWithoutNormals->size());
3685 for(
unsigned int i=0;
i<
indices->size(); ++
i)
3692 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3693 if(
data.cameraModels().size() && !
data.cameraModels()[0].localTransform().isNull())
3695 localTransform =
data.cameraModels()[0].localTransform();
3696 viewPoint[0] =
data.cameraModels()[0].localTransform().x();
3697 viewPoint[1] =
data.cameraModels()[0].localTransform().y();
3698 viewPoint[2] =
data.cameraModels()[0].localTransform().z();
3700 else if(
data.stereoCameraModels().size() && !
data.stereoCameraModels()[0].localTransform().isNull())
3702 localTransform =
data.stereoCameraModels()[0].localTransform();
3703 viewPoint[0] =
data.stereoCameraModels()[0].localTransform().x();
3704 viewPoint[1] =
data.stereoCameraModels()[0].localTransform().y();
3705 viewPoint[2] =
data.stereoCameraModels()[0].localTransform().z();
3708 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
3710 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals,
indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
3711 pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
3712 if(
_ui->doubleSpinBox_groundNormalsUp->value() > 0.0)
3719 pcl::copyPointCloud(*cloudWithoutNormals, *cloud);
3722 if(
_ui->checkBox_subtraction->isChecked() &&
3723 _ui->doubleSpinBox_subtractPointFilteringRadius->value() > 0.0)
3725 pcl::IndicesPtr beforeSubtractionIndices =
indices;
3726 if( cloud->size() &&
3727 previousCloud.get() != 0 &&
3728 previousIndices.get() != 0 &&
3729 previousIndices->size() &&
3739 _ui->doubleSpinBox_subtractPointFilteringRadius->value(),
3740 _ui->doubleSpinBox_subtractPointFilteringAngle->value(),
3741 _ui->spinBox_subtractFilteringMinPts->value());
3743 previousCloud = cloud;
3744 previousIndices = beforeSubtractionIndices;
3745 previousPose =
iter->second;
3749 else if(!
_ui->checkBox_fromDepth->isChecked() && !scan.
isEmpty())
3752 _ui->spinBox_decimation_scan->value(),
3753 _ui->doubleSpinBox_rangeMin->value(),
3754 _ui->doubleSpinBox_rangeMax->value(),
3755 _ui->doubleSpinBox_voxelSize_assembled->value(),
3756 _ui->spinBox_normalKSearch->value(),
3757 _ui->doubleSpinBox_normalRadiusSearch->value());
3761 scansHaveRGB = scan.
hasRGB();
3765 indices->resize(cloud->size());
3766 for(
unsigned int i=0;
i<
indices->size(); ++
i)
3774 if(cachedSignatures.contains(
iter->first))
3776 const Signature &
s = cachedSignatures.find(
iter->first).value();
3777 weight =
s.getWeight();
3785 UERROR(
"Cloud %d not found in cache!",
iter->first);
3789 else if(
_ui->checkBox_fromDepth->isChecked() &&
uContains(cachedClouds,
iter->first))
3791 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
3792 if(!
_ui->checkBox_meshing->isChecked() &&
3793 _ui->doubleSpinBox_voxelSize_assembled->value() > 0.0)
3796 cachedClouds.at(
iter->first).first,
3797 cachedClouds.at(
iter->first).second,
3798 _ui->doubleSpinBox_voxelSize_assembled->value());
3801 indices->resize(cloudWithoutNormals->size());
3802 for(
unsigned int i=0;
i<cloudWithoutNormals->size(); ++
i)
3809 cloudWithoutNormals = cachedClouds.at(
iter->first).first;
3814 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3815 std::vector<CameraModel> models;
3816 std::vector<StereoCameraModel> stereoModels;
3817 if(cachedSignatures.contains(
iter->first))
3819 const Signature &
s = cachedSignatures.find(
iter->first).value();
3820 models =
s.sensorData().cameraModels();
3821 stereoModels =
s.sensorData().stereoCameraModels();
3828 if(models.size() && !models[0].localTransform().isNull())
3830 localTransform = models[0].localTransform();
3831 viewPoint[0] = models[0].localTransform().
x();
3832 viewPoint[1] = models[0].localTransform().y();
3833 viewPoint[2] = models[0].localTransform().z();
3835 else if(stereoModels.size() && !stereoModels[0].localTransform().isNull())
3837 localTransform = stereoModels[0].localTransform();
3838 viewPoint[0] = stereoModels[0].localTransform().
x();
3839 viewPoint[1] = stereoModels[0].localTransform().y();
3840 viewPoint[2] = stereoModels[0].localTransform().z();
3844 _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);
3847 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
3849 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals,
indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
3850 pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
3851 if(
_ui->doubleSpinBox_groundNormalsUp->value() > 0.0)
3858 pcl::copyPointCloud(*cloudWithoutNormals, *cloud);
3861 else if(!
_ui->checkBox_fromDepth->isChecked() &&
uContains(cachedScans,
iter->first))
3864 _ui->spinBox_decimation_scan->value(),
3865 _ui->doubleSpinBox_rangeMin->value(),
3866 _ui->doubleSpinBox_rangeMax->value(),
3867 _ui->doubleSpinBox_voxelSize_assembled->value(),
3868 _ui->spinBox_normalKSearch->value(),
3869 _ui->doubleSpinBox_normalRadiusSearch->value());
3873 scansHaveRGB = scan.
hasRGB();
3877 indices->resize(cloud->size());
3878 for(
unsigned int i=0;
i<
indices->size(); ++
i)
3886 if(cachedSignatures.contains(
iter->first))
3888 const Signature &
s = cachedSignatures.find(
iter->first).value();
3889 weight =
s.getWeight();
3897 _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);
3901 if(
_ui->checkBox_filtering->isChecked())
3904 (
_ui->doubleSpinBox_ceilingHeight->value() != 0.0 ||
3905 _ui->doubleSpinBox_floorHeight->value() != 0.0))
3907 float min =
_ui->doubleSpinBox_floorHeight->value();
3908 float max =
_ui->doubleSpinBox_ceilingHeight->value();
3917 (
_ui->doubleSpinBox_footprintHeight->value() != 0.0 &&
3918 _ui->doubleSpinBox_footprintWidth->value() != 0.0 &&
3919 _ui->doubleSpinBox_footprintLength->value() != 0.0))
3922 float h =
_ui->doubleSpinBox_footprintHeight->value();
3923 float w =
_ui->doubleSpinBox_footprintWidth->value();
3924 float l =
_ui->doubleSpinBox_footprintLength->value();
3943 _ui->doubleSpinBox_filteringRadius->value() > 0.0f &&
3944 _ui->spinBox_filteringMinNeighbors->value() > 0)
3949 UWARN(
"Point cloud %d doesn't have anymore points (had %d points) after radius filtering.",
iter->first, (
int)cloud->size());
3952 if( !
indices->empty() &&
_ui->groupBox_offAxisFiltering->isChecked() &&
3953 (
_ui->checkBox_offAxisFilteringPosX->isChecked() ||
3954 _ui->checkBox_offAxisFilteringNegX->isChecked() ||
3955 _ui->checkBox_offAxisFilteringPosY->isChecked() ||
3956 _ui->checkBox_offAxisFilteringNegY->isChecked() ||
3957 _ui->checkBox_offAxisFilteringPosZ->isChecked() ||
3958 _ui->checkBox_offAxisFilteringNegZ->isChecked()))
3961 std::vector<pcl::IndicesPtr> indicesVector;
3962 double maxDeltaAngle =
_ui->doubleSpinBox_offAxisFilteringAngle->value()*
M_PI/180.0;
3963 Eigen::Vector4f viewpoint(
iter->second.x(),
iter->second.y(),
iter->second.z(), 0);
3964 if(
_ui->checkBox_offAxisFilteringPosX->isChecked())
3966 if(
_ui->checkBox_offAxisFilteringPosY->isChecked())
3968 if(
_ui->checkBox_offAxisFilteringPosZ->isChecked())
3970 if(
_ui->checkBox_offAxisFilteringNegX->isChecked())
3972 if(
_ui->checkBox_offAxisFilteringNegY->isChecked())
3974 if(
_ui->checkBox_offAxisFilteringNegZ->isChecked())
3979 UWARN(
"Point cloud %d doesn't have anymore points (had %d points) after offaxis filtering.",
iter->first, (
int)cloud->size());
3986 if((
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==2) && cloud->isOrganized())
3990 else if(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==3)
3995 clouds.insert(std::make_pair(
iter->first, std::make_pair(cloud,
indices)));
3996 points = (
int)cloud->size();
4002 UERROR(
"transform is null!?");
4007 if(
_ui->checkBox_regenerate->isChecked())
4010 .
arg(
iter->first).
arg(points).arg(totalIndices).arg(index).arg(poses.size()));
4015 .
arg(
iter->first).
arg(points).arg(totalIndices).arg(index).arg(poses.size()));
4023 QApplication::processEvents();
4031 const QString & workingDirectory,
4032 const std::map<int, Transform> & poses,
4033 const std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds,
4035 const std::vector<std::map<int, pcl::PointXY> > & pointToPixels)
4037 if(clouds.size() == 1)
4040 QString
extensions = tr(
"Point cloud data (*.ply *.pcd");
4042 for(std::list<std::string>::iterator
iter=pdalFormats.begin();
iter!=pdalFormats.end(); ++
iter)
4044 if(
iter->compare(
"ply") == 0 ||
iter->compare(
"pcd") == 0)
4051 #elif defined(RTABMAP_LIBLAS)
4052 QString
extensions = tr(
"Point cloud data (*.ply *.pcd *.las *.laz)");
4054 QString
extensions = tr(
"Point cloud data (*.ply *.pcd)");
4056 QString
path = QFileDialog::getSaveFileName(
this, tr(
"Save cloud to ..."), workingDirectory+QDir::separator()+
"cloud.ply",
extensions);
4060 if(QFileInfo(
path).suffix().isEmpty())
4066 if(clouds.begin()->second->size())
4068 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudRGBWithoutNormals;
4069 pcl::PointCloud<pcl::PointXYZI>::Ptr cloudIWithoutNormals;
4070 pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloudIWithNormals;
4072 !(
_ui->checkBox_cameraProjection->isEnabled() &&
4073 _ui->checkBox_cameraProjection->isChecked() &&
4074 _ui->checkBox_camProjRecolorPoints->isChecked() &&
4075 clouds.size()==1 && clouds.begin()->first==0))
4078 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
4080 cloudIWithNormals.reset(
new pcl::PointCloud<pcl::PointXYZINormal>);
4081 cloudIWithNormals->resize(clouds.begin()->second->size());
4082 for(
unsigned int i=0;
i<cloudIWithNormals->size(); ++
i)
4084 cloudIWithNormals->points[
i].x = clouds.begin()->second->points[
i].x;
4085 cloudIWithNormals->points[
i].y = clouds.begin()->second->points[
i].y;
4086 cloudIWithNormals->points[
i].z = clouds.begin()->second->points[
i].z;
4087 cloudIWithNormals->points[
i].normal_x = clouds.begin()->second->points[
i].normal_x;
4088 cloudIWithNormals->points[
i].normal_y = clouds.begin()->second->points[
i].normal_y;
4089 cloudIWithNormals->points[
i].normal_z = clouds.begin()->second->points[
i].normal_z;
4090 cloudIWithNormals->points[
i].curvature = clouds.begin()->second->points[
i].curvature;
4091 int * intensity = (
int *)&cloudIWithNormals->points[
i].intensity;
4093 int(clouds.begin()->second->points[
i].r) |
4094 int(clouds.begin()->second->points[
i].g) << 8 |
4095 int(clouds.begin()->second->points[
i].b) << 16 |
4096 int(clouds.begin()->second->points[
i].a) << 24;
4101 cloudIWithoutNormals.reset(
new pcl::PointCloud<pcl::PointXYZI>);
4102 cloudIWithoutNormals->resize(clouds.begin()->second->size());
4103 for(
unsigned int i=0;
i<cloudIWithoutNormals->size(); ++
i)
4105 cloudIWithoutNormals->points[
i].x = clouds.begin()->second->points[
i].x;
4106 cloudIWithoutNormals->points[
i].y = clouds.begin()->second->points[
i].y;
4107 cloudIWithoutNormals->points[
i].z = clouds.begin()->second->points[
i].z;
4108 int * intensity = (
int *)&cloudIWithoutNormals->points[
i].intensity;
4110 int(clouds.begin()->second->points[
i].r) |
4111 int(clouds.begin()->second->points[
i].g) << 8 |
4112 int(clouds.begin()->second->points[
i].b) << 16 |
4113 int(clouds.begin()->second->points[
i].a) << 24;
4117 else if(
_ui->spinBox_normalKSearch->value()<=0 &&
_ui->doubleSpinBox_normalRadiusSearch->value()<=0.0)
4119 cloudRGBWithoutNormals.reset(
new pcl::PointCloud<pcl::PointXYZRGB>);
4120 pcl::copyPointCloud(*clouds.begin()->second, *cloudRGBWithoutNormals);
4125 bool success =
false;
4126 if(QFileInfo(
path).suffix() ==
"pcd")
4128 if(cloudIWithNormals.get())
4130 success = pcl::io::savePCDFile(
path.toStdString(), *cloudIWithNormals, binaryMode) == 0;
4132 else if(cloudIWithoutNormals.get())
4134 success = pcl::io::savePCDFile(
path.toStdString(), *cloudIWithoutNormals, binaryMode) == 0;
4136 else if(cloudRGBWithoutNormals.get())
4138 success = pcl::io::savePCDFile(
path.toStdString(), *cloudRGBWithoutNormals, binaryMode) == 0;
4142 success = pcl::io::savePCDFile(
path.toStdString(), *clouds.begin()->second, binaryMode) == 0;
4146 else if(QFileInfo(
path).suffix() ==
"ply" && pointToPixels.empty()) {
4148 else if(QFileInfo(
path).suffix() ==
"ply") {
4150 if(cloudIWithNormals.get())
4152 success = pcl::io::savePLYFile(
path.toStdString(), *cloudIWithNormals, binaryMode) == 0;
4154 else if(cloudIWithoutNormals.get())
4156 success = pcl::io::savePLYFile(
path.toStdString(), *cloudIWithoutNormals, binaryMode) == 0;
4158 else if(cloudRGBWithoutNormals.get())
4160 success = pcl::io::savePLYFile(
path.toStdString(), *cloudRGBWithoutNormals, binaryMode) == 0;
4164 success = pcl::io::savePLYFile(
path.toStdString(), *clouds.begin()->second, binaryMode) == 0;
4167 #if defined(RTABMAP_PDAL) || defined(RTABMAP_LIBLAS)
4168 else if(!QFileInfo(
path).suffix().isEmpty())
4170 std::vector<int> cameraIds(pointToPixels.size(), 0);
4171 for(
size_t i=0;
i<pointToPixels.size(); ++
i)
4173 if(!pointToPixels[
i].
empty())
4175 cameraIds[
i] = pointToPixels[
i].begin()->first;
4178 if(cloudIWithNormals.get())
4181 success =
savePDALFile(
path.toStdString(), *cloudIWithNormals, cameraIds, binaryMode) == 0;
4183 UERROR(
"Normals cannot be save with current libLAS implementation, disable normals estimation.");
4187 else if(cloudIWithoutNormals.get())
4190 success =
savePDALFile(
path.toStdString(), *cloudIWithoutNormals, cameraIds, binaryMode) == 0;
4192 success =
saveLASFile(
path.toStdString(), *cloudIWithoutNormals, cameraIds) == 0;
4195 else if(cloudRGBWithoutNormals.get())
4198 success =
savePDALFile(
path.toStdString(), *cloudRGBWithoutNormals, cameraIds, binaryMode) == 0;
4200 success =
saveLASFile(
path.toStdString(), *cloudRGBWithoutNormals, cameraIds) == 0;
4206 success =
savePDALFile(
path.toStdString(), *clouds.begin()->second, cameraIds, binaryMode) == 0;
4208 UERROR(
"Normals cannot be save with current libLAS implementation, disable normals estimation.");
4216 UERROR(
"Extension not recognized! (%s) Should be one of (*.ply *.pcd *.las).", QFileInfo(
path).suffix().toStdString().
c_str());
4223 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Cloud saved to \"%1\"").
arg(
path));
4227 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").
arg(
path));
4232 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Cloud is empty..."));
4236 else if(clouds.size())
4239 items.push_back(
"ply");
4240 items.push_back(
"pcd");
4242 QString
extensions = tr(
"Save clouds to (*.ply *.pcd");
4244 for(std::list<std::string>::iterator
iter=pdalFormats.begin();
iter!=pdalFormats.end(); ++
iter)
4246 if(
iter->compare(
"ply") == 0 ||
iter->compare(
"pcd") == 0)
4252 items.push_back(
iter->c_str());
4255 #elif defined(RTABMAP_LIBLAS)
4256 QString
extensions = tr(
"Save clouds to (*.ply *.pcd *.las *.laz)...");
4258 QString
extensions = tr(
"Save clouds to (*.ply *.pcd)...");
4260 QString
path = QFileDialog::getExistingDirectory(
this,
extensions, workingDirectory, QFileDialog::ShowDirsOnly);
4264 QString suffix = QInputDialog::getItem(
this, tr(
"File format"), tr(
"Which format?"), items, 0,
false, &ok);
4268 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"cloud", &ok);
4272 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::const_iterator
iter=clouds.begin();
iter!=clouds.end(); ++
iter)
4274 if(
iter->second->size())
4276 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformedCloud;
4279 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudRGBWithoutNormals;
4280 pcl::PointCloud<pcl::PointXYZI>::Ptr cloudIWithoutNormals;
4281 pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloudIWithNormals;
4285 if(
_ui->spinBox_normalKSearch->value()>0 ||
_ui->doubleSpinBox_normalRadiusSearch->value()>0.0)
4287 cloudIWithNormals.reset(
new pcl::PointCloud<pcl::PointXYZINormal>);
4288 cloudIWithNormals->resize(transformedCloud->size());
4289 for(
unsigned int i=0;
i<cloudIWithNormals->size(); ++
i)
4291 cloudIWithNormals->points[
i].x = transformedCloud->points[
i].x;
4292 cloudIWithNormals->points[
i].y = transformedCloud->points[
i].y;
4293 cloudIWithNormals->points[
i].z = transformedCloud->points[
i].z;
4294 cloudIWithNormals->points[
i].normal_x = transformedCloud->points[
i].normal_x;
4295 cloudIWithNormals->points[
i].normal_y = transformedCloud->points[
i].normal_y;
4296 cloudIWithNormals->points[
i].normal_z = transformedCloud->points[
i].normal_z;
4297 cloudIWithNormals->points[
i].curvature = transformedCloud->points[
i].curvature;
4298 int * intensity = (
int *)&cloudIWithNormals->points[
i].intensity;
4300 int(transformedCloud->points[
i].r) |
4301 int(transformedCloud->points[
i].g) << 8 |
4302 int(transformedCloud->points[
i].b) << 16 |
4303 int(transformedCloud->points[
i].a) << 24;
4308 cloudIWithoutNormals.reset(
new pcl::PointCloud<pcl::PointXYZI>);
4309 cloudIWithoutNormals->resize(transformedCloud->size());
4310 for(
unsigned int i=0;
i<cloudIWithoutNormals->size(); ++
i)
4312 cloudIWithoutNormals->points[
i].x = transformedCloud->points[
i].x;
4313 cloudIWithoutNormals->points[
i].y = transformedCloud->points[
i].y;
4314 cloudIWithoutNormals->points[
i].z = transformedCloud->points[
i].z;
4315 int * intensity = (
int *)&cloudIWithoutNormals->points[
i].intensity;
4317 int(transformedCloud->points[
i].r) |
4318 int(transformedCloud->points[
i].g) << 8 |
4319 int(transformedCloud->points[
i].b) << 16 |
4320 int(transformedCloud->points[
i].a) << 24;
4324 else if(
_ui->spinBox_normalKSearch->value()<=0 &&
_ui->doubleSpinBox_normalRadiusSearch->value()<=0.0)
4326 cloudRGBWithoutNormals.reset(
new pcl::PointCloud<pcl::PointXYZRGB>);
4327 pcl::copyPointCloud(*transformedCloud, *cloudRGBWithoutNormals);
4330 QString pathFile =
path+QDir::separator()+QString(
"%1%2.%3").arg(prefix).arg(
iter->first).arg(suffix);
4331 bool success =
false;
4334 if(cloudIWithNormals.get())
4336 success = pcl::io::savePCDFile(pathFile.toStdString(), *cloudIWithNormals, binaryMode) == 0;
4338 else if(cloudIWithoutNormals.get())
4340 success = pcl::io::savePCDFile(pathFile.toStdString(), *cloudIWithoutNormals, binaryMode) == 0;
4342 else if(cloudRGBWithoutNormals.get())
4344 success = pcl::io::savePCDFile(pathFile.toStdString(), *cloudRGBWithoutNormals, binaryMode) == 0;
4348 success = pcl::io::savePCDFile(pathFile.toStdString(), *transformedCloud, binaryMode) == 0;
4351 else if(suffix ==
"ply")
4353 if(cloudIWithNormals.get())
4355 success = pcl::io::savePLYFile(pathFile.toStdString(), *cloudIWithNormals, binaryMode) == 0;
4357 else if(cloudIWithoutNormals.get())
4359 success = pcl::io::savePLYFile(pathFile.toStdString(), *cloudIWithoutNormals, binaryMode) == 0;
4361 else if(cloudRGBWithoutNormals.get())
4363 success = pcl::io::savePLYFile(pathFile.toStdString(), *cloudRGBWithoutNormals, binaryMode) == 0;
4367 success = pcl::io::savePLYFile(pathFile.toStdString(), *transformedCloud, binaryMode) == 0;
4370 #if defined(RTABMAP_PDAL) || defined(RTABMAP_LIBLAS)
4371 else if(!suffix.isEmpty())
4373 if(cloudIWithNormals.get())
4376 success =
savePDALFile(pathFile.toStdString(), *cloudIWithNormals) == 0;
4378 UERROR(
"Normals cannot be save with current libLAS implementation, disable normals estimation.");
4382 else if(cloudIWithoutNormals.get())
4385 success =
savePDALFile(pathFile.toStdString(), *cloudIWithoutNormals) == 0;
4387 success =
saveLASFile(pathFile.toStdString(), *cloudIWithoutNormals) == 0;
4390 else if(cloudRGBWithoutNormals.get())
4393 success =
savePDALFile(pathFile.toStdString(), *cloudRGBWithoutNormals) == 0;
4395 success =
saveLASFile(pathFile.toStdString(), *cloudRGBWithoutNormals) == 0;
4401 success =
savePDALFile(pathFile.toStdString(), *transformedCloud) == 0;
4403 UERROR(
"Normals cannot be save with current libLAS implementation, disable normals estimation.");
4411 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
4428 QApplication::processEvents();
4441 const QString & workingDirectory,
4442 const std::map<int, Transform> & poses,
4443 const std::map<int, pcl::PolygonMesh::Ptr> & meshes,
4446 if(meshes.size() == 1)
4448 QString
path = QFileDialog::getSaveFileName(
this, tr(
"Save mesh to ..."), workingDirectory+QDir::separator()+
"mesh.ply", tr(
"Mesh (*.ply)"));
4451 if(meshes.begin()->second->polygons.size())
4454 QApplication::processEvents();
4456 QApplication::processEvents();
4458 bool success =
false;
4459 if(QFileInfo(
path).suffix() ==
"")
4464 if(QFileInfo(
path).suffix() ==
"ply")
4468 success = pcl::io::savePLYFileBinary(
path.toStdString(), *meshes.begin()->second) == 0;
4472 success = pcl::io::savePLYFile(
path.toStdString(), *meshes.begin()->second) == 0;
4475 else if(QFileInfo(
path).suffix() ==
"obj")
4481 UERROR(
"Extension not recognized! (%s) Should be (*.ply) or (*.obj).", QFileInfo(
path).suffix().toStdString().
c_str());
4488 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Mesh saved to \"%1\"").
arg(
path));
4492 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").
arg(
path));
4497 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Cloud is empty..."));
4501 else if(meshes.size())
4503 QString
path = QFileDialog::getExistingDirectory(
this, tr(
"Save meshes to (*.ply *.obj)..."), workingDirectory, QFileDialog::ShowDirsOnly);
4508 items.push_back(
"ply");
4509 items.push_back(
"obj");
4510 QString suffix = QInputDialog::getItem(
this, tr(
"File format"), tr(
"Which format?"), items, 0,
false, &ok);
4514 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"mesh", &ok);
4518 for(std::map<int, pcl::PolygonMesh::Ptr>::const_iterator
iter=meshes.begin();
iter!=meshes.end(); ++
iter)
4520 if(
iter->second->polygons.size())
4522 pcl::PolygonMesh mesh;
4523 mesh.polygons =
iter->second->polygons;
4525 for(
unsigned int i=0;
i<
iter->second->cloud.fields.size(); ++
i)
4527 if(
iter->second->cloud.fields[
i].name.compare(
"rgb") == 0)
4535 pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp(
new pcl::PointCloud<pcl::PointXYZRGB>);
4536 pcl::fromPCLPointCloud2(
iter->second->cloud, *tmp);
4538 pcl::toPCLPointCloud2(*tmp, mesh.cloud);
4542 pcl::PointCloud<pcl::PointXYZ>::Ptr tmp(
new pcl::PointCloud<pcl::PointXYZ>);
4543 pcl::fromPCLPointCloud2(
iter->second->cloud, *tmp);
4545 pcl::toPCLPointCloud2(*tmp, mesh.cloud);
4548 QString pathFile =
path+QDir::separator()+QString(
"%1%2.%3").arg(prefix).arg(
iter->first).arg(suffix);
4549 bool success =
false;
4554 success = pcl::io::savePLYFileBinary(pathFile.toStdString(), mesh) == 0;
4558 success = pcl::io::savePLYFile(pathFile.toStdString(), mesh) == 0;
4561 else if(suffix ==
"obj")
4567 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
4572 .
arg(
iter->first).
arg(
iter->second->polygons.size()).arg(pathFile));
4577 .
arg(
iter->first).
arg(
iter->second->polygons.size()).arg(pathFile), Qt::darkRed);
4586 QApplication::processEvents();
4599 const QString & workingDirectory,
4600 const std::map<int, Transform> & poses,
4601 std::map<int, pcl::TextureMesh::Ptr> & meshes,
4602 const QMap<int, Signature> & cachedSignatures,
4603 const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels)
4605 std::map<int, cv::Mat> images;
4606 std::map<int, std::vector<CameraModel> > calibrations;
4607 for(QMap<int, Signature>::const_iterator
iter=cachedSignatures.constBegin();
iter!=cachedSignatures.constEnd(); ++
iter)
4609 std::vector<CameraModel> models;
4610 if(
iter->sensorData().cameraModels().size())
4612 models =
iter->sensorData().cameraModels();
4614 else if(
iter->sensorData().stereoCameraModels().size())
4616 for(
size_t i=0;
i<
iter->sensorData().stereoCameraModels().
size(); ++
i)
4618 models.push_back(
iter->sensorData().stereoCameraModels()[
i].left());
4624 if(!
iter->sensorData().imageRaw().empty())
4626 calibrations.insert(std::make_pair(
iter.key(), models));
4627 images.insert(std::make_pair(
iter.key(),
iter->sensorData().imageRaw()));
4629 else if(!
iter->sensorData().imageCompressed().empty())
4631 calibrations.insert(std::make_pair(
iter.key(), models));
4632 images.insert(std::make_pair(
iter.key(),
iter->sensorData().imageCompressed()));
4636 int textureSize = 1024;
4637 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
4639 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
4641 int blendingDecimation = 0;
4642 if(
_ui->checkBox_blending->isChecked())
4644 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
4646 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
4650 if(meshes.size() == 1)
4652 QString
path = QFileDialog::getSaveFileName(
this, tr(
"Save texture mesh to ..."), workingDirectory+QDir::separator()+
"mesh.obj", tr(
"Mesh (*.obj)"));
4655 if(meshes.begin()->second->tex_materials.size())
4658 QApplication::processEvents();
4660 QApplication::processEvents();
4662 bool success =
false;
4663 if(QFileInfo(
path).suffix() ==
"")
4668 pcl::TextureMesh::Ptr mesh = meshes.begin()->second;
4670 cv::Mat globalTextures;
4671 bool texturesMerged =
_ui->comboBox_meshingTextureSize->isEnabled() &&
_ui->comboBox_meshingTextureSize->currentIndex() > 0;
4672 if(texturesMerged && mesh->tex_materials.size()>1)
4675 QApplication::processEvents();
4677 QApplication::processEvents();
4679 std::map<int, std::map<int, cv::Vec4d> > gains;
4680 std::map<int, std::map<int, cv::Mat> > blendingGains;
4681 std::pair<float, float> contrastValues(0,0);
4689 _ui->checkBox_multiband->isEnabled() &&
_ui->checkBox_multiband->isChecked()?1:
_ui->spinBox_mesh_maxTextures->value(),
4690 textureVertexToPixels,
4691 _ui->checkBox_gainCompensation->isChecked(),
4692 _ui->doubleSpinBox_gainBeta->value(),
4693 _ui->checkBox_gainRGB->isChecked(),
4694 _ui->checkBox_blending->isChecked(),
4696 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
4697 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
4698 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked(),
4706 QApplication::processEvents();
4708 QApplication::processEvents();
4710 if(
_ui->checkBox_multiband->isEnabled() &&
_ui->checkBox_multiband->isChecked() && mesh->tex_polygons.size() == 1)
4713 QApplication::processEvents();
4715 QApplication::processEvents();
4720 mesh->tex_polygons[0],
4722 textureVertexToPixels,
4728 _ui->spinBox_multiband_downscale->value(),
4729 _ui->lineEdit_multiband_nbcontrib->text().toStdString(),
4730 _ui->comboBox_meshingTextureFormat->currentText().toStdString(),
4735 _ui->comboBox_multiband_unwrap->currentIndex(),
4736 _ui->checkBox_multiband_fillholes->isChecked(),
4737 _ui->spinBox_multiband_padding->value(),
4738 _ui->doubleSpinBox_multiband_bestscore->value(),
4739 _ui->doubleSpinBox_multiband_angle->value(),
4740 _ui->checkBox_multiband_forcevisible->isChecked());
4746 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Mesh saved to \"%1\"").
arg(
path));
4750 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").
arg(
path));
4756 bool singleTexture = mesh->tex_materials.size() == 1;
4760 QDir(QFileInfo(
path).absoluteDir().absolutePath()).mkdir(QFileInfo(
path).baseName());
4764 cv::Mat previousImage;
4765 int previousTextureId = 0;
4766 std::vector<CameraModel> previousCameraModels;
4769 for(
unsigned int i=0;
i<mesh->tex_materials.size(); ++
i)
4771 if(!mesh->tex_materials[
i].tex_file.empty())
4777 fullPath = QFileInfo(
path).absoluteDir().absolutePath()+QDir::separator()+QFileInfo(
path).baseName()+
_ui->comboBox_meshingTextureFormat->currentText();
4781 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();
4783 UDEBUG(
"Saving %s...", fullPath.toStdString().c_str());
4784 if(singleTexture || !QFileInfo(fullPath).exists())
4786 std::list<std::string> texFileSplit =
uSplit(mesh->tex_materials[
i].tex_file,
'_');
4787 if(texFileSplit.size() &&
uIsInteger(texFileSplit.front(),
false))
4789 int textureId =
uStr2Int(texFileSplit.front());
4790 int textureSubCamera = -1;
4791 if(texFileSplit.size() == 2 &&
4794 textureSubCamera =
uStr2Int(texFileSplit.back());
4797 std::vector<CameraModel> cameraModels;
4799 if(textureId == previousTextureId)
4801 image = previousImage;
4802 cameraModels = previousCameraModels;
4806 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
4808 cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
4809 cameraModels = cachedSignatures.value(textureId).sensorData().cameraModels();
4815 data.uncompressDataConst(&image, 0);
4816 std::vector<StereoCameraModel> stereoModels;
4818 if(cameraModels.empty())
4820 for(
size_t i=0;
i<stereoModels.size(); ++
i)
4822 cameraModels.push_back(stereoModels[
i].left());
4827 previousImage = image;
4828 previousCameraModels = cameraModels;
4829 previousTextureId = textureId;
4832 imageSize = image.size();
4833 if(textureSubCamera>=0)
4836 imageSize.width/=cameraModels.size();
4837 image = image.colRange(imageSize.width*textureSubCamera, imageSize.width*(textureSubCamera+1));
4844 if(!cv::imwrite(fullPath.toStdString(), image))
4847 .
arg(mesh->tex_materials[
i].tex_file.c_str()).
arg(fullPath), Qt::darkRed);
4851 else if(imageSize.height && imageSize.width)
4854 cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
4855 cv::imwrite(fullPath.toStdString(), image);
4857 else if(!globalTextures.empty())
4859 if(!cv::imwrite(fullPath.toStdString(), globalTextures(
cv::Range::all(), cv::Range(
i*globalTextures.rows, (
i+1)*globalTextures.rows))))
4862 .
arg(mesh->tex_materials[
i].tex_file.c_str()).
arg(fullPath), Qt::darkRed);
4868 UWARN(
"Ignored texture %s (no image size set yet)", mesh->tex_materials[
i].tex_file.c_str());
4873 UWARN(
"File %s already exists!", fullPath.toStdString().c_str());
4878 mesh->tex_materials[
i].tex_file=QFileInfo(
path).baseName().toStdString()+
_ui->comboBox_meshingTextureFormat->currentText().toStdString();
4882 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();
4892 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Mesh saved to \"%1\"").
arg(
path));
4896 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").
arg(
path));
4901 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"No textures..."));
4905 else if(meshes.size())
4907 QString
path = QFileDialog::getExistingDirectory(
this, tr(
"Save texture meshes to (*.obj)..."), workingDirectory, QFileDialog::ShowDirsOnly);
4911 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"mesh", &ok);
4912 QString suffix =
"obj";
4916 for(std::map<int, pcl::TextureMesh::Ptr>::iterator
iter=meshes.begin();
iter!=meshes.end(); ++
iter)
4918 QString currentPrefix=prefix+QString::number(
iter->first);
4919 if(
iter->second->tex_materials.size())
4921 pcl::TextureMesh::Ptr mesh =
iter->second;
4922 cv::Mat globalTextures;
4923 bool texturesMerged =
_ui->comboBox_meshingTextureSize->isEnabled() &&
_ui->comboBox_meshingTextureSize->currentIndex() > 0;
4924 if(texturesMerged && mesh->tex_materials.size()>1)
4933 _ui->spinBox_mesh_maxTextures->value(),
4934 textureVertexToPixels,
4935 _ui->checkBox_gainCompensation->isChecked(),
4936 _ui->doubleSpinBox_gainBeta->value(),
4937 _ui->checkBox_gainRGB->isChecked(),
4938 _ui->checkBox_blending->isChecked(),
4940 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
4941 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
4942 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked());
4944 bool singleTexture = mesh->tex_materials.size() == 1;
4948 QDir(
path).mkdir(currentPrefix);
4952 cv::Mat previousImage;
4953 int previousTextureId = 0;
4954 std::vector<CameraModel> previousCameraModels;
4957 for(
unsigned int i=0;
i<mesh->tex_materials.size(); ++
i)
4959 if(!mesh->tex_materials[
i].tex_file.empty())
4961 std::list<std::string> texFileSplit =
uSplit(mesh->tex_materials[
i].tex_file,
'_');
4963 int textureSubCamera = -1;
4964 if(texFileSplit.size() &&
uIsInteger(texFileSplit.front(),
false))
4966 textureId =
uStr2Int(texFileSplit.front());
4967 if(texFileSplit.size() == 2 &&
4970 textureSubCamera =
uStr2Int(texFileSplit.back());
4979 fullPath =
path+QDir::separator()+prefix + QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText();
4983 fullPath =
path+QDir::separator()+currentPrefix+QDir::separator()+QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText();
4988 std::vector<CameraModel> cameraModels;
4990 if(textureId == previousTextureId)
4992 image = previousImage;
4993 cameraModels = previousCameraModels;
4997 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
4999 cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
5000 cameraModels = cachedSignatures.value(textureId).sensorData().cameraModels();
5006 data.uncompressDataConst(&image, 0);
5007 std::vector<StereoCameraModel> stereoModels;
5009 if(cameraModels.empty())
5011 for(
size_t i=0;
i<stereoModels.size(); ++
i)
5013 cameraModels.push_back(stereoModels[
i].left());
5018 previousImage = image;
5019 previousCameraModels = cameraModels;
5020 previousTextureId = textureId;
5025 imageSize = image.size();
5026 if(textureSubCamera>=0)
5029 imageSize.width/=cameraModels.size();
5030 image = image.colRange(imageSize.width*textureSubCamera, imageSize.width*(textureSubCamera+1));
5037 if(!cv::imwrite(fullPath.toStdString(), image))
5040 .
arg(mesh->tex_materials[
i].tex_file.c_str()).
arg(fullPath), Qt::darkRed);
5044 else if(imageSize.height && imageSize.width)
5047 cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
5048 cv::imwrite(fullPath.toStdString(), image);
5050 else if(!globalTextures.empty())
5052 if(!cv::imwrite(fullPath.toStdString(), globalTextures(
cv::Range::all(), cv::Range(
i*globalTextures.rows, (
i+1)*globalTextures.rows))))
5055 .
arg(mesh->tex_materials[
i].tex_file.c_str()).
arg(fullPath), Qt::darkRed);
5061 UWARN(
"Ignored texture %s (no image size set yet)", mesh->tex_materials[
i].tex_file.c_str());
5066 mesh->tex_materials[
i].tex_file=(prefix+ QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
5070 mesh->tex_materials[
i].tex_file=(currentPrefix+QDir::separator()+QString(mesh->tex_materials[
i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
5074 pcl::PointCloud<pcl::PointNormal>::Ptr tmp(
new pcl::PointCloud<pcl::PointNormal>);
5075 pcl::fromPCLPointCloud2(mesh->cloud, *tmp);
5077 pcl::toPCLPointCloud2(*tmp, mesh->cloud);
5079 QString pathFile =
path+QDir::separator()+QString(
"%1.%3").arg(currentPrefix).arg(suffix);
5080 bool success =
false;
5087 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
5092 .
arg(
iter->first).
arg(mesh->tex_materials.size()).arg(pathFile));
5097 .
arg(
iter->first).
arg(mesh->tex_materials.size()).arg(pathFile), Qt::darkRed);
5106 QApplication::processEvents();
5118 #if PCL_VERSION_COMPARE(>=, 1, 13, 0)
5119 mesh->tex_coord_indices = std::vector<std::vector<pcl::Vertices>>();
5120 auto nr_meshes =
static_cast<unsigned>(mesh->tex_polygons.size());
5122 for (
unsigned m = 0;
m < nr_meshes;
m++) {
5123 std::vector<pcl::Vertices> ci = mesh->tex_polygons[
m];
5124 for(std::size_t
i = 0;
i < ci.size();
i++) {
5125 for (std::size_t
j = 0;
j < ci[
i].vertices.size();
j++) {
5126 ci[
i].vertices[
j] = ci[
i].vertices.size() * (
i + f_idx) +
j;
5129 mesh->tex_coord_indices.push_back(ci);
5130 f_idx +=
static_cast<unsigned>(mesh->tex_polygons[
m].size());
5133 return pcl::io::saveOBJFile(
path.toStdString(), *mesh) == 0;
5137 return pcl::io::saveOBJFile(
path.toStdString(), mesh) == 0;