From c3aeae5ed734e75918230e175c948b0c6c74d659 Mon Sep 17 00:00:00 2001 From: matlabbe Date: Thu, 15 Jun 2017 14:10:08 -0400 Subject: [PATCH] Moved clean texture mesh stuff from ExportCloudsDialog to util3d::cleanTextureMesh() --- corelib/include/rtabmap/core/util3d_surface.h | 9 +- corelib/src/util3d_surface.cpp | 133 ++++++++++++++++ guilib/src/ExportCloudsDialog.cpp | 143 ++---------------- 3 files changed, 154 insertions(+), 131 deletions(-) diff --git a/corelib/include/rtabmap/core/util3d_surface.h b/corelib/include/rtabmap/core/util3d_surface.h index 8ef3abcc..a2fc915b 100644 --- a/corelib/include/rtabmap/core/util3d_surface.h +++ b/corelib/include/rtabmap/core/util3d_surface.h @@ -161,6 +161,13 @@ pcl::TextureMesh::Ptr RTABMAP_EXP createTextureMesh( const ProgressState * state = 0, std::vector > * vertexToPixels = 0); +/** + * Remove not textured polygon clusters. If minClusterSize<0, only the largest cluster is kept. + */ +void RTABMAP_EXP cleanTextureMesh( + pcl::TextureMesh & textureMesh, + int minClusterSize); + pcl::TextureMesh::Ptr RTABMAP_EXP concatenateTextureMeshes( const std::list & meshes); @@ -168,7 +175,7 @@ void RTABMAP_EXP concatenateTextureMaterials( pcl::TextureMesh & mesh, const cv::Size & imageSize, int textureSize, int maxTextures, float & scale, std::vector * materialsKept=0); -/* +/** * Merge all textures in the mesh into "textureCount" textures of size "textureSize". * @return merged textures corresponding to new materials set in TextureMesh */ diff --git a/corelib/src/util3d_surface.cpp b/corelib/src/util3d_surface.cpp index 525123a4..fd13ea57 100644 --- a/corelib/src/util3d_surface.cpp +++ b/corelib/src/util3d_surface.cpp @@ -840,6 +840,139 @@ pcl::TextureMesh::Ptr createTextureMesh( return textureMesh; } +void cleanTextureMesh( + pcl::TextureMesh & textureMesh, + int minClusterSize) +{ + UDEBUG("minClusterSize=%d", minClusterSize); + // Remove occluded polygons (polygons with no texture) + if(textureMesh.tex_coordinates.size()) + { + // assume last texture is the occluded texture + textureMesh.tex_coordinates.pop_back(); + textureMesh.tex_polygons.pop_back(); + textureMesh.tex_materials.pop_back(); + + if(minClusterSize!=0) + { + // concatenate all polygons + unsigned int totalSize = 0; + for(unsigned int t=0; t allPolygons(totalSize); + int oi=0; + for(unsigned int t=0; t > neighbors; + std::vector > vertexToPolygons; + util3d::createPolygonIndexes(allPolygons, + (int)textureMesh.cloud.data.size()/textureMesh.cloud.point_step, + neighbors, + vertexToPolygons); + + std::list > clusters = util3d::clusterPolygons( + neighbors, + minClusterSize<0?0:minClusterSize); + + std::set validPolygons; + if(minClusterSize < 0) + { + // only keep the biggest cluster + std::list >::iterator biggestClusterIndex = clusters.end(); + unsigned int biggestClusterSize = 0; + for(std::list >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter) + { + if(iter->size() > biggestClusterSize) + { + biggestClusterIndex = iter; + biggestClusterSize = iter->size(); + } + } + if(biggestClusterIndex != clusters.end()) + { + for(std::list::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter) + { + validPolygons.insert(*jter); + } + } + } + else + { + for(std::list >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter) + { + for(std::list::iterator jter=iter->begin(); jter!=iter->end(); ++jter) + { + validPolygons.insert(*jter); + } + } + } + + if(validPolygons.size() == 0) + { + UWARN("All %d polygons filtered after polygon cluster filtering. Cluster minimum size is %d.",totalSize, minClusterSize); + } + + // for each texture + unsigned int allPolygonsIndex = 0; + for(unsigned int t=0; t filteredPolygons(textureMesh.tex_polygons[t].size()); +#if PCL_VERSION_COMPARE(>=, 1, 8, 0) + std::vector > filteredCoordinates(textureMesh->tex_coordinates[t].size()); +#else + std::vector filteredCoordinates(textureMesh.tex_coordinates[t].size()); +#endif + + if(textureMesh.tex_polygons[t].size()) + { + UASSERT_MSG(allPolygonsIndex < allPolygons.size(), uFormat("%d vs %d", (int)allPolygonsIndex, (int)allPolygons.size()).c_str()); + + // make index polygon to coordinate + std::vector polygonToCoord(textureMesh.tex_polygons[t].size()); + unsigned int totalCoord = 0; + for(unsigned int i=0; i & meshes) { pcl::TextureMesh::Ptr output(new pcl::TextureMesh); diff --git a/guilib/src/ExportCloudsDialog.cpp b/guilib/src/ExportCloudsDialog.cpp index af54dde5..90d30fda 100644 --- a/guilib/src/ExportCloudsDialog.cpp +++ b/guilib/src/ExportCloudsDialog.cpp @@ -2241,139 +2241,22 @@ bool ExportCloudsDialog::getExportedClouds( } // Remove occluded polygons (polygons with no texture) - if(_ui->checkBox_cleanMesh->isChecked() && - textureMesh->tex_coordinates.size()) + if(_ui->checkBox_cleanMesh->isChecked()) { - // assume last texture is the occluded texture - textureMesh->tex_coordinates.pop_back(); - textureMesh->tex_polygons.pop_back(); - textureMesh->tex_materials.pop_back(); - - if(_ui->spinBox_mesh_minClusterSize->value()) + unsigned int totalSize = 0; + for(unsigned int t=0; ttex_polygons.size(); ++t) { - _progressDialog->appendText(tr("Filter small polygon clusters...")); - QApplication::processEvents(); - - // concatenate all polygons - unsigned int totalSize = 0; - for(unsigned int t=0; ttex_polygons.size(); ++t) - { - totalSize+=textureMesh->tex_polygons[t].size(); - } - std::vector allPolygons(totalSize); - int oi=0; - for(unsigned int t=0; ttex_polygons.size(); ++t) - { - for(unsigned int i=0; itex_polygons[t].size(); ++i) - { - allPolygons[oi++] = textureMesh->tex_polygons[t][i]; - } - } - - // filter polygons - std::vector > neighbors; - std::vector > vertexToPolygons; - util3d::createPolygonIndexes(allPolygons, - (int)textureMesh->cloud.data.size()/textureMesh->cloud.point_step, - neighbors, - vertexToPolygons); - - std::list > clusters = util3d::clusterPolygons( - neighbors, - _ui->spinBox_mesh_minClusterSize->value()<0?0:_ui->spinBox_mesh_minClusterSize->value()); - - std::set validPolygons; - if(_ui->spinBox_mesh_minClusterSize->value() < 0) - { - // only keep the biggest cluster - std::list >::iterator biggestClusterIndex = clusters.end(); - unsigned int biggestClusterSize = 0; - for(std::list >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter) - { - if(iter->size() > biggestClusterSize) - { - biggestClusterIndex = iter; - biggestClusterSize = iter->size(); - } - } - if(biggestClusterIndex != clusters.end()) - { - for(std::list::iterator jter=biggestClusterIndex->begin(); jter!=biggestClusterIndex->end(); ++jter) - { - validPolygons.insert(*jter); - } - } - } - else - { - for(std::list >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter) - { - for(std::list::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()); - _progressDialog->appendText(msg.c_str(), Qt::darkYellow); - UWARN(msg.c_str()); - } - - // for each texture - unsigned int allPolygonsIndex = 0; - for(unsigned int t=0; ttex_polygons.size(); ++t) - { - std::vector filteredPolygons(textureMesh->tex_polygons[t].size()); -#if PCL_VERSION_COMPARE(>=, 1, 8, 0) - std::vector > filteredCoordinates(textureMesh->tex_coordinates[t].size()); -#else - std::vector filteredCoordinates(textureMesh->tex_coordinates[t].size()); -#endif - - if(textureMesh->tex_polygons[t].size()) - { - UASSERT_MSG(allPolygonsIndex < allPolygons.size(), uFormat("%d vs %d", (int)allPolygonsIndex, (int)allPolygons.size()).c_str()); - - // make index polygon to coordinate - std::vector polygonToCoord(textureMesh->tex_polygons[t].size()); - unsigned int totalCoord = 0; - for(unsigned int i=0; itex_polygons[t].size(); ++i) - { - polygonToCoord[i] = totalCoord; - totalCoord+=textureMesh->tex_polygons[t][i].vertices.size(); - } - UASSERT_MSG(totalCoord == textureMesh->tex_coordinates[t].size(), uFormat("%d vs %d", totalCoord, (int)textureMesh->tex_coordinates[t].size()).c_str()); - - int oi=0; - int ci=0; - for(unsigned int i=0; itex_polygons[t].size(); ++i) - { - if(validPolygons.find(allPolygonsIndex) != validPolygons.end()) - { - filteredPolygons[oi] = textureMesh->tex_polygons[t].at(i); - for(unsigned int j=0; jtex_coordinates[t].size()); - filteredCoordinates[ci] = textureMesh->tex_coordinates[t][polygonToCoord[i]+j]; - ++ci; - } - ++oi; - } - ++allPolygonsIndex; - } - filteredPolygons.resize(oi); - filteredCoordinates.resize(ci); - textureMesh->tex_polygons[t] = filteredPolygons; - textureMesh->tex_coordinates[t] = filteredCoordinates; - } - } - - _progressDialog->appendText(tr("Filtered %1 polygons.").arg(allPolygons.size()-validPolygons.size())); - QApplication::processEvents(); + totalSize+=textureMesh->tex_polygons[t].size(); } + + util3d::cleanTextureMesh(*textureMesh, _ui->spinBox_mesh_minClusterSize->value()); + + unsigned int totalSizeAfter = 0; + for(unsigned int t=0; ttex_polygons.size(); ++t) + { + totalSizeAfter+=textureMesh->tex_polygons[t].size(); + } + _progressDialog->appendText(tr("Cleaned texture mesh: %1 -> %2 polygons").arg(totalSize).arg(totalSizeAfter)); } }