diff --git a/meshroom/aliceVision/SfMFilter.py b/meshroom/aliceVision/SfMFilter.py index 06d89f4bad..c978883ed1 100644 --- a/meshroom/aliceVision/SfMFilter.py +++ b/meshroom/aliceVision/SfMFilter.py @@ -1,4 +1,4 @@ -__version__ = "1.0" +__version__ = "1.1" from meshroom.core import desc from meshroom.core.utils import VERBOSE_LEVEL @@ -30,6 +30,12 @@ class SfMFilter(desc.CommandLineNode): r'".*\/(.*?)_.*\.\w{3}"', value=r'.*\/(.*?)\.\w{3}', ), + desc.BoolParam( + name="prunePoses", + label="Remove unselected poses", + description="Set to True to prune poses related to views that are not selected.", + value=False, + ), desc.ChoiceParam( name="verboseLevel", label="Verbose Level", diff --git a/src/software/utils/main_sfmFilter.cpp b/src/software/utils/main_sfmFilter.cpp index 20dca089ab..f23d62b186 100644 --- a/src/software/utils/main_sfmFilter.cpp +++ b/src/software/utils/main_sfmFilter.cpp @@ -21,7 +21,7 @@ // These constants define the current software version. // They must be updated when the command line is changed. #define ALICEVISION_SOFTWARE_VERSION_MAJOR 1 -#define ALICEVISION_SOFTWARE_VERSION_MINOR 0 +#define ALICEVISION_SOFTWARE_VERSION_MINOR 1 using namespace aliceVision; using namespace aliceVision::sfm; @@ -37,6 +37,7 @@ int aliceVision_main(int argc, char** argv) std::string outputSfMFilenameSelected; std::string outputSfMFilenameUnselected; std::string fileMatchingPattern; + bool prunePoses; // clang-format off po::options_description requiredParams("Required parameters"); @@ -45,6 +46,7 @@ int aliceVision_main(int argc, char** argv) "Path to the input SfMData file.\n") ("fileMatchingPattern,m", po::value(&fileMatchingPattern)->required(), "Matching pattern for the from_filepath method.\n") + ("prunePoses,p", po::value(&prunePoses)->required(), "Prune unselected poses.\n") ("outputSfMData_selected,o", po::value(&outputSfMFilenameSelected)->required(), "Path to the output SfMData file.\n") ("outputSfMData_unselected,o", po::value(&outputSfMFilenameUnselected)->required(), @@ -69,6 +71,7 @@ int aliceVision_main(int argc, char** argv) std::regex re(fileMatchingPattern); std::vector selectedViews; + std::vector selectedPoses; for (auto& viewIt : sfmData.getViews()) { @@ -77,9 +80,13 @@ int aliceVision_main(int argc, char** argv) if (std::regex_search(imagePath, matches, re)) { selectedViews.push_back(viewIt.first); + if (prunePoses) + selectedPoses.push_back(viewIt.second->getPoseId()); } } + // Split views into the selected and unselected SfmData + sfmData::SfMData outputSfMData_selected = sfmData; sfmData::SfMData outputSfMData_unselected = sfmData; std::set viewIdsToRemove; @@ -109,6 +116,38 @@ int aliceVision_main(int argc, char** argv) outputSfMData_unselected.getViews().erase(r); } + // Split poses into the selected and unselected SfmData + + if (prunePoses) + { + std::set poseIdsToRemove; + std::set poseIdsToKeep; + + for (auto& poseIt : outputSfMData_selected.getPoses()) + { + const IndexT poseId = poseIt.first; + auto it = std::find(selectedPoses.begin(), selectedPoses.end(), poseId); + if (it == selectedPoses.end()) + { + poseIdsToRemove.insert(poseId); + } + else + { + poseIdsToKeep.insert(poseId); + } + } + + for (auto r : poseIdsToRemove) + { + outputSfMData_selected.getPoses().erase(r); + } + + for (auto r : poseIdsToKeep) + { + outputSfMData_unselected.getPoses().erase(r); + } + } + ALICEVISION_LOG_INFO("Save into '" << outputSfMFilenameSelected << "'"); // Export the SfMData scene in the expected format