MainWindow: Added statistics about how much size the created clouds take in RAM. Avoid caching data on small movements. Export: Fixed meshing checkbox and pipeline combo box not saved/loaded. PreferencesDialog: Added option to disable caching the point clouds. computeNormals(): added viewpoint parameter. mls(): making sure that all returned normals are normalized.

This commit is contained in:
matlabbe
2016-06-12 17:53:35 -04:00
parent cb7c76889d
commit 543b8df045
12 changed files with 288 additions and 97 deletions

View File

@@ -194,6 +194,8 @@ public:
void setGroundTruth(const Transform & pose) {groundTruth_ = pose;} void setGroundTruth(const Transform & pose) {groundTruth_ = pose;}
const Transform & groundTruth() const {return groundTruth_;} const Transform & groundTruth() const {return groundTruth_;}
long getMemoryUsed() const; // Return memory usage in Bytes
private: private:
int _id; int _id;
double _stamp; double _stamp;

View File

@@ -126,28 +126,34 @@ pcl::TextureMesh::Ptr RTABMAP_EXP createTextureMesh(
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals( pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
int normalKSearch = 20); int normalKSearch = 20,
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals( pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
int normalKSearch = 20); int normalKSearch = 20,
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals( pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
int normalKSearch = 20); int normalKSearch = 20,
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals( pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
int normalKSearch = 20); int normalKSearch = 20,
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals( pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
float maxDepthChangeFactor = 0.02f, float maxDepthChangeFactor = 0.02f,
float normalSmoothingSize = 10.0f); float normalSmoothingSize = 10.0f,
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals( pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
float maxDepthChangeFactor = 0.02f, float maxDepthChangeFactor = 0.02f,
float normalSmoothingSize = 10.0f); float normalSmoothingSize = 10.0f,
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr RTABMAP_EXP mls( pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr RTABMAP_EXP mls(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,

View File

@@ -193,7 +193,21 @@ void CameraThread::mainLoop()
cv::Mat scan; cv::Mat scan;
if(_scanNormalsK>0) if(_scanNormalsK>0)
{ {
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, _scanNormalsK); // view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
{
viewPoint[0] = data.cameraModels()[0].localTransform().x();
viewPoint[1] = data.cameraModels()[0].localTransform().y();
viewPoint[2] = data.cameraModels()[0].localTransform().z();
}
else if(!data.stereoCameraModel().localTransform().isNull())
{
viewPoint[0] = data.stereoCameraModel().localTransform().x();
viewPoint[1] = data.stereoCameraModel().localTransform().y();
viewPoint[2] = data.stereoCameraModel().localTransform().z();
}
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, _scanNormalsK, viewPoint);
pcl::PointCloud<pcl::PointNormal>::Ptr cloudNormals(new pcl::PointCloud<pcl::PointNormal>); pcl::PointCloud<pcl::PointNormal>::Ptr cloudNormals(new pcl::PointCloud<pcl::PointNormal>);
pcl::concatenateFields(*cloud, *normals, *cloudNormals); pcl::concatenateFields(*cloud, *normals, *cloudNormals);
scan = util3d::laserScanFromPointCloud(*cloudNormals); scan = util3d::laserScanFromPointCloud(*cloudNormals);

View File

@@ -448,7 +448,6 @@ void SensorData::setUserDataRaw(const cv::Mat & userDataRaw)
return; return;
} }
_userDataRaw = userDataRaw; _userDataRaw = userDataRaw;
_userDataCompressed = cv::Mat();
} }
void SensorData::setUserData(const cv::Mat & userData) void SensorData::setUserData(const cv::Mat & userData)
@@ -607,5 +606,17 @@ void SensorData::uncompressDataConst(cv::Mat * imageRaw, cv::Mat * depthRaw, cv:
} }
} }
long SensorData::getMemoryUsed() const // Return memory usage in Bytes
{
return _imageCompressed.total()*_imageCompressed.elemSize() +
_imageRaw.total()*_imageRaw.elemSize() +
_depthOrRightCompressed.total()*_depthOrRightCompressed.elemSize() +
_depthOrRightRaw.total()*_depthOrRightRaw.elemSize() +
_userDataCompressed.total()*_userDataCompressed.elemSize() +
_userDataRaw.total()*_userDataRaw.elemSize() +
_laserScanCompressed.total()*_laserScanCompressed.elemSize() +
_laserScanRaw.total()*_laserScanRaw.elemSize();
}
} // namespace rtabmap } // namespace rtabmap

View File

