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> 65 #include <QDesktopWidget> 67 #ifdef RTABMAP_CPUTSDF 68 #include <cpu_tsdf/tsdf_volume_octree.h> 69 #include <cpu_tsdf/marching_cubes_tsdf_octree.h> 72 #ifdef RTABMAP_OPENCHISEL 74 #include <open_chisel/ProjectionIntegrator.h> 75 #include <open_chisel/truncation/QuadraticTruncator.h> 76 #include <open_chisel/weighting/ConstantWeighter.h> 87 _ui =
new Ui_ExportCloudsDialog();
90 connect(
_ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()),
this, SLOT(
restoreDefaults()));
91 QPushButton * loadSettingsButton =
_ui->buttonBox->addButton(
"Load Settings", QDialogButtonBox::ActionRole);
92 QPushButton * saveSettingsButton =
_ui->buttonBox->addButton(
"Save Settings", QDialogButtonBox::ActionRole);
93 connect(loadSettingsButton, SIGNAL(clicked()),
this, SLOT(
loadSettings()));
94 connect(saveSettingsButton, SIGNAL(clicked()),
this, SLOT(
saveSettings()));
97 _ui->comboBox_upsamplingMethod->setItemData(1, 0, Qt::UserRole - 1);
99 connect(
_ui->checkBox_fromDepth, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
101 connect(
_ui->checkBox_binary, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
102 connect(
_ui->spinBox_normalKSearch, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
103 connect(
_ui->doubleSpinBox_normalRadiusSearch, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
104 connect(
_ui->comboBox_pipeline, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
106 connect(
_ui->comboBox_meshingApproach, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
109 connect(
_ui->checkBox_regenerate, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
111 connect(
_ui->spinBox_decimation, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
112 connect(
_ui->doubleSpinBox_maxDepth, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
113 connect(
_ui->doubleSpinBox_minDepth, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
114 connect(
_ui->spinBox_fillDepthHoles, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
115 connect(
_ui->spinBox_fillDepthHolesError, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
116 connect(
_ui->lineEdit_roiRatios, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
117 connect(
_ui->lineEdit_distortionModel, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
120 connect(
_ui->checkBox_bilateral, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
122 connect(
_ui->doubleSpinBox_bilateral_sigmaS, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
123 connect(
_ui->doubleSpinBox_bilateral_sigmaR, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
125 connect(
_ui->checkBox_filtering, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
127 connect(
_ui->doubleSpinBox_filteringRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
128 connect(
_ui->spinBox_filteringMinNeighbors, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
130 connect(
_ui->checkBox_assemble, SIGNAL(clicked(
bool)),
this, SIGNAL(
configChanged()));
132 connect(
_ui->doubleSpinBox_voxelSize_assembled, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
133 connect(
_ui->comboBox_frame, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
136 connect(
_ui->checkBox_subtraction, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
138 connect(
_ui->doubleSpinBox_subtractPointFilteringRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
139 connect(
_ui->doubleSpinBox_subtractPointFilteringAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
140 connect(
_ui->spinBox_subtractFilteringMinPts, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
142 connect(
_ui->checkBox_smoothing, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
144 connect(
_ui->doubleSpinBox_mlsRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
145 connect(
_ui->spinBox_polygonialOrder, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
146 connect(
_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
147 connect(
_ui->doubleSpinBox_sampleStep, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
148 connect(
_ui->spinBox_randomPoints, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
149 connect(
_ui->doubleSpinBox_dilationVoxelSize, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
150 connect(
_ui->spinBox_dilationSteps, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
151 connect(
_ui->doubleSpinBox_mls_outputVoxelSize, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
152 _ui->stackedWidget_upsampling->setCurrentIndex(
_ui->comboBox_upsamplingMethod->currentIndex());
153 connect(
_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(
int)),
_ui->stackedWidget_upsampling, SLOT(setCurrentIndex(
int)));
156 connect(
_ui->checkBox_gainCompensation, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
158 connect(
_ui->doubleSpinBox_gainRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
159 connect(
_ui->doubleSpinBox_gainOverlap, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
160 connect(
_ui->doubleSpinBox_gainBeta, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
161 connect(
_ui->checkBox_gainRGB, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
162 connect(
_ui->checkBox_gainFull, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
163 connect(
_ui->spinBox_textureBrightnessContrastRatioLow, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
164 connect(
_ui->spinBox_textureBrightnessContrastRatioHigh, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
165 connect(
_ui->checkBox_exposureFusion, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
166 connect(
_ui->checkBox_blending, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
167 connect(
_ui->comboBox_blendingDecimation, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
169 connect(
_ui->checkBox_meshing, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
172 connect(
_ui->doubleSpinBox_gp3Radius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
173 connect(
_ui->doubleSpinBox_gp3Mu, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
174 connect(
_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
176 connect(
_ui->spinBox_meshMaxPolygons, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
178 connect(
_ui->doubleSpinBox_transferColorRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
179 connect(
_ui->checkBox_cleanMesh, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
180 connect(
_ui->spinBox_mesh_minClusterSize, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
181 connect(
_ui->checkBox_textureMapping, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
183 connect(
_ui->comboBox_meshingTextureFormat, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
184 connect(
_ui->comboBox_meshingTextureSize, SIGNAL(currentIndexChanged(
int)),
this, SIGNAL(
configChanged()));
185 connect(
_ui->spinBox_mesh_maxTextures, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
186 connect(
_ui->doubleSpinBox_meshingTextureMaxDistance, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
187 connect(
_ui->doubleSpinBox_meshingTextureMaxDepthError, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
188 connect(
_ui->doubleSpinBox_meshingTextureMaxAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
189 connect(
_ui->spinBox_mesh_minTextureClusterSize, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
190 connect(
_ui->lineEdit_meshingTextureRoiRatios, SIGNAL(textChanged(
const QString &)),
this, SIGNAL(
configChanged()));
191 connect(
_ui->checkBox_cameraFilter, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
193 connect(
_ui->doubleSpinBox_cameraFilterRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
194 connect(
_ui->doubleSpinBox_cameraFilterAngle, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
195 connect(
_ui->doubleSpinBox_cameraFilterVel, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
196 connect(
_ui->doubleSpinBox_cameraFilterVelRad, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
197 connect(
_ui->doubleSpinBox_laplacianVariance, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
199 connect(
_ui->checkBox_poisson_outputPolygons, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
200 connect(
_ui->checkBox_poisson_manifold, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
201 connect(
_ui->spinBox_poisson_depth, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
202 connect(
_ui->spinBox_poisson_iso, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
203 connect(
_ui->spinBox_poisson_solver, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
204 connect(
_ui->spinBox_poisson_minDepth, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
205 connect(
_ui->doubleSpinBox_poisson_samples, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
206 connect(
_ui->doubleSpinBox_poisson_pointWeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
207 connect(
_ui->doubleSpinBox_poisson_scale, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
209 connect(
_ui->doubleSpinBox_cputsdf_size, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
210 connect(
_ui->doubleSpinBox_cputsdf_resolution, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
211 connect(
_ui->doubleSpinBox_cputsdf_tuncPos, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
212 connect(
_ui->doubleSpinBox_cputsdf_tuncNeg, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
213 connect(
_ui->doubleSpinBox_cputsdf_minWeight, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
214 connect(
_ui->doubleSpinBox_cputsdf_flattenRadius, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
215 connect(
_ui->spinBox_cputsdf_randomSplit, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
217 connect(
_ui->checkBox_openchisel_mergeVertices, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
218 connect(
_ui->spinBox_openchisel_chunk_size_x, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
219 connect(
_ui->spinBox_openchisel_chunk_size_y, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
220 connect(
_ui->spinBox_openchisel_chunk_size_z, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
221 connect(
_ui->doubleSpinBox_openchisel_truncation_constant, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
222 connect(
_ui->doubleSpinBox_openchisel_truncation_linear, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
223 connect(
_ui->doubleSpinBox_openchisel_truncation_quadratic, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
224 connect(
_ui->doubleSpinBox_openchisel_truncation_scale, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
225 connect(
_ui->spinBox_openchisel_integration_weight, SIGNAL(valueChanged(
int)),
this, SIGNAL(
configChanged()));
226 connect(
_ui->checkBox_openchisel_use_voxel_carving, SIGNAL(stateChanged(
int)),
this, SIGNAL(
configChanged()));
227 connect(
_ui->doubleSpinBox_openchisel_carving_dist_m, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
228 connect(
_ui->doubleSpinBox_openchisel_near_plane_dist, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
229 connect(
_ui->doubleSpinBox_openchisel_far_plane_dist, SIGNAL(valueChanged(
double)),
this, SIGNAL(
configChanged()));
240 _ui->doubleSpinBox_meshDecimationFactor->setEnabled(
false);
241 _ui->spinBox_meshMaxPolygons->setEnabled(
false);
242 _ui->label_meshDecimation->setEnabled(
false);
243 _ui->label_meshMaxPolygons->setEnabled(
false);
246 #if CV_MAJOR_VERSION < 3 247 _ui->checkBox_exposureFusion->setEnabled(
false);
248 _ui->checkBox_exposureFusion->setChecked(
false);
249 _ui->label_exposureFusion->setEnabled(
false);
261 _ui->groupBox->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 0);
262 _ui->groupBox_2->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 1);
263 _ui->groupBox_3->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 2);
264 _ui->groupBox_4->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 3);
265 _ui->groupBox_5->setVisible(
_ui->comboBox_upsamplingMethod->currentIndex() == 4);
278 _ui->checkBox_assemble->setChecked(
true);
279 _ui->checkBox_assemble->setEnabled(
false);
283 _ui->checkBox_assemble->setEnabled(
true);
296 settings.beginGroup(group);
298 settings.setValue(
"pipeline",
_ui->comboBox_pipeline->currentIndex());
299 settings.setValue(
"from_depth",
_ui->checkBox_fromDepth->isChecked());
300 settings.setValue(
"binary",
_ui->checkBox_binary->isChecked());
301 settings.setValue(
"normals_k",
_ui->spinBox_normalKSearch->value());
302 settings.setValue(
"normals_radius",
_ui->doubleSpinBox_normalRadiusSearch->value());
304 settings.setValue(
"regenerate",
_ui->checkBox_regenerate->isChecked());
305 settings.setValue(
"regenerate_decimation",
_ui->spinBox_decimation->value());
306 settings.setValue(
"regenerate_max_depth",
_ui->doubleSpinBox_maxDepth->value());
307 settings.setValue(
"regenerate_min_depth",
_ui->doubleSpinBox_minDepth->value());
308 settings.setValue(
"regenerate_fill_size",
_ui->spinBox_fillDepthHoles->value());
309 settings.setValue(
"regenerate_fill_error",
_ui->spinBox_fillDepthHolesError->value());
310 settings.setValue(
"regenerate_roi",
_ui->lineEdit_roiRatios->text());
311 settings.setValue(
"regenerate_distortion_model",
_ui->lineEdit_distortionModel->text());
313 settings.setValue(
"bilateral",
_ui->checkBox_bilateral->isChecked());
314 settings.setValue(
"bilateral_sigma_s",
_ui->doubleSpinBox_bilateral_sigmaS->value());
315 settings.setValue(
"bilateral_sigma_r",
_ui->doubleSpinBox_bilateral_sigmaR->value());
317 settings.setValue(
"filtering",
_ui->checkBox_filtering->isChecked());
318 settings.setValue(
"filtering_radius",
_ui->doubleSpinBox_filteringRadius->value());
319 settings.setValue(
"filtering_min_neighbors",
_ui->spinBox_filteringMinNeighbors->value());
321 settings.setValue(
"assemble",
_ui->checkBox_assemble->isChecked());
322 settings.setValue(
"assemble_voxel",
_ui->doubleSpinBox_voxelSize_assembled->value());
323 settings.setValue(
"frame",
_ui->comboBox_frame->currentIndex());
325 settings.setValue(
"subtract",
_ui->checkBox_subtraction->isChecked());
326 settings.setValue(
"subtract_point_radius",
_ui->doubleSpinBox_subtractPointFilteringRadius->value());
327 settings.setValue(
"subtract_point_angle",
_ui->doubleSpinBox_subtractPointFilteringAngle->value());
328 settings.setValue(
"subtract_min_neighbors",
_ui->spinBox_subtractFilteringMinPts->value());
330 settings.setValue(
"mls",
_ui->checkBox_smoothing->isChecked());
331 settings.setValue(
"mls_radius",
_ui->doubleSpinBox_mlsRadius->value());
332 settings.setValue(
"mls_polygonial_order",
_ui->spinBox_polygonialOrder->value());
333 settings.setValue(
"mls_upsampling_method",
_ui->comboBox_upsamplingMethod->currentIndex());
334 settings.setValue(
"mls_upsampling_radius",
_ui->doubleSpinBox_sampleRadius->value());
335 settings.setValue(
"mls_upsampling_step",
_ui->doubleSpinBox_sampleStep->value());
336 settings.setValue(
"mls_point_density",
_ui->spinBox_randomPoints->value());
337 settings.setValue(
"mls_dilation_voxel_size",
_ui->doubleSpinBox_dilationVoxelSize->value());
338 settings.setValue(
"mls_dilation_iterations",
_ui->spinBox_dilationSteps->value());
339 settings.setValue(
"mls_output_voxel_size",
_ui->doubleSpinBox_mls_outputVoxelSize->value());
341 settings.setValue(
"gain",
_ui->checkBox_gainCompensation->isChecked());
342 settings.setValue(
"gain_radius",
_ui->doubleSpinBox_gainRadius->value());
343 settings.setValue(
"gain_overlap",
_ui->doubleSpinBox_gainOverlap->value());
344 settings.setValue(
"gain_beta",
_ui->doubleSpinBox_gainBeta->value());
345 settings.setValue(
"gain_rgb",
_ui->checkBox_gainRGB->isChecked());
346 settings.setValue(
"gain_full",
_ui->checkBox_gainFull->isChecked());
348 settings.setValue(
"mesh",
_ui->checkBox_meshing->isChecked());
349 settings.setValue(
"mesh_radius",
_ui->doubleSpinBox_gp3Radius->value());
350 settings.setValue(
"mesh_mu",
_ui->doubleSpinBox_gp3Mu->value());
351 settings.setValue(
"mesh_decimation_factor",
_ui->doubleSpinBox_meshDecimationFactor->value());
352 settings.setValue(
"mesh_max_polygons",
_ui->spinBox_meshMaxPolygons->value());
353 settings.setValue(
"mesh_color_radius",
_ui->doubleSpinBox_transferColorRadius->value());
354 settings.setValue(
"mesh_clean",
_ui->checkBox_cleanMesh->isChecked());
355 settings.setValue(
"mesh_min_cluster_size",
_ui->spinBox_mesh_minClusterSize->value());
357 settings.setValue(
"mesh_dense_strategy",
_ui->comboBox_meshingApproach->currentIndex());
359 settings.setValue(
"mesh_texture",
_ui->checkBox_textureMapping->isChecked());
360 settings.setValue(
"mesh_textureFormat",
_ui->comboBox_meshingTextureFormat->currentIndex());
361 settings.setValue(
"mesh_textureSize",
_ui->comboBox_meshingTextureSize->currentIndex());
362 settings.setValue(
"mesh_textureMaxCount",
_ui->spinBox_mesh_maxTextures->value());
363 settings.setValue(
"mesh_textureMaxDistance",
_ui->doubleSpinBox_meshingTextureMaxDistance->value());
364 settings.setValue(
"mesh_textureMaxDepthError",
_ui->doubleSpinBox_meshingTextureMaxDepthError->value());
365 settings.setValue(
"mesh_textureMaxAngle",
_ui->doubleSpinBox_meshingTextureMaxAngle->value());
366 settings.setValue(
"mesh_textureMinCluster",
_ui->spinBox_mesh_minTextureClusterSize->value());
367 settings.setValue(
"mesh_textureRoiRatios",
_ui->lineEdit_meshingTextureRoiRatios->text());
368 settings.setValue(
"mesh_textureCameraFiltering",
_ui->checkBox_cameraFilter->isChecked());
369 settings.setValue(
"mesh_textureCameraFilteringRadius",
_ui->doubleSpinBox_cameraFilterRadius->value());
370 settings.setValue(
"mesh_textureCameraFilteringAngle",
_ui->doubleSpinBox_cameraFilterAngle->value());
371 settings.setValue(
"mesh_textureCameraFilteringVel",
_ui->doubleSpinBox_cameraFilterVel->value());
372 settings.setValue(
"mesh_textureCameraFilteringVelRad",
_ui->doubleSpinBox_cameraFilterVelRad->value());
373 settings.setValue(
"mesh_textureCameraFilteringLaplacian",
_ui->doubleSpinBox_laplacianVariance->value());
374 settings.setValue(
"mesh_textureBrightnessConstrastRatioLow",
_ui->spinBox_textureBrightnessContrastRatioLow->value());
375 settings.setValue(
"mesh_textureBrightnessConstrastRatioHigh",
_ui->spinBox_textureBrightnessContrastRatioHigh->value());
376 settings.setValue(
"mesh_textureExposureFusion",
_ui->checkBox_exposureFusion->isChecked());
377 settings.setValue(
"mesh_textureBlending",
_ui->checkBox_blending->isChecked());
378 settings.setValue(
"mesh_textureBlendingDecimation",
_ui->comboBox_blendingDecimation->currentIndex());
381 settings.setValue(
"mesh_angle_tolerance",
_ui->doubleSpinBox_mesh_angleTolerance->value());
382 settings.setValue(
"mesh_quad",
_ui->checkBox_mesh_quad->isChecked());
383 settings.setValue(
"mesh_triangle_size",
_ui->spinBox_mesh_triangleSize->value());
385 settings.setValue(
"poisson_outputPolygons",
_ui->checkBox_poisson_outputPolygons->isChecked());
386 settings.setValue(
"poisson_manifold",
_ui->checkBox_poisson_manifold->isChecked());
387 settings.setValue(
"poisson_depth",
_ui->spinBox_poisson_depth->value());
388 settings.setValue(
"poisson_iso",
_ui->spinBox_poisson_iso->value());
389 settings.setValue(
"poisson_solver",
_ui->spinBox_poisson_solver->value());
390 settings.setValue(
"poisson_minDepth",
_ui->spinBox_poisson_minDepth->value());
391 settings.setValue(
"poisson_samples",
_ui->doubleSpinBox_poisson_samples->value());
392 settings.setValue(
"poisson_pointWeight",
_ui->doubleSpinBox_poisson_pointWeight->value());
393 settings.setValue(
"poisson_scale",
_ui->doubleSpinBox_poisson_scale->value());
395 settings.setValue(
"cputsdf_size",
_ui->doubleSpinBox_cputsdf_size->value());
396 settings.setValue(
"cputsdf_resolution",
_ui->doubleSpinBox_cputsdf_resolution->value());
397 settings.setValue(
"cputsdf_truncPos",
_ui->doubleSpinBox_cputsdf_tuncPos->value());
398 settings.setValue(
"cputsdf_truncNeg",
_ui->doubleSpinBox_cputsdf_tuncNeg->value());
399 settings.setValue(
"cputsdf_minWeight",
_ui->doubleSpinBox_cputsdf_minWeight->value());
400 settings.setValue(
"cputsdf_flattenRadius",
_ui->doubleSpinBox_cputsdf_flattenRadius->value());
401 settings.setValue(
"cputsdf_randomSplit",
_ui->spinBox_cputsdf_randomSplit->value());
403 settings.setValue(
"openchisel_merge_vertices",
_ui->checkBox_openchisel_mergeVertices->isChecked());
404 settings.setValue(
"openchisel_chunk_size_x",
_ui->spinBox_openchisel_chunk_size_x->value());
405 settings.setValue(
"openchisel_chunk_size_y",
_ui->spinBox_openchisel_chunk_size_y->value());
406 settings.setValue(
"openchisel_chunk_size_z",
_ui->spinBox_openchisel_chunk_size_z->value());
407 settings.setValue(
"openchisel_truncation_constant",
_ui->doubleSpinBox_openchisel_truncation_constant->value());
408 settings.setValue(
"openchisel_truncation_linear",
_ui->doubleSpinBox_openchisel_truncation_linear->value());
409 settings.setValue(
"openchisel_truncation_quadratic",
_ui->doubleSpinBox_openchisel_truncation_quadratic->value());
410 settings.setValue(
"openchisel_truncation_scale",
_ui->doubleSpinBox_openchisel_truncation_scale->value());
411 settings.setValue(
"openchisel_integration_weight",
_ui->spinBox_openchisel_integration_weight->value());
412 settings.setValue(
"openchisel_use_voxel_carving",
_ui->checkBox_openchisel_use_voxel_carving->isChecked());
413 settings.setValue(
"openchisel_carving_dist_m",
_ui->doubleSpinBox_openchisel_carving_dist_m->value());
414 settings.setValue(
"openchisel_near_plane_dist",
_ui->doubleSpinBox_openchisel_near_plane_dist->value());
415 settings.setValue(
"openchisel_far_plane_dist",
_ui->doubleSpinBox_openchisel_far_plane_dist->value());
427 settings.beginGroup(group);
430 _ui->comboBox_pipeline->setCurrentIndex(settings.value(
"pipeline",
_ui->comboBox_pipeline->currentIndex()).toInt());
431 _ui->checkBox_fromDepth->setChecked(settings.value(
"from_depth",
_ui->checkBox_fromDepth->isChecked()).toBool());
432 _ui->checkBox_binary->setChecked(settings.value(
"binary",
_ui->checkBox_binary->isChecked()).toBool());
433 _ui->spinBox_normalKSearch->setValue(settings.value(
"normals_k",
_ui->spinBox_normalKSearch->value()).toInt());
434 _ui->doubleSpinBox_normalRadiusSearch->setValue(settings.value(
"normals_radius",
_ui->doubleSpinBox_normalRadiusSearch->value()).toDouble());
436 _ui->checkBox_regenerate->setChecked(settings.value(
"regenerate",
_ui->checkBox_regenerate->isChecked()).toBool());
437 _ui->spinBox_decimation->setValue(settings.value(
"regenerate_decimation",
_ui->spinBox_decimation->value()).toInt());
438 _ui->doubleSpinBox_maxDepth->setValue(settings.value(
"regenerate_max_depth",
_ui->doubleSpinBox_maxDepth->value()).toDouble());
439 _ui->doubleSpinBox_minDepth->setValue(settings.value(
"regenerate_min_depth",
_ui->doubleSpinBox_minDepth->value()).toDouble());
440 _ui->spinBox_fillDepthHoles->setValue(settings.value(
"regenerate_fill_size",
_ui->spinBox_fillDepthHoles->value()).toInt());
441 _ui->spinBox_fillDepthHolesError->setValue(settings.value(
"regenerate_fill_error",
_ui->spinBox_fillDepthHolesError->value()).toInt());
442 _ui->lineEdit_roiRatios->setText(settings.value(
"regenerate_roi",
_ui->lineEdit_roiRatios->text()).toString());
443 _ui->lineEdit_distortionModel->setText(settings.value(
"regenerate_distortion_model",
_ui->lineEdit_distortionModel->text()).toString());
445 _ui->checkBox_bilateral->setChecked(settings.value(
"bilateral",
_ui->checkBox_bilateral->isChecked()).toBool());
446 _ui->doubleSpinBox_bilateral_sigmaS->setValue(settings.value(
"bilateral_sigma_s",
_ui->doubleSpinBox_bilateral_sigmaS->value()).toDouble());
447 _ui->doubleSpinBox_bilateral_sigmaR->setValue(settings.value(
"bilateral_sigma_r",
_ui->doubleSpinBox_bilateral_sigmaR->value()).toDouble());
449 _ui->checkBox_filtering->setChecked(settings.value(
"filtering",
_ui->checkBox_filtering->isChecked()).toBool());
450 _ui->doubleSpinBox_filteringRadius->setValue(settings.value(
"filtering_radius",
_ui->doubleSpinBox_filteringRadius->value()).toDouble());
451 _ui->spinBox_filteringMinNeighbors->setValue(settings.value(
"filtering_min_neighbors",
_ui->spinBox_filteringMinNeighbors->value()).toInt());
453 if(
_ui->checkBox_assemble->isEnabled())
455 _ui->checkBox_assemble->setChecked(settings.value(
"assemble",
_ui->checkBox_assemble->isChecked()).toBool());
457 _ui->doubleSpinBox_voxelSize_assembled->setValue(settings.value(
"assemble_voxel",
_ui->doubleSpinBox_voxelSize_assembled->value()).toDouble());
458 _ui->comboBox_frame->setCurrentIndex(settings.value(
"frame",
_ui->comboBox_frame->currentIndex()).toInt());
460 _ui->checkBox_subtraction->setChecked(settings.value(
"subtract",
_ui->checkBox_subtraction->isChecked()).toBool());
461 _ui->doubleSpinBox_subtractPointFilteringRadius->setValue(settings.value(
"subtract_point_radius",
_ui->doubleSpinBox_subtractPointFilteringRadius->value()).toDouble());
462 _ui->doubleSpinBox_subtractPointFilteringAngle->setValue(settings.value(
"subtract_point_angle",
_ui->doubleSpinBox_subtractPointFilteringAngle->value()).toDouble());
463 _ui->spinBox_subtractFilteringMinPts->setValue(settings.value(
"subtract_min_neighbors",
_ui->spinBox_subtractFilteringMinPts->value()).toInt());
465 _ui->checkBox_smoothing->setChecked(settings.value(
"mls",
_ui->checkBox_smoothing->isChecked()).toBool());
466 _ui->doubleSpinBox_mlsRadius->setValue(settings.value(
"mls_radius",
_ui->doubleSpinBox_mlsRadius->value()).toDouble());
467 _ui->spinBox_polygonialOrder->setValue(settings.value(
"mls_polygonial_order",
_ui->spinBox_polygonialOrder->value()).toInt());
468 _ui->comboBox_upsamplingMethod->setCurrentIndex(settings.value(
"mls_upsampling_method",
_ui->comboBox_upsamplingMethod->currentIndex()).toInt());
469 _ui->doubleSpinBox_sampleRadius->setValue(settings.value(
"mls_upsampling_radius",
_ui->doubleSpinBox_sampleRadius->value()).toDouble());
470 _ui->doubleSpinBox_sampleStep->setValue(settings.value(
"mls_upsampling_step",
_ui->doubleSpinBox_sampleStep->value()).toDouble());
471 _ui->spinBox_randomPoints->setValue(settings.value(
"mls_point_density",
_ui->spinBox_randomPoints->value()).toInt());
472 _ui->doubleSpinBox_dilationVoxelSize->setValue(settings.value(
"mls_dilation_voxel_size",
_ui->doubleSpinBox_dilationVoxelSize->value()).toDouble());
473 _ui->spinBox_dilationSteps->setValue(settings.value(
"mls_dilation_iterations",
_ui->spinBox_dilationSteps->value()).toInt());
474 _ui->doubleSpinBox_mls_outputVoxelSize->setValue(settings.value(
"mls_output_voxel_size",
_ui->doubleSpinBox_mls_outputVoxelSize->value()).toInt());
476 _ui->checkBox_gainCompensation->setChecked(settings.value(
"gain",
_ui->checkBox_gainCompensation->isChecked()).toBool());
477 _ui->doubleSpinBox_gainRadius->setValue(settings.value(
"gain_radius",
_ui->doubleSpinBox_gainRadius->value()).toDouble());
478 _ui->doubleSpinBox_gainOverlap->setValue(settings.value(
"gain_overlap",
_ui->doubleSpinBox_gainOverlap->value()).toDouble());
479 _ui->doubleSpinBox_gainBeta->setValue(settings.value(
"gain_beta",
_ui->doubleSpinBox_gainBeta->value()).toDouble());
480 _ui->checkBox_gainRGB->setChecked(settings.value(
"gain_rgb",
_ui->checkBox_gainRGB->isChecked()).toBool());
481 _ui->checkBox_gainFull->setChecked(settings.value(
"gain_full",
_ui->checkBox_gainFull->isChecked()).toBool());
483 _ui->checkBox_meshing->setChecked(settings.value(
"mesh",
_ui->checkBox_meshing->isChecked()).toBool());
484 _ui->doubleSpinBox_gp3Radius->setValue(settings.value(
"mesh_radius",
_ui->doubleSpinBox_gp3Radius->value()).toDouble());
485 _ui->doubleSpinBox_gp3Mu->setValue(settings.value(
"mesh_mu",
_ui->doubleSpinBox_gp3Mu->value()).toDouble());
486 _ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value(
"mesh_decimation_factor",
_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble());
487 _ui->spinBox_meshMaxPolygons->setValue(settings.value(
"mesh_max_polygons",
_ui->spinBox_meshMaxPolygons->value()).toDouble());
488 _ui->doubleSpinBox_transferColorRadius->setValue(settings.value(
"mesh_color_radius",
_ui->doubleSpinBox_transferColorRadius->value()).toDouble());
489 _ui->checkBox_cleanMesh->setChecked(settings.value(
"mesh_clean",
_ui->checkBox_cleanMesh->isChecked()).toBool());
490 _ui->spinBox_mesh_minClusterSize->setValue(settings.value(
"mesh_min_cluster_size",
_ui->spinBox_mesh_minClusterSize->value()).toInt());
492 _ui->comboBox_meshingApproach->setCurrentIndex(settings.value(
"mesh_dense_strategy",
_ui->comboBox_meshingApproach->currentIndex()).toInt());
494 _ui->checkBox_textureMapping->setChecked(settings.value(
"mesh_texture",
_ui->checkBox_textureMapping->isChecked()).toBool());
495 _ui->comboBox_meshingTextureFormat->setCurrentIndex(settings.value(
"mesh_textureFormat",
_ui->comboBox_meshingTextureFormat->currentIndex()).toInt());
496 _ui->comboBox_meshingTextureSize->setCurrentIndex(settings.value(
"mesh_textureSize",
_ui->comboBox_meshingTextureSize->currentIndex()).toInt());
497 _ui->spinBox_mesh_maxTextures->setValue(settings.value(
"mesh_textureMaxCount",
_ui->spinBox_mesh_maxTextures->value()).toInt());
498 _ui->doubleSpinBox_meshingTextureMaxDistance->setValue(settings.value(
"mesh_textureMaxDistance",
_ui->doubleSpinBox_meshingTextureMaxDistance->value()).toDouble());
499 _ui->doubleSpinBox_meshingTextureMaxDepthError->setValue(settings.value(
"mesh_textureMaxDepthError",
_ui->doubleSpinBox_meshingTextureMaxDepthError->value()).toDouble());
500 _ui->doubleSpinBox_meshingTextureMaxAngle->setValue(settings.value(
"mesh_textureMaxAngle",
_ui->doubleSpinBox_meshingTextureMaxAngle->value()).toDouble());
501 _ui->spinBox_mesh_minTextureClusterSize->setValue(settings.value(
"mesh_textureMinCluster",
_ui->spinBox_mesh_minTextureClusterSize->value()).toDouble());
502 _ui->lineEdit_meshingTextureRoiRatios->setText(settings.value(
"mesh_textureRoiRatios",
_ui->lineEdit_meshingTextureRoiRatios->text()).toString());
503 _ui->checkBox_cameraFilter->setChecked(settings.value(
"mesh_textureCameraFiltering",
_ui->checkBox_cameraFilter->isChecked()).toBool());
504 _ui->doubleSpinBox_cameraFilterRadius->setValue(settings.value(
"mesh_textureCameraFilteringRadius",
_ui->doubleSpinBox_cameraFilterRadius->value()).toDouble());
505 _ui->doubleSpinBox_cameraFilterAngle->setValue(settings.value(
"mesh_textureCameraFilteringAngle",
_ui->doubleSpinBox_cameraFilterAngle->value()).toDouble());
506 _ui->doubleSpinBox_cameraFilterVel->setValue(settings.value(
"mesh_textureCameraFilteringVel",
_ui->doubleSpinBox_cameraFilterVel->value()).toDouble());
507 _ui->doubleSpinBox_cameraFilterVelRad->setValue(settings.value(
"mesh_textureCameraFilteringVelRad",
_ui->doubleSpinBox_cameraFilterVelRad->value()).toDouble());
508 _ui->doubleSpinBox_laplacianVariance->setValue(settings.value(
"mesh_textureCameraFilteringLaplacian",
_ui->doubleSpinBox_laplacianVariance->value()).toDouble());
509 _ui->spinBox_textureBrightnessContrastRatioLow->setValue(settings.value(
"mesh_textureBrightnessConstrastRatioLow",
_ui->spinBox_textureBrightnessContrastRatioLow->value()).toDouble());
510 _ui->spinBox_textureBrightnessContrastRatioHigh->setValue(settings.value(
"mesh_textureBrightnessConstrastRatioHigh",
_ui->spinBox_textureBrightnessContrastRatioHigh->value()).toDouble());
511 if(
_ui->checkBox_exposureFusion->isEnabled())
513 _ui->checkBox_exposureFusion->setChecked(settings.value(
"mesh_textureExposureFusion",
_ui->checkBox_exposureFusion->isChecked()).toBool());
515 _ui->checkBox_blending->setChecked(settings.value(
"mesh_textureBlending",
_ui->checkBox_blending->isChecked()).toBool());
516 _ui->comboBox_blendingDecimation->setCurrentIndex(settings.value(
"mesh_textureBlendingDecimation",
_ui->comboBox_blendingDecimation->currentIndex()).toInt());
518 _ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value(
"mesh_angle_tolerance",
_ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble());
519 _ui->checkBox_mesh_quad->setChecked(settings.value(
"mesh_quad",
_ui->checkBox_mesh_quad->isChecked()).toBool());
520 _ui->spinBox_mesh_triangleSize->setValue(settings.value(
"mesh_triangle_size",
_ui->spinBox_mesh_triangleSize->value()).toInt());
522 _ui->checkBox_poisson_outputPolygons->setChecked(settings.value(
"poisson_outputPolygons",
_ui->checkBox_poisson_outputPolygons->isChecked()).toBool());
523 _ui->checkBox_poisson_manifold->setChecked(settings.value(
"poisson_manifold",
_ui->checkBox_poisson_manifold->isChecked()).toBool());
524 _ui->spinBox_poisson_depth->setValue(settings.value(
"poisson_depth",
_ui->spinBox_poisson_depth->value()).toInt());
525 _ui->spinBox_poisson_iso->setValue(settings.value(
"poisson_iso",
_ui->spinBox_poisson_iso->value()).toInt());
526 _ui->spinBox_poisson_solver->setValue(settings.value(
"poisson_solver",
_ui->spinBox_poisson_solver->value()).toInt());
527 _ui->spinBox_poisson_minDepth->setValue(settings.value(
"poisson_minDepth",
_ui->spinBox_poisson_minDepth->value()).toInt());
528 _ui->doubleSpinBox_poisson_samples->setValue(settings.value(
"poisson_samples",
_ui->doubleSpinBox_poisson_samples->value()).toDouble());
529 _ui->doubleSpinBox_poisson_pointWeight->setValue(settings.value(
"poisson_pointWeight",
_ui->doubleSpinBox_poisson_pointWeight->value()).toDouble());
530 _ui->doubleSpinBox_poisson_scale->setValue(settings.value(
"poisson_scale",
_ui->doubleSpinBox_poisson_scale->value()).toDouble());
532 _ui->doubleSpinBox_cputsdf_size->setValue(settings.value(
"cputsdf_size",
_ui->doubleSpinBox_cputsdf_size->value()).toDouble());
533 _ui->doubleSpinBox_cputsdf_resolution->setValue(settings.value(
"cputsdf_resolution",
_ui->doubleSpinBox_cputsdf_resolution->value()).toDouble());
534 _ui->doubleSpinBox_cputsdf_tuncPos->setValue(settings.value(
"cputsdf_truncPos",
_ui->doubleSpinBox_cputsdf_tuncPos->value()).toDouble());
535 _ui->doubleSpinBox_cputsdf_tuncNeg->setValue(settings.value(
"cputsdf_truncNeg",
_ui->doubleSpinBox_cputsdf_tuncNeg->value()).toDouble());
536 _ui->doubleSpinBox_cputsdf_minWeight->setValue(settings.value(
"cputsdf_minWeight",
_ui->doubleSpinBox_cputsdf_minWeight->value()).toDouble());
537 _ui->doubleSpinBox_cputsdf_flattenRadius->setValue(settings.value(
"cputsdf_flattenRadius",
_ui->doubleSpinBox_cputsdf_flattenRadius->value()).toDouble());
538 _ui->spinBox_cputsdf_randomSplit->setValue(settings.value(
"cputsdf_randomSplit",
_ui->spinBox_cputsdf_randomSplit->value()).toInt());
540 _ui->checkBox_openchisel_mergeVertices->setChecked(settings.value(
"openchisel_merge_vertices",
_ui->checkBox_openchisel_mergeVertices->isChecked()).toBool());
541 _ui->spinBox_openchisel_chunk_size_x->setValue(settings.value(
"openchisel_chunk_size_x",
_ui->spinBox_openchisel_chunk_size_x->value()).toInt());
542 _ui->spinBox_openchisel_chunk_size_y->setValue(settings.value(
"openchisel_chunk_size_y",
_ui->spinBox_openchisel_chunk_size_y->value()).toInt());
543 _ui->spinBox_openchisel_chunk_size_z->setValue(settings.value(
"openchisel_chunk_size_z",
_ui->spinBox_openchisel_chunk_size_z->value()).toInt());
544 _ui->doubleSpinBox_openchisel_truncation_constant->setValue(settings.value(
"openchisel_truncation_constant",
_ui->doubleSpinBox_openchisel_truncation_constant->value()).toDouble());
545 _ui->doubleSpinBox_openchisel_truncation_linear->setValue(settings.value(
"openchisel_truncation_linear",
_ui->doubleSpinBox_openchisel_truncation_linear->value()).toDouble());
546 _ui->doubleSpinBox_openchisel_truncation_quadratic->setValue(settings.value(
"openchisel_truncation_quadratic",
_ui->doubleSpinBox_openchisel_truncation_quadratic->value()).toDouble());
547 _ui->doubleSpinBox_openchisel_truncation_scale->setValue(settings.value(
"openchisel_truncation_scale",
_ui->doubleSpinBox_openchisel_truncation_scale->value()).toDouble());
548 _ui->spinBox_openchisel_integration_weight->setValue(settings.value(
"openchisel_integration_weight",
_ui->spinBox_openchisel_integration_weight->value()).toInt());
549 _ui->checkBox_openchisel_use_voxel_carving->setChecked(settings.value(
"openchisel_use_voxel_carving",
_ui->checkBox_openchisel_use_voxel_carving->isChecked()).toBool());
550 _ui->doubleSpinBox_openchisel_carving_dist_m->setValue(settings.value(
"openchisel_carving_dist_m",
_ui->doubleSpinBox_openchisel_carving_dist_m->value()).toDouble());
551 _ui->doubleSpinBox_openchisel_near_plane_dist->setValue(settings.value(
"openchisel_near_plane_dist",
_ui->doubleSpinBox_openchisel_near_plane_dist->value()).toDouble());
552 _ui->doubleSpinBox_openchisel_far_plane_dist->setValue(settings.value(
"openchisel_far_plane_dist",
_ui->doubleSpinBox_openchisel_far_plane_dist->value()).toDouble());
565 _ui->comboBox_pipeline->setCurrentIndex(1);
566 _ui->checkBox_fromDepth->setChecked(
true);
567 _ui->checkBox_binary->setChecked(
true);
568 _ui->spinBox_normalKSearch->setValue(20);
569 _ui->doubleSpinBox_normalRadiusSearch->setValue(0.0);
571 _ui->checkBox_regenerate->setChecked(
_dbDriver!=0?
true:
false);
572 _ui->spinBox_decimation->setValue(1);
573 _ui->doubleSpinBox_maxDepth->setValue(4);
574 _ui->doubleSpinBox_minDepth->setValue(0);
575 _ui->spinBox_fillDepthHoles->setValue(0);
576 _ui->spinBox_fillDepthHolesError->setValue(2);
577 _ui->lineEdit_roiRatios->setText(
"0.0 0.0 0.0 0.0");
578 _ui->lineEdit_distortionModel->setText(
"");
580 _ui->checkBox_bilateral->setChecked(
false);
581 _ui->doubleSpinBox_bilateral_sigmaS->setValue(10.0);
582 _ui->doubleSpinBox_bilateral_sigmaR->setValue(0.1);
584 _ui->checkBox_filtering->setChecked(
false);
585 _ui->doubleSpinBox_filteringRadius->setValue(0.02);
586 _ui->spinBox_filteringMinNeighbors->setValue(2);
588 _ui->checkBox_assemble->setChecked(
true);
589 _ui->doubleSpinBox_voxelSize_assembled->setValue(0.01);
590 _ui->comboBox_frame->setCurrentIndex(0);
592 _ui->checkBox_subtraction->setChecked(
false);
593 _ui->doubleSpinBox_subtractPointFilteringRadius->setValue(0.02);
594 _ui->doubleSpinBox_subtractPointFilteringAngle->setValue(0);
595 _ui->spinBox_subtractFilteringMinPts->setValue(5);
597 _ui->checkBox_smoothing->setChecked(
false);
598 _ui->doubleSpinBox_mlsRadius->setValue(0.04);
599 _ui->spinBox_polygonialOrder->setValue(2);
600 _ui->comboBox_upsamplingMethod->setCurrentIndex(0);
601 _ui->doubleSpinBox_sampleRadius->setValue(0.01);
602 _ui->doubleSpinBox_sampleStep->setValue(0.005);
603 _ui->spinBox_randomPoints->setValue(10);
604 _ui->doubleSpinBox_dilationVoxelSize->setValue(0.005);
605 _ui->spinBox_dilationSteps->setValue(1);
606 _ui->doubleSpinBox_mls_outputVoxelSize->setValue(0);
608 _ui->checkBox_gainCompensation->setChecked(
false);
609 _ui->doubleSpinBox_gainRadius->setValue(0.02);
610 _ui->doubleSpinBox_gainOverlap->setValue(0.0);
611 _ui->doubleSpinBox_gainBeta->setValue(10);
612 _ui->checkBox_gainRGB->setChecked(
true);
613 _ui->checkBox_gainFull->setChecked(
false);
615 _ui->checkBox_meshing->setChecked(
false);
616 _ui->doubleSpinBox_gp3Radius->setValue(0.2);
617 _ui->doubleSpinBox_gp3Mu->setValue(2.5);
618 _ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
619 _ui->spinBox_meshMaxPolygons->setValue(0);
620 _ui->doubleSpinBox_transferColorRadius->setValue(0.025);
621 _ui->checkBox_cleanMesh->setChecked(
true);
622 _ui->spinBox_mesh_minClusterSize->setValue(0);
624 _ui->comboBox_meshingApproach->setCurrentIndex(1);
626 _ui->checkBox_textureMapping->setChecked(
false);
627 _ui->comboBox_meshingTextureFormat->setCurrentIndex(0);
628 _ui->comboBox_meshingTextureSize->setCurrentIndex(5);
629 _ui->spinBox_mesh_maxTextures->setValue(1);
630 _ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0);
631 _ui->doubleSpinBox_meshingTextureMaxDepthError->setValue(0.0);
632 _ui->doubleSpinBox_meshingTextureMaxAngle->setValue(0.0);
633 _ui->spinBox_mesh_minTextureClusterSize->setValue(50);
634 _ui->lineEdit_meshingTextureRoiRatios->setText(
"0.0 0.0 0.0 0.0");
635 _ui->checkBox_cameraFilter->setChecked(
false);
636 _ui->doubleSpinBox_cameraFilterRadius->setValue(0);
637 _ui->doubleSpinBox_cameraFilterAngle->setValue(30);
638 _ui->doubleSpinBox_cameraFilterVel->setValue(0);
639 _ui->doubleSpinBox_cameraFilterVelRad->setValue(0);
640 _ui->doubleSpinBox_laplacianVariance->setValue(0);
641 _ui->spinBox_textureBrightnessContrastRatioLow->setValue(0);
642 _ui->spinBox_textureBrightnessContrastRatioHigh->setValue(0);
643 _ui->checkBox_exposureFusion->setChecked(
false);
644 _ui->checkBox_blending->setChecked(
true);
645 _ui->comboBox_blendingDecimation->setCurrentIndex(0);
647 _ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0);
648 _ui->checkBox_mesh_quad->setChecked(
false);
649 _ui->spinBox_mesh_triangleSize->setValue(1);
651 _ui->checkBox_poisson_outputPolygons->setChecked(
false);
652 _ui->checkBox_poisson_manifold->setChecked(
true);
653 _ui->spinBox_poisson_depth->setValue(0);
654 _ui->spinBox_poisson_iso->setValue(8);
655 _ui->spinBox_poisson_solver->setValue(8);
656 _ui->spinBox_poisson_minDepth->setValue(5);
657 _ui->doubleSpinBox_poisson_samples->setValue(1.0);
658 _ui->doubleSpinBox_poisson_pointWeight->setValue(4.0);
659 _ui->doubleSpinBox_poisson_scale->setValue(1.1);
661 _ui->doubleSpinBox_cputsdf_size->setValue(12.0);
662 _ui->doubleSpinBox_cputsdf_resolution->setValue(0.01);
663 _ui->doubleSpinBox_cputsdf_tuncPos->setValue(0.03);
664 _ui->doubleSpinBox_cputsdf_tuncNeg->setValue(0.03);
665 _ui->doubleSpinBox_cputsdf_minWeight->setValue(0);
666 _ui->doubleSpinBox_cputsdf_flattenRadius->setValue(0.005);
667 _ui->spinBox_cputsdf_randomSplit->setValue(1);
669 _ui->checkBox_openchisel_mergeVertices->setChecked(
true);
670 _ui->spinBox_openchisel_chunk_size_x->setValue(16);
671 _ui->spinBox_openchisel_chunk_size_y->setValue(16);
672 _ui->spinBox_openchisel_chunk_size_z->setValue(16);
673 _ui->doubleSpinBox_openchisel_truncation_constant->setValue(0.001504);
674 _ui->doubleSpinBox_openchisel_truncation_linear->setValue(0.00152);
675 _ui->doubleSpinBox_openchisel_truncation_quadratic->setValue(0.0019);
676 _ui->doubleSpinBox_openchisel_truncation_scale->setValue(10.0);
677 _ui->spinBox_openchisel_integration_weight->setValue(1);
678 _ui->checkBox_openchisel_use_voxel_carving->setChecked(
false);
679 _ui->doubleSpinBox_openchisel_carving_dist_m->setValue(0.05);
680 _ui->doubleSpinBox_openchisel_near_plane_dist->setValue(0.05);
681 _ui->doubleSpinBox_openchisel_far_plane_dist->setValue(1.1);
692 QString path = QFileDialog::getOpenFileName(
this, tr(
"Load Settings"),
_workingDirectory, tr(
"Config (*.ini)"));
695 QSettings settings(path, QSettings::IniFormat);
696 settings.beginGroup(
"Gui");
697 settings.beginGroup(this->objectName());
706 QString path = QFileDialog::getSaveFileName(
this, tr(
"Save Settings"),
_workingDirectory, tr(
"Config (*.ini)"));
709 QSettings settings(path, QSettings::IniFormat);
710 settings.beginGroup(
"Gui");
711 settings.beginGroup(this->objectName());
720 if(!
_ui->checkBox_fromDepth->isChecked())
722 _ui->comboBox_pipeline->setCurrentIndex(1);
723 _ui->comboBox_pipeline->setEnabled(
false);
724 _ui->comboBox_frame->setItemData(2, 0,Qt::UserRole - 1);
725 _ui->comboBox_frame->setItemData(3, 1|32,Qt::UserRole - 1);
726 if(
_ui->comboBox_frame->currentIndex() == 2)
728 _ui->comboBox_frame->setCurrentIndex(0);
733 _ui->comboBox_pipeline->setEnabled(
true);
734 _ui->comboBox_frame->setItemData(2, 1|32,Qt::UserRole - 1);
735 _ui->comboBox_frame->setItemData(3, 0,Qt::UserRole - 1);
736 if(
_ui->comboBox_frame->currentIndex() == 3)
738 _ui->comboBox_frame->setCurrentIndex(0);
742 _ui->checkBox_smoothing->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1);
743 _ui->checkBox_smoothing->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
744 _ui->label_smoothing->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1);
746 _ui->comboBox_frame->setEnabled(!
_ui->checkBox_assemble->isChecked() &&
_ui->checkBox_binary->isEnabled());
747 _ui->comboBox_frame->setVisible(
_ui->comboBox_frame->isEnabled());
748 _ui->label_frame->setVisible(
_ui->comboBox_frame->isEnabled());
749 _ui->checkBox_gainCompensation->setEnabled(!(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex() == 2));
750 _ui->checkBox_gainCompensation->setVisible(
_ui->checkBox_gainCompensation->isEnabled());
751 _ui->label_gainCompensation->setVisible(
_ui->checkBox_gainCompensation->isEnabled());
753 _ui->groupBox_regenerate->setVisible(
_ui->checkBox_regenerate->isChecked() &&
_ui->checkBox_fromDepth->isChecked());
754 _ui->groupBox_regenerateScans->setVisible(
_ui->checkBox_regenerate->isChecked() && !
_ui->checkBox_fromDepth->isChecked());
755 _ui->groupBox_bilateral->setVisible(
_ui->checkBox_bilateral->isChecked());
756 _ui->groupBox_filtering->setVisible(
_ui->checkBox_filtering->isChecked());
757 _ui->groupBox_gain->setVisible(
_ui->checkBox_gainCompensation->isEnabled() &&
_ui->checkBox_gainCompensation->isChecked());
758 _ui->groupBox_mls->setVisible(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked());
759 _ui->groupBox_meshing->setVisible(
_ui->checkBox_meshing->isChecked());
760 _ui->groupBox_subtraction->setVisible(
_ui->checkBox_subtraction->isChecked());
761 _ui->groupBox_textureMapping->setVisible(
_ui->checkBox_textureMapping->isChecked());
762 _ui->groupBox_cameraFilter->setVisible(
_ui->checkBox_cameraFilter->isChecked());
765 if(
_ui->checkBox_meshing->isChecked())
768 _ui->comboBox_meshingApproach->setItemData(0,
_ui->comboBox_pipeline->currentIndex() == 1?1 | 32:0,Qt::UserRole - 1);
771 _ui->comboBox_meshingApproach->setItemData(1,
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
774 #ifdef RTABMAP_CPUTSDF 775 _ui->comboBox_meshingApproach->setItemData(2,
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
777 _ui->comboBox_meshingApproach->setItemData(2, 0, Qt::UserRole - 1);
781 _ui->comboBox_meshingApproach->setItemData(3,
_ui->comboBox_pipeline->currentIndex() == 0?1 | 32:0,Qt::UserRole - 1);
784 #ifdef RTABMAP_OPENCHISEL 785 _ui->comboBox_meshingApproach->setItemData(4,
_ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
787 _ui->comboBox_meshingApproach->setItemData(4, 0, Qt::UserRole - 1);
790 if(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()<2)
792 _ui->comboBox_meshingApproach->setCurrentIndex(3);
794 if(
_ui->comboBox_pipeline->currentIndex() == 1 && (
_ui->comboBox_meshingApproach->currentIndex()==2 ||
_ui->comboBox_meshingApproach->currentIndex()==3))
796 _ui->comboBox_meshingApproach->setCurrentIndex(1);
798 if(!
_ui->checkBox_assemble->isChecked())
800 _ui->comboBox_meshingApproach->setCurrentIndex(
_ui->comboBox_pipeline->currentIndex() == 1?0:3);
803 _ui->checkBox_poisson_outputPolygons->setDisabled(
804 _ui->checkBox_binary->isEnabled() ||
805 _ui->doubleSpinBox_meshDecimationFactor->value()!=0.0 ||
806 _ui->spinBox_meshMaxPolygons->value()!=0 ||
807 _ui->checkBox_textureMapping->isChecked());
809 _ui->checkBox_cleanMesh->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
810 _ui->label_meshClean->setEnabled(
_ui->comboBox_pipeline->currentIndex() == 1);
812 _ui->groupBox_gp3->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->comboBox_meshingApproach->currentIndex()==0);
813 _ui->groupBox_poisson->setVisible(
_ui->comboBox_pipeline->currentIndex() == 1 &&
_ui->comboBox_meshingApproach->currentIndex()==1);
814 _ui->groupBox_cputsdf->setVisible(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()==2);
815 _ui->groupBox_organized->setVisible(
_ui->comboBox_pipeline->currentIndex() == 0 &&
_ui->comboBox_meshingApproach->currentIndex()==3);
816 _ui->groupBox_openchisel->setVisible(
_ui->comboBox_meshingApproach->currentIndex()==4);
819 _ui->doubleSpinBox_meshDecimationFactor->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
820 _ui->label_meshDecimation->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
821 _ui->spinBox_meshMaxPolygons->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
822 _ui->label_meshMaxPolygons->setEnabled(
_ui->comboBox_meshingApproach->currentIndex()!=3);
829 QString dir =
_ui->lineEdit_distortionModel->text();
834 QString path = QFileDialog::getOpenFileName(
this, tr(
"Select file"), dir, tr(
"Distortion model (*.bin *.txt)"));
837 _ui->lineEdit_distortionModel->setText(path);
843 _ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
false);
844 _ui->buttonBox->button(QDialogButtonBox::Save)->setVisible(
true);
845 _ui->checkBox_binary->setVisible(
true);
846 _ui->checkBox_binary->setEnabled(
true);
847 _ui->label_binaryFile->setVisible(
true);
848 _ui->checkBox_mesh_quad->setVisible(
false);
849 _ui->checkBox_mesh_quad->setEnabled(
false);
850 _ui->label_quad->setVisible(
false);
856 _ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(
true);
857 _ui->buttonBox->button(QDialogButtonBox::Save)->setVisible(
false);
858 _ui->checkBox_binary->setVisible(
false);
859 _ui->checkBox_binary->setEnabled(
false);
860 _ui->label_binaryFile->setVisible(
false);
861 _ui->checkBox_mesh_quad->setVisible(
true);
862 _ui->checkBox_mesh_quad->setEnabled(
true);
863 _ui->label_quad->setVisible(
true);
868 const std::map<int, Transform> & poses,
869 const std::multimap<int, Link> & links,
870 const std::map<int, int> & mapIds,
871 const QMap<int, Signature> & cachedSignatures,
872 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
873 const std::map<int, LaserScan> & cachedScans,
874 const QString & workingDirectory,
877 std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> clouds;
878 std::map<int, pcl::PolygonMesh::Ptr> meshes;
879 std::map<int, pcl::TextureMesh::Ptr> textureMeshes;
880 std::vector<std::map<int, pcl::PointXY> > textureVertexToPixels;
896 textureVertexToPixels))
898 if(textureMeshes.size())
900 saveTextureMeshes(workingDirectory, poses, textureMeshes, cachedSignatures, textureVertexToPixels);
902 else if(meshes.size())
904 bool exportMeshes =
true;
905 if(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked())
907 QMessageBox::StandardButton r = QMessageBox::warning(
this, tr(
"Exporting Texture Mesh"),
908 tr(
"No texture mesh could be created, do you want to continue with saving only the meshes (%1)?").arg(meshes.size()),
909 QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
910 exportMeshes = r == QMessageBox::Yes;
914 saveMeshes(workingDirectory, poses, meshes,
_ui->checkBox_binary->isChecked());
919 saveClouds(workingDirectory, poses, clouds,
_ui->checkBox_binary->isChecked());
930 const std::map<int, Transform> & poses,
931 const std::multimap<int, Link> & links,
932 const std::map<int, int> & mapIds,
933 const QMap<int, Signature> & cachedSignatures,
934 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
935 const std::map<int, LaserScan> & cachedScans,
936 const QString & workingDirectory,
939 std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> clouds;
940 std::map<int, pcl::PolygonMesh::Ptr> meshes;
941 std::map<int, pcl::TextureMesh::Ptr> textureMeshes;
942 std::vector<std::map<int, pcl::PointXY> > textureVertexToPixels;
958 textureVertexToPixels))
960 QDialog * window =
new QDialog(this->parentWidget()?this->parentWidget():
this, Qt::Window);
961 window->setAttribute(Qt::WA_DeleteOnClose,
true);
964 window->setWindowTitle(tr(
"Meshes (%1 nodes)").arg(meshes.size()));
968 window->setWindowTitle(tr(
"Clouds (%1 nodes)").arg(clouds.size()));
970 window->setMinimumWidth(120);
971 window->setMinimumHeight(90);
972 window->resize(QDesktopWidget().availableGeometry(
this).size() * 0.7);
975 if(
_ui->comboBox_pipeline->currentIndex() == 0)
983 QVBoxLayout *layout =
new QVBoxLayout();
984 layout->addWidget(viewer);
985 layout->setContentsMargins(0,0,0,0);
986 window->setLayout(layout);
987 connect(window, SIGNAL(finished(
int)), viewer, SLOT(clear()));
992 QApplication::processEvents();
994 QApplication::processEvents();
996 if(textureMeshes.size())
999 std::map<int, cv::Mat> images;
1000 std::map<int, std::vector<CameraModel> > calibrations;
1001 for(QMap<int, Signature>::const_iterator iter=cachedSignatures.constBegin(); iter!=cachedSignatures.constEnd(); ++iter)
1003 std::vector<CameraModel> models;
1004 if(iter->sensorData().cameraModels().size())
1006 models = iter->sensorData().cameraModels();
1008 else if(iter->sensorData().stereoCameraModel().isValidForProjection())
1010 models.push_back(iter->sensorData().stereoCameraModel().left());
1015 if(!iter->sensorData().imageRaw().empty())
1017 calibrations.insert(std::make_pair(iter.key(), models));
1018 images.insert(std::make_pair(iter.key(), iter->sensorData().imageRaw()));
1020 else if(!iter->sensorData().imageCompressed().empty())
1022 calibrations.insert(std::make_pair(iter.key(), models));
1023 images.insert(std::make_pair(iter.key(), iter->sensorData().imageCompressed()));
1027 int textureSize = 1024;
1028 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
1030 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
1032 int blendingDecimation = 0;
1033 if(
_ui->checkBox_blending->isChecked())
1035 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
1037 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
1041 for (std::map<int, pcl::TextureMesh::Ptr>::iterator iter = textureMeshes.begin(); iter != textureMeshes.end(); ++iter)
1043 pcl::TextureMesh::Ptr mesh = iter->second;
1046 cv::Mat globalTexture;
1047 if (mesh->tex_materials.size() > 1)
1049 cv::Mat globalTextures;
1058 textureVertexToPixels,
1059 _ui->checkBox_gainCompensation->isChecked(),
1060 _ui->doubleSpinBox_gainBeta->value(),
1061 _ui->checkBox_gainRGB->isChecked(),
1062 _ui->checkBox_blending->isChecked(),
1064 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
1065 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
1066 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked());
1067 if(globalTextures.rows == globalTextures.cols)
1069 globalTexture = globalTextures;
1073 _progressDialog->
appendText(tr(
"Viewing the mesh %1 (%2 polygons)...").arg(iter->first).arg(mesh->tex_polygons.size()?mesh->tex_polygons[0].size():0));
1080 for (
unsigned int t = 0; t < mesh->tex_coordinates.size(); ++t)
1082 if(mesh->tex_polygons[t].size())
1085 pcl::PointCloud<pcl::PointXYZ>::Ptr originalCloud(
new pcl::PointCloud<pcl::PointXYZ>);
1086 pcl::fromPCLPointCloud2(mesh->cloud, *originalCloud);
1089 unsigned int nPoints = mesh->tex_coordinates[t].size();
1090 UASSERT(nPoints == mesh->tex_polygons[t].size()*mesh->tex_polygons[t][0].vertices.size());
1092 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
1093 cloud->resize(nPoints);
1095 unsigned int oi = 0;
1096 for (
unsigned int i = 0; i < mesh->tex_polygons[t].size(); ++i)
1098 pcl::Vertices &
vertices = mesh->tex_polygons[t][i];
1100 for(
unsigned int j=0; j<vertices.vertices.size(); ++j)
1103 UASSERT_MSG(vertices.vertices[j] < originalCloud->size(),
uFormat(
"%d vs %d", vertices.vertices[j], (
int)originalCloud->size()).c_str());
1104 cloud->at(oi) = originalCloud->at(vertices.vertices[j]);
1105 vertices.vertices[j] = oi;
1109 pcl::toPCLPointCloud2(*cloud, mesh->cloud);
1113 UWARN(
"No polygons for texture %d of mesh %d?!", t, iter->first);
1117 if (globalTexture.empty())
1119 if(mesh->tex_materials.size()==1 &&
1120 !mesh->tex_materials[0].tex_file.empty() &&
1121 uIsInteger(mesh->tex_materials[0].tex_file,
false))
1123 int textureId =
uStr2Int(mesh->tex_materials[0].tex_file);
1125 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
1127 data = cachedSignatures.value(textureId).sensorData();
1135 UASSERT(!globalTexture.empty());
1149 _progressDialog->
appendText(tr(
"Viewing the mesh %1 (%2 polygons)... done.").arg(iter->first).arg(mesh->tex_polygons.size()?mesh->tex_polygons[0].size():0));
1150 QApplication::processEvents();
1153 else if(meshes.size())
1156 for(std::map<int, pcl::PolygonMesh::Ptr>::iterator iter = meshes.begin(); iter!=meshes.end(); ++iter)
1158 _progressDialog->
appendText(tr(
"Viewing the mesh %1 (%2 polygons)...").arg(iter->first).arg(iter->second->polygons.size()));
1161 for(
unsigned int i=0; i<iter->second->cloud.fields.size(); ++i)
1163 if(iter->second->cloud.fields[i].name.compare(
"rgb") == 0)
1171 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
1172 pcl::fromPCLPointCloud2(iter->second->cloud, *cloud);
1177 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
1178 pcl::fromPCLPointCloud2(iter->second->cloud, *cloud);
1181 _progressDialog->
appendText(tr(
"Viewing the mesh %1 (%2 polygons)... done.").arg(iter->first).arg(iter->second->polygons.size()));
1182 QApplication::processEvents();
1185 else if(clouds.size())
1187 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::iterator iter = clouds.begin(); iter!=clouds.end(); ++iter)
1192 QColor color = Qt::gray;
1193 int mapId =
uValue(mapIds, iter->first, -1);
1196 color = (Qt::GlobalColor)(mapId % 12 + 7 );
1200 _progressDialog->
appendText(tr(
"Viewing the cloud %1 (%2 points)... done.").arg(iter->first).arg(iter->second->size()));
1214 int textureSize = 1024;
1215 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
1217 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
1223 return _ui->spinBox_mesh_maxTextures->value();
1227 return _ui->checkBox_gainCompensation->isChecked();
1231 return _ui->doubleSpinBox_gainBeta->value();
1235 return _ui->checkBox_gainRGB->isChecked();
1239 return _ui->checkBox_blending->isChecked();
1243 int blendingDecimation = 0;
1244 if(
_ui->checkBox_blending->isChecked())
1246 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
1248 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
1251 return blendingDecimation;
1255 return _ui->spinBox_textureBrightnessContrastRatioLow->value();
1259 return _ui->spinBox_textureBrightnessContrastRatioHigh->value();
1263 return _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked();
1271 if (dir.exists(dirName)) {
1272 Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
1277 result = QFile::remove(info.absoluteFilePath());
1284 result = dir.rmdir(dirName);
1290 const std::map<int, Transform> & poses,
1291 const std::multimap<int, Link> & links,
1292 const std::map<int, int> & mapIds,
1293 const QMap<int, Signature> & cachedSignatures,
1294 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
1295 const std::map<int, LaserScan> & cachedScans,
1296 const QString & workingDirectory,
1298 std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & cloudsWithNormals,
1299 std::map<int, pcl::PolygonMesh::Ptr> & meshes,
1300 std::map<int, pcl::TextureMesh::Ptr> & textureMeshes,
1301 std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels)
1305 _ui->checkBox_regenerate->setEnabled(
true);
1306 if(cachedSignatures.empty() &&
_dbDriver)
1308 _ui->checkBox_regenerate->setChecked(
true);
1309 _ui->checkBox_regenerate->setEnabled(
false);
1316 if(this->exec() == QDialog::Accepted)
1320 QMessageBox::critical(
this, tr(
"Creating clouds..."), tr(
"Poses are null! Cannot export/view clouds."));
1326 if(
_ui->checkBox_meshing->isChecked())
1330 if(
_ui->checkBox_assemble->isChecked())
1335 if(
_ui->checkBox_subtraction->isChecked())
1339 if(
_ui->checkBox_textureMapping->isChecked())
1343 if(
_ui->checkBox_gainCompensation->isChecked())
1347 if(
_ui->checkBox_mesh_quad->isEnabled())
1353 bool loadClouds =
true;
1354 #ifdef RTABMAP_OPENCHISEL 1355 if(
_ui->comboBox_meshingApproach->currentIndex()==4 &&
_ui->checkBox_assemble->isChecked())
1357 loadClouds = !
_ui->checkBox_fromDepth->isChecked();
1361 bool has2dScans =
false;
1362 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
1376 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
1378 clouds.insert(std::make_pair(iter->first,
1380 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr(
new pcl::PointCloud<pcl::PointXYZRGBNormal>),
1381 pcl::IndicesPtr(
new std::vector<int>))));
1386 std::set<int> validCameras =
uKeysSet(clouds);
1397 if(
_ui->checkBox_regenerate->isEnabled() && !
_ui->checkBox_regenerate->isChecked())
1399 QMessageBox::warning(
this, tr(
"Creating clouds..."), tr(
"Could create clouds for %1 node(s). You " 1400 "may want to activate clouds regeneration option.").arg(poses.size()));
1404 QMessageBox::warning(
this, tr(
"Creating clouds..."), tr(
"Could not create clouds for %1 " 1405 "node(s). The cache may not contain point cloud data. Try re-downloading the map.").arg(poses.size()));
1411 if(
_ui->checkBox_gainCompensation->isChecked() &&
_ui->checkBox_fromDepth->isChecked() && clouds.size() > 1 &&
1413 !(
_ui->checkBox_meshing->isChecked() &&
1414 _ui->checkBox_textureMapping->isEnabled() &&
1415 _ui->checkBox_textureMapping->isChecked() &&
1416 _ui->comboBox_pipeline->currentIndex()==1 &&
1417 _ui->checkBox_assemble->isChecked() &&
1418 _ui->comboBox_meshingTextureSize->isEnabled() &&
1419 _ui->comboBox_meshingTextureSize->currentIndex() > 0) &&
1421 !(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==2))
1426 if(
_ui->checkBox_gainFull->isChecked())
1434 QApplication::processEvents();
1436 QApplication::processEvents();
1438 if(
_ui->checkBox_gainFull->isChecked())
1440 std::multimap<int, Link> allLinks;
1441 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::const_iterator iter=clouds.begin(); iter!=clouds.end(); ++iter)
1443 int from = iter->first;
1444 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::const_iterator jter = iter;
1446 for(;jter!=clouds.end(); ++jter)
1448 int to = jter->first;
1449 allLinks.insert(std::make_pair(from,
Link(from, to,
Link::kUserClosure, poses.at(from).inverse()*poses.at(to))));
1460 if(!(
_ui->checkBox_meshing->isChecked() &&
1461 _ui->checkBox_textureMapping->isEnabled() &&
1462 _ui->checkBox_textureMapping->isChecked()))
1465 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::iterator jter=clouds.begin();jter!=clouds.end(); ++jter)
1467 if(jter!=clouds.end())
1470 _compensator->
apply(jter->first, jter->second.first, jter->second.second,
_ui->checkBox_gainRGB->isChecked());
1474 QApplication::processEvents();
1485 std::map<int, Transform> normalViewpoints = poses;
1486 if(
_ui->checkBox_assemble->isChecked())
1489 for(std::map<int, Transform>::iterator iter= normalViewpoints.begin(); iter!=normalViewpoints.end(); ++iter)
1491 if(
_ui->checkBox_fromDepth->isChecked())
1493 std::vector<CameraModel> models;
1495 if(cachedSignatures.contains(iter->first))
1497 const SensorData & data = cachedSignatures.find(iter->first)->sensorData();
1506 if(models.size() && !models[0].localTransform().isNull())
1508 iter->second *= models[0].localTransform();
1519 iter->second *= cachedScans.at(iter->first).localTransform();
1521 else if(cachedSignatures.contains(iter->first))
1523 const SensorData & data = cachedSignatures.find(iter->first)->sensorData();
1544 pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(
new pcl::PointCloud<pcl::PointXYZ>);
1545 std::vector<int> rawCameraIndices;
1546 if(
_ui->checkBox_assemble->isChecked() &&
1547 !((
_ui->comboBox_pipeline->currentIndex()==0 ||
_ui->comboBox_meshingApproach->currentIndex()==4) &&
_ui->checkBox_meshing->isChecked()))
1550 QApplication::processEvents();
1553 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
1554 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::iterator iter=clouds.begin();
1555 iter!= clouds.end();
1558 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformed(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
1559 if(iter->second.first->isOrganized())
1561 pcl::copyPointCloud(*iter->second.first, *iter->second.second, *transformed);
1568 pcl::copyPointCloud(*iter->second.first, *iter->second.second, *transformed);
1572 *assembledCloud += *transformed;
1573 rawCameraIndices.resize(assembledCloud->size(), iter->first);
1575 _progressDialog->
appendText(tr(
"Assembled cloud %1, total=%2 (%3/%4).").arg(iter->first).arg(assembledCloud->size()).arg(++i).arg(clouds.size()));
1577 QApplication::processEvents();
1584 assembledCloud->is_dense =
true;
1585 pcl::copyPointCloud(*assembledCloud, *rawAssembledCloud);
1587 if(
_ui->doubleSpinBox_voxelSize_assembled->value())
1590 .arg(assembledCloud->size())
1591 .arg(
_ui->doubleSpinBox_voxelSize_assembled->value()));
1592 QApplication::processEvents();
1593 unsigned int before = assembledCloud->size();
1596 _ui->doubleSpinBox_voxelSize_assembled->value());
1599 .arg(
_ui->doubleSpinBox_voxelSize_assembled->value())
1600 .arg(assembledCloud->size()));
1604 pcl::IndicesPtr indices(
new std::vector<int>);
1605 indices->resize(assembledCloud->size());
1606 for(
unsigned int i=0; i<indices->size(); ++i)
1611 if(!
_ui->checkBox_fromDepth->isChecked() && !has2dScans)
1614 pcl::PointCloud<pcl::PointXYZ>::Ptr cloudWithoutNormals(
new pcl::PointCloud<pcl::PointXYZ>);
1615 pcl::copyPointCloud(*assembledCloud, *cloudWithoutNormals);
1616 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals, indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value());
1618 UASSERT(assembledCloud->size() == normals->size());
1619 for(
unsigned int i=0; i<normals->size(); ++i)
1621 assembledCloud->points[i].normal_x = normals->points[i].normal_x;
1622 assembledCloud->points[i].normal_y = normals->points[i].normal_y;
1623 assembledCloud->points[i].normal_z = normals->points[i].normal_z;
1634 clouds.insert(std::make_pair(0, std::make_pair(assembledCloud, indices)));
1643 if(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked() && !has2dScans)
1646 "[search radius=%1m voxel=%2m]").arg(
_ui->doubleSpinBox_mlsRadius->value()).arg(
_ui->doubleSpinBox_voxelSize_assembled->value()));
1647 QApplication::processEvents();
1649 QApplication::processEvents();
1653 for(std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::iterator iter=clouds.begin();
1654 iter!= clouds.end();)
1656 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals = iter->second.first;
1658 if(
_ui->checkBox_smoothing->isEnabled() &&
_ui->checkBox_smoothing->isChecked() && !has2dScans)
1660 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals(
new pcl::PointCloud<pcl::PointXYZRGB>);
1661 if(iter->second.second->size())
1663 pcl::copyPointCloud(*cloudWithNormals, *iter->second.second, *cloudWithoutNormals);
1667 pcl::copyPointCloud(*cloudWithNormals, *cloudWithoutNormals);
1671 QApplication::processEvents();
1673 QApplication::processEvents();
1680 cloudWithoutNormals,
1681 (
float)
_ui->doubleSpinBox_mlsRadius->value(),
1682 _ui->spinBox_polygonialOrder->value(),
1683 _ui->comboBox_upsamplingMethod->currentIndex(),
1684 (float)
_ui->doubleSpinBox_sampleRadius->value(),
1685 (float)
_ui->doubleSpinBox_sampleStep->value(),
1686 _ui->spinBox_randomPoints->value(),
1687 (float)
_ui->doubleSpinBox_dilationVoxelSize->value(),
1688 _ui->spinBox_dilationSteps->value());
1691 UDEBUG(
"NaNs filtering... size before = %d", cloudWithNormals->size());
1693 UDEBUG(
"NaNs filtering... size after = %d", cloudWithNormals->size());
1695 if(
_ui->checkBox_assemble->isChecked())
1698 if(
_ui->doubleSpinBox_mls_outputVoxelSize->value())
1701 .arg(cloudWithNormals->size())
1702 .arg(
_ui->doubleSpinBox_mls_outputVoxelSize->value()));
1703 QApplication::processEvents();
1707 _ui->doubleSpinBox_mls_outputVoxelSize->value());
1710 _progressDialog->
appendText(tr(
"Update %1 normals with %2 camera views...").arg(cloudWithNormals->size()).arg(poses.size()));
1719 else if(iter->second.first->isOrganized() &&
_ui->checkBox_filtering->isChecked())
1724 cloudsWithNormals.insert(std::make_pair(iter->first, cloudWithNormals));
1727 clouds.erase(iter++);
1730 QApplication::processEvents();
1738 #ifdef RTABMAP_CPUTSDF 1739 cpu_tsdf::TSDFVolumeOctree::Ptr tsdf;
1741 #ifdef RTABMAP_OPENCHISEL 1742 chisel::ChiselPtr chiselMap;
1743 chisel::ProjectionIntegrator projectionIntegrator;
1747 std::map<int, std::vector<int> > organizedIndices;
1748 std::map<int, cv::Size> organizedCloudSizes;
1751 UDEBUG(
"Meshing=%d",
_ui->checkBox_meshing->isChecked()?1:0);
1752 if(
_ui->checkBox_meshing->isChecked() && !has2dScans)
1755 #ifdef RTABMAP_OPENCHISEL 1756 if(
_ui->comboBox_meshingApproach->currentIndex()==4 &&
_ui->checkBox_assemble->isChecked())
1760 QApplication::processEvents();
1762 QApplication::processEvents();
1764 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
1765 std::vector<pcl::Vertices> mergedPolygons;
1767 int cloudsAdded = 1;
1768 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::iterator iter=cloudsWithNormals.begin();
1769 iter!= cloudsWithNormals.end();
1770 ++iter,++cloudsAdded)
1772 std::vector<CameraModel> models;
1774 bool cacheHasCompressedImage =
false;
1776 if(cachedSignatures.contains(iter->first))
1778 const SensorData & data = cachedSignatures.find(iter->first)->sensorData();
1789 if(chiselMap.get() == 0)
1792 int chunkSizeX =
_ui->spinBox_openchisel_chunk_size_x->value();
1793 int chunkSizeY =
_ui->spinBox_openchisel_chunk_size_y->value();
1794 int chunkSizeZ =
_ui->spinBox_openchisel_chunk_size_z->value();
1795 float voxelResolution =
_ui->doubleSpinBox_voxelSize_assembled->value();
1796 if(voxelResolution <=0.0
f)
1802 bool useColor =
_ui->checkBox_fromDepth->isChecked();
1803 chiselMap.reset(
new chisel::Chisel(Eigen::Vector3i(chunkSizeX, chunkSizeY, chunkSizeZ), voxelResolution, useColor));
1804 double truncationDistConst =
_ui->doubleSpinBox_openchisel_truncation_constant->value();
1805 double truncationDistLinear =
_ui->doubleSpinBox_openchisel_truncation_linear->value();
1806 double truncationDistQuad =
_ui->doubleSpinBox_openchisel_truncation_quadratic->value();
1807 double truncationDistScale =
_ui->doubleSpinBox_openchisel_truncation_scale->value();
1808 int weight =
_ui->spinBox_openchisel_integration_weight->value();
1809 bool useCarving =
_ui->checkBox_openchisel_use_voxel_carving->isChecked();
1810 double carvingDist =
_ui->doubleSpinBox_openchisel_carving_dist_m->value();
1811 chisel::Vec4 truncation(truncationDistQuad, truncationDistLinear, truncationDistConst, truncationDistScale);
1812 UDEBUG(
"If crashing just after this message, make sure PCL and OpenChisel are built both with -march=native or both without -march=native");
1813 projectionIntegrator.SetCentroids(chiselMap->GetChunkManager().GetCentroids());
1814 projectionIntegrator.SetTruncator(chisel::TruncatorPtr(
new chisel::QuadraticTruncator(truncation(0), truncation(1), truncation(2), truncation(3))));
1815 projectionIntegrator.SetWeighter(chisel::WeighterPtr(
new chisel::ConstantWeighter(weight)));
1816 projectionIntegrator.SetCarvingDist(carvingDist);
1817 projectionIntegrator.SetCarvingEnabled(useCarving);
1821 double nearPlaneDist =
_ui->doubleSpinBox_openchisel_near_plane_dist->value();
1822 double farPlaneDist =
_ui->doubleSpinBox_openchisel_far_plane_dist->value();
1823 if(
_ui->checkBox_fromDepth->isChecked())
1825 if(models.size() == 1 && !models[0].localTransform().isNull())
1830 if(cacheHasCompressedImage)
1832 cachedSignatures.find(iter->first)->sensorData().uncompressDataConst(&rgb, &depth);
1840 if(!rgb.empty() && !depth.empty())
1844 if(rgb.cols > depth.cols)
1846 UASSERT(rgb.cols % depth.cols == 0);
1847 depthModel = depthModel.
scaled(
double(depth.cols)/
double(rgb.cols));
1850 if(depth.type() == CV_16UC1)
1855 std::shared_ptr<chisel::ColorImage<unsigned char> > colorChisel =
colorImageToChisel(rgb);
1860 cameraColor.SetNearPlane(nearPlaneDist);
1861 cameraColor.SetFarPlane(farPlaneDist);
1862 cameraDepth.SetNearPlane(nearPlaneDist);
1863 cameraDepth.SetFarPlane(farPlaneDist);
1865 chisel::Transform pose_rel_to_first_frame = (poses.at(iter->first)*models[0].localTransform()).toEigen3f();
1866 chiselMap->IntegrateDepthScanColor<float,
unsigned char>(projectionIntegrator, depthChisel, pose_rel_to_first_frame, cameraDepth, colorChisel, pose_rel_to_first_frame, cameraColor);
1876 _progressDialog->
appendText(tr(
"OpenChisel: Invalid camera model for cloud %1! Only single RGB-D camera supported.").arg(iter->first), Qt::darkYellow);
1884 chisel::Transform pose_rel_to_first_frame = (poses.at(iter->first)*scanInfo.
localTransform()).toEigen3f();
1885 chiselMap->IntegratePointCloud(projectionIntegrator, *chiselCloud, pose_rel_to_first_frame, farPlaneDist);
1894 chiselMap->UpdateMeshes();
1896 _progressDialog->
appendText(tr(
"OpenChisel: Integrated cloud %1 (%2/%3) to TSDF volume").arg(iter->first).arg(cloudsAdded).arg(cloudsWithNormals.size()));
1899 QApplication::processEvents();
1909 if(
_ui->comboBox_pipeline->currentIndex() == 0)
1911 if(
_ui->comboBox_meshingApproach->currentIndex()==2)
1919 QApplication::processEvents();
1921 QApplication::processEvents();
1923 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
1924 std::vector<pcl::Vertices> mergedPolygons;
1926 int cloudsAdded = 1;
1927 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::iterator iter=cloudsWithNormals.begin();
1928 iter!= cloudsWithNormals.end();
1929 ++iter,++cloudsAdded)
1931 if(iter->second->isOrganized())
1933 if(iter->second->size())
1935 Eigen::Vector3f viewpoint(0.0
f,0.0
f,0.0
f);
1937 std::vector<CameraModel> models;
1939 if(cachedSignatures.contains(iter->first))
1941 const SensorData & data = cachedSignatures.find(iter->first)->sensorData();
1950 #ifdef RTABMAP_CPUTSDF 1951 if(
_ui->comboBox_meshingApproach->currentIndex()==2 &&
_ui->checkBox_assemble->isChecked())
1955 if(models.size()==1 && models[0].isValidForProjection() && models[0].imageHeight()>0 && models[0].imageWidth()>0)
1957 float tsdf_size =
_ui->doubleSpinBox_cputsdf_size->value();
1958 float cell_size =
_ui->doubleSpinBox_cputsdf_resolution->value();
1959 int num_random_splits =
_ui->spinBox_cputsdf_randomSplit->value();
1961 int desired_res = tsdf_size / cell_size;
1964 while (desired_res > n)
1970 tsdf.reset (
new cpu_tsdf::TSDFVolumeOctree);
1971 tsdf->setGridSize (tsdf_size, tsdf_size, tsdf_size);
1972 tsdf->setResolution (tsdf_res, tsdf_res, tsdf_res);
1973 float decimation = float(models[0].imageWidth()) / float(iter->second->width);
1974 tsdf->setImageSize (models[0].imageWidth()/decimation, models[0].imageHeight()/decimation);
1975 tsdf->setCameraIntrinsics (models[0].fx()/decimation, models[0].fy()/decimation, models[0].cx()/decimation, models[0].cy()/decimation);
1976 tsdf->setNumRandomSplts (num_random_splits);
1977 tsdf->setSensorDistanceBounds (0, 9999);
1978 tsdf->setIntegrateColor(
true);
1979 tsdf->setDepthTruncationLimits (
_ui->doubleSpinBox_cputsdf_tuncPos->value(),
_ui->doubleSpinBox_cputsdf_tuncNeg->value());
1992 if(tsdf.get() && models.size() == 1 && !models[0].localTransform().isNull())
1994 Eigen::Affine3d pose_rel_to_first_frame = ((poses.begin()->second.inverse() * poses.at(iter->first))*models[0].localTransform()).toEigen3d();
1995 if(!tsdf->integrateCloud(*
util3d::transformPointCloud(iter->second, models[0].localTransform().inverse()), pcl::PointCloud<pcl::Normal>(), pose_rel_to_first_frame))
1997 _progressDialog->
appendText(tr(
"CPU-TSDF: Failed integrating cloud %1 (%2/%3) to TSDF volume").arg(iter->first).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2001 _progressDialog->
appendText(tr(
"CPU-TSDF: Integrated cloud %1 (%2/%3) to TSDF volume").arg(iter->first).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2009 if((
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex() != 2) ||
2010 !iter->second->isOrganized())
2012 if(models.size() && !models[0].localTransform().isNull())
2014 viewpoint[0] = models[0].localTransform().x();
2015 viewpoint[1] = models[0].localTransform().y();
2016 viewpoint[2] = models[0].localTransform().z();
2028 _ui->doubleSpinBox_mesh_angleTolerance->value()*
M_PI/180.0,
2029 _ui->checkBox_mesh_quad->isEnabled() &&
_ui->checkBox_mesh_quad->isChecked(),
2030 _ui->spinBox_mesh_triangleSize->value(),
2033 if(
_ui->spinBox_mesh_minClusterSize->value() != 0)
2036 QApplication::processEvents();
2039 std::vector<std::set<int> > neighbors;
2040 std::vector<std::set<int> > vertexToPolygons;
2042 (
int)iter->second->size(),
2047 _ui->spinBox_mesh_minClusterSize->value()<0?0:
_ui->spinBox_mesh_minClusterSize->value());
2049 std::vector<pcl::Vertices> filteredPolygons(polygons.size());
2050 if(
_ui->spinBox_mesh_minClusterSize->value() < 0)
2053 std::list<std::list<int> >::iterator biggestClusterIndex = clusters.end();
2054 unsigned int biggestClusterSize = 0;
2055 for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
2057 if(iter->size() > biggestClusterSize)
2059 biggestClusterIndex = iter;
2060 biggestClusterSize = iter->size();
2063 if(biggestClusterIndex != clusters.end())
2066 for(std::list<int>::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter)
2068 filteredPolygons[oi++] = polygons.at(*jter);
2070 filteredPolygons.resize(oi);
2076 for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
2078 for(std::list<int>::iterator jter=iter->begin(); jter!=iter->end(); ++jter)
2080 filteredPolygons[oi++] = polygons.at(*jter);
2083 filteredPolygons.resize(oi);
2085 int before = (int)polygons.size();
2086 polygons = filteredPolygons;
2088 if(polygons.size() == 0)
2090 std::string msg =
uFormat(
"All %d polygons filtered after polygon cluster filtering. Cluster minimum size is %d.", before,
_ui->spinBox_mesh_minClusterSize->value());
2096 QApplication::processEvents();
2099 _progressDialog->
appendText(tr(
"Mesh %1 created with %2 polygons (%3/%4).").arg(iter->first).arg(polygons.size()).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2101 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr denseCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2102 std::vector<pcl::Vertices> densePolygons;
2105 if(!
_ui->checkBox_assemble->isChecked() ||
2106 (
_ui->checkBox_textureMapping->isEnabled() &&
2107 _ui->checkBox_textureMapping->isChecked() &&
2108 _ui->doubleSpinBox_voxelSize_assembled->value() == 0.0))
2110 if(
_ui->checkBox_assemble->isChecked())
2115 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2116 pcl::toPCLPointCloud2(*denseCloud, mesh->cloud);
2117 mesh->polygons = densePolygons;
2119 organizedIndices.insert(std::make_pair(iter->first, denseToOrganizedIndices));
2120 organizedCloudSizes.insert(std::make_pair(iter->first, cv::Size(iter->second->width, iter->second->height)));
2122 meshes.insert(std::make_pair(iter->first, mesh));
2127 if(mergedClouds->size() == 0)
2129 *mergedClouds = *denseCloud;
2130 mergedPolygons = densePolygons;
2141 _progressDialog->
appendText(tr(
"Mesh %1 not created (no valid points) (%2/%3).").arg(iter->first).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2147 if(cachedSignatures.contains(iter->first))
2149 const Signature & s = cachedSignatures.find(iter->first).value();
2158 _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()));
2163 QApplication::processEvents();
2170 if(
_ui->checkBox_assemble->isChecked() && mergedClouds->size())
2172 if(
_ui->doubleSpinBox_voxelSize_assembled->value())
2174 _progressDialog->
appendText(tr(
"Filtering assembled mesh for close vertices (points=%1, polygons=%2)...").arg(mergedClouds->size()).arg(mergedPolygons.size()));
2175 QApplication::processEvents();
2180 _ui->doubleSpinBox_voxelSize_assembled->value(),
2185 unsigned int count = mergedPolygons.size();
2188 QApplication::processEvents();
2191 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr filteredCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2192 std::vector<pcl::Vertices> filteredPolygons;
2194 mergedClouds = filteredCloud;
2195 mergedPolygons = filteredPolygons;
2198 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2199 pcl::toPCLPointCloud2(*mergedClouds, mesh->cloud);
2200 mesh->polygons = mergedPolygons;
2202 meshes.insert(std::make_pair(0, mesh));
2205 QApplication::processEvents();
2210 if(
_ui->comboBox_meshingApproach->currentIndex() == 0)
2218 QApplication::processEvents();
2220 QApplication::processEvents();
2223 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::iterator iter=cloudsWithNormals.begin();
2224 iter!= cloudsWithNormals.end();
2225 ++iter,++cloudsAdded)
2227 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2228 if(
_ui->comboBox_meshingApproach->currentIndex() == 0)
2232 _ui->doubleSpinBox_gp3Radius->value(),
2233 _ui->doubleSpinBox_gp3Mu->value());
2237 pcl::Poisson<pcl::PointXYZRGBNormal> poisson;
2238 poisson.setOutputPolygons(
_ui->checkBox_poisson_outputPolygons->isEnabled()?
_ui->checkBox_poisson_outputPolygons->isChecked():
false);
2239 poisson.setManifold(
_ui->checkBox_poisson_manifold->isChecked());
2240 poisson.setSamplesPerNode(
_ui->doubleSpinBox_poisson_samples->value());
2241 int depth =
_ui->spinBox_poisson_depth->value();
2246 float mapLength =
uMax3(max[0]-min[0], max[1]-min[1], max[2]-min[2]);
2248 for(
int i=6; i<12; ++i)
2250 if(mapLength/
float(1<<i) < 0.03
f)
2258 .arg(
int(max[0]-min[0]))
2259 .arg(
int(max[1]-min[1]))
2260 .arg(
int(max[2]-min[2])));
2261 QApplication::processEvents();
2263 QApplication::processEvents();
2265 poisson.setDepth(depth);
2266 poisson.setIsoDivide(
_ui->spinBox_poisson_iso->value());
2267 poisson.setSolverDivide(
_ui->spinBox_poisson_solver->value());
2268 poisson.setMinDepth(
_ui->spinBox_poisson_minDepth->value());
2269 poisson.setPointWeight(
_ui->doubleSpinBox_poisson_pointWeight->value());
2270 poisson.setScale(
_ui->doubleSpinBox_poisson_scale->value());
2271 poisson.setInputCloud(iter->second);
2272 poisson.reconstruct(*mesh);
2275 _progressDialog->
appendText(tr(
"Mesh %1 created with %2 polygons (%3/%4).").arg(iter->first).arg(mesh->polygons.size()).arg(cloudsAdded).arg(cloudsWithNormals.size()));
2276 QApplication::processEvents();
2278 if(mesh->polygons.size()>0)
2281 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
2283 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
2284 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
2286 (float)
_ui->doubleSpinBox_transferColorRadius->value(),
2287 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
2288 _ui->checkBox_cleanMesh->isChecked(),
2289 _ui->spinBox_mesh_minClusterSize->value(),
2291 meshes.insert(std::make_pair(iter->first, mesh));
2300 QApplication::processEvents();
2308 else if(
_ui->checkBox_meshing->isChecked())
2310 std::string msg =
uFormat(
"Some clouds are 2D laser scans. Meshing can be done only from RGB-D clouds or 3D laser scans.");
2316 #ifdef RTABMAP_CPUTSDF 2320 QApplication::processEvents();
2322 QApplication::processEvents();
2324 cpu_tsdf::MarchingCubesTSDFOctree mc;
2325 mc.setMinWeight (
_ui->doubleSpinBox_cputsdf_minWeight->value());
2326 mc.setInputTSDF (tsdf);
2327 mc.setColorByRGB (
true);
2328 pcl::PolygonMesh::Ptr mesh (
new pcl::PolygonMesh);
2329 mc.reconstruct (*mesh);
2330 _progressDialog->
appendText(tr(
"CPU-TSDF: Creating mesh from TSDF volume...done! %1 polygons").arg(mesh->polygons.size()));
2333 if(mesh->polygons.size()>0)
2336 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr
vertices (
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2337 pcl::fromPCLPointCloud2 (mesh->cloud, *vertices);
2339 if(
_ui->doubleSpinBox_cputsdf_flattenRadius->value()>0.0)
2342 QApplication::processEvents();
2344 QApplication::processEvents();
2346 float min_dist =
_ui->doubleSpinBox_cputsdf_flattenRadius->value();
2347 pcl::search::KdTree<pcl::PointXYZRGBNormal> vert_tree (
true);
2348 vert_tree.setInputCloud (vertices);
2350 std::vector<int> vertex_remap (vertices->size (), -1);
2352 std::vector<int> neighbors;
2353 std::vector<float> dists;
2354 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr vertices_new(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2355 vertices_new->resize(vertices->size ());
2356 for (
size_t i = 0; i < vertices->size (); i++)
2358 if (vertex_remap[i] >= 0)
2360 vertex_remap[i] = idx;
2361 vert_tree.radiusSearch (i, min_dist, neighbors, dists);
2362 for (
size_t j = 1; j < neighbors.size (); j++)
2364 if (dists[j] < min_dist)
2365 vertex_remap[neighbors[j]] = idx;
2367 vertices_new->at(idx++) = vertices->at (i);
2369 vertices_new->resize(idx);
2370 std::vector<size_t> faces_to_remove;
2371 size_t face_idx = 0;
2372 for (
size_t i = 0; i < mesh->polygons.size (); i++)
2374 pcl::Vertices &v = mesh->polygons[i];
2375 for (
size_t j = 0; j < v.vertices.size (); j++)
2377 v.vertices[j] = vertex_remap[v.vertices[j]];
2379 if (!(v.vertices[0] == v.vertices[1] || v.vertices[1] == v.vertices[2] || v.vertices[2] == v.vertices[0]))
2381 mesh->polygons[face_idx++] = mesh->polygons[i];
2384 mesh->polygons.resize (face_idx);
2385 pcl::toPCLPointCloud2 (*vertices_new, mesh->cloud);
2386 vertices = vertices_new;
2389 pcl::fromPCLPointCloud2(mesh->cloud, *vertices);
2391 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
2393 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
2394 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
2396 (float)
_ui->doubleSpinBox_transferColorRadius->value(),
2397 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
2398 _ui->checkBox_cleanMesh->isChecked(),
2399 _ui->spinBox_mesh_minClusterSize->value(),
2401 meshes.insert(std::make_pair(0, mesh));
2410 #ifdef RTABMAP_OPENCHISEL 2414 QApplication::processEvents();
2416 QApplication::processEvents();
2418 const chisel::MeshMap& meshMap = chiselMap->GetChunkManager().GetAllMeshes();
2426 _progressDialog->
appendText(tr(
"OpenChisel: Creating mesh from TSDF volume...done! %1 polygons").arg(mesh->polygons.size()));
2429 if(mesh->polygons.size()>0)
2431 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2432 pcl::fromPCLPointCloud2(mesh->cloud, *mergedClouds);
2433 if(
_ui->checkBox_openchisel_mergeVertices->isChecked())
2435 _progressDialog->
appendText(tr(
"Filtering assembled mesh for close vertices (points=%1, polygons=%2)...").arg(mergedClouds->size()).arg(mesh->polygons.size()));
2436 QApplication::processEvents();
2441 _ui->doubleSpinBox_voxelSize_assembled->value()/2.0,
2446 unsigned int count = mesh->polygons.size();
2449 QApplication::processEvents();
2452 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr filteredCloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2453 std::vector<pcl::Vertices> filteredPolygons;
2454 count = mergedClouds->size();
2456 mergedClouds = filteredCloud;
2457 pcl::toPCLPointCloud2(*mergedClouds, mesh->cloud);
2458 mesh->polygons = filteredPolygons;
2460 QApplication::processEvents();
2463 util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
2465 _ui->doubleSpinBox_meshDecimationFactor->isEnabled()?(float)
_ui->doubleSpinBox_meshDecimationFactor->value():0.0f,
2466 _ui->spinBox_meshMaxPolygons->isEnabled()?
_ui->spinBox_meshMaxPolygons->value():0,
2468 (float)
_ui->doubleSpinBox_transferColorRadius->value(),
2469 !(
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()),
2470 _ui->checkBox_cleanMesh->isChecked(),
2471 _ui->spinBox_mesh_minClusterSize->value(),
2473 meshes.insert(std::make_pair(0, mesh));
2490 UDEBUG(
"texture mapping=%d",
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked()?1:0);
2491 if(!has2dScans &&
_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked())
2494 QApplication::processEvents();
2496 QApplication::processEvents();
2499 for(std::map<int, pcl::PolygonMesh::Ptr>::iterator iter=meshes.begin();
2500 iter!= meshes.end();
2503 std::map<int, Transform> cameras;
2504 if(iter->first == 0)
2511 cameras.insert(std::make_pair(iter->first,
_ui->checkBox_assemble->isChecked()?poses.at(iter->first):
Transform::getIdentity()));
2513 std::map<int, Transform> cameraPoses;
2514 std::map<int, std::vector<CameraModel> > cameraModels;
2515 std::map<int, cv::Mat > cameraDepths;
2516 int ignoredCameras = 0;
2517 for(std::map<int, Transform>::iterator jter=cameras.begin(); jter!=cameras.end(); ++jter)
2519 if(validCameras.find(jter->first) != validCameras.end())
2521 std::vector<CameraModel> models;
2523 bool cacheHasCompressedImage =
false;
2524 if(cachedSignatures.contains(jter->first))
2526 const SensorData & data = cachedSignatures.find(jter->first)->sensorData();
2541 models.push_back(stereoModel.
left());
2543 else if(models.size() == 0 || !models[0].isValidForProjection())
2548 if(!jter->second.isNull() && models.size())
2551 bool blurryImage =
false;
2552 bool getDepth = !stereo &&
_ui->doubleSpinBox_meshingTextureMaxDepthError->value() >= 0.0f;
2554 std::vector<float> velocity;
2555 if(models[0].imageWidth() == 0 || models[0].imageHeight() == 0)
2559 if(cacheHasCompressedImage)
2561 cachedSignatures.find(jter->first)->sensorData().uncompressDataConst(&img, getDepth?&depth:0);
2562 velocity = cachedSignatures.find(jter->first)->getVelocity();
2570 if(
_ui->checkBox_cameraFilter->isChecked() &&
2571 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
2581 cv::Size imageSize = img.size();
2582 imageSize.width /= models.size();
2583 for(
unsigned int i=0; i<models.size(); ++i)
2585 models[i].setImageSize(imageSize);
2590 bool getImg =
_ui->checkBox_cameraFilter->isChecked() &&
_ui->doubleSpinBox_laplacianVariance->value()>0.0;
2592 if(cacheHasCompressedImage)
2594 cachedSignatures.find(jter->first)->sensorData().uncompressDataConst(getImg?&img:0, getDepth?&depth:0);
2595 velocity = cachedSignatures.find(jter->first)->getVelocity();
2603 if(
_ui->checkBox_cameraFilter->isChecked() &&
2604 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
2615 if(
_ui->checkBox_cameraFilter->isChecked())
2619 (
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 ||
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0))
2621 if(velocity.size() == 6)
2623 float transVel =
uMax3(fabs(velocity[0]), fabs(velocity[1]), fabs(velocity[2]));
2624 float rotVel =
uMax3(fabs(velocity[3]), fabs(velocity[4]), fabs(velocity[5]));
2625 if(
_ui->doubleSpinBox_cameraFilterVel->value()>0.0 && transVel >
_ui->doubleSpinBox_cameraFilterVel->value())
2627 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());
2630 else if(
_ui->doubleSpinBox_cameraFilterVelRad->value()>0.0 && rotVel >
_ui->doubleSpinBox_cameraFilterVelRad->value())
2632 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());
2638 UWARN(
"Camera motion filtering is set, but velocity of camera %d is not available.", jter->first);
2642 if(!blurryImage && !img.empty() &&
_ui->doubleSpinBox_laplacianVariance->value()>0.0)
2644 cv::Mat imgLaplacian;
2645 cv::Laplacian(img, imgLaplacian, CV_16S);
2647 cv::meanStdDev(imgLaplacian, m, s);
2648 double stddev_pxl = s.at<
double>(0);
2649 double var = stddev_pxl*stddev_pxl;
2650 if(var < _ui->doubleSpinBox_laplacianVariance->value())
2653 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());
2659 QApplication::processEvents();
2664 if(!blurryImage && models[0].imageWidth() != 0 && models[0].imageHeight() != 0)
2666 cameraPoses.insert(std::make_pair(jter->first, jter->second));
2667 cameraModels.insert(std::make_pair(jter->first, models));
2670 cameraDepths.insert(std::make_pair(jter->first, depth));
2676 if(ignoredCameras > (
int)validCameras.size()/2)
2678 std::string msg =
uFormat(
"More than 50%% of the cameras (%d/%d) have been filtered for " 2679 "too fast motion and/or blur level. You may adjust the corresponding thresholds.",
2680 ignoredCameras, (
int)validCameras.size());
2684 QApplication::processEvents();
2687 if(cameraPoses.size() && iter->second->polygons.size())
2689 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
2690 std::map<int, std::vector<int> >::iterator oter = organizedIndices.find(iter->first);
2691 std::map<int, cv::Size>::iterator ster = organizedCloudSizes.find(iter->first);
2692 if(iter->first != 0 && oter != organizedIndices.end())
2694 UASSERT(ster!=organizedCloudSizes.end()&&ster->first == oter->first);
2695 UDEBUG(
"Texture by pixels");
2696 textureMesh->cloud = iter->second->cloud;
2697 textureMesh->tex_polygons.push_back(iter->second->polygons);
2698 int w = ster->second.width;
2699 int h = ster->second.height;
2701 if(textureMesh->tex_polygons.size() && textureMesh->tex_polygons[0].size())
2703 textureMesh->tex_coordinates.resize(1);
2706 int polygonSize = (int)textureMesh->tex_polygons[0][0].vertices.size();
2707 textureMesh->tex_coordinates[0].resize(polygonSize*textureMesh->tex_polygons[0].size());
2708 for(
unsigned int i=0; i<textureMesh->tex_polygons[0].size(); ++i)
2710 const pcl::Vertices &
vertices = textureMesh->tex_polygons[0][i];
2711 UASSERT(polygonSize == (
int)vertices.vertices.size());
2712 for(
int k=0; k<polygonSize; ++k)
2715 UASSERT(vertices.vertices[k] < oter->second.size());
2716 int originalVertex = oter->second[vertices.vertices[k]];
2717 textureMesh->tex_coordinates[0][i*polygonSize+k] = Eigen::Vector2f(
2718 float(originalVertex % w) /
float(w),
2719 float(h - originalVertex / w) /
float(h));
2723 pcl::TexMaterial mesh_material;
2724 mesh_material.tex_d = 1.0f;
2725 mesh_material.tex_Ns = 75.0f;
2726 mesh_material.tex_illum = 1;
2728 std::stringstream tex_name;
2729 tex_name <<
"material_" << iter->first;
2730 tex_name >> mesh_material.tex_name;
2732 mesh_material.tex_file =
uFormat(
"%d", iter->first);
2733 textureMesh->tex_materials.push_back(mesh_material);
2737 UWARN(
"No polygons for mesh %d!?", iter->first);
2742 UDEBUG(
"Texture by projection");
2744 if(cameraPoses.size() &&
_ui->checkBox_cameraFilter->isChecked())
2746 int before = (int)cameraPoses.size();
2748 _ui->doubleSpinBox_cameraFilterRadius->value(),
2749 _ui->doubleSpinBox_cameraFilterAngle->value());
2750 for(std::map<
int, std::vector<CameraModel> >::iterator modelIter = cameraModels.begin(); modelIter!=cameraModels.end();)
2752 if(cameraPoses.find(modelIter->first)==cameraPoses.end())
2754 cameraModels.erase(modelIter++);
2755 cameraDepths.erase(modelIter->first);
2762 _progressDialog->
appendText(tr(
"Camera filtering: keeping %1/%2 cameras for texturing.").arg(cameraPoses.size()).arg(before));
2763 QApplication::processEvents();
2765 QApplication::processEvents();
2775 if(cameraModels.size() && cameraModels.begin()->second.size()>1)
2780 std::vector<float> roiRatios;
2781 QStringList strings =
_ui->lineEdit_meshingTextureRoiRatios->text().split(
' ');
2782 if(!
_ui->lineEdit_meshingTextureRoiRatios->text().isEmpty())
2784 if(strings.size()==4)
2786 roiRatios.resize(4);
2787 roiRatios[0]=strings[0].toDouble();
2788 roiRatios[1]=strings[1].toDouble();
2789 roiRatios[2]=strings[2].toDouble();
2790 roiRatios[3]=strings[3].toDouble();
2791 if(!(roiRatios[0]>=0.0
f && roiRatios[0]<=1.0
f &&
2792 roiRatios[1]>=0.0
f && roiRatios[1]<=1.0
f &&
2793 roiRatios[2]>=0.0
f && roiRatios[2]<=1.0
f &&
2794 roiRatios[3]>=0.0
f && roiRatios[3]<=1.0
f))
2799 if(roiRatios.empty())
2801 QString msg = tr(
"Wrong ROI format. Region of Interest (ROI) must have 4 values [left right top bottom] between 0 and 1 separated by space (%1), ignoring it for texturing...").arg(
_ui->lineEdit_meshingTextureRoiRatios->text());
2802 UWARN(msg.toStdString().c_str());
2813 _ui->doubleSpinBox_meshingTextureMaxDistance->value(),
2814 _ui->doubleSpinBox_meshingTextureMaxDepthError->value(),
2815 _ui->doubleSpinBox_meshingTextureMaxAngle->value()*
M_PI/180.0,
2816 _ui->spinBox_mesh_minTextureClusterSize->value(),
2819 cameraPoses.size()>1?&textureVertexToPixels:0);
2827 if(
_ui->checkBox_cleanMesh->isChecked())
2829 unsigned int totalSize = 0;
2830 for(
unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
2832 totalSize+=textureMesh->tex_polygons[t].size();
2837 unsigned int totalSizeAfter = 0;
2838 for(
unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
2840 totalSizeAfter+=textureMesh->tex_polygons[t].size();
2846 textureMeshes.insert(std::make_pair(iter->first, textureMesh));
2848 else if(cameraPoses.size() == 0)
2850 _progressDialog->
appendText(tr(
"No cameras from %1 poses with valid calibration found!").arg(poses.size()), Qt::darkYellow);
2852 UWARN(
"No camera poses!?");
2858 UWARN(
"No polygons!");
2861 _progressDialog->
appendText(tr(
"TextureMesh %1 created [cameras=%2] (%3/%4).").arg(iter->first).arg(cameraPoses.size()).arg(++i).arg(meshes.size()));
2863 QApplication::processEvents();
2870 if(textureMeshes.size() > 1 &&
_ui->checkBox_assemble->isChecked())
2872 UDEBUG(
"Concatenate texture meshes");
2874 QApplication::processEvents();
2876 QApplication::processEvents();
2879 textureMeshes.clear();
2880 textureMeshes.insert(std::make_pair(0, assembledMesh));
2891 const std::map<int, Transform> & poses,
2892 const QMap<int, Signature> & cachedSignatures,
2893 const std::map<
int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
2894 const std::map<int, LaserScan> & cachedScans,
2896 bool & has2dScans)
const 2899 std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
2901 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr previousCloud;
2902 pcl::IndicesPtr previousIndices;
2904 for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end() && !
_canceled; ++iter, ++index)
2907 int totalIndices = 0;
2908 if(!iter->second.isNull())
2910 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2911 pcl::IndicesPtr indices(
new std::vector<int>);
2913 if(
_ui->checkBox_regenerate->isChecked())
2916 cv::Mat image, depth;
2918 if(cachedSignatures.contains(iter->first))
2920 const Signature & s = cachedSignatures.find(iter->first).value();
2923 _ui->checkBox_fromDepth->isChecked()?&image:0,
2924 _ui->checkBox_fromDepth->isChecked()?&depth:0,
2925 !
_ui->checkBox_fromDepth->isChecked()?&scan:0);
2929 _dbDriver->
getNodeData(iter->first, data,
_ui->checkBox_fromDepth->isChecked(), !
_ui->checkBox_fromDepth->isChecked(),
false,
false);
2931 _ui->checkBox_fromDepth->isChecked()?&image:0,
2932 _ui->checkBox_fromDepth->isChecked()?&depth:0,
2933 !
_ui->checkBox_fromDepth->isChecked()?&scan:0);
2936 if(
_ui->checkBox_fromDepth->isChecked() && !image.empty() && !depth.empty())
2938 if(
_ui->spinBox_fillDepthHoles->value() > 0)
2943 if(!
_ui->lineEdit_distortionModel->text().isEmpty() &&
2944 QFileInfo(
_ui->lineEdit_distortionModel->text()).exists())
2947 model.
load(
_ui->lineEdit_distortionModel->text().toStdString());
2948 depth = depth.clone();
2954 if(
_ui->checkBox_bilateral->isChecked())
2957 _ui->doubleSpinBox_bilateral_sigmaS->value(),
2958 _ui->doubleSpinBox_bilateral_sigmaR->value());
2963 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
2964 std::vector<float> roiRatios;
2965 if(!
_ui->lineEdit_roiRatios->text().isEmpty())
2967 QStringList values =
_ui->lineEdit_roiRatios->text().split(
' ');
2968 if(values.size() == 4)
2970 roiRatios.resize(4);
2971 for(
int i=0; i<values.size(); ++i)
2973 roiRatios[i] =
uStr2Float(values[i].toStdString().c_str());
2979 _ui->spinBox_decimation->value() == 0?1:
_ui->spinBox_decimation->value(),
2980 _ui->doubleSpinBox_maxDepth->value(),
2981 _ui->doubleSpinBox_minDepth->value(),
2986 if(cloudWithoutNormals->size())
2989 if(!(
_ui->comboBox_pipeline->currentIndex()==0 &&
_ui->checkBox_meshing->isChecked()) &&
_ui->doubleSpinBox_voxelSize_assembled->value()>0.0)
2991 cloudWithoutNormals =
util3d::voxelize(cloudWithoutNormals, indices,
_ui->doubleSpinBox_voxelSize_assembled->value());
2992 indices->resize(cloudWithoutNormals->size());
2993 for(
unsigned int i=0; i<indices->size(); ++i)
3000 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3003 localTransform = data.
cameraModels()[0].localTransform();
3004 viewPoint[0] = data.
cameraModels()[0].localTransform().x();
3005 viewPoint[1] = data.
cameraModels()[0].localTransform().y();
3006 viewPoint[2] = data.
cameraModels()[0].localTransform().z();
3016 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals, indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
3017 pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
3019 if(
_ui->checkBox_subtraction->isChecked() &&
3020 _ui->doubleSpinBox_subtractPointFilteringRadius->value() > 0.0)
3022 pcl::IndicesPtr beforeSubtractionIndices = indices;
3023 if( cloud->size() &&
3024 previousCloud.get() != 0 &&
3025 previousIndices.get() != 0 &&
3026 previousIndices->size() &&
3036 _ui->doubleSpinBox_subtractPointFilteringRadius->value(),
3037 _ui->doubleSpinBox_subtractPointFilteringAngle->value(),
3038 _ui->spinBox_subtractFilteringMinPts->value());
3040 previousCloud = cloud;
3041 previousIndices = beforeSubtractionIndices;
3042 previousPose = iter->second;
3046 else if(!
_ui->checkBox_fromDepth->isChecked() && !scan.
isEmpty())
3048 bool is2D = scan.
is2d();
3049 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
3051 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3053 viewPoint[0] = localTransform.
x();
3054 viewPoint[1] = localTransform.
y();
3055 viewPoint[2] = localTransform.
z();
3058 if(cloudWithoutNormals->size())
3060 if(
_ui->doubleSpinBox_voxelSize_assembled->value()>0.0)
3062 cloudWithoutNormals =
util3d::voxelize(cloudWithoutNormals,
_ui->doubleSpinBox_voxelSize_assembled->value());
3064 indices->resize(cloudWithoutNormals->size());
3065 for(
unsigned int i=0; i<indices->size(); ++i)
3069 pcl::PointCloud<pcl::Normal>::Ptr normals;
3073 normals.reset(
new pcl::PointCloud<pcl::Normal>);
3074 normals->resize(cloudWithoutNormals->size());
3075 for(
unsigned int i=0;i<cloudWithoutNormals->size(); ++i)
3077 normals->points[i].normal_x =std::numeric_limits<float>::quiet_NaN();
3078 normals->points[i].normal_y =std::numeric_limits<float>::quiet_NaN();
3079 normals->points[i].normal_z =std::numeric_limits<float>::quiet_NaN();
3085 normals =
util3d::computeNormals(cloudWithoutNormals, indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
3087 pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
3093 if(cachedSignatures.contains(iter->first))
3095 const Signature & s = cachedSignatures.find(iter->first).value();
3104 UERROR(
"Cloud %d not found in cache!", iter->first);
3108 else if(
_ui->checkBox_fromDepth->isChecked() &&
uContains(cachedClouds, iter->first))
3110 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
3111 if(!
_ui->checkBox_meshing->isChecked() &&
3112 _ui->doubleSpinBox_voxelSize_assembled->value() > 0.0)
3115 cachedClouds.at(iter->first).first,
3116 cachedClouds.at(iter->first).second,
3117 _ui->doubleSpinBox_voxelSize_assembled->value());
3120 indices->resize(cloudWithoutNormals->size());
3121 for(
unsigned int i=0; i<cloudWithoutNormals->size(); ++i)
3128 cloudWithoutNormals = cachedClouds.at(iter->first).first;
3129 indices = cachedClouds.at(iter->first).second;
3133 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3134 std::vector<CameraModel> models;
3136 if(cachedSignatures.contains(iter->first))
3138 const Signature & s = cachedSignatures.find(iter->first).value();
3147 if(models.size() && !models[0].localTransform().isNull())
3149 localTransform = models[0].localTransform();
3150 viewPoint[0] = models[0].localTransform().
x();
3151 viewPoint[1] = models[0].localTransform().y();
3152 viewPoint[2] = models[0].localTransform().z();
3163 _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);
3166 pcl::PointCloud<pcl::Normal>::Ptr normals =
util3d::computeNormals(cloudWithoutNormals, indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
3167 pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
3169 else if(!
_ui->checkBox_fromDepth->isChecked() &&
uContains(cachedScans, iter->first))
3171 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
3173 localTransform = cachedScans.at(iter->first).localTransform();
3174 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3175 viewPoint[0] = localTransform.
x();
3176 viewPoint[1] = localTransform.
y();
3177 viewPoint[2] = localTransform.
z();
3179 bool is2D = cachedScans.at(iter->first).is2d();
3181 if(cloudWithoutNormals->size())
3183 if(
_ui->doubleSpinBox_voxelSize_assembled->value()>0.0)
3185 cloudWithoutNormals =
util3d::voxelize(cloudWithoutNormals,
_ui->doubleSpinBox_voxelSize_assembled->value());
3187 indices->resize(cloudWithoutNormals->size());
3188 for(
unsigned int i=0; i<indices->size(); ++i)
3193 pcl::PointCloud<pcl::Normal>::Ptr normals;
3197 normals.reset(
new pcl::PointCloud<pcl::Normal>);
3198 normals->resize(cloudWithoutNormals->size());
3199 for(
unsigned int i=0;i<cloudWithoutNormals->size(); ++i)
3201 normals->points[i].normal_x =std::numeric_limits<float>::quiet_NaN();
3202 normals->points[i].normal_y =std::numeric_limits<float>::quiet_NaN();
3203 normals->points[i].normal_z =std::numeric_limits<float>::quiet_NaN();
3209 normals =
util3d::computeNormals(cloudWithoutNormals, indices,
_ui->spinBox_normalKSearch->value(),
_ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
3211 pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
3217 if(cachedSignatures.contains(iter->first))
3219 const Signature & s = cachedSignatures.find(iter->first).value();
3228 _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);
3234 if(
_ui->checkBox_filtering->isChecked() &&
3235 _ui->doubleSpinBox_filteringRadius->value() > 0.0f &&
3236 _ui->spinBox_filteringMinNeighbors->value() > 0)
3238 indices =
util3d::radiusFiltering(cloud, indices,
_ui->doubleSpinBox_filteringRadius->value(),
_ui->spinBox_filteringMinNeighbors->value());
3241 if((
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==2) && cloud->isOrganized())
3245 else if(
_ui->comboBox_frame->isEnabled() &&
_ui->comboBox_frame->currentIndex()==3)
3250 clouds.insert(std::make_pair(iter->first, std::make_pair(cloud, indices)));
3251 points = (int)cloud->size();
3252 totalIndices = (int)indices->size();
3257 UERROR(
"transform is null!?");
3262 if(
_ui->checkBox_regenerate->isChecked())
3265 .arg(iter->first).arg(points).arg(totalIndices).arg(index).arg(poses.size()));
3270 .arg(iter->first).arg(points).arg(totalIndices).arg(index).arg(poses.size()));
3278 QApplication::processEvents();
3286 const QString & workingDirectory,
3287 const std::map<int, Transform> & poses,
3288 const std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds,
3291 if(clouds.size() == 1)
3293 QString path = QFileDialog::getSaveFileName(
this, tr(
"Save cloud to ..."), workingDirectory+QDir::separator()+
"cloud.ply", tr(
"Point cloud data (*.ply *.pcd)"));
3296 if(clouds.begin()->second->size())
3300 bool success =
false;
3301 if(QFileInfo(path).suffix() ==
"pcd")
3303 success = pcl::io::savePCDFile(path.toStdString(), *clouds.begin()->second, binaryMode) == 0;
3305 else if(QFileInfo(path).suffix() ==
"ply")
3307 success = pcl::io::savePLYFile(path.toStdString(), *clouds.begin()->second, binaryMode) == 0;
3309 else if(QFileInfo(path).suffix() ==
"")
3313 success = pcl::io::savePLYFile(path.toStdString(), *clouds.begin()->second, binaryMode) == 0;
3317 UERROR(
"Extension not recognized! (%s) Should be one of (*.ply *.pcd).", QFileInfo(path).suffix().toStdString().c_str());
3324 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Cloud saved to \"%1\"").arg(path));
3328 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").arg(path));
3333 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Cloud is empty..."));
3337 else if(clouds.size())
3339 QString path = QFileDialog::getExistingDirectory(
this, tr(
"Save clouds to (*.ply *.pcd)..."), workingDirectory, 0);
3344 items.push_back(
"ply");
3345 items.push_back(
"pcd");
3346 QString suffix = QInputDialog::getItem(
this, tr(
"File format"), tr(
"Which format?"), items, 0,
false, &ok);
3350 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"cloud", &ok);
3354 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr >::const_iterator iter=clouds.begin(); iter!=clouds.end(); ++iter)
3356 if(iter->second->size())
3358 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformedCloud;
3361 QString pathFile = path+QDir::separator()+QString(
"%1%2.%3").arg(prefix).arg(iter->first).arg(suffix);
3362 bool success =
false;
3365 success = pcl::io::savePCDFile(pathFile.toStdString(), *transformedCloud, binaryMode) == 0;
3367 else if(suffix ==
"ply")
3369 success = pcl::io::savePLYFile(pathFile.toStdString(), *transformedCloud, binaryMode) == 0;
3373 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
3377 _progressDialog->
appendText(tr(
"Saved cloud %1 (%2 points) to %3.").arg(iter->first).arg(iter->second->size()).arg(pathFile));
3381 _progressDialog->
appendText(tr(
"Failed saving cloud %1 (%2 points) to %3.").arg(iter->first).arg(iter->second->size()).arg(pathFile), Qt::darkRed);
3390 QApplication::processEvents();
3403 const QString & workingDirectory,
3404 const std::map<int, Transform> & poses,
3405 const std::map<int, pcl::PolygonMesh::Ptr> & meshes,
3408 if(meshes.size() == 1)
3410 QString path = QFileDialog::getSaveFileName(
this, tr(
"Save mesh to ..."), workingDirectory+QDir::separator()+
"mesh.ply", tr(
"Mesh (*.ply)"));
3413 if(meshes.begin()->second->polygons.size())
3416 QApplication::processEvents();
3418 QApplication::processEvents();
3420 bool success =
false;
3421 if(QFileInfo(path).suffix() ==
"")
3426 if(QFileInfo(path).suffix() ==
"ply")
3430 success = pcl::io::savePLYFileBinary(path.toStdString(), *meshes.begin()->second) == 0;
3434 success = pcl::io::savePLYFile(path.toStdString(), *meshes.begin()->second) == 0;
3437 else if(QFileInfo(path).suffix() ==
"obj")
3439 success = pcl::io::saveOBJFile(path.toStdString(), *meshes.begin()->second) == 0;
3443 UERROR(
"Extension not recognized! (%s) Should be (*.ply).", QFileInfo(path).suffix().toStdString().c_str());
3450 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Mesh saved to \"%1\"").arg(path));
3454 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").arg(path));
3459 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Cloud is empty..."));
3463 else if(meshes.size())
3465 QString path = QFileDialog::getExistingDirectory(
this, tr(
"Save meshes to (*.ply *.obj)..."), workingDirectory, 0);
3470 items.push_back(
"ply");
3471 items.push_back(
"obj");
3472 QString suffix = QInputDialog::getItem(
this, tr(
"File format"), tr(
"Which format?"), items, 0,
false, &ok);
3476 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"mesh", &ok);
3480 for(std::map<int, pcl::PolygonMesh::Ptr>::const_iterator iter=meshes.begin(); iter!=meshes.end(); ++iter)
3482 if(iter->second->polygons.size())
3484 pcl::PolygonMesh mesh;
3485 mesh.polygons = iter->second->polygons;
3487 for(
unsigned int i=0; i<iter->second->cloud.fields.size(); ++i)
3489 if(iter->second->cloud.fields[i].name.compare(
"rgb") == 0)
3497 pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp(
new pcl::PointCloud<pcl::PointXYZRGB>);
3498 pcl::fromPCLPointCloud2(iter->second->cloud, *tmp);
3500 pcl::toPCLPointCloud2(*tmp, mesh.cloud);
3504 pcl::PointCloud<pcl::PointXYZ>::Ptr tmp(
new pcl::PointCloud<pcl::PointXYZ>);
3505 pcl::fromPCLPointCloud2(iter->second->cloud, *tmp);
3507 pcl::toPCLPointCloud2(*tmp, mesh.cloud);
3510 QString pathFile = path+QDir::separator()+QString(
"%1%2.%3").arg(prefix).arg(iter->first).arg(suffix);
3511 bool success =
false;
3516 success = pcl::io::savePLYFileBinary(pathFile.toStdString(), mesh) == 0;
3520 success = pcl::io::savePLYFile(pathFile.toStdString(), mesh) == 0;
3523 else if(suffix ==
"obj")
3525 success = pcl::io::saveOBJFile(pathFile.toStdString(), mesh) == 0;
3529 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
3534 .arg(iter->first).arg(iter->second->polygons.size()).arg(pathFile));
3539 .arg(iter->first).arg(iter->second->polygons.size()).arg(pathFile), Qt::darkRed);
3548 QApplication::processEvents();
3561 const QString & workingDirectory,
3562 const std::map<int, Transform> & poses,
3563 std::map<int, pcl::TextureMesh::Ptr> & meshes,
3564 const QMap<int, Signature> & cachedSignatures,
3565 const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels)
3567 std::map<int, cv::Mat> images;
3568 std::map<int, std::vector<CameraModel> > calibrations;
3569 for(QMap<int, Signature>::const_iterator iter=cachedSignatures.constBegin(); iter!=cachedSignatures.constEnd(); ++iter)
3571 std::vector<CameraModel> models;
3572 if(iter->sensorData().cameraModels().size())
3574 models = iter->sensorData().cameraModels();
3576 else if(iter->sensorData().stereoCameraModel().isValidForProjection())
3578 models.push_back(iter->sensorData().stereoCameraModel().left());
3583 if(!iter->sensorData().imageRaw().empty())
3585 calibrations.insert(std::make_pair(iter.key(), models));
3586 images.insert(std::make_pair(iter.key(), iter->sensorData().imageRaw()));
3588 else if(!iter->sensorData().imageCompressed().empty())
3590 calibrations.insert(std::make_pair(iter.key(), models));
3591 images.insert(std::make_pair(iter.key(), iter->sensorData().imageCompressed()));
3595 int textureSize = 1024;
3596 if(
_ui->comboBox_meshingTextureSize->currentIndex() > 0)
3598 textureSize = 128 <<
_ui->comboBox_meshingTextureSize->currentIndex();
3600 int blendingDecimation = 0;
3601 if(
_ui->checkBox_blending->isChecked())
3603 if(
_ui->comboBox_blendingDecimation->currentIndex() > 0)
3605 blendingDecimation = 1 << (
_ui->comboBox_blendingDecimation->currentIndex()-1);
3609 if(meshes.size() == 1)
3611 QString path = QFileDialog::getSaveFileName(
this, tr(
"Save texture mesh to ..."), workingDirectory+QDir::separator()+
"mesh.obj", tr(
"Mesh (*.obj)"));
3614 if(meshes.begin()->second->tex_materials.size())
3616 _progressDialog->
appendText(tr(
"Saving the mesh (with %1 textures)...").arg(meshes.begin()->second->tex_materials.size()));
3617 QApplication::processEvents();
3619 QApplication::processEvents();
3621 bool success =
false;
3622 if(QFileInfo(path).suffix() ==
"")
3627 pcl::TextureMesh::Ptr mesh = meshes.begin()->second;
3629 cv::Mat globalTextures;
3630 bool texturesMerged =
_ui->comboBox_meshingTextureSize->isEnabled() &&
_ui->comboBox_meshingTextureSize->currentIndex() > 0;
3631 if(texturesMerged && mesh->tex_materials.size()>1)
3640 _ui->spinBox_mesh_maxTextures->value(),
3641 textureVertexToPixels,
3642 _ui->checkBox_gainCompensation->isChecked(),
3643 _ui->doubleSpinBox_gainBeta->value(),
3644 _ui->checkBox_gainRGB->isChecked(),
3645 _ui->checkBox_blending->isChecked(),
3647 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
3648 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
3649 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked());
3652 bool singleTexture = mesh->tex_materials.size() == 1;
3655 removeDirRecursively(QFileInfo(path).absoluteDir().absolutePath()+QDir::separator()+QFileInfo(path).baseName());
3656 QDir(QFileInfo(path).absoluteDir().absolutePath()).mkdir(QFileInfo(path).baseName());
3660 cv::Mat previousImage;
3661 int previousTextureId = 0;
3662 std::vector<CameraModel> previousCameraModels;
3665 for(
unsigned int i=0; i<mesh->tex_materials.size(); ++i)
3667 if(!mesh->tex_materials[i].tex_file.empty())
3673 fullPath = QFileInfo(path).absoluteDir().absolutePath()+QDir::separator()+QFileInfo(path).baseName()+
_ui->comboBox_meshingTextureFormat->currentText();
3677 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();
3679 UDEBUG(
"Saving %s...", fullPath.toStdString().c_str());
3680 if(singleTexture || !QFileInfo(fullPath).exists())
3682 std::list<std::string> texFileSplit =
uSplit(mesh->tex_materials[i].tex_file,
'_');
3683 if(texFileSplit.size() &&
uIsInteger(texFileSplit.front(),
false))
3685 int textureId =
uStr2Int(texFileSplit.front());
3686 int textureSubCamera = -1;
3687 if(texFileSplit.size() == 2 &&
3690 textureSubCamera =
uStr2Int(texFileSplit.back());
3693 std::vector<CameraModel> cameraModels;
3695 if(textureId == previousTextureId)
3697 image = previousImage;
3698 cameraModels = previousCameraModels;
3702 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
3704 cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
3705 cameraModels = cachedSignatures.value(textureId).sensorData().cameraModels();
3716 previousImage = image;
3717 previousCameraModels = cameraModels;
3718 previousTextureId = textureId;
3721 imageSize = image.size();
3722 if(textureSubCamera>=0)
3725 imageSize.width/=cameraModels.size();
3726 image = image.colRange(imageSize.width*textureSubCamera, imageSize.width*(textureSubCamera+1));
3733 if(!cv::imwrite(fullPath.toStdString(), image))
3736 .arg(mesh->tex_materials[i].tex_file.c_str()).arg(fullPath), Qt::darkRed);
3740 else if(imageSize.height && imageSize.width)
3743 cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
3744 cv::imwrite(fullPath.toStdString(), image);
3746 else if(!globalTextures.empty())
3748 if(!cv::imwrite(fullPath.toStdString(), globalTextures(
cv::Range::all(), cv::Range(i*globalTextures.rows, (i+1)*globalTextures.rows))))
3751 .arg(mesh->tex_materials[i].tex_file.c_str()).arg(fullPath), Qt::darkRed);
3757 UWARN(
"Ignored texture %s (no image size set yet)", mesh->tex_materials[i].tex_file.c_str());
3762 UWARN(
"File %s already exists!", fullPath.toStdString().c_str());
3767 mesh->tex_materials[i].tex_file=QFileInfo(path).baseName().toStdString()+
_ui->comboBox_meshingTextureFormat->currentText().toStdString();
3771 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();
3776 success = pcl::io::saveOBJFile(path.toStdString(), *mesh) == 0;
3782 QMessageBox::information(
this, tr(
"Save successful!"), tr(
"Mesh saved to \"%1\"").arg(path));
3786 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"Failed to save to \"%1\"").arg(path));
3791 QMessageBox::warning(
this, tr(
"Save failed!"), tr(
"No textures..."));
3795 else if(meshes.size())
3797 QString path = QFileDialog::getExistingDirectory(
this, tr(
"Save texture meshes to (*.obj)..."), workingDirectory, 0);
3801 QString prefix = QInputDialog::getText(
this, tr(
"File prefix"), tr(
"Prefix:"), QLineEdit::Normal,
"mesh", &ok);
3802 QString suffix =
"obj";
3806 for(std::map<int, pcl::TextureMesh::Ptr>::iterator iter=meshes.begin(); iter!=meshes.end(); ++iter)
3808 QString currentPrefix=prefix+QString::number(iter->first);
3809 if(iter->second->tex_materials.size())
3811 pcl::TextureMesh::Ptr mesh = iter->second;
3812 cv::Mat globalTextures;
3813 bool texturesMerged =
_ui->comboBox_meshingTextureSize->isEnabled() &&
_ui->comboBox_meshingTextureSize->currentIndex() > 0;
3814 if(texturesMerged && mesh->tex_materials.size()>1)
3823 _ui->spinBox_mesh_maxTextures->value(),
3824 textureVertexToPixels,
3825 _ui->checkBox_gainCompensation->isChecked(),
3826 _ui->doubleSpinBox_gainBeta->value(),
3827 _ui->checkBox_gainRGB->isChecked(),
3828 _ui->checkBox_blending->isChecked(),
3830 _ui->spinBox_textureBrightnessContrastRatioLow->value(),
3831 _ui->spinBox_textureBrightnessContrastRatioHigh->value(),
3832 _ui->checkBox_exposureFusion->isEnabled() &&
_ui->checkBox_exposureFusion->isChecked());
3834 bool singleTexture = mesh->tex_materials.size() == 1;
3838 QDir(path).mkdir(currentPrefix);
3842 cv::Mat previousImage;
3843 int previousTextureId = 0;
3844 std::vector<CameraModel> previousCameraModels;
3847 for(
unsigned int i=0;i<mesh->tex_materials.size(); ++i)
3849 if(!mesh->tex_materials[i].tex_file.empty())
3851 std::list<std::string> texFileSplit =
uSplit(mesh->tex_materials[i].tex_file,
'_');
3853 int textureSubCamera = -1;
3854 if(texFileSplit.size() &&
uIsInteger(texFileSplit.front(),
false))
3856 textureId =
uStr2Int(texFileSplit.front());
3857 if(texFileSplit.size() == 2 &&
3860 textureSubCamera =
uStr2Int(texFileSplit.back());
3868 mesh->tex_materials[i].tex_file =
uNumber2Str(iter->first);
3869 fullPath = path+QDir::separator()+prefix + QString(mesh->tex_materials[i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText();
3873 fullPath = path+QDir::separator()+currentPrefix+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText();
3878 std::vector<CameraModel> cameraModels;
3880 if(textureId == previousTextureId)
3882 image = previousImage;
3883 cameraModels = previousCameraModels;
3887 if(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty())
3889 cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
3890 cameraModels = cachedSignatures.value(textureId).sensorData().cameraModels();
3901 previousImage = image;
3902 previousCameraModels = cameraModels;
3903 previousTextureId = textureId;
3908 imageSize = image.size();
3909 if(textureSubCamera>=0)
3912 imageSize.width/=cameraModels.size();
3913 image = image.colRange(imageSize.width*textureSubCamera, imageSize.width*(textureSubCamera+1));
3920 if(!cv::imwrite(fullPath.toStdString(), image))
3923 .arg(mesh->tex_materials[i].tex_file.c_str()).arg(fullPath), Qt::darkRed);
3927 else if(imageSize.height && imageSize.width)
3930 cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
3931 cv::imwrite(fullPath.toStdString(), image);
3933 else if(!globalTextures.empty())
3935 if(!cv::imwrite(fullPath.toStdString(), globalTextures(
cv::Range::all(), cv::Range(i*globalTextures.rows, (i+1)*globalTextures.rows))))
3938 .arg(mesh->tex_materials[i].tex_file.c_str()).arg(fullPath), Qt::darkRed);
3944 UWARN(
"Ignored texture %s (no image size set yet)", mesh->tex_materials[i].tex_file.c_str());
3949 mesh->tex_materials[i].tex_file=(prefix+ QString(mesh->tex_materials[i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
3953 mesh->tex_materials[i].tex_file=(currentPrefix+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str())+
_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
3957 pcl::PointCloud<pcl::PointNormal>::Ptr tmp(
new pcl::PointCloud<pcl::PointNormal>);
3958 pcl::fromPCLPointCloud2(mesh->cloud, *tmp);
3960 pcl::toPCLPointCloud2(*tmp, mesh->cloud);
3962 QString pathFile = path+QDir::separator()+QString(
"%1.%3").arg(currentPrefix).arg(suffix);
3963 bool success =
false;
3966 success = pcl::io::saveOBJFile(pathFile.toStdString(), *mesh) == 0;
3970 UFATAL(
"Extension not recognized! (%s)", suffix.toStdString().c_str());
3975 .arg(iter->first).arg(mesh->tex_materials.size()).arg(pathFile));
3980 .arg(iter->first).arg(mesh->tex_materials.size()).arg(pathFile), Qt::darkRed);
3989 QApplication::processEvents();
bool uIsInteger(const std::string &str, bool checkForSign=true)
void setDefaultBackgroundColor(const QColor &color)
int UTILITE_EXP uStr2Int(const std::string &str)
pcl::PolygonMesh::Ptr chiselToPolygonMesh(const chisel::MeshMap &meshMap, unsigned char r=100, unsigned char g=100, unsigned char b=100)
ProgressDialog * _progressDialog
void setAutoClose(bool on, int delayedClosingTimeMsec=-1)
cv::Mat RTABMAP_EXP mergeTextures(pcl::TextureMesh &mesh, const std::map< int, cv::Mat > &images, const std::map< int, CameraModel > &calibrations, const Memory *memory=0, const DBDriver *dbDriver=0, int textureSize=4096, int textureCount=1, const std::vector< std::map< int, pcl::PointXY > > &vertexToPixels=std::vector< std::map< int, pcl::PointXY > >(), bool gainCompensation=true, float gainBeta=10.0f, bool gainRGB=true, bool blending=true, int blendingDecimation=0, int brightnessContrastRatioLow=0, int brightnessContrastRatioHigh=0, bool exposureFusion=false, const ProgressState *state=0)
void incrementStep(int steps=1)
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP subtractFiltering(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &substractCloud, float radiusSearch, int minNeighborsInRadius=1)
void uncompressDataConst(cv::Mat *imageRaw, cv::Mat *depthOrRightRaw, LaserScan *laserScanRaw=0, cv::Mat *userDataRaw=0, cv::Mat *groundCellsRaw=0, cv::Mat *obstacleCellsRaw=0, cv::Mat *emptyCellsRaw=0) const
int getMaxTextures() const
pcl::TextureMesh::Ptr RTABMAP_EXP concatenateTextureMeshes(const std::list< pcl::TextureMesh::Ptr > &meshes)
std::shared_ptr< chisel::ColorImage< unsigned char > > colorImageToChisel(const cv::Mat &image)
std::map< int, Transform > RTABMAP_EXP radiusPosesFiltering(const std::map< int, Transform > &poses, float radius, float angle, bool keepLatest=true)
cv::Mat RTABMAP_EXP cvtDepthToFloat(const cv::Mat &depth16U)
GLM_FUNC_DECL genType min(genType const &x, genType const &y)
void setCancelButtonVisible(bool visible)
int getBlendingDecimation() const
const LaserScan & laserScanCompressed() const
std::map< int, std::pair< pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr, pcl::IndicesPtr > > getClouds(const std::map< int, Transform > &poses, const QMap< int, Signature > &cachedSignatures, const std::map< int, std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::IndicesPtr > > &cachedClouds, const std::map< int, LaserScan > &cachedScans, const ParametersMap ¶meters, bool &has2dScans) const
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP transformPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const Transform &transform)
void updateMLSGrpVisibility()
pcl::TextureMesh::Ptr RTABMAP_EXP createTextureMesh(const pcl::PolygonMesh::Ptr &mesh, const std::map< int, Transform > &poses, const std::map< int, CameraModel > &cameraModels, const std::map< int, cv::Mat > &cameraDepths, float maxDistance=0.0f, float maxDepthError=0.0f, float maxAngle=0.0f, int minClusterSize=50, const std::vector< float > &roiRatios=std::vector< float >(), const ProgressState *state=0, std::vector< std::map< int, pcl::PointXY > > *vertexToPixels=0)
bool isGainCompensation() const
void RTABMAP_EXP getMinMax3D(const cv::Mat &laserScan, cv::Point3f &min, cv::Point3f &max)
std::vector< pcl::Vertices > RTABMAP_EXP filterCloseVerticesFromMesh(const pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr cloud, const std::vector< pcl::Vertices > &polygons, float radius, float angle, bool keepLatestInRadius)
std::vector< int > RTABMAP_EXP filterNotUsedVerticesFromMesh(const pcl::PointCloud< pcl::PointXYZRGBNormal > &cloud, const std::vector< pcl::Vertices > &polygons, pcl::PointCloud< pcl::PointXYZRGBNormal > &outputCloud, std::vector< pcl::Vertices > &outputPolygons)
chisel::PinholeCamera cameraModelToChiselCamera(const CameraModel &camera)
std::set< K > uKeysSet(const std::map< K, V > &m)
std::list< V > uValuesList(const std::multimap< K, V > &mm)
float UTILITE_EXP uStr2Float(const std::string &str)
GLM_FUNC_DECL bool all(vecType< bool, P > const &v)
static const float vertices[]
void viewClouds(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, int > &mapIds, const QMap< int, Signature > &cachedSignatures, const std::map< int, std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::IndicesPtr > > &cachedClouds, const std::map< int, LaserScan > &cachedScans, const QString &workingDirectory, const ParametersMap ¶meters)
void getNodeData(int signatureId, SensorData &data, bool images=true, bool scan=true, bool userData=true, bool occupancyGrid=true) const
bool getExportedClouds(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, int > &mapIds, const QMap< int, Signature > &cachedSignatures, const std::map< int, std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::IndicesPtr > > &cachedClouds, const std::map< int, LaserScan > &cachedScans, const QString &workingDirectory, const ParametersMap ¶meters, std::map< int, pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr > &clouds, std::map< int, pcl::PolygonMesh::Ptr > &meshes, std::map< int, pcl::TextureMesh::Ptr > &textureMeshes, std::vector< std::map< int, pcl::PointXY > > &textureVertexToPixels)
std::map< std::string, std::string > ParametersMap
cv::Mat RTABMAP_EXP fastBilateralFiltering(const cv::Mat &depth, float sigmaS=15.0f, float sigmaR=0.05f, bool earlyDivision=false)
void setLighting(bool on)
Basic mathematics functions.
Some conversion functions.
void setPolygonPicking(bool enabled)
bool getNodeInfo(int signatureId, Transform &pose, int &mapId, int &weight, std::string &label, double &stamp, Transform &groundTruthPose, std::vector< float > &velocity, GPS &gps) const
const LaserScan & laserScanRaw() const
void buildPickingLocator(bool enable)
double getGain(int id, double *r=0, double *g=0, double *b=0) const
pcl::IndicesPtr RTABMAP_EXP extractIndices(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, bool negative)
bool addCloudTextureMesh(const std::string &id, const pcl::TextureMesh::Ptr &textureMesh, const cv::Mat &texture, const Transform &pose=Transform::getIdentity())
void saveClouds(const QString &workingDirectory, const std::map< int, Transform > &poses, const std::map< int, pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr > &clouds, bool binaryMode=true)
std::list< std::string > uSplit(const std::string &str, char separator= ' ')
bool addCloud(const std::string &id, const pcl::PCLPointCloud2Ptr &binaryCloud, const Transform &pose, bool rgb, bool hasNormals, bool hasIntensity, const QColor &color=QColor())
pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr RTABMAP_EXP mls(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, float searchRadius=0.0f, int polygonialOrder=2, int upsamplingMethod=0, float upsamplingRadius=0.0f, float upsamplingStep=0.0f, int pointDensity=0, float dilationVoxelSize=1.0f, int dilationIterations=0)
#define UASSERT(condition)
Wrappers of STL for convenient functions.
void getWeight(int signatureId, int &weight) const
bool getLaserScanInfo(int signatureId, LaserScan &info) const
bool isValidForProjection() const
const CameraModel & left() const
std::list< std::list< int > > RTABMAP_EXP clusterPolygons(const std::vector< std::set< int > > &neighborPolygons, int minClusterSize=0)
T uMax3(const T &a, const T &b, const T &c)
void saveTextureMeshes(const QString &workingDirectory, const std::map< int, Transform > &poses, std::map< int, pcl::TextureMesh::Ptr > &textureMeshes, const QMap< int, Signature > &cachedSignatures, const std::vector< std::map< int, pcl::PointXY > > &textureVertexToPixels)
void RTABMAP_EXP appendMesh(pcl::PointCloud< pcl::PointXYZRGBNormal > &cloudA, std::vector< pcl::Vertices > &polygonsA, const pcl::PointCloud< pcl::PointXYZRGBNormal > &cloudB, const std::vector< pcl::Vertices > &polygonsB)
#define UASSERT_MSG(condition, msg_str)
int getTextureBrightnessConstrastRatioHigh() const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP cloudRGBFromSensorData(const SensorData &sensorData, int decimation=1, float maxDepth=0.0f, float minDepth=0.0f, std::vector< int > *validIndices=0, const ParametersMap &stereoParameters=ParametersMap(), const std::vector< float > &roiRatios=std::vector< float >())
chisel::PointCloudPtr pointCloudRGBToChisel(const typename pcl::PointCloud< PointRGBT > &cloud, const Transform &transform=Transform::getIdentity())
void setCloudPointSize(const std::string &id, int size)
bool getCalibration(int signatureId, std::vector< CameraModel > &models, StereoCameraModel &stereoModel) const
bool isExposeFusion() const
QString _workingDirectory
cv::Mat RTABMAP_EXP computeNormals(const cv::Mat &laserScan, int searchK, float searchRadius)
void setMaximumSteps(int steps)
Transform localTransform() const
double getGainBeta() const
pcl::PolygonMesh::Ptr RTABMAP_EXP createMesh(const pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr &cloudWithNormals, float gp3SearchRadius=0.025, float gp3Mu=2.5, int gp3MaximumNearestNeighbors=100, float gp3MaximumSurfaceAngle=M_PI/4, float gp3MinimumAngle=M_PI/18, float gp3MaximumAngle=2 *M_PI/3, bool gp3NormalConsistency=true)
std::vector< pcl::Vertices > RTABMAP_EXP organizedFastMesh(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, double angleTolerance, bool quad, int trianglePixelSize, const Eigen::Vector3f &viewpoint=Eigen::Vector3f(0, 0, 0))
ExportCloudsDialog(QWidget *parent=0)
void setProgressDialogToMax()
bool uContains(const std::list< V > &list, const V &value)
void load(const std::string &path)
void exportClouds(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, int > &mapIds, const QMap< int, Signature > &cachedSignatures, const std::map< int, std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::IndicesPtr > > &cachedClouds, const std::map< int, LaserScan > &cachedScans, const QString &workingDirectory, const ParametersMap ¶meters)
void apply(int id, pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, bool rgb=true) const
void uSleep(unsigned int ms)
void RTABMAP_EXP adjustNormalsToViewPoints(const std::map< int, Transform > &poses, const pcl::PointCloud< pcl::PointXYZ >::Ptr &rawCloud, const std::vector< int > &rawCameraIndices, pcl::PointCloud< pcl::PointNormal >::Ptr &cloud)
pcl::IndicesPtr RTABMAP_EXP radiusFiltering(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, float radiusSearch, int minNeighborsInRadius)
const std::vector< CameraModel > & cameraModels() const
std::vector< pcl::Vertices > RTABMAP_EXP filterInvalidPolygons(const std::vector< pcl::Vertices > &polygons)
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
SensorData & sensorData()
void RTABMAP_EXP cleanTextureMesh(pcl::TextureMesh &textureMesh, int minClusterSize)
Ui_ExportCloudsDialog * _ui
void undistort(cv::Mat &depth) const
void updateReconstructionFlavor()
void RTABMAP_EXP createPolygonIndexes(const std::vector< pcl::Vertices > &polygons, int cloudSize, std::vector< std::set< int > > &neighborPolygons, std::vector< std::set< int > > &vertexPolygons)
Given a set of polygons, create two indexes: polygons to neighbor polygons and vertices to polygons...
cv::Mat RTABMAP_EXP fillDepthHoles(const cv::Mat &depth, int maximumHoleSize=1, float errorRatio=0.02f)
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
void setBackfaceCulling(bool enabled, bool frontfaceCulling)
void feed(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloudA, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloudB, const Transform &transformB)
void saveMeshes(const QString &workingDirectory, const std::map< int, Transform > &poses, const std::map< int, pcl::PolygonMesh::Ptr > &meshes, bool binaryMode=true)
const cv::Mat & imageCompressed() const
pcl::PointCloud< pcl::PointNormal >::Ptr RTABMAP_EXP removeNaNNormalsFromPointCloud(const pcl::PointCloud< pcl::PointNormal >::Ptr &cloud)
void forceAssembling(bool enabled)
int getTextureSize() const
bool addCloudMesh(const std::string &id, const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const std::vector< pcl::Vertices > &polygons, const Transform &pose=Transform::getIdentity())
const DBDriver * _dbDriver
float RTABMAP_EXP getDepth(const cv::Mat &depthImage, float x, float y, bool smoothing, float depthErrorRatio=0.02f, bool estWithNeighborsIfNull=false)
int getIndex(int id) const
void appendText(const QString &text, const QColor &color=Qt::black)
static bool removeDirRecursively(const QString &dirName)
void selectDistortionModel()
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP voxelize(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float voxelSize)
int getTextureBrightnessConstrastRatioLow() const
const Transform & localTransform() const
void setDepthOrRightRaw(const cv::Mat &depthOrImageRaw)
std::string UTILITE_EXP uFormat(const char *fmt,...)
std::string UTILITE_EXP uNumber2Str(unsigned int number)
virtual ~ExportCloudsDialog()
CameraModel scaled(double scale) const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP laserScanToPointCloudRGB(const LaserScan &laserScan, const Transform &transform=Transform(), unsigned char r=255, unsigned char g=255, unsigned char b=255)
V uValue(const std::map< K, V > &m, const K &key, const V &defaultValue=V())
std::shared_ptr< chisel::DepthImage< float > > depthImageToChisel(const cv::Mat &image)
GainCompensator * _compensator