mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 17:40:23 +08:00
Added GainCompensator class. GUI/3D Rendering: added texturing option.
This commit is contained in:
@@ -642,22 +642,29 @@ bool CloudViewer::addCloudTextureMesh(
|
||||
const pcl::TextureMesh::Ptr & textureMesh,
|
||||
const Transform & pose)
|
||||
{
|
||||
#if PCL_VERSION_COMPARE(>=, 1, 7, 2)
|
||||
if(_addedClouds.contains(id))
|
||||
{
|
||||
this->removeCloud(id);
|
||||
}
|
||||
|
||||
UDEBUG("Adding %s", id.c_str());
|
||||
if(_visualizer->addTextureMesh(*textureMesh, id))
|
||||
if(this->addTextureMesh(*textureMesh, id))
|
||||
{
|
||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->LightingOff();
|
||||
if(_backfaceCulling)
|
||||
{
|
||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->BackfaceCullingOn();
|
||||
}
|
||||
if(_frontfaceCulling)
|
||||
{
|
||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->FrontfaceCullingOn();
|
||||
}
|
||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetTexture()->SetInterpolate(1);
|
||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetTexture()->SetBlendingMode(vtkTexture::VTK_TEXTURE_BLENDING_MODE_REPLACE);
|
||||
_visualizer->updatePointCloudPose(id, pose.toEigen3f());
|
||||
_addedClouds.insert(id, pose);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
// not implemented on lower version of PCL
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -895,7 +902,7 @@ bool CloudViewer::addTextureMesh (
|
||||
int viewport)
|
||||
{
|
||||
#if PCL_VERSION_COMPARE(>=, 1, 7, 2)
|
||||
return addTextureMesh(mesh, id, viewport);
|
||||
return _visualizer->addTextureMesh(mesh, id, viewport);
|
||||
#else
|
||||
// Copied from PCL 1.8
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "rtabmap/core/OccupancyGrid.h"
|
||||
#include "rtabmap/gui/DataRecorder.h"
|
||||
#include "rtabmap/core/SensorData.h"
|
||||
#include "rtabmap/core/GainCompensator.h"
|
||||
#include "ExportDialog.h"
|
||||
#include "rtabmap/gui/ProgressDialog.h"
|
||||
#include "ParametersToolBox.h"
|
||||
@@ -253,6 +254,7 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
|
||||
connect(ui_->checkBox_ignoreUserLoop, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
|
||||
connect(ui_->spinBox_optimizationDepth, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
|
||||
connect(ui_->checkBox_gridErode, SIGNAL(stateChanged(int)), this, SLOT(updateGrid()));
|
||||
connect(ui_->doubleSpinBox_gainCompensationRadius, SIGNAL(valueChanged(double)), this, SLOT(updateConstraintView()));
|
||||
connect(ui_->groupBox_posefiltering, SIGNAL(clicked(bool)), this, SLOT(updateGraphView()));
|
||||
connect(ui_->doubleSpinBox_posefilteringRadius, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
|
||||
connect(ui_->doubleSpinBox_posefilteringAngle, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
|
||||
@@ -280,6 +282,7 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
|
||||
connect(ui_->checkBox_ignoreUserLoop, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
|
||||
connect(ui_->spinBox_optimizationDepth, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
|
||||
connect(ui_->checkBox_gridErode, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
|
||||
connect(ui_->doubleSpinBox_gainCompensationRadius, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
|
||||
connect(ui_->doubleSpinBox_gridCellSize, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
|
||||
connect(ui_->groupBox_posefiltering, SIGNAL(clicked(bool)), this, SLOT(configModified()));
|
||||
connect(ui_->doubleSpinBox_posefilteringRadius, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
|
||||
@@ -392,6 +395,7 @@ void DatabaseViewer::readSettings()
|
||||
ui_->checkBox_ignoreUserLoop->setChecked(settings.value("ignoreUserLoop", ui_->checkBox_ignoreUserLoop->isChecked()).toBool());
|
||||
ui_->spinBox_optimizationDepth->setValue(settings.value("depth", ui_->spinBox_optimizationDepth->value()).toInt());
|
||||
ui_->checkBox_gridErode->setChecked(settings.value("erode", ui_->checkBox_gridErode->isChecked()).toBool());
|
||||
ui_->doubleSpinBox_gainCompensationRadius->setValue(settings.value("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value()).toDouble());
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("grid");
|
||||
@@ -473,6 +477,7 @@ void DatabaseViewer::writeSettings()
|
||||
//settings.setValue("slam2d", ui_->checkBox_2dslam->isChecked());
|
||||
settings.setValue("depth", ui_->spinBox_optimizationDepth->value());
|
||||
settings.setValue("erode", ui_->checkBox_gridErode->isChecked());
|
||||
settings.setValue("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value());
|
||||
settings.endGroup();
|
||||
|
||||
// save Grid settings
|
||||
@@ -3285,13 +3290,33 @@ void DatabaseViewer::updateConstraintView(
|
||||
if(ui_->checkBox_show3Dclouds->isChecked())
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFrom, cloudTo;
|
||||
pcl::IndicesPtr indicesFrom(new std::vector<int>);
|
||||
pcl::IndicesPtr indicesTo(new std::vector<int>);
|
||||
if(!dataFrom.imageRaw().empty() && !dataFrom.depthOrRightRaw().empty())
|
||||
{
|
||||
cloudFrom=util3d::cloudRGBFromSensorData(dataFrom, 1, 0, 0, 0, ui_->parameters_toolbox->getParameters());
|
||||
cloudFrom=util3d::cloudRGBFromSensorData(dataFrom, 1, 0, 0, indicesFrom.get(), ui_->parameters_toolbox->getParameters());
|
||||
}
|
||||
if(!dataTo.imageRaw().empty() && !dataTo.depthOrRightRaw().empty())
|
||||
{
|
||||
cloudTo=util3d::cloudRGBFromSensorData(dataTo, 1, 0, 0, 0, ui_->parameters_toolbox->getParameters());
|
||||
cloudTo=util3d::cloudRGBFromSensorData(dataTo, 1, 0, 0, indicesTo.get(), ui_->parameters_toolbox->getParameters());
|
||||
}
|
||||
|
||||
if(cloudTo.get() && cloudTo->size())
|
||||
{
|
||||
cloudTo = rtabmap::util3d::transformPointCloud(cloudTo, t);
|
||||
}
|
||||
|
||||
// Gain compensation
|
||||
if(ui_->doubleSpinBox_gainCompensationRadius->value()>0.0 &&
|
||||
cloudFrom.get() && cloudFrom->size() &&
|
||||
cloudTo.get() && cloudTo->size())
|
||||
{
|
||||
UTimer t;
|
||||
GainCompensator compensator(ui_->doubleSpinBox_gainCompensationRadius->value());
|
||||
compensator.feed(cloudFrom, indicesFrom, cloudTo, indicesTo, Transform::getIdentity());
|
||||
compensator.apply(0, cloudFrom, indicesFrom);
|
||||
compensator.apply(1, cloudTo, indicesTo);
|
||||
UINFO("Gain compensation time = %fs", t.ticks());
|
||||
}
|
||||
|
||||
if(cloudFrom.get() && cloudFrom->size())
|
||||
@@ -3300,7 +3325,6 @@ void DatabaseViewer::updateConstraintView(
|
||||
}
|
||||
if(cloudTo.get() && cloudTo->size())
|
||||
{
|
||||
cloudTo = rtabmap::util3d::transformPointCloud(cloudTo, t);
|
||||
constraintsViewer_->addCloud("cloud1", cloudTo, Transform::getIdentity(), Qt::cyan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "rtabmap/core/util3d_transforms.h"
|
||||
#include "rtabmap/core/util3d.h"
|
||||
#include "rtabmap/core/Graph.h"
|
||||
#include "rtabmap/core/GainCompensator.h"
|
||||
|
||||
#include <pcl/conversions.h>
|
||||
#include <pcl/io/pcd_io.h>
|
||||
@@ -82,6 +83,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
||||
connect(_ui->spinBox_filteringMinNeighbors, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||
|
||||
connect(_ui->checkBox_assemble, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->checkBox_assemble, SIGNAL(clicked(bool)), this, SLOT(updateTexturingAvailability()));
|
||||
connect(_ui->doubleSpinBox_voxelSize_assembled, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
|
||||
connect(_ui->groupBox_subtraction, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
||||
@@ -100,13 +102,19 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
||||
_ui->stackedWidget_upsampling->setCurrentIndex(_ui->comboBox_upsamplingMethod->currentIndex());
|
||||
connect(_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_upsampling, SLOT(setCurrentIndex(int)));
|
||||
connect(_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMLSGrpVisibility()));
|
||||
updateMLSGrpVisibility();
|
||||
|
||||
connect(_ui->groupBox_gain, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->doubleSpinBox_gainRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->doubleSpinBox_gainOverlap, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->doubleSpinBox_gainAlpha, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->doubleSpinBox_gainBeta, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
|
||||
connect(_ui->groupBox_meshing, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->doubleSpinBox_gp3Radius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->doubleSpinBox_gp3Mu, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SLOT(updateTexturingAvailability()));
|
||||
|
||||
_progressDialog = new ProgressDialog(this);
|
||||
_progressDialog->setVisible(false);
|
||||
@@ -132,6 +140,14 @@ void ExportCloudsDialog::updateMLSGrpVisibility()
|
||||
_ui->groupBox_5->setVisible(_ui->comboBox_upsamplingMethod->currentIndex() == 4);
|
||||
}
|
||||
|
||||
void ExportCloudsDialog::updateTexturingAvailability()
|
||||
{
|
||||
_ui->checkBox_textureMapping->setEnabled(!_ui->checkBox_assemble->isChecked() || _ui->checkBox_binary->isVisible());
|
||||
_ui->label_textureMapping->setEnabled(_ui->checkBox_textureMapping->isEnabled());
|
||||
_ui->doubleSpinBox_meshDecimationFactor->setEnabled(!_ui->checkBox_textureMapping->isEnabled() || !_ui->checkBox_textureMapping->isChecked());
|
||||
_ui->label_meshDecimation->setEnabled(_ui->doubleSpinBox_meshDecimationFactor->isEnabled());
|
||||
}
|
||||
|
||||
void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & group) const
|
||||
{
|
||||
if(!group.isEmpty())
|
||||
@@ -170,6 +186,12 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
||||
settings.setValue("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value());
|
||||
settings.setValue("mls_dilation_iterations", _ui->spinBox_dilationSteps->value());
|
||||
|
||||
settings.setValue("gain", _ui->groupBox_gain->isChecked());
|
||||
settings.setValue("gain_radius", _ui->doubleSpinBox_gainRadius->value());
|
||||
settings.setValue("gain_overlap", _ui->doubleSpinBox_gainOverlap->value());
|
||||
settings.setValue("gain_alpha", _ui->doubleSpinBox_gainAlpha->value());
|
||||
settings.setValue("gain_beta", _ui->doubleSpinBox_gainBeta->value());
|
||||
|
||||
settings.setValue("mesh", _ui->groupBox_meshing->isChecked());
|
||||
settings.setValue("mesh_radius", _ui->doubleSpinBox_gp3Radius->value());
|
||||
settings.setValue("mesh_mu", _ui->doubleSpinBox_gp3Mu->value());
|
||||
@@ -226,6 +248,12 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
||||
_ui->doubleSpinBox_dilationVoxelSize->setValue(settings.value("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value()).toDouble());
|
||||
_ui->spinBox_dilationSteps->setValue(settings.value("mls_dilation_iterations", _ui->spinBox_dilationSteps->value()).toInt());
|
||||
|
||||
_ui->groupBox_gain->setChecked(settings.value("gain", _ui->groupBox_gain->isChecked()).toBool());
|
||||
_ui->doubleSpinBox_gainRadius->setValue(settings.value("gain_radius", _ui->doubleSpinBox_gainRadius->value()).toDouble());
|
||||
_ui->doubleSpinBox_gainOverlap->setValue(settings.value("gain_overlap", _ui->doubleSpinBox_gainOverlap->value()).toDouble());
|
||||
_ui->doubleSpinBox_gainAlpha->setValue(settings.value("gain_alpha", _ui->doubleSpinBox_gainAlpha->value()).toDouble());
|
||||
_ui->doubleSpinBox_gainBeta->setValue(settings.value("gain_beta", _ui->doubleSpinBox_gainBeta->value()).toDouble());
|
||||
|
||||
_ui->groupBox_meshing->setChecked(settings.value("mesh", _ui->groupBox_meshing->isChecked()).toBool());
|
||||
_ui->doubleSpinBox_gp3Radius->setValue(settings.value("mesh_radius", _ui->doubleSpinBox_gp3Radius->value()).toDouble());
|
||||
_ui->doubleSpinBox_gp3Mu->setValue(settings.value("mesh_mu", _ui->doubleSpinBox_gp3Mu->value()).toDouble());
|
||||
@@ -238,6 +266,10 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
||||
_ui->checkBox_mesh_quad->setChecked(settings.value("mesh_quad", _ui->checkBox_mesh_quad->isChecked()).toBool());
|
||||
_ui->spinBox_mesh_triangleSize->setValue(settings.value("mesh_triangle_size", _ui->spinBox_mesh_triangleSize->value()).toInt());
|
||||
|
||||
updateReconstructionFlavor();
|
||||
updateTexturingAvailability();
|
||||
updateMLSGrpVisibility();
|
||||
|
||||
if(!group.isEmpty())
|
||||
{
|
||||
settings.endGroup();
|
||||
@@ -276,6 +308,12 @@ void ExportCloudsDialog::restoreDefaults()
|
||||
_ui->doubleSpinBox_dilationVoxelSize->setValue(0.01);
|
||||
_ui->spinBox_dilationSteps->setValue(0);
|
||||
|
||||
_ui->groupBox_gain->setChecked(true);
|
||||
_ui->doubleSpinBox_gainRadius->setValue(0.02);
|
||||
_ui->doubleSpinBox_gainOverlap->setValue(0.05);
|
||||
_ui->doubleSpinBox_gainAlpha->setValue(0.01);
|
||||
_ui->doubleSpinBox_gainBeta->setValue(10);
|
||||
|
||||
_ui->groupBox_meshing->setChecked(false);
|
||||
_ui->doubleSpinBox_gp3Radius->setValue(0.04);
|
||||
_ui->doubleSpinBox_gp3Mu->setValue(2.5);
|
||||
@@ -288,6 +326,8 @@ void ExportCloudsDialog::restoreDefaults()
|
||||
_ui->spinBox_mesh_triangleSize->setValue(2);
|
||||
|
||||
updateReconstructionFlavor();
|
||||
updateTexturingAvailability();
|
||||
updateMLSGrpVisibility();
|
||||
|
||||
this->update();
|
||||
}
|
||||
@@ -305,12 +345,10 @@ void ExportCloudsDialog::setSaveButton()
|
||||
_ui->buttonBox->button(QDialogButtonBox::Save)->setVisible(true);
|
||||
_ui->checkBox_binary->setVisible(true);
|
||||
_ui->label_binaryFile->setVisible(true);
|
||||
_ui->checkBox_textureMapping->setVisible(true);
|
||||
_ui->checkBox_textureMapping->setEnabled(true);
|
||||
_ui->label_textureMapping->setVisible(true);
|
||||
_ui->checkBox_mesh_quad->setVisible(false);
|
||||
_ui->checkBox_mesh_quad->setEnabled(false);
|
||||
_ui->label_quad->setVisible(false);
|
||||
updateTexturingAvailability();
|
||||
}
|
||||
|
||||
void ExportCloudsDialog::setOkButton()
|
||||
@@ -319,12 +357,10 @@ void ExportCloudsDialog::setOkButton()
|
||||
_ui->buttonBox->button(QDialogButtonBox::Save)->setVisible(false);
|
||||
_ui->checkBox_binary->setVisible(false);
|
||||
_ui->label_binaryFile->setVisible(false);
|
||||
_ui->checkBox_textureMapping->setVisible(false);
|
||||
_ui->checkBox_textureMapping->setEnabled(false);
|
||||
_ui->label_textureMapping->setVisible(false);
|
||||
_ui->checkBox_mesh_quad->setVisible(true);
|
||||
_ui->checkBox_mesh_quad->setEnabled(true);
|
||||
_ui->label_quad->setVisible(true);
|
||||
updateTexturingAvailability();
|
||||
}
|
||||
|
||||
void ExportCloudsDialog::enableRegeneration(bool enabled)
|
||||
@@ -338,6 +374,7 @@ void ExportCloudsDialog::enableRegeneration(bool enabled)
|
||||
|
||||
void ExportCloudsDialog::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,
|
||||
@@ -352,6 +389,7 @@ void ExportCloudsDialog::exportClouds(
|
||||
|
||||
if(getExportedClouds(
|
||||
poses,
|
||||
links,
|
||||
mapIds,
|
||||
cachedSignatures,
|
||||
cachedClouds,
|
||||
@@ -384,12 +422,17 @@ void ExportCloudsDialog::exportClouds(
|
||||
{
|
||||
saveClouds(workingDirectory, poses, clouds, _ui->checkBox_binary->isChecked());
|
||||
}
|
||||
_progressDialog->setValue(_progressDialog->maximumSteps());
|
||||
}
|
||||
else
|
||||
{
|
||||
_progressDialog->setAutoClose(false);
|
||||
}
|
||||
_progressDialog->setValue(_progressDialog->maximumSteps());
|
||||
}
|
||||
|
||||
void ExportCloudsDialog::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,
|
||||
@@ -404,6 +447,7 @@ void ExportCloudsDialog::viewClouds(
|
||||
|
||||
if(getExportedClouds(
|
||||
poses,
|
||||
links,
|
||||
mapIds,
|
||||
cachedSignatures,
|
||||
cachedClouds,
|
||||
@@ -442,7 +486,34 @@ void ExportCloudsDialog::viewClouds(
|
||||
|
||||
uSleep(500);
|
||||
|
||||
if(meshes.size())
|
||||
if(textureMeshes.size())
|
||||
{
|
||||
for(std::map<int, pcl::TextureMesh::Ptr>::iterator iter = textureMeshes.begin(); iter!=textureMeshes.end(); ++iter)
|
||||
{
|
||||
_progressDialog->appendText(tr("Viewing the mesh %1 (%2 polygons)...").arg(iter->first).arg(iter->second->tex_polygons.size()?iter->second->tex_polygons[0].size():0));
|
||||
_progressDialog->incrementStep();
|
||||
bool isRGB = false;
|
||||
for(unsigned int i=0; i<iter->second->cloud.fields.size(); ++i)
|
||||
{
|
||||
if(iter->second->cloud.fields[i].name.compare("rgb") == 0)
|
||||
{
|
||||
isRGB=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isRGB)
|
||||
{
|
||||
viewer->addCloudTextureMesh(uFormat("mesh%d",iter->first), iter->second, iter->first>0?poses.at(iter->first):Transform::getIdentity());
|
||||
}
|
||||
else
|
||||
{
|
||||
viewer->addCloudTextureMesh(uFormat("mesh%d",iter->first), iter->second, iter->first>0?poses.at(iter->first):Transform::getIdentity());
|
||||
}
|
||||
_progressDialog->appendText(tr("Viewing the mesh %1 (%2 polygons)... done.").arg(iter->first).arg(iter->second->tex_polygons.size()?iter->second->tex_polygons[0].size():0));
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
else if(meshes.size())
|
||||
{
|
||||
for(std::map<int, pcl::PolygonMesh::Ptr>::iterator iter = meshes.begin(); iter!=meshes.end(); ++iter)
|
||||
{
|
||||
@@ -490,13 +561,16 @@ void ExportCloudsDialog::viewClouds(
|
||||
_progressDialog->appendText(tr("Viewing the cloud %1 (%2 points)... done.").arg(iter->first).arg(iter->second->size()));
|
||||
}
|
||||
}
|
||||
|
||||
_progressDialog->setValue(_progressDialog->maximumSteps());
|
||||
viewer->update();
|
||||
}
|
||||
else
|
||||
{
|
||||
_progressDialog->setAutoClose(false);
|
||||
}
|
||||
_progressDialog->setValue(_progressDialog->maximumSteps());
|
||||
}
|
||||
|
||||
bool removeDirRecursively(const QString & dirName)
|
||||
bool ExportCloudsDialog::removeDirRecursively(const QString & dirName)
|
||||
{
|
||||
bool result = true;
|
||||
QDir dir(dirName);
|
||||
@@ -521,6 +595,7 @@ bool removeDirRecursively(const QString & dirName)
|
||||
|
||||
bool ExportCloudsDialog::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,
|
||||
@@ -533,6 +608,11 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
enableRegeneration(cachedSignatures.size());
|
||||
if(this->exec() == QDialog::Accepted)
|
||||
{
|
||||
if(poses.empty())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Creating clouds..."), tr("Poses are null! Cannot export/view clouds."));
|
||||
return false;
|
||||
}
|
||||
_progressDialog->resetProgress();
|
||||
_progressDialog->show();
|
||||
int mul = 1;
|
||||
@@ -554,6 +634,14 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
{
|
||||
mul+=1;
|
||||
}
|
||||
if(_ui->groupBox_gain->isChecked())
|
||||
{
|
||||
mul+=1;
|
||||
}
|
||||
if(_ui->checkBox_mesh_quad->isEnabled()) // when enabled we are viewing the clouds
|
||||
{
|
||||
mul+=1;
|
||||
}
|
||||
_progressDialog->setMaximumSteps(int(poses.size())*mul+1);
|
||||
|
||||
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds = this->getClouds(
|
||||
@@ -562,6 +650,46 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
cachedClouds,
|
||||
parameters);
|
||||
|
||||
if(clouds.empty())
|
||||
{
|
||||
_progressDialog->setAutoClose(false);
|
||||
if(_ui->groupBox_regenerate->isEnabled() && !_ui->groupBox_regenerate->isChecked())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Creating clouds..."), tr("Could create clouds for %1 node(s). You "
|
||||
"may want to activate clouds regeneration option.").arg(poses.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(this, tr("Creating clouds..."), tr("Could not create clouds for %1 "
|
||||
"node(s). The cache may not contain point cloud data. Try re-downloading the map.").arg(poses.size()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
GainCompensator compensator(_ui->doubleSpinBox_gainRadius->value(), _ui->doubleSpinBox_gainOverlap->value(), _ui->doubleSpinBox_gainAlpha->value(), _ui->doubleSpinBox_gainBeta->value());
|
||||
if(_ui->groupBox_gain->isChecked() && clouds.size() > 1)
|
||||
{
|
||||
_progressDialog->appendText(tr("Gain compensation of %1 clouds...").arg(clouds.size()));
|
||||
QApplication::processEvents();
|
||||
QApplication::processEvents();
|
||||
|
||||
compensator.feed(clouds, links);
|
||||
|
||||
_progressDialog->appendText(tr("Applying gain compensation..."));
|
||||
for(std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> >::iterator jter=clouds.begin();jter!=clouds.end(); ++jter)
|
||||
{
|
||||
if(jter!=clouds.end())
|
||||
{
|
||||
double gain = compensator.getGain(jter->first);;
|
||||
compensator.apply(jter->first, jter->second.first, jter->second.second);
|
||||
|
||||
_progressDialog->appendText(tr("Cloud %1 has gain %2").arg(jter->first).arg(gain));
|
||||
_progressDialog->incrementStep();
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
std::vector<int> rawCameraIndices;
|
||||
if(_ui->checkBox_assemble->isChecked() &&
|
||||
@@ -707,7 +835,8 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
}
|
||||
|
||||
//used for organized texturing below
|
||||
std::map<int, std::pair<std::map<int, int>, std::pair<int, int> > > organizedIndices;
|
||||
std::map<int, std::map<int, int> > organizedIndices;
|
||||
std::map<int, cv::Size> organizedCloudSizes;
|
||||
|
||||
//mesh
|
||||
UDEBUG("Meshing=%d", _ui->groupBox_meshing->isChecked()?1:0);
|
||||
@@ -808,7 +937,8 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
}
|
||||
else
|
||||
{
|
||||
organizedIndices.insert(std::make_pair(iter->first, std::make_pair(newToOldIndices, std::make_pair(iter->second->width, iter->second->height))));
|
||||
organizedIndices.insert(std::make_pair(iter->first, newToOldIndices));
|
||||
organizedCloudSizes.insert(std::make_pair(iter->first, cv::Size(iter->second->width, iter->second->height)));
|
||||
}
|
||||
meshes.insert(std::make_pair(iter->first, mesh));
|
||||
}
|
||||
@@ -995,6 +1125,10 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
{
|
||||
cameraPoses.insert(std::make_pair(jter->first, jter->second));
|
||||
cameraModels.insert(std::make_pair(jter->first, model));
|
||||
if(_ui->groupBox_gain->isChecked() && compensator.getIndex(jter->first) >= 0)
|
||||
{
|
||||
compensator.apply(jter->first, image);
|
||||
}
|
||||
images.insert(std::make_pair(jter->first, image));
|
||||
}
|
||||
}
|
||||
@@ -1002,34 +1136,57 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
if(cameraPoses.size())
|
||||
{
|
||||
pcl::TextureMesh::Ptr textureMesh(new pcl::TextureMesh);
|
||||
std::map<int, std::pair<std::map<int, int>, std::pair<int, int> > >::iterator oter = organizedIndices.find(iter->first);
|
||||
std::map<int, std::map<int, int> >::iterator oter = organizedIndices.find(iter->first);
|
||||
std::map<int, cv::Size>::iterator ster = organizedCloudSizes.find(iter->first);
|
||||
if(iter->first != 0 && oter != organizedIndices.end())
|
||||
{
|
||||
UASSERT(ster!=organizedCloudSizes.end()&&ster->first == oter->first);
|
||||
UDEBUG("Texture by pixels");
|
||||
textureMesh->cloud = iter->second->cloud;
|
||||
textureMesh->tex_polygons.push_back(iter->second->polygons);
|
||||
int w = oter->second.second.first;
|
||||
int h = oter->second.second.second;
|
||||
int w = ster->second.width;
|
||||
int h = ster->second.height;
|
||||
UASSERT(w > 1 && h > 1);
|
||||
UASSERT(textureMesh->tex_polygons.size() && textureMesh->tex_polygons[0].size());
|
||||
|
||||
textureMesh->tex_coordinates.resize(1);
|
||||
int polygonSize = textureMesh->tex_polygons[0][0].vertices.size();
|
||||
textureMesh->tex_coordinates[0].resize(polygonSize*textureMesh->tex_polygons[0].size());
|
||||
for(unsigned int i=0; i<textureMesh->tex_polygons[0].size(); ++i)
|
||||
if(!_ui->checkBox_mesh_quad->isEnabled()) // disabled -> we are exporting to file
|
||||
{
|
||||
const pcl::Vertices & vertices = textureMesh->tex_polygons[0][i];
|
||||
UASSERT(polygonSize == (int)vertices.vertices.size());
|
||||
for(int k=0; k<polygonSize; ++k)
|
||||
// When saving to file, tex_coordinates should be linked to polygon vertices, not points
|
||||
int polygonSize = textureMesh->tex_polygons[0][0].vertices.size();
|
||||
textureMesh->tex_coordinates[0].resize(polygonSize*textureMesh->tex_polygons[0].size());
|
||||
for(unsigned int i=0; i<textureMesh->tex_polygons[0].size(); ++i)
|
||||
{
|
||||
const pcl::Vertices & vertices = textureMesh->tex_polygons[0][i];
|
||||
UASSERT(polygonSize == (int)vertices.vertices.size());
|
||||
for(int k=0; k<polygonSize; ++k)
|
||||
{
|
||||
//uv
|
||||
std::map<int, int>::iterator vter = oter->second.find(vertices.vertices[k]);
|
||||
UASSERT(vter != oter->second.end());
|
||||
int originalVertex = vter->second;
|
||||
textureMesh->tex_coordinates[0][i*polygonSize+k] = Eigen::Vector2f(
|
||||
float(originalVertex % w) / float(w), // u
|
||||
float(h - originalVertex / w) / float(h)); // v
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
|
||||
textureMesh->tex_coordinates[0].resize(nPoints);
|
||||
for(int i=0; i<nPoints; ++i)
|
||||
{
|
||||
//uv
|
||||
std::map<int, int>::iterator vter = oter->second.first.find(vertices.vertices[k]);
|
||||
UASSERT(vter != oter->second.first.end());
|
||||
std::map<int, int>::iterator vter = oter->second.find(i);
|
||||
UASSERT(vter != oter->second.end());
|
||||
int originalVertex = vter->second;
|
||||
textureMesh->tex_coordinates[0][i*polygonSize+k] = Eigen::Vector2f(
|
||||
float(originalVertex % w) / float(w), // u
|
||||
textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
|
||||
float(originalVertex % w) / float(w), // u
|
||||
float(h - originalVertex / w) / float(h)); // v
|
||||
}
|
||||
}
|
||||
|
||||
pcl::TexMaterial mesh_material;
|
||||
mesh_material.tex_d = 1.0f;
|
||||
mesh_material.tex_Ns = 75.0f;
|
||||
@@ -1101,11 +1258,11 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
||||
const ParametersMap & parameters) const
|
||||
{
|
||||
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
|
||||
int i=0;
|
||||
int index=1;
|
||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr previousCloud;
|
||||
pcl::IndicesPtr previousIndices;
|
||||
Transform previousPose;
|
||||
for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
|
||||
for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter, ++index)
|
||||
{
|
||||
int points = 0;
|
||||
int totalIndices = 0;
|
||||
@@ -1134,7 +1291,7 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
||||
parameters);
|
||||
|
||||
// Don't voxelize if we create organized mesh
|
||||
if(!(_ui->comboBox_pipeline->currentIndex()==0 && _ui->groupBox_meshing->isChecked()))
|
||||
if(!(_ui->comboBox_pipeline->currentIndex()==0 && _ui->groupBox_meshing->isChecked()) && _ui->doubleSpinBox_voxelSize_assembled->value()>0.0)
|
||||
{
|
||||
cloudWithoutNormals = util3d::voxelize(cloudWithoutNormals, indices, _ui->doubleSpinBox_voxelSize_assembled->value());
|
||||
indices->resize(cloudWithoutNormals->size());
|
||||
@@ -1187,23 +1344,6 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
||||
previousIndices = beforeSubtractionIndices;
|
||||
previousPose = iter->second;
|
||||
}
|
||||
|
||||
}
|
||||
else if(s.getWords3().size())
|
||||
{
|
||||
cloud->resize(s.getWords3().size());
|
||||
int oi=0;
|
||||
indices->resize(cloud->size());
|
||||
for(std::multimap<int, cv::Point3f>::const_iterator jter=s.getWords3().begin(); jter!=s.getWords3().end(); ++jter)
|
||||
{
|
||||
indices->at(oi) = oi;
|
||||
(*cloud)[oi].x = jter->second.x;
|
||||
(*cloud)[oi].y = jter->second.y;
|
||||
(*cloud)[oi].z = jter->second.z;
|
||||
(*cloud)[oi].r = 255;
|
||||
(*cloud)[oi].g = 255;
|
||||
(*cloud)[oi++].b = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1256,7 +1396,7 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
||||
}
|
||||
else
|
||||
{
|
||||
_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(++i).arg(poses.size()));
|
||||
_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);
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), viewPoint);
|
||||
@@ -1264,7 +1404,7 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
||||
}
|
||||
else
|
||||
{
|
||||
_progressDialog->appendText(tr("Cached cloud %1 not found. You may want to regenerate the clouds (%2/%3).").arg(iter->first).arg(++i).arg(poses.size()));
|
||||
_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);
|
||||
}
|
||||
|
||||
if(indices->size())
|
||||
@@ -1291,17 +1431,17 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
||||
if(_ui->groupBox_regenerate->isChecked())
|
||||
{
|
||||
_progressDialog->appendText(tr("Generated cloud %1 with %2 points and %3 indices (%4/%5).")
|
||||
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size()));
|
||||
.arg(iter->first).arg(points).arg(totalIndices).arg(index).arg(poses.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
_progressDialog->appendText(tr("Copied cloud %1 from cache with %2 points and %3 indices (%4/%5).")
|
||||
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size()));
|
||||
.arg(iter->first).arg(points).arg(totalIndices).arg(index).arg(poses.size()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_progressDialog->appendText(tr("Ignored cloud %1 (%2/%3).").arg(iter->first).arg(++i).arg(poses.size()));
|
||||
_progressDialog->appendText(tr("Ignored cloud %1 (%2/%3).").arg(iter->first).arg(index).arg(poses.size()));
|
||||
}
|
||||
_progressDialog->incrementStep();
|
||||
QApplication::processEvents();
|
||||
@@ -1407,7 +1547,8 @@ void ExportCloudsDialog::saveClouds(
|
||||
}
|
||||
else
|
||||
{
|
||||
_progressDialog->appendText(tr("Failed saving cloud %1 (%2 points) to %3.").arg(iter->first).arg(iter->second->size()).arg(pathFile));
|
||||
_progressDialog->appendText(tr("Failed saving cloud %1 (%2 points) to %3.").arg(iter->first).arg(iter->second->size()).arg(pathFile), Qt::darkRed);
|
||||
_progressDialog->setAutoClose(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1559,7 +1700,8 @@ void ExportCloudsDialog::saveMeshes(
|
||||
else
|
||||
{
|
||||
_progressDialog->appendText(tr("Failed saving mesh %1 (%2 polygons) to %3.")
|
||||
.arg(iter->first).arg(iter->second->polygons.size()).arg(pathFile));
|
||||
.arg(iter->first).arg(iter->second->polygons.size()).arg(pathFile), Qt::darkRed);
|
||||
_progressDialog->setAutoClose(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1698,6 +1840,7 @@ void ExportCloudsDialog::saveTextureMeshes(
|
||||
{
|
||||
_progressDialog->appendText(tr("Failed saving mesh %1 (%2 textures) to %3.")
|
||||
.arg(iter->first).arg(iter->second->tex_materials.size()-1).arg(pathFile), Qt::darkRed);
|
||||
_progressDialog->setAutoClose(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
|
||||
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,
|
||||
@@ -69,12 +70,15 @@ public:
|
||||
|
||||
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 QString & workingDirectory,
|
||||
const ParametersMap & parameters);
|
||||
|
||||
static bool removeDirRecursively(const QString & dirName);
|
||||
|
||||
signals:
|
||||
void configChanged();
|
||||
|
||||
@@ -84,6 +88,7 @@ public slots:
|
||||
private slots:
|
||||
void updateReconstructionFlavor();
|
||||
void updateMLSGrpVisibility();
|
||||
void updateTexturingAvailability();
|
||||
|
||||
private:
|
||||
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > getClouds(
|
||||
@@ -93,6 +98,7 @@ private:
|
||||
const ParametersMap & parameters) 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,
|
||||
|
||||
@@ -41,6 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "rtabmap/core/DBDriver.h"
|
||||
#include "rtabmap/core/RegistrationVis.h"
|
||||
#include "rtabmap/core/OccupancyGrid.h"
|
||||
#include "rtabmap/core/GainCompensator.h"
|
||||
|
||||
#include "rtabmap/gui/ImageView.h"
|
||||
#include "rtabmap/gui/KeypointItem.h"
|
||||
@@ -984,7 +985,55 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
|
||||
Eigen::Vector3f(pose.x(), pose.y(), pose.z()) + viewpoint);
|
||||
if(polygons.size())
|
||||
{
|
||||
if(!_cloudViewer->addCloudMesh("cloudOdom", output, polygons, _odometryCorrection))
|
||||
if(_preferencesDialog->isCloudMeshingTexture() && !odom.data().imageRaw().empty())
|
||||
{
|
||||
pcl::TextureMesh::Ptr textureMesh(new pcl::TextureMesh);
|
||||
pcl::toPCLPointCloud2(*cloud, textureMesh->cloud);
|
||||
textureMesh->tex_polygons.push_back(polygons);
|
||||
int w = cloud->width;
|
||||
int h = cloud->height;
|
||||
UASSERT(w > 1 && h > 1);
|
||||
textureMesh->tex_coordinates.resize(1);
|
||||
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
|
||||
textureMesh->tex_coordinates[0].resize(nPoints);
|
||||
for(int i=0; i<nPoints; ++i)
|
||||
{
|
||||
//uv
|
||||
textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
|
||||
float(i % w) / float(w), // u
|
||||
float(h - i / w) / float(h)); // v
|
||||
}
|
||||
|
||||
pcl::TexMaterial mesh_material;
|
||||
mesh_material.tex_d = 1.0f;
|
||||
mesh_material.tex_Ns = 75.0f;
|
||||
mesh_material.tex_illum = 1;
|
||||
|
||||
mesh_material.tex_name = "material_odom";
|
||||
|
||||
QDir dir(_preferencesDialog->getWorkingDirectory());
|
||||
ExportCloudsDialog::removeDirRecursively(_preferencesDialog->getWorkingDirectory()+QDir::separator()+"tmp_textures");
|
||||
dir.mkdir("tmp_textures");
|
||||
|
||||
std::string tmpDirectory = dir.filePath("tmp_textures").toStdString();
|
||||
mesh_material.tex_file = uFormat("%s/%s.png", tmpDirectory.c_str(), "texture_odom");
|
||||
if(!cv::imwrite(mesh_material.tex_file, odom.data().imageRaw()))
|
||||
{
|
||||
UERROR("Cannot save texture of image odom");
|
||||
}
|
||||
else
|
||||
{
|
||||
UINFO("Saved temporary texture: \"%s\"", mesh_material.tex_file.c_str());
|
||||
}
|
||||
|
||||
textureMesh->tex_materials.push_back(mesh_material);
|
||||
|
||||
if(!_cloudViewer->addCloudTextureMesh("cloudOdom", textureMesh, _odometryCorrection))
|
||||
{
|
||||
UERROR("Adding cloudOdom to viewer failed!");
|
||||
}
|
||||
}
|
||||
else if(!_cloudViewer->addCloudMesh("cloudOdom", output, polygons, _odometryCorrection))
|
||||
{
|
||||
UERROR("Adding cloudOdom to viewer failed!");
|
||||
}
|
||||
@@ -2477,8 +2526,10 @@ std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> MainWindow::c
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
|
||||
if(_preferencesDialog->isSubtractFiltering() &&
|
||||
_preferencesDialog->getSubtractFilteringRadius() > 0.0)
|
||||
GainCompensator compensator;
|
||||
if((_preferencesDialog->isSubtractFiltering() &&
|
||||
_preferencesDialog->getSubtractFilteringRadius() > 0.0) ||
|
||||
_preferencesDialog->gainCompensation())
|
||||
{
|
||||
pcl::IndicesPtr beforeFiltering = indices;
|
||||
if( cloud->size() &&
|
||||
@@ -2496,53 +2547,63 @@ std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> MainWindow::c
|
||||
//pcl::io::savePCDFile("new.pcd", *cloud, *indices);
|
||||
//pcl::io::savePCDFile("old.pcd", *previousCloud, *_previousCloud.second.second);
|
||||
|
||||
if(_preferencesDialog->getSubtractFilteringAngle() > 0.0f)
|
||||
if(_preferencesDialog->gainCompensation())
|
||||
{
|
||||
//normals required
|
||||
if(_preferencesDialog->getNormalKSearch() > 0)
|
||||
compensator.feed(cloud, indices, _previousCloud.second.first.first, _previousCloud.second.second, t);
|
||||
compensator.apply(0, cloud, indices);
|
||||
UINFO("Time gain compensation = %fs", time.ticks());
|
||||
}
|
||||
|
||||
if(_preferencesDialog->isSubtractFiltering())
|
||||
{
|
||||
if(_preferencesDialog->getSubtractFilteringAngle() > 0.0f)
|
||||
{
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch(), viewPoint);
|
||||
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
|
||||
//normals required
|
||||
if(_preferencesDialog->getNormalKSearch() > 0)
|
||||
{
|
||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch(), viewPoint);
|
||||
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
|
||||
}
|
||||
else
|
||||
{
|
||||
UWARN("Cloud subtraction with angle filtering is activated but "
|
||||
"cloud normal K search is 0. Subtraction is done with angle.");
|
||||
}
|
||||
}
|
||||
|
||||
if(cloudWithNormals->size() &&
|
||||
_previousCloud.second.first.second.get() &&
|
||||
_previousCloud.second.first.second->size())
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr previousCloud = rtabmap::util3d::transformPointCloud(_previousCloud.second.first.second, t);
|
||||
indices = rtabmap::util3d::subtractFiltering(
|
||||
cloudWithNormals,
|
||||
indices,
|
||||
previousCloud,
|
||||
_previousCloud.second.second,
|
||||
_preferencesDialog->getSubtractFilteringRadius(),
|
||||
_preferencesDialog->getSubtractFilteringAngle(),
|
||||
_preferencesDialog->getSubtractFilteringMinPts());
|
||||
}
|
||||
else
|
||||
{
|
||||
UWARN("Cloud subtraction with angle filtering is activated but "
|
||||
"cloud normal K search is 0. Subtraction is done with angle.");
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr previousCloud = rtabmap::util3d::transformPointCloud(_previousCloud.second.first.first, t);
|
||||
indices = rtabmap::util3d::subtractFiltering(
|
||||
cloud,
|
||||
indices,
|
||||
previousCloud,
|
||||
_previousCloud.second.second,
|
||||
_preferencesDialog->getSubtractFilteringRadius(),
|
||||
_preferencesDialog->getSubtractFilteringMinPts());
|
||||
}
|
||||
}
|
||||
|
||||
if(cloudWithNormals->size() &&
|
||||
_previousCloud.second.first.second.get() &&
|
||||
_previousCloud.second.first.second->size())
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr previousCloud = rtabmap::util3d::transformPointCloud(_previousCloud.second.first.second, t);
|
||||
indices = rtabmap::util3d::subtractFiltering(
|
||||
cloudWithNormals,
|
||||
indices,
|
||||
previousCloud,
|
||||
_previousCloud.second.second,
|
||||
_preferencesDialog->getSubtractFilteringRadius(),
|
||||
_preferencesDialog->getSubtractFilteringAngle(),
|
||||
_preferencesDialog->getSubtractFilteringMinPts());
|
||||
}
|
||||
else
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr previousCloud = rtabmap::util3d::transformPointCloud(_previousCloud.second.first.first, t);
|
||||
indices = rtabmap::util3d::subtractFiltering(
|
||||
cloud,
|
||||
indices,
|
||||
previousCloud,
|
||||
_previousCloud.second.second,
|
||||
_preferencesDialog->getSubtractFilteringRadius(),
|
||||
_preferencesDialog->getSubtractFilteringMinPts());
|
||||
}
|
||||
|
||||
|
||||
UINFO("Time subtract filtering %d from %d -> %d (%fs)",
|
||||
(int)_previousCloud.second.second->size(),
|
||||
(int)beforeFiltering->size(),
|
||||
(int)indices->size(),
|
||||
time.ticks());
|
||||
UINFO("Time subtract filtering %d from %d -> %d (%fs)",
|
||||
(int)_previousCloud.second.second->size(),
|
||||
(int)beforeFiltering->size(),
|
||||
(int)indices->size(),
|
||||
time.ticks());
|
||||
}
|
||||
}
|
||||
// keep all indices for next subtraction
|
||||
_previousCloud.first = nodeId;
|
||||
@@ -2571,8 +2632,70 @@ std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> MainWindow::c
|
||||
// remove unused vertices to save memory
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr outputFiltered(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||
std::vector<pcl::Vertices> outputPolygons;
|
||||
util3d::filterNotUsedVerticesFromMesh(*output, polygons, *outputFiltered, outputPolygons);
|
||||
if(!_cloudViewer->addCloudMesh(cloudName, outputFiltered, outputPolygons, pose))
|
||||
std::map<int, int> newToOldIndices = util3d::filterNotUsedVerticesFromMesh(*output, polygons, *outputFiltered, outputPolygons);
|
||||
|
||||
if(_preferencesDialog->isCloudMeshingTexture() && !image.empty())
|
||||
{
|
||||
pcl::TextureMesh::Ptr textureMesh(new pcl::TextureMesh);
|
||||
pcl::toPCLPointCloud2(*outputFiltered, textureMesh->cloud);
|
||||
textureMesh->tex_polygons.push_back(outputPolygons);
|
||||
int w = cloud->width;
|
||||
int h = cloud->height;
|
||||
UASSERT(w > 1 && h > 1);
|
||||
textureMesh->tex_coordinates.resize(1);
|
||||
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
|
||||
textureMesh->tex_coordinates[0].resize(nPoints);
|
||||
for(int i=0; i<nPoints; ++i)
|
||||
{
|
||||
//uv
|
||||
std::map<int, int>::iterator vter = newToOldIndices.find(i);
|
||||
UASSERT(vter != newToOldIndices.end());
|
||||
int originalVertex = vter->second;
|
||||
textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
|
||||
float(originalVertex % w) / float(w), // u
|
||||
float(h - originalVertex / w) / float(h)); // v
|
||||
}
|
||||
|
||||
pcl::TexMaterial mesh_material;
|
||||
mesh_material.tex_d = 1.0f;
|
||||
mesh_material.tex_Ns = 75.0f;
|
||||
mesh_material.tex_illum = 1;
|
||||
|
||||
std::stringstream tex_name;
|
||||
tex_name << "material_" << nodeId;
|
||||
tex_name >> mesh_material.tex_name;
|
||||
|
||||
QDir dir(_preferencesDialog->getWorkingDirectory());
|
||||
ExportCloudsDialog::removeDirRecursively(_preferencesDialog->getWorkingDirectory()+QDir::separator()+"tmp_textures");
|
||||
dir.mkdir("tmp_textures");
|
||||
|
||||
std::string tmpDirectory = dir.filePath("tmp_textures").toStdString();
|
||||
mesh_material.tex_file = uFormat("%s/%s%d.png", tmpDirectory.c_str(), "texture_", nodeId);
|
||||
if(_preferencesDialog->gainCompensation() && compensator.getIndex(0) >= 0)
|
||||
{
|
||||
compensator.apply(0, image);
|
||||
}
|
||||
if(!cv::imwrite(mesh_material.tex_file, image))
|
||||
{
|
||||
UERROR("Cannot save texture of image %d", nodeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINFO("Saved temporary texture: \"%s\"", mesh_material.tex_file.c_str());
|
||||
}
|
||||
|
||||
textureMesh->tex_materials.push_back(mesh_material);
|
||||
|
||||
if(!_cloudViewer->addCloudTextureMesh(cloudName, textureMesh, pose))
|
||||
{
|
||||
UERROR("Adding texture mesh %d to viewer failed!", nodeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
else if(!_cloudViewer->addCloudMesh(cloudName, outputFiltered, outputPolygons, pose))
|
||||
{
|
||||
UERROR("Adding mesh cloud %d to viewer failed!", nodeId);
|
||||
}
|
||||
@@ -3036,7 +3159,7 @@ void MainWindow::processRtabmapEventInit(int status, const QString & info)
|
||||
{
|
||||
UINFO("Deleted temporary database \"%s\".", _newDatabasePath.toStdString().c_str());
|
||||
}
|
||||
else
|
||||
else if(!uStr2Bool(_preferencesDialog->getAllParameters().at(Parameters::kDbSqlite3InMemory())))
|
||||
{
|
||||
UERROR("Temporary database \"%s\" could not be deleted.", _newDatabasePath.toStdString().c_str());
|
||||
}
|
||||
@@ -5435,6 +5558,7 @@ void MainWindow::exportClouds()
|
||||
|
||||
_exportCloudsDialog->exportClouds(
|
||||
_ui->widget_mapVisibility->getVisiblePoses(),
|
||||
_currentLinksMap,
|
||||
_currentMapIds,
|
||||
_cachedSignatures,
|
||||
_cachedClouds,
|
||||
@@ -5450,7 +5574,8 @@ void MainWindow::viewClouds()
|
||||
}
|
||||
|
||||
_exportCloudsDialog->viewClouds(
|
||||
_currentPosesMap,
|
||||
_ui->widget_mapVisibility->getVisiblePoses(),
|
||||
_currentLinksMap,
|
||||
_currentMapIds,
|
||||
_cachedSignatures,
|
||||
_cachedClouds,
|
||||
|
||||
@@ -141,7 +141,7 @@ void PostProcessingDialog::restoreDefaults()
|
||||
setDetectMoreLoopClosures(true);
|
||||
setClusterRadius(0.5);
|
||||
setClusterAngle(30);
|
||||
setIterations(1);
|
||||
setIterations(3);
|
||||
setRefineNeighborLinks(false);
|
||||
setRefineLoopClosureLinks(false);
|
||||
setSBA(false);
|
||||
|
||||
@@ -365,6 +365,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->doubleSpinBox_subtractFilteringRadius, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->doubleSpinBox_subtractFilteringAngle, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->spinBox_normalKSearch, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->checkBox_gainCompensation, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
|
||||
connect(_ui->checkBox_map_shown, SIGNAL(clicked(bool)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->doubleSpinBox_map_resolution, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
@@ -380,6 +381,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->groupBox_organized, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->doubleSpinBox_mesh_angleTolerance, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->checkBox_mesh_quad, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->checkBox_mesh_texture, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->spinBox_mesh_triangleSize, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
|
||||
//Logging panel
|
||||
@@ -1210,15 +1212,16 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
||||
_ui->checkBox_showLabels->setChecked(false);
|
||||
|
||||
_ui->spinBox_normalKSearch->setValue(10);
|
||||
_ui->checkBox_gainCompensation->setChecked(false);
|
||||
|
||||
_ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0);
|
||||
#if PCL_VERSION_COMPARE(>=, 1, 7, 2)
|
||||
_ui->groupBox_organized->setChecked(false);
|
||||
#if PCL_VERSION_COMPARE(>=, 1, 7, 2)
|
||||
_ui->checkBox_mesh_quad->setChecked(true);
|
||||
#else
|
||||
_ui->groupBox_organized->setChecked(false);
|
||||
_ui->checkBox_mesh_quad->setChecked(false);
|
||||
#endif
|
||||
_ui->checkBox_mesh_texture->setChecked(false);
|
||||
_ui->spinBox_mesh_triangleSize->setValue(2);
|
||||
}
|
||||
else if(groupBox->objectName() == _ui->groupBox_filtering2->objectName())
|
||||
@@ -1585,6 +1588,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
|
||||
_ui->doubleSpinBox_subtractFilteringRadius->setValue(settings.value("subtractFilteringRadius", _ui->doubleSpinBox_subtractFilteringRadius->value()).toDouble());
|
||||
_ui->doubleSpinBox_subtractFilteringAngle->setValue(settings.value("subtractFilteringAngle", _ui->doubleSpinBox_subtractFilteringAngle->value()).toDouble());
|
||||
_ui->spinBox_normalKSearch->setValue(settings.value("normalKSearch", _ui->spinBox_normalKSearch->value()).toInt());
|
||||
_ui->checkBox_gainCompensation->setChecked(settings.value("gainCompensation", _ui->checkBox_gainCompensation->isChecked()).toBool());
|
||||
|
||||
_ui->checkBox_map_shown->setChecked(settings.value("gridMapShown", _ui->checkBox_map_shown->isChecked()).toBool());
|
||||
_ui->doubleSpinBox_map_resolution->setValue(settings.value("gridMapResolution", _ui->doubleSpinBox_map_resolution->value()).toDouble());
|
||||
@@ -1602,6 +1606,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
|
||||
_ui->groupBox_organized->setChecked(settings.value("meshing", _ui->groupBox_organized->isChecked()).toBool());
|
||||
_ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value("meshing_angle", _ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble());
|
||||
_ui->checkBox_mesh_quad->setChecked(settings.value("meshing_quad", _ui->checkBox_mesh_quad->isChecked()).toBool());
|
||||
_ui->checkBox_mesh_texture->setChecked(settings.value("meshing_texture", _ui->checkBox_mesh_texture->isChecked()).toBool());
|
||||
_ui->spinBox_mesh_triangleSize->setValue(settings.value("meshing_triangle_size", _ui->spinBox_mesh_triangleSize->value()).toInt());
|
||||
|
||||
settings.endGroup(); // General
|
||||
@@ -1925,7 +1930,16 @@ void PreferencesDialog::writeSettings(const QString & filePath)
|
||||
|
||||
for(ParametersMap::iterator iter = _modifiedParameters.begin(); iter!=_modifiedParameters.end(); ++iter)
|
||||
{
|
||||
if( _parameters.at(iter->first).compare(iter->second) != 0)
|
||||
bool different = true;
|
||||
if(Parameters::getType(iter->first).compare("double") ==0 ||
|
||||
Parameters::getType(iter->first).compare("float") == 0)
|
||||
{
|
||||
if(uStr2Double(_parameters.at(iter->first)) == uStr2Double(iter->second))
|
||||
{
|
||||
different = false;
|
||||
}
|
||||
}
|
||||
if(different)
|
||||
{
|
||||
UINFO("modified %s = %s->%s", iter->first.c_str(), _parameters.at(iter->first).c_str(), iter->second.c_str());
|
||||
}
|
||||
@@ -1998,6 +2012,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
|
||||
settings.setValue("subtractFilteringRadius", _ui->doubleSpinBox_subtractFilteringRadius->value());
|
||||
settings.setValue("subtractFilteringAngle", _ui->doubleSpinBox_subtractFilteringAngle->value());
|
||||
settings.setValue("normalKSearch", _ui->spinBox_normalKSearch->value());
|
||||
settings.setValue("gainCompensation", _ui->checkBox_gainCompensation->isChecked());
|
||||
|
||||
settings.setValue("gridMapShown", _ui->checkBox_map_shown->isChecked());
|
||||
settings.setValue("gridMapResolution", _ui->doubleSpinBox_map_resolution->value());
|
||||
@@ -2016,6 +2031,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
|
||||
settings.setValue("meshing", _ui->groupBox_organized->isChecked());
|
||||
settings.setValue("meshing_angle", _ui->doubleSpinBox_mesh_angleTolerance->value());
|
||||
settings.setValue("meshing_quad", _ui->checkBox_mesh_quad->isChecked());
|
||||
settings.setValue("meshing_texture", _ui->checkBox_mesh_texture->isChecked());
|
||||
settings.setValue("meshing_triangle_size", _ui->spinBox_mesh_triangleSize->value());
|
||||
|
||||
settings.endGroup(); // General
|
||||
@@ -3759,6 +3775,10 @@ bool PreferencesDialog::isCloudMeshingQuad() const
|
||||
{
|
||||
return _ui->checkBox_mesh_quad->isChecked();
|
||||
}
|
||||
bool PreferencesDialog::isCloudMeshingTexture() const
|
||||
{
|
||||
return _ui->checkBox_mesh_texture->isChecked();
|
||||
}
|
||||
int PreferencesDialog::getCloudMeshingTriangleSize()
|
||||
{
|
||||
return _ui->spinBox_mesh_triangleSize->value();
|
||||
@@ -3858,6 +3878,10 @@ int PreferencesDialog::getNormalKSearch() const
|
||||
{
|
||||
return _ui->spinBox_normalKSearch->value();
|
||||
}
|
||||
bool PreferencesDialog::gainCompensation() const
|
||||
{
|
||||
return _ui->checkBox_gainCompensation->isChecked();
|
||||
}
|
||||
bool PreferencesDialog::getGridMapShown() const
|
||||
{
|
||||
return _ui->checkBox_map_shown->isChecked();
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>205</width>
|
||||
<width>204</width>
|
||||
<height>208</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -210,7 +210,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>203</width>
|
||||
<width>202</width>
|
||||
<height>208</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -1125,9 +1125,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-225</y>
|
||||
<y>-32</y>
|
||||
<width>280</width>
|
||||
<height>465</height>
|
||||
<height>584</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
@@ -1170,6 +1170,38 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_51">
|
||||
<property name="text">
|
||||
<string>Gain compensation radius (Constraints view)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainCompensationRadius">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -1411,8 +1443,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>265</width>
|
||||
<height>126</height>
|
||||
<width>282</width>
|
||||
<height>163</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
@@ -1511,7 +1543,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>265</width>
|
||||
<width>267</width>
|
||||
<height>168</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
||||
@@ -23,24 +23,14 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-860</y>
|
||||
<y>0</y>
|
||||
<width>773</width>
|
||||
<height>1463</height>
|
||||
<height>1648</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_8" columnstretch="0,1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_binaryFile_2">
|
||||
<property name="text">
|
||||
<string>Assemble clouds/meshes to a single output cloud/mesh.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_normalKSearch">
|
||||
<property name="minimum">
|
||||
@@ -51,10 +41,17 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_binaryFile">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_assemble">
|
||||
<property name="text">
|
||||
<string>Binary file.</string>
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_binaryFile_2">
|
||||
<property name="text">
|
||||
<string>Assemble clouds/meshes to a single output cloud/mesh.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -71,23 +68,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_assemble">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_voxel">
|
||||
<property name="text">
|
||||
<string>Voxel size. Set 0 to disable. When organized meshes are assembled, this is the radius in which the vertices of the polygons are merged.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSize_assembled">
|
||||
<property name="suffix">
|
||||
@@ -138,6 +118,26 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_binaryFile">
|
||||
<property name="text">
|
||||
<string>Binary file.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_voxel">
|
||||
<property name="text">
|
||||
<string>Voxel size. Set 0 to disable. When organized meshes are assembled, this is the radius in which the vertices of the polygons are merged.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -782,6 +782,146 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_gain">
|
||||
<property name="title">
|
||||
<string>Gain Compensation</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_12" columnstretch="0,1">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_binaryFile_3">
|
||||
<property name="text">
|
||||
<string>Correspondence radius</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_binaryFile_5">
|
||||
<property name="text">
|
||||
<string>Beta</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainRadius">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.020000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_binaryFile_4">
|
||||
<property name="text">
|
||||
<string>Alpha</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainAlpha">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.001000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainBeta">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>100.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_binaryFile_6">
|
||||
<property name="text">
|
||||
<string>Min overlap (%)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainOverlap">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.050000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_meshing">
|
||||
<property name="title">
|
||||
@@ -793,34 +933,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_15">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_10" columnstretch="0,1">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_170">
|
||||
<property name="text">
|
||||
<string>Mesh quadric decimation factor (0=no decimation). Used to reduce the number of polygons.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_textureMapping">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_textureMapping">
|
||||
<property name="text">
|
||||
<string>Texture mapping. Images of the cameras will be projected on the mesh(es). Output is a *.obj format.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_meshDecimationFactor">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
@@ -839,20 +952,47 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Min polygon cluster size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_mesh_minClusterSize">
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_meshDecimation">
|
||||
<property name="text">
|
||||
<string>Mesh quadric decimation factor (0=no decimation). Used to reduce the number of polygons. Cannot be used if texturing is on and organized mesh flavor is selected.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_textureMapping">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_textureMapping">
|
||||
<property name="text">
|
||||
<string>Texture mapping. Images of the cameras will be projected on the mesh(es). Output is a *.obj format.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>678</width>
|
||||
<height>2417</height>
|
||||
<width>673</width>
|
||||
<height>2496</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
@@ -86,7 +86,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||
@@ -414,19 +414,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
<layout class="QVBoxLayout" name="verticalLayout_98">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,1">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_137">
|
||||
<property name="text">
|
||||
<string>Odometry</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_154">
|
||||
<property name="text">
|
||||
@@ -459,51 +446,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_150">
|
||||
<property name="text">
|
||||
<string>3D cloud minimum depth.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="label_171">
|
||||
<property name="text">
|
||||
<string>3D cloud voxel filtering size (0=disabled).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_noiseRadius">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.050000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLabel" name="label_168">
|
||||
<property name="text">
|
||||
@@ -517,19 +459,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_noiseMinNeighbors">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_maxDepth_odom">
|
||||
<property name="suffix">
|
||||
@@ -549,19 +478,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="label_132">
|
||||
<property name="text">
|
||||
<string>3D cloud maximum depth (0 means no limit).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth">
|
||||
<property name="suffix">
|
||||
@@ -581,7 +497,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<item row="17" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_showOdomFeatures">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -591,7 +507,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="2">
|
||||
<item row="17" column="2">
|
||||
<widget class="QLabel" name="label_123">
|
||||
<property name="text">
|
||||
<string>Show 3D features.</string>
|
||||
@@ -604,30 +520,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize_features">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_210">
|
||||
<property name="text">
|
||||
<string>3D cloud normal K search. If not 0, normals will be computed and added to created cloud for visualization (keys 7, 8 and 9).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<item row="12" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_showScans">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -637,7 +530,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="12" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_showOdomScans">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -647,7 +540,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<item row="12" column="2">
|
||||
<widget class="QLabel" name="label_110">
|
||||
<property name="text">
|
||||
<string>Show scans.</string>
|
||||
@@ -660,7 +553,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<item row="13" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_downsamplingScan">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
@@ -670,17 +563,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_downsamplingScan_odom">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="2">
|
||||
<item row="13" column="2">
|
||||
<widget class="QLabel" name="label_273">
|
||||
<property name="text">
|
||||
<string>Scan downsampling step size.</string>
|
||||
@@ -693,7 +576,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<item row="14" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSizeScan">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
@@ -712,7 +595,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<item row="14" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSizeScan_odom">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
@@ -731,39 +614,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="2">
|
||||
<widget class="QLabel" name="label_271">
|
||||
<property name="text">
|
||||
<string>Scan voxel size.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_scan">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<item row="15" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_odom_scan">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
@@ -782,19 +633,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="2">
|
||||
<widget class="QLabel" name="label_156">
|
||||
<property name="text">
|
||||
<string>Scan opacity.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QLabel" name="label_169">
|
||||
<property name="text">
|
||||
@@ -808,20 +646,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_normalKSearch">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<item row="18" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize_odom_features">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
@@ -831,7 +656,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="2">
|
||||
<item row="18" column="2">
|
||||
<widget class="QLabel" name="label_166">
|
||||
<property name="text">
|
||||
<string>Feature point size.</string>
|
||||
@@ -844,7 +669,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
@@ -863,39 +688,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_odom">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLabel" name="label_155">
|
||||
<property name="text">
|
||||
<string>3D cloud opacity.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="11" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
@@ -908,20 +701,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize_odom">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<item row="11" column="2">
|
||||
<widget class="QLabel" name="label_157">
|
||||
<property name="text">
|
||||
<string>3D cloud point size (1..64).</string>
|
||||
@@ -934,17 +714,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize_scan">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<item row="16" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize_odom_scan">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
@@ -954,20 +724,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="2">
|
||||
<widget class="QLabel" name="label_158">
|
||||
<property name="text">
|
||||
<string>Scan point size (1..64).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<item row="17" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_showFeatures">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -977,19 +734,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_decimation_odom">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_showClouds">
|
||||
<property name="text">
|
||||
@@ -1045,16 +789,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_showOdomClouds">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth_odom">
|
||||
<property name="suffix">
|
||||
@@ -1077,6 +811,285 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="2">
|
||||
<widget class="QLabel" name="label_213">
|
||||
<property name="text">
|
||||
<string>Show graphs.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_137">
|
||||
<property name="text">
|
||||
<string>Odometry</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_150">
|
||||
<property name="text">
|
||||
<string>3D cloud minimum depth.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="label_171">
|
||||
<property name="text">
|
||||
<string>3D cloud voxel filtering size (0=disabled).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_noiseRadius">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.050000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_noiseMinNeighbors">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="label_132">
|
||||
<property name="text">
|
||||
<string>3D cloud maximum depth (0 means no limit).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize_features">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_210">
|
||||
<property name="text">
|
||||
<string>3D cloud normal K search. If not 0, normals will be computed and added to created cloud for visualization (keys 7, 8 and 9).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_downsamplingScan_odom">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="2">
|
||||
<widget class="QLabel" name="label_271">
|
||||
<property name="text">
|
||||
<string>Scan voxel size.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_scan">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="2">
|
||||
<widget class="QLabel" name="label_156">
|
||||
<property name="text">
|
||||
<string>Scan opacity.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_normalKSearch">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_odom">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QLabel" name="label_155">
|
||||
<property name="text">
|
||||
<string>3D cloud opacity.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize_odom">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_ptsize_scan">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="2">
|
||||
<widget class="QLabel" name="label_158">
|
||||
<property name="text">
|
||||
<string>Scan point size (1..64).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_decimation_odom">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_showOdomClouds">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_119">
|
||||
<property name="text">
|
||||
@@ -1090,20 +1103,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="2">
|
||||
<widget class="QLabel" name="label_213">
|
||||
<property name="text">
|
||||
<string>Show graphs.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="2">
|
||||
<item row="20" column="2">
|
||||
<widget class="QLabel" name="label_243">
|
||||
<property name="text">
|
||||
<string>Show labels.</string>
|
||||
@@ -1116,7 +1116,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<item row="19" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_showGraphs">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -1126,7 +1126,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="0">
|
||||
<item row="20" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_showLabels">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -1136,6 +1136,29 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLabel" name="label_338">
|
||||
<property name="text">
|
||||
<string>Gain compensation.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_gainCompensation">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -1156,16 +1179,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_mesh_quad">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_quad">
|
||||
<property name="text">
|
||||
@@ -1193,6 +1206,16 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_mesh_quad">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_mesh_angleTolerance">
|
||||
<property name="suffix">
|
||||
@@ -1212,6 +1235,23 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_337">
|
||||
<property name="text">
|
||||
<string>Texture</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_mesh_texture">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
Reference in New Issue
Block a user