mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 17:40:23 +08:00
Export: for min polygon cluster size, added option -1 to just keep the largest cluster
This commit is contained in:
@@ -193,6 +193,7 @@ CloudViewer::CloudViewer(QWidget *parent) :
|
||||
_aSetBackgroundColor(0),
|
||||
_aSetRenderingRate(0),
|
||||
_aSetLighting(0),
|
||||
_aSetFlatShading(0),
|
||||
_aSetEdgeVisibility(0),
|
||||
_aBackfaceCulling(0),
|
||||
_menu(0),
|
||||
@@ -314,6 +315,9 @@ void CloudViewer::createMenu()
|
||||
_aSetLighting = new QAction("Lighting", this);
|
||||
_aSetLighting->setCheckable(true);
|
||||
_aSetLighting->setChecked(false);
|
||||
_aSetFlatShading = new QAction("Flat Shading", this);
|
||||
_aSetFlatShading->setCheckable(true);
|
||||
_aSetFlatShading->setChecked(true);
|
||||
_aSetEdgeVisibility = new QAction("Show edges", this);
|
||||
_aSetEdgeVisibility->setCheckable(true);
|
||||
_aSetEdgeVisibility->setChecked(false);
|
||||
@@ -357,6 +361,7 @@ void CloudViewer::createMenu()
|
||||
_menu->addAction(_aSetBackgroundColor);
|
||||
_menu->addAction(_aSetRenderingRate);
|
||||
_menu->addAction(_aSetLighting);
|
||||
_menu->addAction(_aSetFlatShading);
|
||||
_menu->addAction(_aSetEdgeVisibility);
|
||||
_menu->addAction(_aBackfaceCulling);
|
||||
}
|
||||
@@ -621,6 +626,7 @@ bool CloudViewer::addCloudMesh(
|
||||
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()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG);
|
||||
_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()->SetFrontfaceCulling(_frontfaceCulling);
|
||||
@@ -646,6 +652,7 @@ bool CloudViewer::addCloudMesh(
|
||||
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()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG);
|
||||
_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()->SetFrontfaceCulling(_frontfaceCulling);
|
||||
@@ -671,6 +678,7 @@ bool CloudViewer::addCloudMesh(
|
||||
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()->SetInterpolation(_aSetFlatShading->isChecked()?VTK_FLAT:VTK_PHONG);
|
||||
_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()->SetFrontfaceCulling(_frontfaceCulling);
|
||||
@@ -721,6 +729,7 @@ bool CloudViewer::addCloudTextureMesh(
|
||||
if(this->addTextureMesh(*textureMesh, texture, id))
|
||||
{
|
||||
_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()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
||||
@@ -1007,6 +1016,7 @@ bool CloudViewer::addTextureMesh (
|
||||
(*_visualizer->getCloudActorMap())[id].viewpoint_transformation_ = transformation;
|
||||
|
||||
_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()->SetBackfaceCulling(_aBackfaceCulling->isChecked());
|
||||
_visualizer->getCloudActorMap()->find(id)->second.actor->GetProperty()->SetFrontfaceCulling(_frontfaceCulling);
|
||||
@@ -1614,6 +1624,17 @@ void CloudViewer::setLighting(bool on)
|
||||
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)
|
||||
{
|
||||
_aSetEdgeVisibility->setChecked(visible);
|
||||
@@ -2363,6 +2384,10 @@ void CloudViewer::handleAction(QAction * a)
|
||||
{
|
||||
this->setLighting(_aSetLighting->isChecked());
|
||||
}
|
||||
else if(a == _aSetFlatShading)
|
||||
{
|
||||
this->setShading(_aSetFlatShading->isChecked());
|
||||
}
|
||||
else if(a == _aSetEdgeVisibility)
|
||||
{
|
||||
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_transferColorRadius, SIGNAL(valueChanged(double)), 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, SLOT(updateReconstructionFlavor()));
|
||||
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()
|
||||
{
|
||||
_ui->comboBox_pipeline->setCurrentIndex(0);
|
||||
_ui->comboBox_pipeline->setCurrentIndex(1);
|
||||
_ui->checkBox_binary->setChecked(true);
|
||||
_ui->spinBox_normalKSearch->setValue(10);
|
||||
|
||||
@@ -421,12 +422,13 @@ void ExportCloudsDialog::restoreDefaults()
|
||||
_ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
|
||||
_ui->doubleSpinBox_transferColorRadius->setValue(0.0);
|
||||
_ui->checkBox_cleanMesh->setChecked(true);
|
||||
_ui->spinBox_mesh_minClusterSize->setValue(0);
|
||||
|
||||
_ui->comboBox_meshingApproach->setCurrentIndex(1);
|
||||
|
||||
_ui->checkBox_textureMapping->setChecked(false);
|
||||
_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_mesh_angleTolerance->setValue(15.0);
|
||||
@@ -472,7 +474,7 @@ void ExportCloudsDialog::updateReconstructionFlavor()
|
||||
_ui->doubleSpinBox_meshDecimationFactor->value()!=0.0 ||
|
||||
_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);
|
||||
}
|
||||
}
|
||||
@@ -1173,7 +1175,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
_ui->spinBox_mesh_triangleSize->value(),
|
||||
viewpoint);
|
||||
|
||||
if(_ui->spinBox_mesh_minClusterSize->value())
|
||||
if(_ui->spinBox_mesh_minClusterSize->value() != 0)
|
||||
{
|
||||
_progressDialog->appendText(tr("Filter small polygon clusters..."));
|
||||
QApplication::processEvents();
|
||||
@@ -1187,28 +1189,55 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
vertexToPolygons);
|
||||
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
||||
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());
|
||||
int oi=0;
|
||||
for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
|
||||
if(_ui->spinBox_mesh_minClusterSize->value() < 0)
|
||||
{
|
||||
for(std::list<int>::iterator jter=iter->begin(); jter!=iter->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)
|
||||
{
|
||||
filteredPolygons[oi++] = polygons.at(*jter);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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++] = polygons.at(*jter);
|
||||
}
|
||||
}
|
||||
filteredPolygons.resize(oi);
|
||||
}
|
||||
int before = (int)polygons.size();
|
||||
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());
|
||||
_progressDialog->appendText(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();
|
||||
}
|
||||
|
||||
@@ -1525,21 +1554,49 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
vertexToPolygons);
|
||||
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
||||
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());
|
||||
int oi=0;
|
||||
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)
|
||||
{
|
||||
filteredPolygons[oi++] = mesh->polygons.at(*jter);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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-oi));
|
||||
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-(int)mesh->polygons.size()));
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
@@ -1706,18 +1763,44 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
(int)textureMesh->cloud.data.size()/textureMesh->cloud.point_step,
|
||||
neighbors,
|
||||
vertexToPolygons);
|
||||
|
||||
std::list<std::list<int> > clusters = util3d::clusterPolygons(
|
||||
neighbors,
|
||||
_ui->spinBox_mesh_minClusterSize->value());
|
||||
_ui->spinBox_mesh_minClusterSize->value()<0?0:_ui->spinBox_mesh_minClusterSize->value());
|
||||
|
||||
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)
|
||||
{
|
||||
validPolygons.insert(*jter);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
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">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-1504</y>
|
||||
<y>-1643</y>
|
||||
<width>773</width>
|
||||
<height>2810</height>
|
||||
</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">
|
||||
<item row="8" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_mesh_minClusterSize">
|
||||
<property name="minimum">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
<number>99999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1261,7 +1264,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_meshDecimation_2">
|
||||
<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 name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -1317,7 +1320,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user