@@ -596,15 +596,17 @@ pcl::TextureMesh::Ptr createTextureMesh(
pcl::PointCloud<pcl::Normal>::Ptr computeNormals( pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
int normalKSearch) int normalKSearch,
const Eigen::Vector3f & viewPoint)
{ {
pcl::IndicesPtr indices(new std::vector<int>); pcl::IndicesPtr indices(new std::vector<int>);
return computeNormals(cloud, indices, normalKSearch); return computeNormals(cloud, indices, normalKSearch, viewPoint);
} }
pcl::PointCloud<pcl::Normal>::Ptr computeNormals( pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
int normalKSearch) int normalKSearch,
const Eigen::Vector3f & viewPoint)
{ {
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>); pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
if(indices->size()) if(indices->size())
@@ -627,6 +629,7 @@ pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
//} //}
n.setSearchMethod (tree); n.setSearchMethod (tree);
n.setKSearch (normalKSearch); n.setKSearch (normalKSearch);
n.setViewPoint(viewPoint[0], viewPoint[1], viewPoint[2]);
n.compute (*normals); n.compute (*normals);
return normals; return normals;
@@ -634,15 +637,17 @@ pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
pcl::PointCloud<pcl::Normal>::Ptr computeNormals( pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
int normalKSearch) int normalKSearch,
const Eigen::Vector3f & viewPoint)
{ {
pcl::IndicesPtr indices(new std::vector<int>); pcl::IndicesPtr indices(new std::vector<int>);
return computeNormals(cloud, indices, normalKSearch); return computeNormals(cloud, indices, normalKSearch, viewPoint);
} }
pcl::PointCloud<pcl::Normal>::Ptr computeNormals( pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
int normalKSearch) int normalKSearch,
const Eigen::Vector3f & viewPoint)
{ {
pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>); pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>);
if(indices->size()) if(indices->size())
@@ -665,6 +670,7 @@ pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
//} //}
n.setSearchMethod (tree); n.setSearchMethod (tree);
n.setKSearch (normalKSearch); n.setKSearch (normalKSearch);
n.setViewPoint(viewPoint[0], viewPoint[1], viewPoint[2]);
n.compute (*normals); n.compute (*normals);
return normals; return normals;
@@ -673,16 +679,18 @@ pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals( pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
float maxDepthChangeFactor, float maxDepthChangeFactor,
float normalSmoothingSize) float normalSmoothingSize,
const Eigen::Vector3f & viewPoint)
{ {
pcl::IndicesPtr indices(new std::vector<int>); pcl::IndicesPtr indices(new std::vector<int>);
return computeFastOrganizedNormals(cloud, indices, maxDepthChangeFactor, normalSmoothingSize); return computeFastOrganizedNormals(cloud, indices, maxDepthChangeFactor, normalSmoothingSize, viewPoint);
} }
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals( pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
float maxDepthChangeFactor, float maxDepthChangeFactor,
float normalSmoothingSize) float normalSmoothingSize,
const Eigen::Vector3f & viewPoint)
{ {
UASSERT(cloud->isOrganized()); UASSERT(cloud->isOrganized());
@@ -698,6 +706,7 @@ pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
//{ //{
// ne.setIndices(indices); // ne.setIndices(indices);
//} //}
ne.setViewPoint(viewPoint[0], viewPoint[1], viewPoint[2]);
ne.compute(*normals); ne.compute(*normals);
return normals; return normals;
@@ -783,6 +792,16 @@ pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mls(
mls.setSearchMethod (tree); mls.setSearchMethod (tree);
mls.process (*cloud_with_normals); mls.process (*cloud_with_normals);
// It seems that returned normals are not normalized!? FIXME: Is it a bug only in PCL 1.7.1?
for(unsigned int i=0; i<cloud_with_normals->size(); ++i)
{
Eigen::Vector3f normal(cloud_with_normals->at(i).normal_x, cloud_with_normals->at(i).normal_y, cloud_with_normals->at(i).normal_z);
normal.normalize();
cloud_with_normals->at(i).normal_x = normal[0];
cloud_with_normals->at(i).normal_y = normal[1];
cloud_with_normals->at(i).normal_z = normal[2];
}
return cloud_with_normals; return cloud_with_normals;
} }

View File

@@ -281,12 +281,14 @@ private:
int _waypointsIndex; int _waypointsIndex;
QMap<int, Signature> _cachedSignatures; QMap<int, Signature> _cachedSignatures;
long _cachedMemoryUsage;
std::map<int, Transform> _currentPosesMap; // <nodeId, pose> std::map<int, Transform> _currentPosesMap; // <nodeId, pose>
std::map<int, Transform> _currentGTPosesMap; // <nodeId, pose> std::map<int, Transform> _currentGTPosesMap; // <nodeId, pose>
std::multimap<int, Link> _currentLinksMap; // <nodeFromId, link> std::multimap<int, Link> _currentLinksMap; // <nodeFromId, link>
std::map<int, int> _currentMapIds; // <nodeId, mapId> std::map<int, int> _currentMapIds; // <nodeId, mapId>
std::map<int, std::string> _currentLabels; // <nodeId, label> std::map<int, std::string> _currentLabels; // <nodeId, label>
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > _createdClouds; std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > _cachedClouds;
long _createdCloudsMemoryUsage;
std::pair<int, std::pair<std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>, pcl::IndicesPtr> > _previousCloud; // used for subtraction std::pair<int, std::pair<std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>, pcl::IndicesPtr> > _previousCloud; // used for subtraction
std::map<int, cv::Mat> _createdScans; std::map<int, cv::Mat> _createdScans;

View File

@@ -224,6 +224,7 @@ public:
// //
bool isImagesKept() const; bool isImagesKept() const;
bool isCloudsKept() const;
float getTimeLimit() const; float getTimeLimit() const;
float getDetectionRate() const; float getDetectionRate() const;
bool isSLAMMode() const; bool isSLAMMode() const;

View File

@@ -102,7 +102,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMLSGrpVisibility())); connect(_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMLSGrpVisibility()));
updateMLSGrpVisibility(); updateMLSGrpVisibility();
connect(_ui->groupBox_gp3, SIGNAL(clicked(bool)), 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_gp3Radius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_gp3Mu, 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->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
@@ -138,6 +138,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
{ {
settings.beginGroup(group); settings.beginGroup(group);
} }
settings.setValue("pipeline", _ui->comboBox_pipeline->currentIndex());
settings.setValue("binary", _ui->checkBox_binary->isChecked()); settings.setValue("binary", _ui->checkBox_binary->isChecked());
settings.setValue("normals_k", _ui->spinBox_normalKSearch->value()); settings.setValue("normals_k", _ui->spinBox_normalKSearch->value());
@@ -169,7 +170,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
settings.setValue("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value()); settings.setValue("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value());
settings.setValue("mls_dilation_iterations", _ui->spinBox_dilationSteps->value()); settings.setValue("mls_dilation_iterations", _ui->spinBox_dilationSteps->value());
settings.setValue("mesh", _ui->groupBox_gp3->isChecked()); settings.setValue("mesh", _ui->groupBox_meshing->isChecked());
settings.setValue("mesh_radius", _ui->doubleSpinBox_gp3Radius->value()); settings.setValue("mesh_radius", _ui->doubleSpinBox_gp3Radius->value());
settings.setValue("mesh_mu", _ui->doubleSpinBox_gp3Mu->value()); settings.setValue("mesh_mu", _ui->doubleSpinBox_gp3Mu->value());
settings.setValue("mesh_decimation_factor", _ui->doubleSpinBox_meshDecimationFactor->value()); settings.setValue("mesh_decimation_factor", _ui->doubleSpinBox_meshDecimationFactor->value());
@@ -193,6 +194,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
settings.beginGroup(group); settings.beginGroup(group);
} }
_ui->comboBox_pipeline->setCurrentIndex(settings.value("pipeline", _ui->comboBox_pipeline->currentIndex()).toInt());
_ui->checkBox_binary->setChecked(settings.value("binary", _ui->checkBox_binary->isChecked()).toBool()); _ui->checkBox_binary->setChecked(settings.value("binary", _ui->checkBox_binary->isChecked()).toBool());
_ui->spinBox_normalKSearch->setValue(settings.value("normals_k", _ui->spinBox_normalKSearch->value()).toInt()); _ui->spinBox_normalKSearch->setValue(settings.value("normals_k", _ui->spinBox_normalKSearch->value()).toInt());
@@ -223,7 +225,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_ui->doubleSpinBox_dilationVoxelSize->setValue(settings.value("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value()).toDouble()); _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->spinBox_dilationSteps->setValue(settings.value("mls_dilation_iterations", _ui->spinBox_dilationSteps->value()).toInt());
_ui->groupBox_gp3->setChecked(settings.value("mesh", _ui->groupBox_gp3->isChecked()).toBool()); _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_gp3Radius->setValue(settings.value("mesh_radius", _ui->doubleSpinBox_gp3Radius->value()).toDouble());
_ui->doubleSpinBox_gp3Mu->setValue(settings.value("mesh_mu", _ui->doubleSpinBox_gp3Mu->value()).toDouble()); _ui->doubleSpinBox_gp3Mu->setValue(settings.value("mesh_mu", _ui->doubleSpinBox_gp3Mu->value()).toDouble());
_ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value("mesh_decimation_factor",_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble()); _ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value("mesh_decimation_factor",_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble());
@@ -272,7 +274,7 @@ void ExportCloudsDialog::restoreDefaults()
_ui->doubleSpinBox_dilationVoxelSize->setValue(0.01); _ui->doubleSpinBox_dilationVoxelSize->setValue(0.01);
_ui->spinBox_dilationSteps->setValue(0); _ui->spinBox_dilationSteps->setValue(0);
_ui->groupBox_gp3->setChecked(false); _ui->groupBox_meshing->setChecked(false);
_ui->doubleSpinBox_gp3Radius->setValue(0.04); _ui->doubleSpinBox_gp3Radius->setValue(0.04);
_ui->doubleSpinBox_gp3Mu->setValue(2.5); _ui->doubleSpinBox_gp3Mu->setValue(2.5);
_ui->doubleSpinBox_meshDecimationFactor->setValue(0.0); _ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
@@ -336,7 +338,7 @@ void ExportCloudsDialog::exportClouds(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds, const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures, const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds, const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory, const QString & workingDirectory,
const ParametersMap & parameters) const ParametersMap & parameters)
{ {
@@ -350,7 +352,7 @@ void ExportCloudsDialog::exportClouds(
poses, poses,
mapIds, mapIds,
cachedSignatures, cachedSignatures,
createdClouds, cachedClouds,
workingDirectory, workingDirectory,
parameters, parameters,
clouds, clouds,
@@ -388,7 +390,7 @@ void ExportCloudsDialog::viewClouds(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds, const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures, const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds, const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory, const QString & workingDirectory,
const ParametersMap & parameters) const ParametersMap & parameters)
{ {
@@ -402,7 +404,7 @@ void ExportCloudsDialog::viewClouds(
poses, poses,
mapIds, mapIds,
cachedSignatures, cachedSignatures,
createdClouds, cachedClouds,
workingDirectory, workingDirectory,
parameters, parameters,
clouds, clouds,
@@ -519,7 +521,7 @@ bool ExportCloudsDialog::getExportedClouds(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds, const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures, const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds, const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory, const QString & workingDirectory,
const ParametersMap & parameters, const ParametersMap & parameters,
std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & cloudsWithNormals, std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & cloudsWithNormals,
@@ -555,7 +557,7 @@ bool ExportCloudsDialog::getExportedClouds(
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds = this->getClouds( std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds = this->getClouds(
poses, poses,
cachedSignatures, cachedSignatures,
createdClouds, cachedClouds,
parameters); parameters);
pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(new pcl::PointCloud<pcl::PointXYZ>);
@@ -608,10 +610,30 @@ bool ExportCloudsDialog::getExportedClouds(
clouds.insert(std::make_pair(0, std::make_pair(assembledCloud, pcl::IndicesPtr(new std::vector<int>)))); clouds.insert(std::make_pair(0, std::make_pair(assembledCloud, pcl::IndicesPtr(new std::vector<int>))));
} }
std::map<int, Transform> viewPoints = poses;
if(_ui->groupBox_mls->isChecked()) if(_ui->groupBox_mls->isChecked())
{ {
_progressDialog->appendText(tr("Smoothing the surface using Moving Least Squares (MLS) algorithm... " _progressDialog->appendText(tr("Smoothing the surface using Moving Least Squares (MLS) algorithm... "
"[search radius=%1m voxel=%2m]").arg(_ui->doubleSpinBox_mlsRadius->value()).arg(_ui->doubleSpinBox_voxelSize_assembled->value())); "[search radius=%1m voxel=%2m]").arg(_ui->doubleSpinBox_mlsRadius->value()).arg(_ui->doubleSpinBox_voxelSize_assembled->value()));
QApplication::processEvents();
QApplication::processEvents();
// Adjust view points with local transforms
for(std::map<int, Transform>::iterator iter= viewPoints.begin(); iter!=viewPoints.end(); ++iter)
{
if(cachedSignatures.contains(iter->first))
{
const SensorData & data = cachedSignatures.find(iter->first)->sensorData();
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
{
iter->second *= data.cameraModels()[0].localTransform();
}
else if(!data.stereoCameraModel().localTransform().isNull())
{
iter->second *= data.stereoCameraModel().localTransform();
}
}
}
} }
//fill cloudWithNormals //fill cloudWithNormals
@@ -661,10 +683,11 @@ bool ExportCloudsDialog::getExportedClouds(
cloudWithNormals, cloudWithNormals,
_ui->doubleSpinBox_voxelSize_assembled->value()); _ui->doubleSpinBox_voxelSize_assembled->value());
} }
_progressDialog->appendText(tr("Update %1 normals with %2 camera views...").arg(cloudWithNormals->size()).arg(poses.size())); _progressDialog->appendText(tr("Update %1 normals with %2 camera views...").arg(cloudWithNormals->size()).arg(poses.size()));
util3d::adjustNormalsToViewPoints( util3d::adjustNormalsToViewPoints(
poses, viewPoints,
rawAssembledCloud, rawAssembledCloud,
rawCameraIndices, rawCameraIndices,
cloudWithNormals); cloudWithNormals);
@@ -692,6 +715,7 @@ bool ExportCloudsDialog::getExportedClouds(
{ {
_progressDialog->appendText(tr("Organized fast mesh... ")); _progressDialog->appendText(tr("Organized fast mesh... "));
QApplication::processEvents(); QApplication::processEvents();
QApplication::processEvents();
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(new pcl::PointCloud<pcl::PointXYZRGBNormal>); pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
std::vector<pcl::Vertices> mergedPolygons; std::vector<pcl::Vertices> mergedPolygons;
@@ -839,6 +863,7 @@ bool ExportCloudsDialog::getExportedClouds(
{ {
_progressDialog->appendText(tr("Greedy projection triangulation... [radius=%1m]").arg(_ui->doubleSpinBox_gp3Radius->value())); _progressDialog->appendText(tr("Greedy projection triangulation... [radius=%1m]").arg(_ui->doubleSpinBox_gp3Radius->value()));
QApplication::processEvents(); QApplication::processEvents();
QApplication::processEvents();
int i=0; int i=0;
for(std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::iterator iter=cloudsWithNormals.begin(); for(std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::iterator iter=cloudsWithNormals.begin();
@@ -1018,7 +1043,7 @@ bool ExportCloudsDialog::getExportedClouds(
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > ExportCloudsDialog::getClouds( std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > ExportCloudsDialog::getClouds(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const QMap<int, Signature> & cachedSignatures, const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds, const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const ParametersMap & parameters) const const ParametersMap & parameters) const
{ {
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds; std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
@@ -1065,7 +1090,22 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
} }
} }
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value()); // view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
if(d.cameraModels().size() && !d.cameraModels()[0].localTransform().isNull())
{
viewPoint[0] = d.cameraModels()[0].localTransform().x();
viewPoint[1] = d.cameraModels()[0].localTransform().y();
viewPoint[2] = d.cameraModels()[0].localTransform().z();
}
else if(!d.stereoCameraModel().localTransform().isNull())
{
viewPoint[0] = d.stereoCameraModel().localTransform().x();
viewPoint[1] = d.stereoCameraModel().localTransform().y();
viewPoint[2] = d.stereoCameraModel().localTransform().z();
}
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), viewPoint);
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud); pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
if(_ui->groupBox_subtraction->isChecked() && if(_ui->groupBox_subtraction->isChecked() &&
@@ -1117,15 +1157,15 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
UERROR("Cloud %d not found in cache!", iter->first); UERROR("Cloud %d not found in cache!", iter->first);
} }
} }
else if(uContains(createdClouds, iter->first)) else if(uContains(cachedClouds, iter->first))
{ {
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals; pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
if(!_ui->groupBox_meshing->isChecked() && if(!_ui->groupBox_meshing->isChecked() &&
_ui->doubleSpinBox_voxelSize_assembled->value() > 0.0) _ui->doubleSpinBox_voxelSize_assembled->value() > 0.0)
{ {
cloudWithoutNormals = util3d::voxelize( cloudWithoutNormals = util3d::voxelize(
createdClouds.at(iter->first).first, cachedClouds.at(iter->first).first,
createdClouds.at(iter->first).second, cachedClouds.at(iter->first).second,
_ui->doubleSpinBox_voxelSize_assembled->value()); _ui->doubleSpinBox_voxelSize_assembled->value());
//generate indices for all points (they are all valid) //generate indices for all points (they are all valid)
@@ -1137,12 +1177,41 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
} }
else else
{ {
cloudWithoutNormals = createdClouds.at(iter->first).first; cloudWithoutNormals = cachedClouds.at(iter->first).first;
indices = createdClouds.at(iter->first).second; indices = cachedClouds.at(iter->first).second;
} }
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value());
// view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
if(cachedSignatures.contains(iter->first))
{
const Signature & s = cachedSignatures.find(iter->first).value();
SensorData d = s.sensorData();
if(d.cameraModels().size() && !d.cameraModels()[0].localTransform().isNull())
{
viewPoint[0] = d.cameraModels()[0].localTransform().x();
viewPoint[1] = d.cameraModels()[0].localTransform().y();
viewPoint[2] = d.cameraModels()[0].localTransform().z();
}
else if(!d.stereoCameraModel().localTransform().isNull())
{
viewPoint[0] = d.stereoCameraModel().localTransform().x();
viewPoint[1] = d.stereoCameraModel().localTransform().y();
viewPoint[2] = d.stereoCameraModel().localTransform().z();
}
}
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()));
}
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), viewPoint);
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud); pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
} }
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()));
}
if(indices->size()) if(indices->size())
{ {
@@ -1165,8 +1234,16 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
if(points>0) if(points>0)
{ {
_progressDialog->appendText(tr("Generated cloud %1 with %2 points and %3 indices (%4/%5).") if(_ui->groupBox_regenerate->isChecked())
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size())); {
_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()));
}
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()));
}
} }
else else
{ {

View File

@@ -63,7 +63,7 @@ public:
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds, const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures, const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds, const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory, const QString & workingDirectory,
const ParametersMap & parameters); const ParametersMap & parameters);
@@ -71,7 +71,7 @@ public:
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds, const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures, const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds, const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory, const QString & workingDirectory,
const ParametersMap & parameters); const ParametersMap & parameters);
@@ -89,13 +89,13 @@ private:
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > getClouds( std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > getClouds(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const QMap<int, Signature> & cachedSignatures, const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds, const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const ParametersMap & parameters) const; const ParametersMap & parameters) const;
bool getExportedClouds( bool getExportedClouds(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds, const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures, const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds, const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory, const QString & workingDirectory,
const ParametersMap & parameters, const ParametersMap & parameters,
std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds, std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds,

View File

@@ -145,6 +145,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_odomImageDepthShow(false), _odomImageDepthShow(false),
_savedMaximized(false), _savedMaximized(false),
_waypointsIndex(0), _waypointsIndex(0),
_cachedMemoryUsage(0),
_createdCloudsMemoryUsage(0),
_odometryCorrection(Transform::getIdentity()), _odometryCorrection(Transform::getIdentity()),
_processingOdometry(false), _processingOdometry(false),
_oneSecondTimer(0), _oneSecondTimer(0),
@@ -552,6 +554,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_ui->statsToolBox->updateStat("GUI/RGB-D cloud/ms", 0.0f); _ui->statsToolBox->updateStat("GUI/RGB-D cloud/ms", 0.0f);
_ui->statsToolBox->updateStat("GUI/RGB-D closure_view/ms", 0.0f); _ui->statsToolBox->updateStat("GUI/RGB-D closure_view/ms", 0.0f);
_ui->statsToolBox->updateStat("GUI/Refresh stats/ms", 0.0f); _ui->statsToolBox->updateStat("GUI/Refresh stats/ms", 0.0f);
_ui->statsToolBox->updateStat("GUI/Cache Data Size/MB", 0.0f);
_ui->statsToolBox->updateStat("GUI/Cache Clouds Size/MB", 0.0f);
this->loadFigures(); this->loadFigures();
connect(_ui->statsToolBox, SIGNAL(figuresSetupChanged()), this, SLOT(configGUIModified())); connect(_ui->statsToolBox, SIGNAL(figuresSetupChanged()), this, SLOT(configGUIModified()));
@@ -1307,13 +1311,26 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
UDEBUG(""); UDEBUG("");
bool highestHypothesisIsSaved = (bool)uValue(stat.data(), Statistics::kLoopHypothesis_reactivated(), 0.0f); bool highestHypothesisIsSaved = (bool)uValue(stat.data(), Statistics::kLoopHypothesis_reactivated(), 0.0f);
bool smallMovement = (bool)uValue(stat.data(), Statistics::kMemorySmall_movement(), 0.0f);
// update cache // update cache
Signature signature; Signature signature;
if(uContains(stat.getSignatures(), stat.refImageId())) if(uContains(stat.getSignatures(), stat.refImageId()))
{ {
signature = stat.getSignatures().at(stat.refImageId()); signature = stat.getSignatures().at(stat.refImageId());
signature.sensorData().uncompressData(); // make sure data are uncompressed signature.sensorData().uncompressData(); // make sure data are uncompressed
_cachedSignatures.insert(signature.id(), signature);
if(!smallMovement)
{
// keep in cache only compressed data
Signature signatureWithoutRawData = signature;
signatureWithoutRawData.sensorData().setImageRaw(cv::Mat());
signatureWithoutRawData.sensorData().setDepthOrRightRaw(cv::Mat());
signatureWithoutRawData.sensorData().setUserDataRaw(cv::Mat());
signatureWithoutRawData.sensorData().setLaserScanRaw(cv::Mat(), 0, 0);
_cachedSignatures.insert(signature.id(), signatureWithoutRawData);
_cachedMemoryUsage += signatureWithoutRawData.sensorData().getMemoryUsed();
}
} }
// For intermediate empty nodes, keep latest image shown // For intermediate empty nodes, keep latest image shown
@@ -1332,7 +1349,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
bool rehearsedSimilarity = (float)uValue(stat.data(), Statistics::kMemoryRehearsal_id(), 0.0f) != 0.0f; bool rehearsedSimilarity = (float)uValue(stat.data(), Statistics::kMemoryRehearsal_id(), 0.0f) != 0.0f;
int proximityTimeDetections = (int)uValue(stat.data(), Statistics::kProximityTime_detections(), 0.0f); int proximityTimeDetections = (int)uValue(stat.data(), Statistics::kProximityTime_detections(), 0.0f);
bool scanMatchingSuccess = (bool)uValue(stat.data(), Statistics::kNeighborLinkRefiningAccepted(), 0.0f); bool scanMatchingSuccess = (bool)uValue(stat.data(), Statistics::kNeighborLinkRefiningAccepted(), 0.0f);
bool smallMovement = (bool)uValue(stat.data(), Statistics::kMemorySmall_movement(), 0.0f);
_ui->label_stats_imageNumber->setText(QString("%1 [%2]").arg(stat.refImageId()).arg(refMapId)); _ui->label_stats_imageNumber->setText(QString("%1 [%2]").arg(stat.refImageId()).arg(refMapId));
if(rehearsalMerged > 0) if(rehearsalMerged > 0)
@@ -1437,8 +1453,9 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
QMap<int, Signature>::iterator iter = _cachedSignatures.find(shownLoopId); QMap<int, Signature>::iterator iter = _cachedSignatures.find(shownLoopId);
if(iter != _cachedSignatures.end()) if(iter != _cachedSignatures.end())
{ {
iter.value().sensorData().uncompressData(); // uncompress after copy to avoid keeping uncompressed data in memory
loopSignature = iter.value(); loopSignature = iter.value();
loopSignature.sensorData().uncompressData();
} }
} }
} }
@@ -1764,7 +1781,11 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
if(!_preferencesDialog->isImagesKept()) if(!_preferencesDialog->isImagesKept())
{ {
_cachedSignatures.clear(); _cachedSignatures.clear();
_cachedMemoryUsage = 0;
} }
_ui->statsToolBox->updateStat("GUI/Cache Data Size/MB", stat.refImageId(), _cachedMemoryUsage/(1024*1024));
_ui->statsToolBox->updateStat("GUI/Cache Clouds Size/MB", stat.refImageId(), _createdCloudsMemoryUsage/(1024*1024));
if(_state != kMonitoring && _state != kDetecting) if(_state != kMonitoring && _state != kDetecting)
{ {
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty()); _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
@@ -1889,13 +1910,13 @@ void MainWindow::updateMapCloud(
_cloudViewer->setCloudOpacity(cloudName, _preferencesDialog->getCloudOpacity(0)); _cloudViewer->setCloudOpacity(cloudName, _preferencesDialog->getCloudOpacity(0));
_cloudViewer->setCloudPointSize(cloudName, _preferencesDialog->getCloudPointSize(0)); _cloudViewer->setCloudPointSize(cloudName, _preferencesDialog->getCloudPointSize(0));
} }
else if(_createdClouds.find(iter->first) == _createdClouds.end() && _cachedSignatures.contains(iter->first)) else if(_cachedClouds.find(iter->first) == _cachedClouds.end() && _cachedSignatures.contains(iter->first))
{ {
if((_cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)) || if((_cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)) ||
_projectionLocalMaps.find(iter->first) == _projectionLocalMaps.end()) _projectionLocalMaps.find(iter->first) == _projectionLocalMaps.end())
{ {
this->createAndAddCloudToMap(iter->first, iter->second, uValue(mapIds, iter->first, -1)); this->createAndAddCloudToMap(iter->first, iter->second, uValue(mapIds, iter->first, -1));
if(_createdClouds.find(iter->first) != _createdClouds.end()) if(viewerClouds.contains(cloudName))
{ {
_cloudViewer->setCloudVisibility(cloudName.c_str(), _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)); _cloudViewer->setCloudVisibility(cloudName.c_str(), _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0));
} }
@@ -1992,8 +2013,8 @@ void MainWindow::updateMapCloud(
// activate actions // activate actions
if(_state != kMonitoring && _state != kDetecting) if(_state != kMonitoring && _state != kDetecting)
{ {
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty()); _ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty()); _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty()); _ui->actionView_scans->setEnabled(!_createdScans.empty());
@@ -2223,11 +2244,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
return; return;
} }
if(_createdClouds.find(nodeId) != _createdClouds.end()) UASSERT(_cachedClouds.find(nodeId) == _cachedClouds.end());
{
UDEBUG("Cloud %d already created.");
return;
}
if((!iter->sensorData().imageCompressed().empty() || !iter->sensorData().imageRaw().empty()) && if((!iter->sensorData().imageCompressed().empty() || !iter->sensorData().imageRaw().empty()) &&
(!iter->sensorData().depthOrRightCompressed().empty() || !iter->sensorData().depthOrRightRaw().empty())) (!iter->sensorData().depthOrRightCompressed().empty() || !iter->sensorData().depthOrRightRaw().empty()))
@@ -2259,6 +2276,21 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
indices.get(), indices.get(),
_preferencesDialog->getAllParameters()); _preferencesDialog->getAllParameters());
// view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
{
viewPoint[0] = data.cameraModels()[0].localTransform().x();
viewPoint[1] = data.cameraModels()[0].localTransform().y();
viewPoint[2] = data.cameraModels()[0].localTransform().z();
}
else if(!data.stereoCameraModel().localTransform().isNull())
{
viewPoint[0] = data.stereoCameraModel().localTransform().x();
viewPoint[1] = data.stereoCameraModel().localTransform().y();
viewPoint[2] = data.stereoCameraModel().localTransform().z();
}
// filtering pipeline // filtering pipeline
if(indices->size() && _preferencesDialog->getMapVoxel() > 0.0) if(indices->size() && _preferencesDialog->getMapVoxel() > 0.0)
{ {
@@ -2353,7 +2385,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
//normals required //normals required
if(_preferencesDialog->getNormalKSearch() > 0) if(_preferencesDialog->getNormalKSearch() > 0)
{ {
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch()); pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch(), viewPoint);
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals); pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
} }
else else
@@ -2411,25 +2443,12 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output; pcl::PointCloud<pcl::PointXYZRGB>::Ptr output;
// we need to extract indices as pcl::OrganizedFastMesh doesn't take indices // we need to extract indices as pcl::OrganizedFastMesh doesn't take indices
output = util3d::extractIndices(cloud, indices, false, true); output = util3d::extractIndices(cloud, indices, false, true);
Eigen::Vector3f viewpoint(0.0f,0.0f,0.0f);
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
{
viewpoint[0] = data.cameraModels()[0].localTransform().x();
viewpoint[1] = data.cameraModels()[0].localTransform().y();
viewpoint[2] = data.cameraModels()[0].localTransform().z();
}
else if(!data.stereoCameraModel().localTransform().isNull())
{
viewpoint[0] = data.stereoCameraModel().localTransform().x();
viewpoint[1] = data.stereoCameraModel().localTransform().y();
viewpoint[2] = data.stereoCameraModel().localTransform().z();
}
std::vector<pcl::Vertices> polygons = util3d::organizedFastMesh( std::vector<pcl::Vertices> polygons = util3d::organizedFastMesh(
output, output,
_preferencesDialog->getCloudMeshingAngle(), _preferencesDialog->getCloudMeshingAngle(),
_preferencesDialog->isCloudMeshingQuad(), _preferencesDialog->isCloudMeshingQuad(),
_preferencesDialog->getCloudMeshingTriangleSize(), _preferencesDialog->getCloudMeshingTriangleSize(),
viewpoint); viewPoint);
if(polygons.size()) if(polygons.size())
{ {
// remove unused vertices to save memory // remove unused vertices to save memory
@@ -2440,9 +2459,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
{ {
UERROR("Adding mesh cloud %d to viewer failed!", nodeId); UERROR("Adding mesh cloud %d to viewer failed!", nodeId);
} }
else else if(_preferencesDialog->isCloudsKept())
{ {
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices))); _cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
} }
} }
} }
@@ -2457,7 +2477,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
if(_preferencesDialog->getNormalKSearch() > 0 && cloudWithNormals->size() == 0) if(_preferencesDialog->getNormalKSearch() > 0 && cloudWithNormals->size() == 0)
{ {
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch()); pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch(), viewPoint);
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals); pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
} }
@@ -2479,9 +2499,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
{ {
UERROR("Adding cloud %d to viewer failed!", nodeId); UERROR("Adding cloud %d to viewer failed!", nodeId);
} }
else else if(_preferencesDialog->isCloudsKept())
{ {
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices))); _cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
} }
} }
else else
@@ -2491,9 +2512,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
{ {
UERROR("Adding cloud %d to viewer failed!", nodeId); UERROR("Adding cloud %d to viewer failed!", nodeId);
} }
else else if(_preferencesDialog->isCloudsKept())
{ {
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices))); _cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
} }
} }
} }
@@ -2965,6 +2987,7 @@ void MainWindow::processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap & eve
(_cachedSignatures.value(iter->first).sensorData().imageCompressed().empty() && !iter->second.sensorData().imageCompressed().empty())) (_cachedSignatures.value(iter->first).sensorData().imageCompressed().empty() && !iter->second.sensorData().imageCompressed().empty()))
{ {
_cachedSignatures.insert(iter->first, iter->second); _cachedSignatures.insert(iter->first, iter->second);
_cachedMemoryUsage += iter->second.sensorData().getMemoryUsed();
++addedSignatures; ++addedSignatures;
} }
_initProgressDialog->incrementStep(); _initProgressDialog->incrementStep();
@@ -2997,6 +3020,7 @@ void MainWindow::processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap & eve
if(!_preferencesDialog->isImagesKept()) if(!_preferencesDialog->isImagesKept())
{ {
_cachedSignatures.clear(); _cachedSignatures.clear();
_cachedMemoryUsage = 0;
} }
if(_state != kMonitoring && _state != kDetecting) if(_state != kMonitoring && _state != kDetecting)
{ {
@@ -4842,7 +4866,9 @@ void MainWindow::anchorCloudsToGroundTruth()
void MainWindow::clearTheCache() void MainWindow::clearTheCache()
{ {
_cachedSignatures.clear(); _cachedSignatures.clear();
_createdClouds.clear(); _cachedMemoryUsage = 0;
_cachedClouds.clear();
_createdCloudsMemoryUsage = 0;
_previousCloud.first = 0; _previousCloud.first = 0;
_previousCloud.second.first.first.reset(); _previousCloud.second.first.first.reset();
_previousCloud.second.first.second.reset(); _previousCloud.second.first.second.reset();
@@ -5250,7 +5276,7 @@ void MainWindow::exportClouds()
_ui->widget_mapVisibility->getVisiblePoses(), _ui->widget_mapVisibility->getVisiblePoses(),
_currentMapIds, _currentMapIds,
_cachedSignatures, _cachedSignatures,
_createdClouds, _cachedClouds,
_preferencesDialog->getWorkingDirectory(), _preferencesDialog->getWorkingDirectory(),
_preferencesDialog->getAllParameters()); _preferencesDialog->getAllParameters());
} }
@@ -5266,7 +5292,7 @@ void MainWindow::viewClouds()
_currentPosesMap, _currentPosesMap,
_currentMapIds, _currentMapIds,
_cachedSignatures, _cachedSignatures,
_createdClouds, _cachedClouds,
_preferencesDialog->getWorkingDirectory(), _preferencesDialog->getWorkingDirectory(),
_preferencesDialog->getAllParameters()); _preferencesDialog->getAllParameters());
@@ -5713,8 +5739,8 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty()); _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
_ui->actionGenerate_map->setEnabled(false); _ui->actionGenerate_map->setEnabled(false);
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty()); _ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty()); _ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty()); _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty()); _ui->actionView_scans->setEnabled(!_createdScans.empty());
@@ -5769,8 +5795,8 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty()); _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
_ui->actionGenerate_map->setEnabled(true); _ui->actionGenerate_map->setEnabled(true);
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty()); _ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty()); _ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty()); _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty()); _ui->actionView_scans->setEnabled(!_createdScans.empty());
@@ -5895,8 +5921,8 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty()); _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
_ui->actionGenerate_map->setEnabled(true); _ui->actionGenerate_map->setEnabled(true);
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty()); _ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty()); _ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty()); _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty()); _ui->actionView_scans->setEnabled(!_createdScans.empty());
@@ -5959,8 +5985,8 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionPost_processing->setEnabled(_cachedSignatures.size() >= 2 && _currentPosesMap.size() >= 2 && _currentLinksMap.size() >= 1); _ui->actionPost_processing->setEnabled(_cachedSignatures.size() >= 2 && _currentPosesMap.size() >= 2 && _currentLinksMap.size() >= 1);
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty()); _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty()); _ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty()); _ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty()); _ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty()); _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty()); _ui->actionView_scans->setEnabled(!_createdScans.empty());

