mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-03 01:50:24 +08:00
Export: for min polygon cluster size, added option -1 to just keep the largest cluster
This commit is contained in:
@@ -247,6 +247,7 @@ public:
|
|||||||
void setBackfaceCulling(bool enabled, bool frontfaceCulling);
|
void setBackfaceCulling(bool enabled, bool frontfaceCulling);
|
||||||
void setRenderingRate(double rate);
|
void setRenderingRate(double rate);
|
||||||
void setLighting(bool on);
|
void setLighting(bool on);
|
||||||
|
void setShading(bool on);
|
||||||
void setEdgeVisibility(bool visible);
|
void setEdgeVisibility(bool visible);
|
||||||
double getRenderingRate() const;
|
double getRenderingRate() const;
|
||||||
|
|
||||||
@@ -318,6 +319,7 @@ private:
|
|||||||
QAction * _aSetBackgroundColor;
|
QAction * _aSetBackgroundColor;
|
||||||
QAction * _aSetRenderingRate;
|
QAction * _aSetRenderingRate;
|
||||||
QAction * _aSetLighting;
|
QAction * _aSetLighting;
|
||||||
|
QAction * _aSetFlatShading;
|
||||||
QAction * _aSetEdgeVisibility;
|
QAction * _aSetEdgeVisibility;
|
||||||
QAction * _aBackfaceCulling;
|
QAction * _aBackfaceCulling;
|
||||||
QMenu * _menu;
|
QMenu * _menu;
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ CloudViewer::CloudViewer(QWidget *parent) :
|
|||||||
_aSetBackgroundColor(0),
|
_aSetBackgroundColor(0),
|
||||||
_aSetRenderingRate(0),
|
_aSetRenderingRate(0),
|
||||||
_aSetLighting(0),
|
_aSetLighting(0),
|
||||||
|
_aSetFlatShading(0),
|
||||||
_aSetEdgeVisibility(0),
|
_aSetEdgeVisibility(0),
|
||||||
_aBackfaceCulling(0),
|
_aBackfaceCulling(0),
|
||||||
_menu(0),
|
_menu(0),
|
||||||
@@ -314,6 +315,9 @@ void CloudViewer::createMenu()
|
|||||||
_aSetLighting = new QAction("Lighting", this);
|
_aSetLighting = new QAction("Lighting", this);
|
||||||
_aSetLighting->setCheckable(true);
|
_aSetLighting->setCheckable(true);
|
||||||
_aSetLighting->setChecked(false);
|
_aSetLighting->setChecked(false);
|
||||||
|
_aSetFlatShading = new QAction("Flat Shading", this);
|
||||||
|
_aSetFlatShading->setCheckable(true);
|
||||||
|
_aSetFlatShading->setChecked(true);
|
||||||
_aSetEdgeVisibility = new QAction("Show edges", this);
|
_aSetEdgeVisibility = new QAction("Show edges", this);
|
||||||
_aSetEdgeVisibility->setCheckable(true);
|
_aSetEdgeVisibility->setCheckable(true);
|
||||||
_aSetEdgeVisibility->setChecked(false);
|
_aSetEdgeVisibility->setChecked(false);
|
||||||
@@ -357,6 +361,7 @@ void CloudViewer::createMenu()
|
|||||||
_menu->addAction(_aSetBackgroundColor);
|
_menu->addAction(_aSetBackgroundColor);
|
||||||
_menu->addAction(_aSetRenderingRate);
|
_menu->addAction(_aSetRenderingRate);
|
||||||
_menu->addAction(_aSetLighting);
|
_menu->addAction(_aSetLighting);
|
||||||
|
_menu->addAction(_aSetFlatShading);
|
||||||
_menu->addAction(_aSetEdgeVisibility);
|
_menu->addAction(_aSetEdgeVisibility);
|
||||||
_menu->addAction(_aBackfaceCulling);
|
_menu->addAction(_aBackfaceCulling);
|
||||||
}
|
}
|
||||||
@@ -621,6 +626,7 @@ bool CloudViewer::addCloudMesh(
|
|||||||
if(_visualizer->addPolygonMesh<pcl::PointXYZ>(cloud, polygons, id))
|
if(_visualizer->addPolygonMesh<pcl::PointXYZ>(cloud, polygons, id))
|
||||||
{
|
{
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
||||||
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG);
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
||||||
@@ -646,6 +652,7 @@ bool CloudViewer::addCloudMesh(
|
|||||||
if(_visualizer->addPolygonMesh<pcl::PointXYZRGB>(cloud, polygons, id))
|
if(_visualizer->addPolygonMesh<pcl::PointXYZRGB>(cloud, polygons, id))
|
||||||
{
|
{
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
||||||
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG);
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
||||||
@@ -671,6 +678,7 @@ bool CloudViewer::addCloudMesh(
|
|||||||
if(_visualizer->addPolygonMesh<pcl::PointXYZRGBNormal>(cloud, polygons, id))
|
if(_visualizer->addPolygonMesh<pcl::PointXYZRGBNormal>(cloud, polygons, id))
|
||||||
{
|
{
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
||||||
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG);
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
||||||
@@ -721,6 +729,7 @@ bool CloudViewer::addCloudTextureMesh(
|
|||||||
if(this->addTextureMesh(*textureMesh, texture, id))
|
if(this->addTextureMesh(*textureMesh, texture, id))
|
||||||
{
|
{
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
||||||
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG);
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
||||||
@@ -1007,6 +1016,7 @@ bool CloudViewer::addTextureMesh (
|
|||||||
(*_visualizer->getCloudActorMap())[id].viewpoint_transformation_ = transformation;
|
(*_visualizer->getCloudActorMap())[id].viewpoint_transformation_ = transformation;
|
||||||
|
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetLighting(_aSetLighting->isChecked());
|
||||||
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG);
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
||||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
||||||
@@ -1614,6 +1624,17 @@ void CloudViewer::setLighting(bool on)
|
|||||||
this->update();
|
this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CloudViewer::setShading(bool on)
|
||||||
|
{
|
||||||
|
_aSetFlatShading->setChecked(on);
|
||||||
|
pcl::visualization::CloudActorMapPtr cloudActorMap = _visualizer->getCloudActorMap();
|
||||||
|
for(pcl::visualization::CloudActorMap::iterator iter=cloudActorMap->begin(); iter!=cloudActorMap->end(); ++iter)
|
||||||
|
{
|
||||||
|
iter->second.actor->GetProperty()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG); // VTK_FLAT - VTK_GOURAUD - VTK_PHONG
|
||||||
|
}
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
|
||||||
void CloudViewer::setEdgeVisibility(bool visible)
|
void CloudViewer::setEdgeVisibility(bool visible)
|
||||||
{
|
{
|
||||||
_aSetEdgeVisibility->setChecked(visible);
|
_aSetEdgeVisibility->setChecked(visible);
|
||||||
@@ -2363,6 +2384,10 @@ void CloudViewer::handleAction(QAction * a)
|
|||||||
{
|
{
|
||||||
this->setLighting(_aSetLighting->isChecked());
|
this->setLighting(_aSetLighting->isChecked());
|
||||||
}
|
}
|
||||||
|
else if(a == _aSetFlatShading)
|
||||||
|
{
|
||||||
|
this->setShading(_aSetFlatShading->isChecked());
|
||||||
|
}
|
||||||
else if(a == _aSetEdgeVisibility)
|
else if(a == _aSetEdgeVisibility)
|
||||||
{
|
{
|
||||||
this->setEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
this->setEdgeVisibility(_aSetEdgeVisibility->isChecked());
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
|||||||
connect(_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(double)), this, SLOT(updateReconstructionFlavor()));
|
connect(_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(double)), this, SLOT(updateReconstructionFlavor()));
|
||||||
connect(_ui->doubleSpinBox_transferColorRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_transferColorRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->checkBox_cleanMesh, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->checkBox_cleanMesh, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->spinBox_mesh_minClusterSize, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
|
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
|
||||||
connect(_ui->comboBox_meshingTextureFormat, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->comboBox_meshingTextureFormat, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
||||||
@@ -369,7 +370,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
|
|
||||||
void ExportCloudsDialog::restoreDefaults()
|
void ExportCloudsDialog::restoreDefaults()
|
||||||
{
|
{
|
||||||
_ui->comboBox_pipeline->setCurrentIndex(0);
|
_ui->comboBox_pipeline->setCurrentIndex(1);
|
||||||
_ui->checkBox_binary->setChecked(true);
|
_ui->checkBox_binary->setChecked(true);
|
||||||
_ui->spinBox_normalKSearch->setValue(10);
|
_ui->spinBox_normalKSearch->setValue(10);
|
||||||
|
|
||||||
@@ -421,12 +422,13 @@ void ExportCloudsDialog::restoreDefaults()
|
|||||||
_ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
|
_ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
|
||||||
_ui->doubleSpinBox_transferColorRadius->setValue(0.0);
|
_ui->doubleSpinBox_transferColorRadius->setValue(0.0);
|
||||||
_ui->checkBox_cleanMesh->setChecked(true);
|
_ui->checkBox_cleanMesh->setChecked(true);
|
||||||
|
_ui->spinBox_mesh_minClusterSize->setValue(0);
|
||||||
|
|
||||||
_ui->comboBox_meshingApproach->setCurrentIndex(1);
|
_ui->comboBox_meshingApproach->setCurrentIndex(1);
|
||||||
|
|
||||||
_ui->checkBox_textureMapping->setChecked(false);
|
_ui->checkBox_textureMapping->setChecked(false);
|
||||||
_ui->comboBox_meshingTextureFormat->setCurrentIndex(0);
|
_ui->comboBox_meshingTextureFormat->setCurrentIndex(0);
|
||||||
_ui->comboBox_meshingTextureSize->setCurrentIndex(4); // 2048
|
_ui->comboBox_meshingTextureSize->setCurrentIndex(5); // 4096
|
||||||
_ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0);
|
_ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0);
|
||||||
|
|
||||||
_ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0);
|
_ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0);
|
||||||
@@ -472,7 +474,7 @@ void ExportCloudsDialog::updateReconstructionFlavor()
|
|||||||
_ui->doubleSpinBox_meshDecimationFactor->value()!=0.0 ||
|
_ui->doubleSpinBox_meshDecimationFactor->value()!=0.0 ||
|
||||||
_ui->checkBox_textureMapping->isChecked());
|
_ui->checkBox_textureMapping->isChecked());
|
||||||
|
|
||||||
_ui->spinBox_mesh_minClusterSize->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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1173,7 +1175,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
_ui->spinBox_mesh_triangleSize->value(),
|
_ui->spinBox_mesh_triangleSize->value(),
|
||||||
viewpoint);
|
viewpoint);
|
||||||
|
|
||||||
if(_ui->spinBox_mesh_minClusterSize->value())
|
if(_ui->spinBox_mesh_minClusterSize->value() != 0)
|
||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Filter small polygon clusters..."));
|
_progressDialog->appendText(tr("Filter small polygon clusters..."));
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
@@ -1187,8 +1189,34 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
vertexToPolygons);
|
vertexToPolygons);
|
||||||
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
||||||
neighbors,
|
neighbors,
|
||||||
_ui->spinBox_mesh_minClusterSize->value());
|
_ui->spinBox_mesh_minClusterSize->value()<0?0:_ui->spinBox_mesh_minClusterSize->value());
|
||||||
|
|
||||||
std::vector<pcl::Vertices> filteredPolygons(polygons.size());
|
std::vector<pcl::Vertices> filteredPolygons(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++] = polygons.at(*jter);
|
||||||
|
}
|
||||||
|
filteredPolygons.resize(oi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int oi=0;
|
int oi=0;
|
||||||
for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
||||||
{
|
{
|
||||||
@@ -1198,17 +1226,18 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
filteredPolygons.resize(oi);
|
filteredPolygons.resize(oi);
|
||||||
|
}
|
||||||
int before = (int)polygons.size();
|
int before = (int)polygons.size();
|
||||||
polygons = filteredPolygons;
|
polygons = filteredPolygons;
|
||||||
|
|
||||||
if(oi == 0)
|
if(polygons.size() == 0)
|
||||||
{
|
{
|
||||||
std::string msg = uFormat("All %d polygons filtered after polygon cluster filtering. Cluster minimum size is %d.", before, _ui->spinBox_mesh_minClusterSize->value());
|
std::string msg = uFormat("All %d polygons filtered after polygon cluster filtering. Cluster minimum size is %d.", before, _ui->spinBox_mesh_minClusterSize->value());
|
||||||
_progressDialog->appendText(msg.c_str());
|
_progressDialog->appendText(msg.c_str());
|
||||||
UWARN(msg.c_str());
|
UWARN(msg.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-oi));
|
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-(int)polygons.size()));
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1525,21 +1554,49 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
vertexToPolygons);
|
vertexToPolygons);
|
||||||
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
||||||
neighbors,
|
neighbors,
|
||||||
_ui->spinBox_mesh_minClusterSize->value());
|
_ui->spinBox_mesh_minClusterSize->value()<0?0:_ui->spinBox_mesh_minClusterSize->value());
|
||||||
|
|
||||||
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
||||||
int oi=0;
|
if(_ui->spinBox_mesh_minClusterSize->value() < 0)
|
||||||
for(std::list<std::list<int> >::iterator kter=clusters.begin(); kter!=clusters.end(); ++kter)
|
|
||||||
{
|
{
|
||||||
for(std::list<int>::iterator jter=kter->begin(); jter!=kter->end(); ++jter)
|
// 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[oi++] = mesh->polygons.at(*jter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filteredPolygons.resize(oi);
|
filteredPolygons.resize(oi);
|
||||||
|
}
|
||||||
|
|
||||||
int before = (int)mesh->polygons.size();
|
int before = (int)mesh->polygons.size();
|
||||||
mesh->polygons = filteredPolygons;
|
mesh->polygons = filteredPolygons;
|
||||||
|
|
||||||
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-oi));
|
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-(int)mesh->polygons.size()));
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1706,18 +1763,44 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
(int)textureMesh->cloud.data.size()/textureMesh->cloud.point_step,
|
(int)textureMesh->cloud.data.size()/textureMesh->cloud.point_step,
|
||||||
neighbors,
|
neighbors,
|
||||||
vertexToPolygons);
|
vertexToPolygons);
|
||||||
|
|
||||||
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
||||||
neighbors,
|
neighbors,
|
||||||
_ui->spinBox_mesh_minClusterSize->value());
|
_ui->spinBox_mesh_minClusterSize->value()<0?0:_ui->spinBox_mesh_minClusterSize->value());
|
||||||
|
|
||||||
std::set<int> validPolygons;
|
std::set<int> validPolygons;
|
||||||
for(std::list<std::list<int> >::iterator kter=clusters.begin(); kter!=clusters.end(); ++kter)
|
if(_ui->spinBox_mesh_minClusterSize->value() < 0)
|
||||||
{
|
{
|
||||||
for(std::list<int>::iterator jter=kter->begin(); jter!=kter->end(); ++jter)
|
// 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())
|
||||||
|
{
|
||||||
|
for(std::list<int>::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter)
|
||||||
{
|
{
|
||||||
validPolygons.insert(*jter);
|
validPolygons.insert(*jter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
validPolygons.insert(*jter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(validPolygons.size() == 0)
|
if(validPolygons.size() == 0)
|
||||||
{
|
{
|
||||||
std::string msg = uFormat("All %d polygons filtered after polygon cluster filtering. Cluster minimum size is %d.",totalSize, _ui->spinBox_mesh_minClusterSize->value());
|
std::string msg = uFormat("All %d polygons filtered after polygon cluster filtering. Cluster minimum size is %d.",totalSize, _ui->spinBox_mesh_minClusterSize->value());
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>-1504</y>
|
<y>-1643</y>
|
||||||
<width>773</width>
|
<width>773</width>
|
||||||
<height>2810</height>
|
<height>2810</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -1107,8 +1107,11 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<layout class="QGridLayout" name="gridLayout_10" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_10" columnstretch="0,1">
|
||||||
<item row="8" column="0">
|
<item row="8" column="0">
|
||||||
<widget class="QSpinBox" name="spinBox_mesh_minClusterSize">
|
<widget class="QSpinBox" name="spinBox_mesh_minClusterSize">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>999</number>
|
<number>99999</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -1261,7 +1264,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<item row="6" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QLabel" name="label_meshDecimation_2">
|
<widget class="QLabel" name="label_meshDecimation_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Radius used to transfer color from original cloud to resampled reconstructed surface (e.g., Poisson or mesh decimation). Negative means disabled, 0 means take the nearest point.</string>
|
<string>Transferring color radius. Radius used to transfer color from original cloud to resampled reconstructed surface (e.g., Poisson or mesh decimation). Negative means disabled, 0 means take the nearest point.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -1317,7 +1320,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<item row="8" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QLabel" name="label_16">
|
<widget class="QLabel" name="label_16">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Minimum polygon cluster size.</string>
|
<string>Minimum polygon cluster size (-1 means that only the biggest cluster is kept).</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user