mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-04 17:17:47 +08:00
Export: CPU-TSDF mesh reconstruction integration
This commit is contained in:
@@ -151,6 +151,7 @@ option(WITH_ZED "Include ZED sdk support" ON)
|
|||||||
option(WITH_REALSENSE "Include RealSense support" ON)
|
option(WITH_REALSENSE "Include RealSense support" ON)
|
||||||
option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON)
|
option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON)
|
||||||
option(WITH_OCTOMAP "Include Octomap support" ON)
|
option(WITH_OCTOMAP "Include Octomap support" ON)
|
||||||
|
option(WITH_CPUTSDF "Include CPUTSDF support" ON)
|
||||||
option(PCL_OMP "With PCL OMP implementations" ON)
|
option(PCL_OMP "With PCL OMP implementations" ON)
|
||||||
|
|
||||||
FIND_PACKAGE(OpenCV REQUIRED QUIET)
|
FIND_PACKAGE(OpenCV REQUIRED QUIET)
|
||||||
@@ -336,6 +337,13 @@ IF(WITH_OCTOMAP)
|
|||||||
ENDIF(OCTOMAP_FOUND)
|
ENDIF(OCTOMAP_FOUND)
|
||||||
ENDIF(WITH_OCTOMAP)
|
ENDIF(WITH_OCTOMAP)
|
||||||
|
|
||||||
|
IF(WITH_CPUTSDF)
|
||||||
|
FIND_PACKAGE(CPUTSDF QUIET)
|
||||||
|
IF(CPUTSDF_FOUND)
|
||||||
|
MESSAGE(STATUS "Found CPUTSDF: ${CPUTSDF_INCLUDE_DIRS}")
|
||||||
|
ENDIF(CPUTSDF_FOUND)
|
||||||
|
ENDIF(WITH_CPUTSDF)
|
||||||
|
|
||||||
IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND OR ANDROID OR RealSense_FOUND)
|
IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND OR ANDROID OR RealSense_FOUND)
|
||||||
#Newest versions require std11
|
#Newest versions require std11
|
||||||
IF(NOT MSVC)
|
IF(NOT MSVC)
|
||||||
@@ -453,6 +461,11 @@ IF(NOT OCTOMAP_FOUND)
|
|||||||
ELSE()
|
ELSE()
|
||||||
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${OCTOMAP_LIBRARIES})
|
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${OCTOMAP_LIBRARIES})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
IF(NOT CPUTSDF_FOUND)
|
||||||
|
SET(CPUTSDF "//")
|
||||||
|
ELSE()
|
||||||
|
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${CPUTSDF_LIBRARIES})
|
||||||
|
ENDIF()
|
||||||
IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF)
|
IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF)
|
||||||
SET(CONF_VTK_QT true)
|
SET(CONF_VTK_QT true)
|
||||||
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} vtkGUISupportQt)
|
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} vtkGUISupportQt)
|
||||||
@@ -768,6 +781,14 @@ ELSE()
|
|||||||
MESSAGE(STATUS " With OCTOMAP = NO (octomap not found)")
|
MESSAGE(STATUS " With OCTOMAP = NO (octomap not found)")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF(CPUTSDF_FOUND)
|
||||||
|
MESSAGE(STATUS " With CPUTSDF = YES (License: BSD)")
|
||||||
|
ELSEIF(NOT WITH_CPUTSDF)
|
||||||
|
MESSAGE(STATUS " With CPUTSDF = NO (WITH_CPUTSDF=OFF)")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS " With CPUTSDF = NO (CPUTSDF not found)")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(QT4_FOUND)
|
IF(QT4_FOUND)
|
||||||
MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)")
|
MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)")
|
||||||
ELSEIF(Qt5_FOUND)
|
ELSEIF(Qt5_FOUND)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
@REALSENSE@#define RTABMAP_REALSENSE
|
@REALSENSE@#define RTABMAP_REALSENSE
|
||||||
@REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM
|
@REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM
|
||||||
@OCTOMAP@#define RTABMAP_OCTOMAP
|
@OCTOMAP@#define RTABMAP_OCTOMAP
|
||||||
|
@CPUTSDF@#define RTABMAP_CPUTSDF
|
||||||
|
|
||||||
#endif /* VERSION_H_ */
|
#endif /* VERSION_H_ */
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ AboutDialog::AboutDialog(QWidget * parent) :
|
|||||||
_ui->label_octomap->setText("Yes");
|
_ui->label_octomap->setText("Yes");
|
||||||
#else
|
#else
|
||||||
_ui->label_octomap->setText("No");
|
_ui->label_octomap->setText("No");
|
||||||
|
#endif
|
||||||
|
#ifdef RTABMAP_CPUTSDF
|
||||||
|
_ui->label_cputsdf->setText("Yes");
|
||||||
|
#else
|
||||||
|
_ui->label_cputsdf->setText("No");
|
||||||
#endif
|
#endif
|
||||||
_ui->label_freenect->setText(CameraFreenect::available()?"Yes":"No");
|
_ui->label_freenect->setText(CameraFreenect::available()?"Yes":"No");
|
||||||
_ui->label_openni2->setText(CameraOpenNI2::available()?"Yes":"No");
|
_ui->label_openni2->setText(CameraOpenNI2::available()?"Yes":"No");
|
||||||
|
|||||||
@@ -137,6 +137,17 @@ IF(OCTOMAP_FOUND)
|
|||||||
)
|
)
|
||||||
ENDIF(OCTOMAP_FOUND)
|
ENDIF(OCTOMAP_FOUND)
|
||||||
|
|
||||||
|
IF(CPUTSDF_FOUND)
|
||||||
|
SET(INCLUDE_DIRS
|
||||||
|
${INCLUDE_DIRS}
|
||||||
|
${CPUTSDF_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
SET(LIBRARIES
|
||||||
|
${LIBRARIES}
|
||||||
|
${CPUTSDF_LIBRARIES}
|
||||||
|
)
|
||||||
|
ENDIF(CPUTSDF_FOUND)
|
||||||
|
|
||||||
IF(VTK_USE_QVTK)
|
IF(VTK_USE_QVTK)
|
||||||
SET(INCLUDE_DIRS ${INCLUDE_DIRS} ${QVTK_INCLUDE_DIR})
|
SET(INCLUDE_DIRS ${INCLUDE_DIRS} ${QVTK_INCLUDE_DIR})
|
||||||
SET(LIBRARIES ${LIBRARIES} ${QVTK_LIBRARY})
|
SET(LIBRARIES ${LIBRARIES} ${QVTK_LIBRARY})
|
||||||
|
|||||||
+467
-248
@@ -45,6 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "rtabmap/core/GainCompensator.h"
|
#include "rtabmap/core/GainCompensator.h"
|
||||||
#include "rtabmap/core/clams/discrete_depth_distortion_model.h"
|
#include "rtabmap/core/clams/discrete_depth_distortion_model.h"
|
||||||
#include "rtabmap/core/DBDriver.h"
|
#include "rtabmap/core/DBDriver.h"
|
||||||
|
#include "rtabmap/core/Version.h"
|
||||||
|
|
||||||
#include <pcl/conversions.h>
|
#include <pcl/conversions.h>
|
||||||
#include <pcl/io/pcd_io.h>
|
#include <pcl/io/pcd_io.h>
|
||||||
@@ -62,6 +63,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
|
||||||
|
#ifdef RTABMAP_CPUTSDF
|
||||||
|
#include <cpu_tsdf/tsdf_volume_octree.h>
|
||||||
|
#include <cpu_tsdf/marching_cubes_tsdf_octree.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
||||||
@@ -175,6 +181,14 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
|||||||
connect(_ui->doubleSpinBox_poisson_pointWeight, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_poisson_pointWeight, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_poisson_scale, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_poisson_scale, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
|
||||||
|
connect(_ui->doubleSpinBox_cputsdf_size, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->doubleSpinBox_cputsdf_resolution, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->doubleSpinBox_cputsdf_tuncPos, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->doubleSpinBox_cputsdf_tuncNeg, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->doubleSpinBox_cputsdf_minWeight, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->doubleSpinBox_cputsdf_flattenRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->spinBox_cputsdf_randomSplit, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||||
|
|
||||||
_progressDialog = new ProgressDialog(this);
|
_progressDialog = new ProgressDialog(this);
|
||||||
_progressDialog->setVisible(false);
|
_progressDialog->setVisible(false);
|
||||||
_progressDialog->setAutoClose(true, 2);
|
_progressDialog->setAutoClose(true, 2);
|
||||||
@@ -312,6 +326,14 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
|||||||
settings.setValue("poisson_pointWeight", _ui->doubleSpinBox_poisson_pointWeight->value());
|
settings.setValue("poisson_pointWeight", _ui->doubleSpinBox_poisson_pointWeight->value());
|
||||||
settings.setValue("poisson_scale", _ui->doubleSpinBox_poisson_scale->value());
|
settings.setValue("poisson_scale", _ui->doubleSpinBox_poisson_scale->value());
|
||||||
|
|
||||||
|
settings.setValue("cputsdf_size", _ui->doubleSpinBox_cputsdf_size->value());
|
||||||
|
settings.setValue("cputsdf_resolution", _ui->doubleSpinBox_cputsdf_resolution->value());
|
||||||
|
settings.setValue("cputsdf_truncPos", _ui->doubleSpinBox_cputsdf_tuncPos->value());
|
||||||
|
settings.setValue("cputsdf_truncNeg", _ui->doubleSpinBox_cputsdf_tuncNeg->value());
|
||||||
|
settings.setValue("cputsdf_minWeight", _ui->doubleSpinBox_cputsdf_minWeight->value());
|
||||||
|
settings.setValue("cputsdf_flattenRadius", _ui->doubleSpinBox_cputsdf_flattenRadius->value());
|
||||||
|
settings.setValue("cputsdf_randomSplit", _ui->spinBox_cputsdf_randomSplit->value());
|
||||||
|
|
||||||
if(!group.isEmpty())
|
if(!group.isEmpty())
|
||||||
{
|
{
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
@@ -413,6 +435,14 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
_ui->doubleSpinBox_poisson_pointWeight->setValue(settings.value("poisson_pointWeight", _ui->doubleSpinBox_poisson_pointWeight->value()).toDouble());
|
_ui->doubleSpinBox_poisson_pointWeight->setValue(settings.value("poisson_pointWeight", _ui->doubleSpinBox_poisson_pointWeight->value()).toDouble());
|
||||||
_ui->doubleSpinBox_poisson_scale->setValue(settings.value("poisson_scale", _ui->doubleSpinBox_poisson_scale->value()).toDouble());
|
_ui->doubleSpinBox_poisson_scale->setValue(settings.value("poisson_scale", _ui->doubleSpinBox_poisson_scale->value()).toDouble());
|
||||||
|
|
||||||
|
_ui->doubleSpinBox_cputsdf_size->setValue(settings.value("cputsdf_size", _ui->doubleSpinBox_cputsdf_size->value()).toDouble());
|
||||||
|
_ui->doubleSpinBox_cputsdf_resolution->setValue(settings.value("cputsdf_resolution", _ui->doubleSpinBox_cputsdf_resolution->value()).toDouble());
|
||||||
|
_ui->doubleSpinBox_cputsdf_tuncPos->setValue(settings.value("cputsdf_truncPos", _ui->doubleSpinBox_cputsdf_tuncPos->value()).toDouble());
|
||||||
|
_ui->doubleSpinBox_cputsdf_tuncNeg->setValue(settings.value("cputsdf_truncNeg", _ui->doubleSpinBox_cputsdf_tuncNeg->value()).toDouble());
|
||||||
|
_ui->doubleSpinBox_cputsdf_minWeight->setValue(settings.value("cputsdf_minWeight", _ui->doubleSpinBox_cputsdf_minWeight->value()).toDouble());
|
||||||
|
_ui->doubleSpinBox_cputsdf_flattenRadius->setValue(settings.value("cputsdf_flattenRadius", _ui->doubleSpinBox_cputsdf_flattenRadius->value()).toDouble());
|
||||||
|
_ui->spinBox_cputsdf_randomSplit->setValue(settings.value("cputsdf_randomSplit", _ui->spinBox_cputsdf_randomSplit->value()).toInt());
|
||||||
|
|
||||||
updateReconstructionFlavor();
|
updateReconstructionFlavor();
|
||||||
updateMLSGrpVisibility();
|
updateMLSGrpVisibility();
|
||||||
|
|
||||||
@@ -509,6 +539,14 @@ void ExportCloudsDialog::restoreDefaults()
|
|||||||
_ui->doubleSpinBox_poisson_pointWeight->setValue(4.0);
|
_ui->doubleSpinBox_poisson_pointWeight->setValue(4.0);
|
||||||
_ui->doubleSpinBox_poisson_scale->setValue(1.1);
|
_ui->doubleSpinBox_poisson_scale->setValue(1.1);
|
||||||
|
|
||||||
|
_ui->doubleSpinBox_cputsdf_size->setValue(12.0);
|
||||||
|
_ui->doubleSpinBox_cputsdf_resolution->setValue(0.01);
|
||||||
|
_ui->doubleSpinBox_cputsdf_tuncPos->setValue(0.03);
|
||||||
|
_ui->doubleSpinBox_cputsdf_tuncNeg->setValue(0.03);
|
||||||
|
_ui->doubleSpinBox_cputsdf_minWeight->setValue(0);
|
||||||
|
_ui->doubleSpinBox_cputsdf_flattenRadius->setValue(0.005);
|
||||||
|
_ui->spinBox_cputsdf_randomSplit->setValue(1);
|
||||||
|
|
||||||
updateReconstructionFlavor();
|
updateReconstructionFlavor();
|
||||||
updateMLSGrpVisibility();
|
updateMLSGrpVisibility();
|
||||||
|
|
||||||
@@ -519,14 +557,6 @@ void ExportCloudsDialog::updateReconstructionFlavor()
|
|||||||
{
|
{
|
||||||
_ui->checkBox_smoothing->setVisible(_ui->comboBox_pipeline->currentIndex() == 1);
|
_ui->checkBox_smoothing->setVisible(_ui->comboBox_pipeline->currentIndex() == 1);
|
||||||
_ui->checkBox_smoothing->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
_ui->checkBox_smoothing->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
||||||
_ui->label_denseReconstruction->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
|
||||||
#ifndef DISABLE_VTK
|
|
||||||
_ui->doubleSpinBox_meshDecimationFactor->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
|
||||||
_ui->label_meshDecimation->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
|
||||||
_ui->spinBox_meshMaxPolygons->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
|
||||||
_ui->label_meshMaxPolygons->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
|
||||||
#endif
|
|
||||||
_ui->groupBox_organized->setVisible(_ui->comboBox_pipeline->currentIndex() == 0);
|
|
||||||
|
|
||||||
_ui->groupBox_regenerate->setVisible(_ui->checkBox_regenerate->isChecked());
|
_ui->groupBox_regenerate->setVisible(_ui->checkBox_regenerate->isChecked());
|
||||||
_ui->groupBox_bilateral->setVisible(_ui->checkBox_bilateral->isChecked());
|
_ui->groupBox_bilateral->setVisible(_ui->checkBox_bilateral->isChecked());
|
||||||
@@ -539,15 +569,28 @@ void ExportCloudsDialog::updateReconstructionFlavor()
|
|||||||
_ui->groupBox_cameraFilter->setVisible(_ui->checkBox_cameraFilter->isChecked());
|
_ui->groupBox_cameraFilter->setVisible(_ui->checkBox_cameraFilter->isChecked());
|
||||||
|
|
||||||
// dense texturing options
|
// dense texturing options
|
||||||
_ui->groupBox_gp3->setVisible(_ui->comboBox_pipeline->currentIndex() == 1 && _ui->comboBox_meshingApproach->currentIndex()==0);
|
|
||||||
_ui->groupBox_poisson->setVisible(_ui->comboBox_pipeline->currentIndex() == 1 && _ui->comboBox_meshingApproach->currentIndex()==1);
|
|
||||||
if(_ui->checkBox_meshing->isChecked())
|
if(_ui->checkBox_meshing->isChecked())
|
||||||
{
|
{
|
||||||
_ui->comboBox_meshingApproach->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
_ui->comboBox_meshingApproach->setItemData(0, _ui->comboBox_pipeline->currentIndex() == 1?1 | 32:0,Qt::UserRole - 1);
|
||||||
_ui->comboBox_meshingApproach->setItemData(1, _ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
|
_ui->comboBox_meshingApproach->setItemData(1, _ui->comboBox_pipeline->currentIndex() == 1 && _ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
|
||||||
|
#ifdef RTABMAP_CPUTSDF
|
||||||
|
_ui->comboBox_meshingApproach->setItemData(2, _ui->comboBox_pipeline->currentIndex() == 0 && _ui->checkBox_assemble->isChecked()?1 | 32:0,Qt::UserRole - 1);
|
||||||
|
#else
|
||||||
|
_ui->comboBox_meshingApproach->setItemData(2, Qt::UserRole - 1);
|
||||||
|
#endif
|
||||||
|
_ui->comboBox_meshingApproach->setItemData(3, _ui->comboBox_pipeline->currentIndex() == 0?1 | 32:0,Qt::UserRole - 1);
|
||||||
|
|
||||||
|
if(_ui->comboBox_pipeline->currentIndex() == 0 && _ui->comboBox_meshingApproach->currentIndex()<2)
|
||||||
|
{
|
||||||
|
_ui->comboBox_meshingApproach->setCurrentIndex(3);
|
||||||
|
}
|
||||||
|
if(_ui->comboBox_pipeline->currentIndex() == 1 && _ui->comboBox_meshingApproach->currentIndex()>1)
|
||||||
|
{
|
||||||
|
_ui->comboBox_meshingApproach->setCurrentIndex(1);
|
||||||
|
}
|
||||||
if(!_ui->checkBox_assemble->isChecked())
|
if(!_ui->checkBox_assemble->isChecked())
|
||||||
{
|
{
|
||||||
_ui->comboBox_meshingApproach->setCurrentIndex(0);
|
_ui->comboBox_meshingApproach->setCurrentIndex(_ui->comboBox_pipeline->currentIndex() == 1?0:3);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ui->checkBox_poisson_outputPolygons->setDisabled(
|
_ui->checkBox_poisson_outputPolygons->setDisabled(
|
||||||
@@ -558,6 +601,18 @@ void ExportCloudsDialog::updateReconstructionFlavor()
|
|||||||
|
|
||||||
_ui->checkBox_cleanMesh->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
_ui->checkBox_cleanMesh->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
||||||
_ui->label_meshClean->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
_ui->label_meshClean->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
||||||
|
|
||||||
|
_ui->groupBox_gp3->setVisible(_ui->comboBox_pipeline->currentIndex() == 1 && _ui->comboBox_meshingApproach->currentIndex()==0);
|
||||||
|
_ui->groupBox_poisson->setVisible(_ui->comboBox_pipeline->currentIndex() == 1 && _ui->comboBox_meshingApproach->currentIndex()==1);
|
||||||
|
_ui->groupBox_cputsdf->setVisible(_ui->comboBox_pipeline->currentIndex() == 0 && _ui->comboBox_meshingApproach->currentIndex()==2);
|
||||||
|
_ui->groupBox_organized->setVisible(_ui->comboBox_pipeline->currentIndex() == 0 && _ui->comboBox_meshingApproach->currentIndex()==3);
|
||||||
|
|
||||||
|
#ifndef DISABLE_VTK
|
||||||
|
_ui->doubleSpinBox_meshDecimationFactor->setEnabled(_ui->comboBox_meshingApproach->currentIndex()!=3);
|
||||||
|
_ui->label_meshDecimation->setEnabled(_ui->comboBox_meshingApproach->currentIndex()!=3);
|
||||||
|
_ui->spinBox_meshMaxPolygons->setEnabled(_ui->comboBox_meshingApproach->currentIndex()!=3);
|
||||||
|
_ui->label_meshMaxPolygons->setEnabled(_ui->comboBox_meshingApproach->currentIndex()!=3);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1255,6 +1310,10 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RTABMAP_CPUTSDF
|
||||||
|
cpu_tsdf::TSDFVolumeOctree::Ptr tsdf;
|
||||||
|
#endif
|
||||||
|
|
||||||
//used for organized texturing below
|
//used for organized texturing below
|
||||||
std::map<int, std::vector<int> > organizedIndices;
|
std::map<int, std::vector<int> > organizedIndices;
|
||||||
std::map<int, cv::Size> organizedCloudSizes;
|
std::map<int, cv::Size> organizedCloudSizes;
|
||||||
@@ -1264,8 +1323,15 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
if(_ui->checkBox_meshing->isChecked())
|
if(_ui->checkBox_meshing->isChecked())
|
||||||
{
|
{
|
||||||
if(_ui->comboBox_pipeline->currentIndex() == 0)
|
if(_ui->comboBox_pipeline->currentIndex() == 0)
|
||||||
|
{
|
||||||
|
if(_ui->comboBox_meshingApproach->currentIndex()==2)
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("Creating TSDF volume... "));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Organized fast mesh... "));
|
_progressDialog->appendText(tr("Organized fast mesh... "));
|
||||||
|
}
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
uSleep(100);
|
uSleep(100);
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
@@ -1297,6 +1363,65 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
_dbDriver->getCalibration(iter->first, models, stereoModel);
|
_dbDriver->getCalibration(iter->first, models, stereoModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RTABMAP_CPUTSDF
|
||||||
|
if(_ui->comboBox_meshingApproach->currentIndex()==2 && _ui->checkBox_assemble->isChecked())
|
||||||
|
{
|
||||||
|
if(tsdf.get() == 0)
|
||||||
|
{
|
||||||
|
if(models.size()==1 && models[0].isValidForProjection() && models[0].imageHeight()>0 && models[0].imageWidth()>0)
|
||||||
|
{
|
||||||
|
float tsdf_size = _ui->doubleSpinBox_cputsdf_size->value();
|
||||||
|
float cell_size = _ui->doubleSpinBox_cputsdf_resolution->value();
|
||||||
|
int num_random_splits = _ui->spinBox_cputsdf_randomSplit->value();
|
||||||
|
int tsdf_res;
|
||||||
|
int desired_res = tsdf_size / cell_size;
|
||||||
|
// Snap to nearest power of 2;
|
||||||
|
int n = 1;
|
||||||
|
while (desired_res > n)
|
||||||
|
{
|
||||||
|
n *= 2;
|
||||||
|
}
|
||||||
|
tsdf_res = n;
|
||||||
|
_progressDialog->appendText(tr("CPU-TSDF: Setting resolution: %1 with grid size %2").arg(tsdf_res).arg(tsdf_size));
|
||||||
|
tsdf.reset (new cpu_tsdf::TSDFVolumeOctree);
|
||||||
|
tsdf->setGridSize (tsdf_size, tsdf_size, tsdf_size);
|
||||||
|
tsdf->setResolution (tsdf_res, tsdf_res, tsdf_res);
|
||||||
|
float decimation = float(models[0].imageWidth()) / float(iter->second->width);
|
||||||
|
tsdf->setImageSize (models[0].imageWidth()/decimation, models[0].imageHeight()/decimation);
|
||||||
|
tsdf->setCameraIntrinsics (models[0].fx()/decimation, models[0].fy()/decimation, models[0].cx()/decimation, models[0].cy()/decimation);
|
||||||
|
tsdf->setNumRandomSplts (num_random_splits);
|
||||||
|
tsdf->setSensorDistanceBounds (0, 9999);
|
||||||
|
tsdf->setIntegrateColor(true);
|
||||||
|
tsdf->setDepthTruncationLimits (_ui->doubleSpinBox_cputsdf_tuncPos->value(), _ui->doubleSpinBox_cputsdf_tuncNeg->value());
|
||||||
|
tsdf->reset ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("CPU-TSDF: Invalid camera model! Only single RGB-D camera supported."), Qt::darkYellow);
|
||||||
|
_progressDialog->setAutoClose(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tsdf.get())
|
||||||
|
{
|
||||||
|
if(tsdf.get() && models.size() == 1 && !models[0].localTransform().isNull())
|
||||||
|
{
|
||||||
|
Eigen::Affine3d pose_rel_to_first_frame = ((poses.begin()->second.inverse() * poses.at(iter->first))*models[0].localTransform()).toEigen3d();
|
||||||
|
if(!tsdf->integrateCloud(*util3d::transformPointCloud(iter->second, models[0].localTransform().inverse()), pcl::PointCloud<pcl::Normal>(), pose_rel_to_first_frame))
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("CPU-TSDF: Failed integrating cloud %1 to TSDF volume").arg(iter->first));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("CPU-TSDF: Integrated cloud %1 to TSDF volume").arg(iter->first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
if(models.size() && !models[0].localTransform().isNull())
|
if(models.size() && !models[0].localTransform().isNull())
|
||||||
{
|
{
|
||||||
viewpoint[0] = models[0].localTransform().x();
|
viewpoint[0] = models[0].localTransform().x();
|
||||||
@@ -1422,6 +1547,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Mesh %1 not created (no valid points) (%2/%3).").arg(iter->first).arg(++i).arg(clouds.size()));
|
_progressDialog->appendText(tr("Mesh %1 not created (no valid points) (%2/%3).").arg(iter->first).arg(++i).arg(clouds.size()));
|
||||||
@@ -1529,241 +1655,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
|
|
||||||
if(mesh->polygons.size()>0)
|
if(mesh->polygons.size()>0)
|
||||||
{
|
{
|
||||||
double meshDecimationFactor = 0.0;
|
denseMeshPostProcessing(iter->first, mesh, lostColors, iter->second);
|
||||||
if(_ui->doubleSpinBox_meshDecimationFactor->isEnabled() &&
|
|
||||||
_ui->doubleSpinBox_meshDecimationFactor->value() > 0.0)
|
|
||||||
{
|
|
||||||
meshDecimationFactor = _ui->doubleSpinBox_meshDecimationFactor->value();
|
|
||||||
}
|
|
||||||
if(_ui->spinBox_meshMaxPolygons->isEnabled() &&
|
|
||||||
_ui->spinBox_meshMaxPolygons->value() > 0)
|
|
||||||
{
|
|
||||||
double factor = 1.0-double(_ui->spinBox_meshMaxPolygons->value())/double(mesh->polygons.size());
|
|
||||||
if(factor > meshDecimationFactor)
|
|
||||||
{
|
|
||||||
meshDecimationFactor = factor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(meshDecimationFactor > 0.0)
|
|
||||||
{
|
|
||||||
unsigned int count = mesh->polygons.size();
|
|
||||||
_progressDialog->appendText(tr("Mesh decimation (factor=%1) from %2 polygons...").arg(meshDecimationFactor).arg(count));
|
|
||||||
QApplication::processEvents();
|
|
||||||
uSleep(100);
|
|
||||||
QApplication::processEvents();
|
|
||||||
|
|
||||||
mesh = util3d::meshDecimation(mesh, (float)meshDecimationFactor);
|
|
||||||
_progressDialog->appendText(tr("Mesh decimated (factor=%1) from %2 to %3 polygons").arg(meshDecimationFactor).arg(count).arg(mesh->polygons.size()));
|
|
||||||
if(count < mesh->polygons.size())
|
|
||||||
{
|
|
||||||
_progressDialog->appendText(tr("Decimated mesh %1 has more polygons than before!").arg(iter->first), Qt::darkYellow);
|
|
||||||
_progressDialog->setAutoClose(false);
|
|
||||||
}
|
|
||||||
QApplication::processEvents();
|
|
||||||
lostColors = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lostColors &&
|
|
||||||
_ui->doubleSpinBox_transferColorRadius->value() >= 0.0 &&
|
|
||||||
(!_ui->checkBox_textureMapping->isEnabled() || !_ui->checkBox_textureMapping->isChecked()))
|
|
||||||
{
|
|
||||||
_progressDialog->appendText(tr("Transferring color from point cloud to mesh..."));
|
|
||||||
QApplication::processEvents();
|
|
||||||
|
|
||||||
// transfer color from point cloud to mesh
|
|
||||||
pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGBNormal>(true));
|
|
||||||
tree->setInputCloud(iter->second);
|
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr coloredCloud(new pcl::PointCloud<pcl::PointXYZRGB>);
|
|
||||||
pcl::fromPCLPointCloud2(mesh->cloud, *coloredCloud);
|
|
||||||
std::vector<bool> coloredPts(coloredCloud->size());
|
|
||||||
for(unsigned int i=0; i<coloredCloud->size(); ++i)
|
|
||||||
{
|
|
||||||
std::vector<int> kIndices;
|
|
||||||
std::vector<float> kDistances;
|
|
||||||
pcl::PointXYZRGBNormal pt;
|
|
||||||
pt.x = coloredCloud->at(i).x;
|
|
||||||
pt.y = coloredCloud->at(i).y;
|
|
||||||
pt.z = coloredCloud->at(i).z;
|
|
||||||
if(_ui->doubleSpinBox_transferColorRadius->value() > 0.0)
|
|
||||||
{
|
|
||||||
tree->radiusSearch(pt, _ui->doubleSpinBox_transferColorRadius->value(), kIndices, kDistances);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tree->nearestKSearch(pt, 1, kIndices, kDistances);
|
|
||||||
}
|
|
||||||
if(kIndices.size())
|
|
||||||
{
|
|
||||||
//compute average color
|
|
||||||
int r=0;
|
|
||||||
int g=0;
|
|
||||||
int b=0;
|
|
||||||
int a=0;
|
|
||||||
for(unsigned int j=0; j<kIndices.size(); ++j)
|
|
||||||
{
|
|
||||||
r+=(int)iter->second->at(kIndices[j]).r;
|
|
||||||
g+=(int)iter->second->at(kIndices[j]).g;
|
|
||||||
b+=(int)iter->second->at(kIndices[j]).b;
|
|
||||||
a+=(int)iter->second->at(kIndices[j]).a;
|
|
||||||
}
|
|
||||||
coloredCloud->at(i).r = r/kIndices.size();
|
|
||||||
coloredCloud->at(i).g = g/kIndices.size();
|
|
||||||
coloredCloud->at(i).b = b/kIndices.size();
|
|
||||||
coloredCloud->at(i).a = a/kIndices.size();
|
|
||||||
coloredPts.at(i) = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//white
|
|
||||||
coloredCloud->at(i).r = coloredCloud->at(i).g = coloredCloud->at(i).b = 255;
|
|
||||||
coloredPts.at(i) = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pcl::toPCLPointCloud2(*coloredCloud, mesh->cloud);
|
|
||||||
|
|
||||||
// remove polygons with no color
|
|
||||||
if(_ui->checkBox_cleanMesh->isChecked())
|
|
||||||
{
|
|
||||||
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
|
||||||
int oi=0;
|
|
||||||
for(unsigned int i=0; i<mesh->polygons.size(); ++i)
|
|
||||||
{
|
|
||||||
bool coloredPolygon = true;
|
|
||||||
for(unsigned int j=0; j<mesh->polygons[i].vertices.size(); ++j)
|
|
||||||
{
|
|
||||||
if(!coloredPts.at(mesh->polygons[i].vertices[j]))
|
|
||||||
{
|
|
||||||
coloredPolygon = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(coloredPolygon)
|
|
||||||
{
|
|
||||||
filteredPolygons[oi++] = mesh->polygons[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filteredPolygons.resize(oi);
|
|
||||||
mesh->polygons = filteredPolygons;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(lostColors &&
|
|
||||||
_ui->doubleSpinBox_transferColorRadius->value() > 0.0 &&
|
|
||||||
_ui->checkBox_cleanMesh->isChecked() &&
|
|
||||||
(_ui->checkBox_textureMapping->isEnabled() && _ui->checkBox_textureMapping->isChecked()))
|
|
||||||
{
|
|
||||||
_progressDialog->appendText(tr("Removing polygons too far from the cloud..."));
|
|
||||||
QApplication::processEvents();
|
|
||||||
|
|
||||||
// transfer color from point cloud to mesh
|
|
||||||
pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGBNormal>(true));
|
|
||||||
tree->setInputCloud(iter->second);
|
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr optimizedCloud(new pcl::PointCloud<pcl::PointXYZ>);
|
|
||||||
pcl::fromPCLPointCloud2(mesh->cloud, *optimizedCloud);
|
|
||||||
std::vector<bool> closePts(optimizedCloud->size());
|
|
||||||
for(unsigned int i=0; i<optimizedCloud->size(); ++i)
|
|
||||||
{
|
|
||||||
std::vector<int> kIndices;
|
|
||||||
std::vector<float> kDistances;
|
|
||||||
pcl::PointXYZRGBNormal pt;
|
|
||||||
pt.x = optimizedCloud->at(i).x;
|
|
||||||
pt.y = optimizedCloud->at(i).y;
|
|
||||||
pt.z = optimizedCloud->at(i).z;
|
|
||||||
tree->radiusSearch(pt, _ui->doubleSpinBox_transferColorRadius->value(), kIndices, kDistances);
|
|
||||||
if(kIndices.size())
|
|
||||||
{
|
|
||||||
closePts.at(i) = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
closePts.at(i) = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove far polygons
|
|
||||||
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
|
||||||
int oi=0;
|
|
||||||
for(unsigned int i=0; i<mesh->polygons.size(); ++i)
|
|
||||||
{
|
|
||||||
bool keepPolygon = true;
|
|
||||||
for(unsigned int j=0; j<mesh->polygons[i].vertices.size(); ++j)
|
|
||||||
{
|
|
||||||
if(!closePts.at(mesh->polygons[i].vertices[j]))
|
|
||||||
{
|
|
||||||
keepPolygon = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(keepPolygon)
|
|
||||||
{
|
|
||||||
filteredPolygons[oi++] = mesh->polygons[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filteredPolygons.resize(oi);
|
|
||||||
mesh->polygons = filteredPolygons;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_ui->spinBox_mesh_minClusterSize->value() &&
|
|
||||||
!(_ui->checkBox_textureMapping->isEnabled() &&
|
|
||||||
_ui->checkBox_textureMapping->isChecked() &&
|
|
||||||
_ui->checkBox_cleanMesh->isChecked()))
|
|
||||||
{
|
|
||||||
_progressDialog->appendText(tr("Filter small polygon clusters..."));
|
|
||||||
QApplication::processEvents();
|
|
||||||
|
|
||||||
// filter polygons
|
|
||||||
std::vector<std::set<int> > neighbors;
|
|
||||||
std::vector<std::set<int> > vertexToPolygons;
|
|
||||||
util3d::createPolygonIndexes(mesh->polygons,
|
|
||||||
mesh->cloud.height*mesh->cloud.width,
|
|
||||||
neighbors,
|
|
||||||
vertexToPolygons);
|
|
||||||
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
|
||||||
neighbors,
|
|
||||||
_ui->spinBox_mesh_minClusterSize->value()<0?0:_ui->spinBox_mesh_minClusterSize->value());
|
|
||||||
|
|
||||||
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
|
||||||
if(_ui->spinBox_mesh_minClusterSize->value() < 0)
|
|
||||||
{
|
|
||||||
// only keep the biggest cluster
|
|
||||||
std::list<std::list<int> >::iterator biggestClusterIndex = clusters.end();
|
|
||||||
unsigned int biggestClusterSize = 0;
|
|
||||||
for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
|
||||||
{
|
|
||||||
if(iter->size() > biggestClusterSize)
|
|
||||||
{
|
|
||||||
biggestClusterIndex = iter;
|
|
||||||
biggestClusterSize = iter->size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(biggestClusterIndex != clusters.end())
|
|
||||||
{
|
|
||||||
int oi=0;
|
|
||||||
for(std::list<int>::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter)
|
|
||||||
{
|
|
||||||
filteredPolygons[oi++] = mesh->polygons.at(*jter);
|
|
||||||
}
|
|
||||||
filteredPolygons.resize(oi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int oi=0;
|
|
||||||
for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
|
||||||
{
|
|
||||||
for(std::list<int>::iterator jter=iter->begin(); jter!=iter->end(); ++jter)
|
|
||||||
{
|
|
||||||
filteredPolygons[oi++] = mesh->polygons.at(*jter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filteredPolygons.resize(oi);
|
|
||||||
}
|
|
||||||
|
|
||||||
int before = (int)mesh->polygons.size();
|
|
||||||
mesh->polygons = filteredPolygons;
|
|
||||||
|
|
||||||
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-(int)mesh->polygons.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
meshes.insert(std::make_pair(iter->first, mesh));
|
meshes.insert(std::make_pair(iter->first, mesh));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1782,6 +1674,91 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RTABMAP_CPUTSDF
|
||||||
|
if(tsdf.get())
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("CPU-TSDF: Creating mesh from TSDF volume..."));
|
||||||
|
QApplication::processEvents();
|
||||||
|
uSleep(100);
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
cpu_tsdf::MarchingCubesTSDFOctree mc;
|
||||||
|
mc.setMinWeight (_ui->doubleSpinBox_cputsdf_minWeight->value());
|
||||||
|
mc.setInputTSDF (tsdf);
|
||||||
|
mc.setColorByRGB (true);
|
||||||
|
pcl::PolygonMesh::Ptr mesh (new pcl::PolygonMesh);
|
||||||
|
mc.reconstruct (*mesh);
|
||||||
|
_progressDialog->appendText(tr("CPU-TSDF: Creating mesh from TSDF volume...done!"));
|
||||||
|
meshes.clear();
|
||||||
|
|
||||||
|
if(mesh->polygons.size()>0)
|
||||||
|
{
|
||||||
|
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr vertices (new pcl::PointCloud<pcl::PointXYZRGBNormal>);
|
||||||
|
pcl::fromPCLPointCloud2 (mesh->cloud, *vertices);
|
||||||
|
|
||||||
|
if(_ui->doubleSpinBox_cputsdf_flattenRadius->value()>0.0)
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("CPU-TSDF: Flattening mesh (radius=%1)...").arg(_ui->doubleSpinBox_cputsdf_flattenRadius->value()));
|
||||||
|
QApplication::processEvents();
|
||||||
|
uSleep(100);
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
float min_dist = _ui->doubleSpinBox_cputsdf_flattenRadius->value();
|
||||||
|
pcl::search::KdTree<pcl::PointXYZRGBNormal> vert_tree (true);
|
||||||
|
vert_tree.setInputCloud (vertices);
|
||||||
|
// Find duplicates
|
||||||
|
std::vector<int> vertex_remap (vertices->size (), -1);
|
||||||
|
int idx = 0;
|
||||||
|
std::vector<int> neighbors;
|
||||||
|
std::vector<float> dists;
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr vertices_new(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
|
||||||
|
vertices_new->resize(vertices->size ());
|
||||||
|
for (size_t i = 0; i < vertices->size (); i++)
|
||||||
|
{
|
||||||
|
if (vertex_remap[i] >= 0)
|
||||||
|
continue;
|
||||||
|
vertex_remap[i] = idx;
|
||||||
|
vert_tree.radiusSearch (i, min_dist, neighbors, dists);
|
||||||
|
for (size_t j = 1; j < neighbors.size (); j++)
|
||||||
|
{
|
||||||
|
if (dists[j] < min_dist)
|
||||||
|
vertex_remap[neighbors[j]] = idx;
|
||||||
|
}
|
||||||
|
vertices_new->at(idx++) = vertices->at (i);
|
||||||
|
}
|
||||||
|
vertices_new->resize(idx);
|
||||||
|
std::vector<size_t> faces_to_remove;
|
||||||
|
size_t face_idx = 0;
|
||||||
|
for (size_t i = 0; i < mesh->polygons.size (); i++)
|
||||||
|
{
|
||||||
|
pcl::Vertices &v = mesh->polygons[i];
|
||||||
|
for (size_t j = 0; j < v.vertices.size (); j++)
|
||||||
|
{
|
||||||
|
v.vertices[j] = vertex_remap[v.vertices[j]];
|
||||||
|
}
|
||||||
|
if (!(v.vertices[0] == v.vertices[1] || v.vertices[1] == v.vertices[2] || v.vertices[2] == v.vertices[0]))
|
||||||
|
{
|
||||||
|
mesh->polygons[face_idx++] = mesh->polygons[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mesh->polygons.resize (face_idx);
|
||||||
|
pcl::toPCLPointCloud2 (*vertices_new, mesh->cloud);
|
||||||
|
vertices = vertices_new;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcl::fromPCLPointCloud2(mesh->cloud, *vertices);
|
||||||
|
denseMeshPostProcessing(0, mesh, false, vertices);
|
||||||
|
meshes.insert(std::make_pair(0, mesh));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("No polygons created TSDF volume!"), Qt::darkYellow);
|
||||||
|
_progressDialog->setAutoClose(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(_canceled)
|
if(_canceled)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -3628,4 +3605,246 @@ void ExportCloudsDialog::saveTextureMeshes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExportCloudsDialog::denseMeshPostProcessing(
|
||||||
|
int id,
|
||||||
|
pcl::PolygonMeshPtr & mesh,
|
||||||
|
bool lostColors,
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud)
|
||||||
|
{
|
||||||
|
double meshDecimationFactor = 0.0;
|
||||||
|
if(_ui->doubleSpinBox_meshDecimationFactor->isEnabled() &&
|
||||||
|
_ui->doubleSpinBox_meshDecimationFactor->value() > 0.0)
|
||||||
|
{
|
||||||
|
meshDecimationFactor = _ui->doubleSpinBox_meshDecimationFactor->value();
|
||||||
|
}
|
||||||
|
if(_ui->spinBox_meshMaxPolygons->isEnabled() &&
|
||||||
|
_ui->spinBox_meshMaxPolygons->value() > 0)
|
||||||
|
{
|
||||||
|
double factor = 1.0-double(_ui->spinBox_meshMaxPolygons->value())/double(mesh->polygons.size());
|
||||||
|
if(factor > meshDecimationFactor)
|
||||||
|
{
|
||||||
|
meshDecimationFactor = factor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(meshDecimationFactor > 0.0)
|
||||||
|
{
|
||||||
|
unsigned int count = mesh->polygons.size();
|
||||||
|
_progressDialog->appendText(tr("Mesh decimation (factor=%1) from %2 polygons...").arg(meshDecimationFactor).arg(count));
|
||||||
|
QApplication::processEvents();
|
||||||
|
uSleep(100);
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
mesh = util3d::meshDecimation(mesh, (float)meshDecimationFactor);
|
||||||
|
_progressDialog->appendText(tr("Mesh decimated (factor=%1) from %2 to %3 polygons").arg(meshDecimationFactor).arg(count).arg(mesh->polygons.size()));
|
||||||
|
if(count < mesh->polygons.size())
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("Decimated mesh %1 has more polygons than before!").arg(id), Qt::darkYellow);
|
||||||
|
_progressDialog->setAutoClose(false);
|
||||||
|
}
|
||||||
|
QApplication::processEvents();
|
||||||
|
lostColors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lostColors &&
|
||||||
|
_ui->doubleSpinBox_transferColorRadius->value() >= 0.0 &&
|
||||||
|
(!_ui->checkBox_textureMapping->isEnabled() || !_ui->checkBox_textureMapping->isChecked()))
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("Transferring color from point cloud to mesh..."));
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// transfer color from point cloud to mesh
|
||||||
|
pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGBNormal>(true));
|
||||||
|
tree->setInputCloud(cloud);
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr coloredCloud(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||||
|
pcl::fromPCLPointCloud2(mesh->cloud, *coloredCloud);
|
||||||
|
std::vector<bool> coloredPts(coloredCloud->size());
|
||||||
|
for(unsigned int i=0; i<coloredCloud->size(); ++i)
|
||||||
|
{
|
||||||
|
std::vector<int> kIndices;
|
||||||
|
std::vector<float> kDistances;
|
||||||
|
pcl::PointXYZRGBNormal pt;
|
||||||
|
pt.x = coloredCloud->at(i).x;
|
||||||
|
pt.y = coloredCloud->at(i).y;
|
||||||
|
pt.z = coloredCloud->at(i).z;
|
||||||
|
if(_ui->doubleSpinBox_transferColorRadius->value() > 0.0)
|
||||||
|
{
|
||||||
|
tree->radiusSearch(pt, _ui->doubleSpinBox_transferColorRadius->value(), kIndices, kDistances);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tree->nearestKSearch(pt, 1, kIndices, kDistances);
|
||||||
|
}
|
||||||
|
if(kIndices.size())
|
||||||
|
{
|
||||||
|
//compute average color
|
||||||
|
int r=0;
|
||||||
|
int g=0;
|
||||||
|
int b=0;
|
||||||
|
int a=0;
|
||||||
|
for(unsigned int j=0; j<kIndices.size(); ++j)
|
||||||
|
{
|
||||||
|
r+=(int)cloud->at(kIndices[j]).r;
|
||||||
|
g+=(int)cloud->at(kIndices[j]).g;
|
||||||
|
b+=(int)cloud->at(kIndices[j]).b;
|
||||||
|
a+=(int)cloud->at(kIndices[j]).a;
|
||||||
|
}
|
||||||
|
coloredCloud->at(i).r = r/kIndices.size();
|
||||||
|
coloredCloud->at(i).g = g/kIndices.size();
|
||||||
|
coloredCloud->at(i).b = b/kIndices.size();
|
||||||
|
coloredCloud->at(i).a = a/kIndices.size();
|
||||||
|
coloredPts.at(i) = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//white
|
||||||
|
coloredCloud->at(i).r = coloredCloud->at(i).g = coloredCloud->at(i).b = 255;
|
||||||
|
coloredPts.at(i) = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pcl::toPCLPointCloud2(*coloredCloud, mesh->cloud);
|
||||||
|
|
||||||
|
// remove polygons with no color
|
||||||
|
if(_ui->checkBox_cleanMesh->isChecked())
|
||||||
|
{
|
||||||
|
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
||||||
|
int oi=0;
|
||||||
|
for(unsigned int i=0; i<mesh->polygons.size(); ++i)
|
||||||
|
{
|
||||||
|
bool coloredPolygon = true;
|
||||||
|
for(unsigned int j=0; j<mesh->polygons[i].vertices.size(); ++j)
|
||||||
|
{
|
||||||
|
if(!coloredPts.at(mesh->polygons[i].vertices[j]))
|
||||||
|
{
|
||||||
|
coloredPolygon = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(coloredPolygon)
|
||||||
|
{
|
||||||
|
filteredPolygons[oi++] = mesh->polygons[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filteredPolygons.resize(oi);
|
||||||
|
mesh->polygons = filteredPolygons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(lostColors &&
|
||||||
|
_ui->doubleSpinBox_transferColorRadius->value() > 0.0 &&
|
||||||
|
_ui->checkBox_cleanMesh->isChecked() &&
|
||||||
|
(_ui->checkBox_textureMapping->isEnabled() && _ui->checkBox_textureMapping->isChecked()))
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("Removing polygons too far from the cloud..."));
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// transfer color from point cloud to mesh
|
||||||
|
pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGBNormal>(true));
|
||||||
|
tree->setInputCloud(cloud);
|
||||||
|
pcl::PointCloud<pcl::PointXYZ>::Ptr optimizedCloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||||
|
pcl::fromPCLPointCloud2(mesh->cloud, *optimizedCloud);
|
||||||
|
std::vector<bool> closePts(optimizedCloud->size());
|
||||||
|
for(unsigned int i=0; i<optimizedCloud->size(); ++i)
|
||||||
|
{
|
||||||
|
std::vector<int> kIndices;
|
||||||
|
std::vector<float> kDistances;
|
||||||
|
pcl::PointXYZRGBNormal pt;
|
||||||
|
pt.x = optimizedCloud->at(i).x;
|
||||||
|
pt.y = optimizedCloud->at(i).y;
|
||||||
|
pt.z = optimizedCloud->at(i).z;
|
||||||
|
tree->radiusSearch(pt, _ui->doubleSpinBox_transferColorRadius->value(), kIndices, kDistances);
|
||||||
|
if(kIndices.size())
|
||||||
|
{
|
||||||
|
closePts.at(i) = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
closePts.at(i) = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove far polygons
|
||||||
|
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
||||||
|
int oi=0;
|
||||||
|
for(unsigned int i=0; i<mesh->polygons.size(); ++i)
|
||||||
|
{
|
||||||
|
bool keepPolygon = true;
|
||||||
|
for(unsigned int j=0; j<mesh->polygons[i].vertices.size(); ++j)
|
||||||
|
{
|
||||||
|
if(!closePts.at(mesh->polygons[i].vertices[j]))
|
||||||
|
{
|
||||||
|
keepPolygon = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(keepPolygon)
|
||||||
|
{
|
||||||
|
filteredPolygons[oi++] = mesh->polygons[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filteredPolygons.resize(oi);
|
||||||
|
mesh->polygons = filteredPolygons;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_ui->spinBox_mesh_minClusterSize->value() &&
|
||||||
|
!(_ui->checkBox_textureMapping->isEnabled() &&
|
||||||
|
_ui->checkBox_textureMapping->isChecked() &&
|
||||||
|
_ui->checkBox_cleanMesh->isChecked()))
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("Filter small polygon clusters..."));
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// filter polygons
|
||||||
|
std::vector<std::set<int> > neighbors;
|
||||||
|
std::vector<std::set<int> > vertexToPolygons;
|
||||||
|
util3d::createPolygonIndexes(mesh->polygons,
|
||||||
|
mesh->cloud.height*mesh->cloud.width,
|
||||||
|
neighbors,
|
||||||
|
vertexToPolygons);
|
||||||
|
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
||||||
|
neighbors,
|
||||||
|
_ui->spinBox_mesh_minClusterSize->value()<0?0:_ui->spinBox_mesh_minClusterSize->value());
|
||||||
|
|
||||||
|
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
||||||
|
if(_ui->spinBox_mesh_minClusterSize->value() < 0)
|
||||||
|
{
|
||||||
|
// only keep the biggest cluster
|
||||||
|
std::list<std::list<int> >::iterator biggestClusterIndex = clusters.end();
|
||||||
|
unsigned int biggestClusterSize = 0;
|
||||||
|
for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
||||||
|
{
|
||||||
|
if(iter->size() > biggestClusterSize)
|
||||||
|
{
|
||||||
|
biggestClusterIndex = iter;
|
||||||
|
biggestClusterSize = iter->size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(biggestClusterIndex != clusters.end())
|
||||||
|
{
|
||||||
|
int oi=0;
|
||||||
|
for(std::list<int>::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter)
|
||||||
|
{
|
||||||
|
filteredPolygons[oi++] = mesh->polygons.at(*jter);
|
||||||
|
}
|
||||||
|
filteredPolygons.resize(oi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int oi=0;
|
||||||
|
for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
||||||
|
{
|
||||||
|
for(std::list<int>::iterator jter=iter->begin(); jter!=iter->end(); ++jter)
|
||||||
|
{
|
||||||
|
filteredPolygons[oi++] = mesh->polygons.at(*jter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filteredPolygons.resize(oi);
|
||||||
|
}
|
||||||
|
|
||||||
|
int before = (int)mesh->polygons.size();
|
||||||
|
mesh->polygons = filteredPolygons;
|
||||||
|
|
||||||
|
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-(int)mesh->polygons.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,12 @@ private:
|
|||||||
void setOkButton();
|
void setOkButton();
|
||||||
void enableRegeneration(bool enabled);
|
void enableRegeneration(bool enabled);
|
||||||
|
|
||||||
|
void denseMeshPostProcessing(
|
||||||
|
int id,
|
||||||
|
pcl::PolygonMeshPtr & mesh,
|
||||||
|
bool lostColors,
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui_ExportCloudsDialog * _ui;
|
Ui_ExportCloudsDialog * _ui;
|
||||||
ProgressDialog * _progressDialog;
|
ProgressDialog * _progressDialog;
|
||||||
|
|||||||
+180
-163
@@ -82,30 +82,6 @@ p, li { white-space: pre-wrap; }
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
|
||||||
<item row="9" column="1">
|
|
||||||
<widget class="QLabel" name="label_pcl_version">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Author :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="11" column="0">
|
|
||||||
<widget class="QLabel" name="label_12">
|
|
||||||
<property name="text">
|
|
||||||
<string>With Freenect :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -113,8 +89,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="9" column="1">
|
||||||
<widget class="QLabel" name="label_freenect">
|
<widget class="QLabel" name="label_pcl_version">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -123,44 +99,6 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="1">
|
|
||||||
<widget class="QLabel" name="label_openni2">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="13" column="0">
|
|
||||||
<widget class="QLabel" name="label_15">
|
|
||||||
<property name="text">
|
|
||||||
<string>With Freenect2 :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="16" column="0">
|
|
||||||
<widget class="QLabel" name="label_17">
|
|
||||||
<property name="text">
|
|
||||||
<string>With stereo FlyCapture2 :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="0">
|
|
||||||
<widget class="QLabel" name="label_11">
|
|
||||||
<property name="text">
|
|
||||||
<string>PCL version :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Version :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="20" column="1">
|
<item row="20" column="1">
|
||||||
<widget class="QLabel" name="label_cvsba">
|
<widget class="QLabel" name="label_cvsba">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -171,15 +109,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="19" column="0">
|
<item row="11" column="1">
|
||||||
<widget class="QLabel" name="label_19">
|
<widget class="QLabel" name="label_freenect">
|
||||||
<property name="text">
|
|
||||||
<string>With GTSAM :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="21" column="1">
|
|
||||||
<widget class="QLabel" name="label_octomap">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -188,25 +119,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="17" column="1">
|
<item row="19" column="1">
|
||||||
<widget class="QLabel" name="label_zed">
|
<widget class="QLabel" name="label_gtsam">
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="21" column="0">
|
|
||||||
<widget class="QLabel" name="label_20">
|
|
||||||
<property name="text">
|
|
||||||
<string>With Octomap :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="15" column="1">
|
|
||||||
<widget class="QLabel" name="label_dc1394">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -225,8 +139,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="21" column="1">
|
||||||
<widget class="QLabel" name="label_version">
|
<widget class="QLabel" name="label_octomap">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -235,41 +149,51 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="13" column="0">
|
||||||
<widget class="QLabel" name="label_HomePage_3">
|
<widget class="QLabel" name="label_15">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string>With Freenect2 :</string>
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
</property>
|
||||||
p, li { white-space: pre-wrap; }
|
</widget>
|
||||||
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
|
</item>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://introlab.github.io/rtabmap"><span style=" text-decoration: underline; color:#0000ff;">Home page</span></a></p></body></html></string>
|
<item row="12" column="0">
|
||||||
|
<widget class="QLabel" name="label_13">
|
||||||
|
<property name="text">
|
||||||
|
<string>With OpenNI2 :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="1">
|
||||||
|
<widget class="QLabel" name="label_vtk_version">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="openExternalLinks">
|
</widget>
|
||||||
<bool>true</bool>
|
</item>
|
||||||
|
<item row="12" column="1">
|
||||||
|
<widget class="QLabel" name="label_openni2">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0">
|
<item row="9" column="0">
|
||||||
<widget class="QLabel" name="label_7">
|
<widget class="QLabel" name="label_11">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>OpenCV version :</string>
|
<string>PCL version :</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="18" column="0">
|
<item row="17" column="0">
|
||||||
<widget class="QLabel" name="label_14">
|
<widget class="QLabel" name="label_21">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>With g2o :</string>
|
<string>With stereo Zed :</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="15" column="0">
|
|
||||||
<widget class="QLabel" name="label_16">
|
|
||||||
<property name="text">
|
|
||||||
<string>With stereo dc1394 :</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -283,42 +207,46 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="18" column="0">
|
||||||
<widget class="QLabel" name="label_8">
|
<widget class="QLabel" name="label_14">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Mathieu Labbé, [email protected]</string>
|
<string>With g2o :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="17" column="1">
|
||||||
|
<widget class="QLabel" name="label_zed">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="0">
|
<item row="20" column="0">
|
||||||
<widget class="QLabel" name="label_13">
|
<widget class="QLabel" name="label_18">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>With OpenNI2 :</string>
|
<string>With cvsba :</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="8" column="0">
|
||||||
<widget class="QLabel" name="label_HomePage_2">
|
<widget class="QLabel" name="label_7">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string>OpenCV version :</string>
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
|
||||||
p, li { white-space: pre-wrap; }
|
|
||||||
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
|
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://github.com/introlab/rtabmap"><span style=" text-decoration: underline; color:#0000ff;">Source page</span></a></p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="openExternalLinks">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="1">
|
<item row="15" column="0">
|
||||||
<widget class="QLabel" name="label_opencv_version">
|
<widget class="QLabel" name="label_16">
|
||||||
|
<property name="text">
|
||||||
|
<string>With stereo dc1394 :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QLabel" name="label_version">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -337,30 +265,6 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="17" column="0">
|
|
||||||
<widget class="QLabel" name="label_21">
|
|
||||||
<property name="text">
|
|
||||||
<string>With stereo Zed :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="19" column="1">
|
|
||||||
<widget class="QLabel" name="label_gtsam">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="20" column="0">
|
|
||||||
<widget class="QLabel" name="label_18">
|
|
||||||
<property name="text">
|
|
||||||
<string>With cvsba :</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="14" column="0">
|
<item row="14" column="0">
|
||||||
<widget class="QLabel" name="label_22">
|
<widget class="QLabel" name="label_22">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -378,6 +282,64 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Mathieu Labbé, [email protected]</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Version :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QLabel" name="label_opencv_version">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="0">
|
||||||
|
<widget class="QLabel" name="label_12">
|
||||||
|
<property name="text">
|
||||||
|
<string>With Freenect :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="21" column="0">
|
||||||
|
<widget class="QLabel" name="label_20">
|
||||||
|
<property name="text">
|
||||||
|
<string>With Octomap :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="15" column="1">
|
||||||
|
<widget class="QLabel" name="label_dc1394">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Author :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="10" column="0">
|
<item row="10" column="0">
|
||||||
<widget class="QLabel" name="label_23">
|
<widget class="QLabel" name="label_23">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -385,8 +347,63 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
<item row="16" column="0">
|
||||||
<widget class="QLabel" name="label_vtk_version">
|
<widget class="QLabel" name="label_17">
|
||||||
|
<property name="text">
|
||||||
|
<string>With stereo FlyCapture2 :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_HomePage_2">
|
||||||
|
<property name="text">
|
||||||
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://github.com/introlab/rtabmap"><span style=" text-decoration: underline; color:#0000ff;">Source page</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLabel" name="label_HomePage_3">
|
||||||
|
<property name="text">
|
||||||
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://introlab.github.io/rtabmap"><span style=" text-decoration: underline; color:#0000ff;">Home page</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="19" column="0">
|
||||||
|
<widget class="QLabel" name="label_19">
|
||||||
|
<property name="text">
|
||||||
|
<string>With GTSAM :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="22" column="0">
|
||||||
|
<widget class="QLabel" name="label_24">
|
||||||
|
<property name="text">
|
||||||
|
<string>With CPU-TSDF :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="22" column="1">
|
||||||
|
<widget class="QLabel" name="label_cputsdf">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
@@ -23,9 +23,9 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>-1802</y>
|
<y>-3080</y>
|
||||||
<width>778</width>
|
<width>778</width>
|
||||||
<height>3385</height>
|
<height>3701</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||||
@@ -1205,7 +1205,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_denseReconstruction">
|
<widget class="QLabel" name="label_denseReconstruction">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Surface reconstruction approach. Can be used only when dense reconstruction flavor is selected. Poisson is available when clouds are assembled.</string>
|
<string>Surface reconstruction approach. Poisson is available when clouds are assembled and dense reconstruction flavor is selected. CPU-TSDF is available when clouds are assembled, organized reconstruction flavor is selected and RTAB-Map is built with CPU-TSDF support.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -1244,7 +1244,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="label_meshDecimation">
|
<widget class="QLabel" name="label_meshDecimation">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Mesh quadric decimation factor (0=no decimation). Used to reduce the number of polygons. Higher the factor, lower the output resolution (less polygons). Can be used when dense reconstruction flavor is selected. Can reduce a lot texturing time.</string>
|
<string>Mesh quadric decimation factor (0=no decimation). Used to reduce the number of polygons. Higher the factor, lower the output resolution (less polygons). Can be used when organized mesh approach is not selected. Can reduce a lot texturing time.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -1273,6 +1273,16 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<string>Poisson</string>
|
<string>Poisson</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>CPU-TSDF</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Organized</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
@@ -1998,6 +2008,247 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_cputsdf">
|
||||||
|
<property name="title">
|
||||||
|
<string>CPU-TSDF Reconstruction</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_17">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_25">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><a href="https://github.com/sdmiller/cpu_tsdf"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/sdmiller/cpu_tsdf</span></a></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_17" columnstretch="0,1">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_cputsdf_size">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> m</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>9999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>12.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_19">
|
||||||
|
<property name="text">
|
||||||
|
<string>Volume size.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_cputsdf_resolution">
|
||||||
|
<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>99.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_20">
|
||||||
|
<property name="text">
|
||||||
|
<string>Resolution.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_cputsdf_tuncPos">
|
||||||
|
<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>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.030000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="label_21">
|
||||||
|
<property name="text">
|
||||||
|
<string>Depth truncation positive limit. Maximum distance a voxel will be set to positive.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_cputsdf_tuncNeg">
|
||||||
|
<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>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.030000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_22">
|
||||||
|
<property name="text">
|
||||||
|
<string>Depth truncation negative limit. Maximum distance a voxel will be set to negative.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QSpinBox" name="spinBox_cputsdf_randomSplit">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLabel" name="label_23">
|
||||||
|
<property name="text">
|
||||||
|
<string>Set the number of random samples per surface point the octree should split on. If you don't know what this does, it's almost certainly best to leave it at 1.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_cputsdf_minWeight">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>99.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.500000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="label_18">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimum weight of a voxel to be added in the mesh.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_cputsdf_flattenRadius">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> m</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>9.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.005000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.005000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QLabel" name="label_24">
|
||||||
|
<property name="text">
|
||||||
|
<string>Flatten radius (0=disabled).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_organized">
|
<widget class="QGroupBox" name="groupBox_organized">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -2009,6 +2260,9 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Triangle size</string>
|
<string>Triangle size</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
@@ -2016,6 +2270,9 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Quad</string>
|
<string>Quad</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
@@ -2052,6 +2309,9 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Angle tolerance</string>
|
<string>Angle tolerance</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
|
|||||||
Reference in New Issue
Block a user