View File

@@ -270,6 +270,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
// General panel // General panel
connect(_ui->general_checkBox_imagesKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel())); connect(_ui->general_checkBox_imagesKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
connect(_ui->general_checkBox_cloudsKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
connect(_ui->checkBox_verticalLayoutUsed, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel())); connect(_ui->checkBox_verticalLayoutUsed, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
connect(_ui->checkBox_imageRejectedShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel())); connect(_ui->checkBox_imageRejectedShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
connect(_ui->checkBox_imageHighestHypShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel())); connect(_ui->checkBox_imageHighestHypShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
@@ -1150,6 +1151,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
if(groupBox->objectName() == _ui->groupBox_generalSettingsGui0->objectName()) if(groupBox->objectName() == _ui->groupBox_generalSettingsGui0->objectName())
{ {
_ui->general_checkBox_imagesKept->setChecked(true); _ui->general_checkBox_imagesKept->setChecked(true);
_ui->general_checkBox_cloudsKept->setChecked(true);
_ui->checkBox_beep->setChecked(false); _ui->checkBox_beep->setChecked(false);
_ui->checkBox_notifyWhenNewGlobalPathIsReceived->setChecked(false); _ui->checkBox_notifyWhenNewGlobalPathIsReceived->setChecked(false);
_ui->checkBox_verticalLayoutUsed->setChecked(true); _ui->checkBox_verticalLayoutUsed->setChecked(true);
@@ -1448,7 +1450,9 @@ void PreferencesDialog::loadConfigFrom()
QString path = QFileDialog::getOpenFileName(this, tr("Load settings..."), this->getWorkingDirectory(), "*.ini"); QString path = QFileDialog::getOpenFileName(this, tr("Load settings..."), this->getWorkingDirectory(), "*.ini");
if(!path.isEmpty()) if(!path.isEmpty())
{ {
_ui->checkBox_useOdomFeatures->blockSignals(true);
this->readSettings(path); this->readSettings(path);
_ui->checkBox_useOdomFeatures->blockSignals(false);
} }
} }
@@ -1501,6 +1505,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
settings.beginGroup("Gui"); settings.beginGroup("Gui");
settings.beginGroup("General"); settings.beginGroup("General");
_ui->general_checkBox_imagesKept->setChecked(settings.value("imagesKept", _ui->general_checkBox_imagesKept->isChecked()).toBool()); _ui->general_checkBox_imagesKept->setChecked(settings.value("imagesKept", _ui->general_checkBox_imagesKept->isChecked()).toBool());
_ui->general_checkBox_cloudsKept->setChecked(settings.value("cloudsKept", _ui->general_checkBox_cloudsKept->isChecked()).toBool());
_ui->comboBox_loggerLevel->setCurrentIndex(settings.value("loggerLevel", _ui->comboBox_loggerLevel->currentIndex()).toInt()); _ui->comboBox_loggerLevel->setCurrentIndex(settings.value("loggerLevel", _ui->comboBox_loggerLevel->currentIndex()).toInt());
_ui->comboBox_loggerEventLevel->setCurrentIndex(settings.value("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex()).toInt()); _ui->comboBox_loggerEventLevel->setCurrentIndex(settings.value("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex()).toInt());
_ui->comboBox_loggerPauseLevel->setCurrentIndex(settings.value("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex()).toInt()); _ui->comboBox_loggerPauseLevel->setCurrentIndex(settings.value("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex()).toInt());
@@ -1904,6 +1909,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
settings.beginGroup("General"); settings.beginGroup("General");
settings.remove(""); settings.remove("");
settings.setValue("imagesKept", _ui->general_checkBox_imagesKept->isChecked()); settings.setValue("imagesKept", _ui->general_checkBox_imagesKept->isChecked());
settings.setValue("cloudsKept", _ui->general_checkBox_cloudsKept->isChecked());
settings.setValue("loggerLevel", _ui->comboBox_loggerLevel->currentIndex()); settings.setValue("loggerLevel", _ui->comboBox_loggerLevel->currentIndex());
settings.setValue("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex()); settings.setValue("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex());
settings.setValue("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex()); settings.setValue("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex());
@@ -3440,8 +3446,8 @@ void PreferencesDialog::useOdomFeatures()
if(this->isVisible() && _ui->checkBox_useOdomFeatures->isChecked()) if(this->isVisible() && _ui->checkBox_useOdomFeatures->isChecked())
{ {
int r = QMessageBox::question(this, tr("Using odometry features for vocabulary..."), int r = QMessageBox::question(this, tr("Using odometry features for vocabulary..."),
tr("Do you want to match feature parameters " tr("Do you want to match vocabulary feature parameters "
"below with corresponding ones used for odometry?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); "with corresponding ones used for odometry?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if(r == QMessageBox::Yes) if(r == QMessageBox::Yes)
{ {
@@ -4270,6 +4276,10 @@ bool PreferencesDialog::isImagesKept() const
{ {
return _ui->general_checkBox_imagesKept->isChecked(); return _ui->general_checkBox_imagesKept->isChecked();
} }
bool PreferencesDialog::isCloudsKept() const
{
return _ui->general_checkBox_cloudsKept->isChecked();
}
float PreferencesDialog::getTimeLimit() const float PreferencesDialog::getTimeLimit() const
{ {
return _ui->general_doubleSpinBox_timeThr->value(); return _ui->general_doubleSpinBox_timeThr->value();

View File

@@ -63,7 +63,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-847</y> <y>0</y>
<width>686</width> <width>686</width>
<height>2023</height> <height>2023</height>
</rect> </rect>
@@ -86,7 +86,7 @@
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="page_22"> <widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1"> <layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
@@ -121,14 +121,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="2" column="0">
<widget class="QCheckBox" name="checkBox_beep"> <widget class="QCheckBox" name="checkBox_beep">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QLabel" name="label_88"> <widget class="QLabel" name="label_88">
<property name="text"> <property name="text">
<string>Beep! on special events (finished processing the data set, an error has occured, ...).</string> <string>Beep! on special events (finished processing the data set, an error has occured, ...).</string>
@@ -141,7 +141,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QLabel" name="label_102"> <widget class="QLabel" name="label_102">
<property name="text"> <property name="text">
<string>Notify when a new global path is received.</string> <string>Notify when a new global path is received.</string>
@@ -154,7 +154,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QCheckBox" name="checkBox_notifyWhenNewGlobalPathIsReceived"> <widget class="QCheckBox" name="checkBox_notifyWhenNewGlobalPathIsReceived">
<property name="text"> <property name="text">
<string/> <string/>
@@ -164,6 +164,29 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QLabel" name="label_313">
<property name="text">
<string>Insert created clouds in the GUI cache to avoid regenerating clouds on export.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="general_checkBox_cloudsKept">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>