From e0da602fe086dbf2f5935badf4c15175d54f250b Mon Sep 17 00:00:00 2001 From: Dakota Benjamin Date: Thu, 5 Jul 2018 19:02:00 -0400 Subject: [PATCH] Replace odm_meshing module with external PoissonRecon --- SuperBuild/CMakeLists.txt | 13 + modules/CMakeLists.txt | 1 - modules/odm_meshing/CMakeLists.txt | 26 -- modules/odm_meshing/src/Logger.cpp | 31 --- modules/odm_meshing/src/Logger.hpp | 68 ----- modules/odm_meshing/src/OdmMeshing.cpp | 361 ------------------------- modules/odm_meshing/src/OdmMeshing.hpp | 117 -------- modules/odm_meshing/src/main.cpp | 20 -- opendm/config.py | 21 +- opendm/context.py | 2 + scripts/odm_app.py | 3 +- scripts/odm_meshing.py | 34 +-- 12 files changed, 43 insertions(+), 654 deletions(-) delete mode 100644 modules/odm_meshing/CMakeLists.txt delete mode 100644 modules/odm_meshing/src/Logger.cpp delete mode 100644 modules/odm_meshing/src/Logger.hpp delete mode 100644 modules/odm_meshing/src/OdmMeshing.cpp delete mode 100644 modules/odm_meshing/src/OdmMeshing.hpp delete mode 100644 modules/odm_meshing/src/main.cpp diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt index 18c4ea7b..6ce7a86e 100644 --- a/SuperBuild/CMakeLists.txt +++ b/SuperBuild/CMakeLists.txt @@ -142,6 +142,7 @@ endforeach() externalproject_add(smvs GIT_REPOSITORY https://github.com/flanggut/smvs.git + GIT_TAG 6a7d0c095aa66ab98c5b285c2bc04e34d8993353 UPDATE_COMMAND "" SOURCE_DIR ${SB_SOURCE_DIR}/elibs/smvs CONFIGURE_COMMAND "" @@ -152,6 +153,7 @@ externalproject_add(smvs externalproject_add(mve GIT_REPOSITORY https://github.com/simonfuhrmann/mve.git + GIT_TAG 2106a5b0aef61a7f744551510b1b4c5d8e3be594 UPDATE_COMMAND "" SOURCE_DIR ${SB_SOURCE_DIR}/elibs/mve CONFIGURE_COMMAND "" @@ -159,3 +161,14 @@ externalproject_add(mve BUILD_COMMAND make INSTALL_COMMAND "" ) + +externalproject_add(poissonrecon + GIT_REPOSITORY https://github.com/mkazhdan/PoissonRecon.git + GIT_TAG ce5005ae3094d902d551a65a8b3131e06f45e7cf + SOURCE_DIR ${SB_SOURCE_DIR}/PoissonRecon + UPDATE_COMMAND "" + CONFIGURE_COMMAND "" + BUILD_IN_SOURCE 1 + BUILD_COMMAND make poissonrecon + INSTALL_COMMAND "" +) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 5786f461..2ca1f00b 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -6,7 +6,6 @@ endif() # Add ODM sub-modules add_subdirectory(odm_extract_utm) add_subdirectory(odm_georef) -add_subdirectory(odm_meshing) add_subdirectory(odm_orthophoto) add_subdirectory(odm_25dmeshing) if (ODM_BUILD_SLAM) diff --git a/modules/odm_meshing/CMakeLists.txt b/modules/odm_meshing/CMakeLists.txt deleted file mode 100644 index 4be138c9..00000000 --- a/modules/odm_meshing/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -project(odm_meshing) -cmake_minimum_required(VERSION 2.8) - -# Set pcl dir to the input spedified with option -DPCL_DIR="path" -set(PCL_DIR "PCL_DIR-NOTFOUND" CACHE "PCL_DIR" "Path to the pcl installation directory") - -# Add compiler options. -add_definitions(-Wall -Wextra) - -# Find pcl at the location specified by PCL_DIR -find_package(PCL 1.8 HINTS "${PCL_DIR}/share/pcl-1.8") - -# Add the PCL and Eigen include dirs. -# Necessary since the PCL_INCLUDE_DIR variable set by find_package is broken.) -include_directories(${PCL_ROOT}/include/pcl-${PCL_VERSION_MAJOR}.${PCL_VERSION_MINOR}) -include_directories(${EIGEN_ROOT}) - -# Add source directory -aux_source_directory("./src" SRC_LIST) - -# Add exectuteable -add_executable(${PROJECT_NAME} ${SRC_LIST}) - -# Link -target_link_libraries(odm_meshing ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_SURFACE_LIBRARIES}) - diff --git a/modules/odm_meshing/src/Logger.cpp b/modules/odm_meshing/src/Logger.cpp deleted file mode 100644 index a6c81a8b..00000000 --- a/modules/odm_meshing/src/Logger.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "Logger.hpp" - - -Logger::Logger(bool isPrintingInCout) : isPrintingInCout_(isPrintingInCout) -{ - -} - -Logger::~Logger() -{ - -} - -void Logger::printToFile(std::string filePath) -{ - std::ofstream file(filePath.c_str(), std::ios::binary); - file << logStream_.str(); - file.close(); -} - -bool Logger::isPrintingInCout() const -{ - return isPrintingInCout_; -} - -void Logger::setIsPrintingInCout(bool isPrintingInCout) -{ - isPrintingInCout_ = isPrintingInCout; -} - - diff --git a/modules/odm_meshing/src/Logger.hpp b/modules/odm_meshing/src/Logger.hpp deleted file mode 100644 index 31c5538c..00000000 --- a/modules/odm_meshing/src/Logger.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -// STL -#include -#include -#include -#include - -/*! - * \brief The Logger class is used to store program messages in a log file. - * \details By using the << operator while printInCout is set, the class writes both to - * cout and to file, if the flag is not set, output is written to file only. - */ -class Logger -{ -public: - /*! - * \brief Logger Contains functionality for printing and displaying log information. - * \param printInCout Flag toggling if operator << also writes to cout. - */ - Logger(bool isPrintingInCout = true); - - /*! - * \brief Destructor. - */ - ~Logger(); - - /*! - * \brief print Prints the contents of the log to file. - * \param filePath Path specifying where to write the log. - */ - void printToFile(std::string filePath); - - /*! - * \brief isPrintingInCout Check if console printing flag is set. - * \return Console printing flag. - */ - bool isPrintingInCout() const; - - /*! - * \brief setIsPrintingInCout Set console printing flag. - * \param isPrintingInCout Value, if true, messages added to the log are also printed in cout. - */ - void setIsPrintingInCout(bool isPrintingInCout); - - /*! - * Operator for printing messages to log and in the standard output stream if desired. - */ - template - friend Logger& operator<< (Logger &log, T t) - { - // If console printing is enabled. - if (log.isPrintingInCout_) - { - std::cout << t; - std::cout.flush(); - } - // Write to log. - log.logStream_ << t; - - return log; - } - -private: - bool isPrintingInCout_; /*!< If flag is set, log is printed in cout and written to the log. */ - - std::stringstream logStream_; /*!< Stream for storing the log. */ -}; diff --git a/modules/odm_meshing/src/OdmMeshing.cpp b/modules/odm_meshing/src/OdmMeshing.cpp deleted file mode 100644 index 68bdeaad..00000000 --- a/modules/odm_meshing/src/OdmMeshing.cpp +++ /dev/null @@ -1,361 +0,0 @@ -#include "OdmMeshing.hpp" - - -OdmMeshing::OdmMeshing() : log_(false) -{ - meshCreator_ = pcl::Poisson::Ptr(new pcl::Poisson()); - points_ = pcl::PointCloud::Ptr(new pcl::PointCloud()); - mesh_ = pcl::PolygonMeshPtr(new pcl::PolygonMesh); - decimatedMesh_ = pcl::PolygonMeshPtr(new pcl::PolygonMesh); - - // Set default values - outputFile_ = ""; - logFilePath_ = ""; - - maxVertexCount_ = 0; - treeDepth_ = 0; - - solverDivide_ = 9.0; - samplesPerNode_ = 1.0; - decimationFactor_ = 0.0; - - logFilePath_ = "odm_meshing_log.txt"; - log_ << logFilePath_ << "\n"; -} - -OdmMeshing::~OdmMeshing() -{ - -} - -int OdmMeshing::run(int argc, char **argv) -{ - // If no arguments were passed, print help and return early. - if (argc <= 1) - { - printHelp(); - return EXIT_SUCCESS; - } - - try - { - parseArguments(argc, argv); - - loadPoints(); - - createMesh(); - - decimateMesh(); - - writePlyFile(); - - } - catch (const OdmMeshingException& e) - { - log_.setIsPrintingInCout(true); - log_ << e.what() << "\n"; - log_.printToFile(logFilePath_); - log_ << "For more detailed information, see log file." << "\n"; - return EXIT_FAILURE; - } - catch (const std::exception& e) - { - log_.setIsPrintingInCout(true); - log_ << "Error in OdmMeshing:\n"; - log_ << e.what() << "\n"; - log_.printToFile(logFilePath_); - log_ << "For more detailed information, see log file." << "\n"; - return EXIT_FAILURE; - } - catch (...) - { - log_.setIsPrintingInCout(true); - log_ << "Unknwon error in OdmMeshing:\n"; - log_.printToFile(logFilePath_); - log_ << "For more detailed information, see log file." << "\n"; - return EXIT_FAILURE; - } - - log_.printToFile(logFilePath_); - return EXIT_SUCCESS; -} - - -void OdmMeshing::parseArguments(int argc, char **argv) -{ - - for(int argIndex = 1; argIndex < argc; ++argIndex) - { - // The argument to be parsed. - std::string argument = std::string(argv[argIndex]); - - if(argument == "-help") - { - printHelp(); - } - else if(argument == "-verbose") - { - log_.setIsPrintingInCout(true); - } - else if(argument == "-maxVertexCount" && argIndex < argc) - { - ++argIndex; - if (argIndex >= argc) - { - throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided."); - } - std::stringstream ss(argv[argIndex]); - ss >> maxVertexCount_; - if (ss.bad()) - { - throw OdmMeshingException("Argument '" + argument + "' has a bad value (wrong type)."); - } - log_ << "Vertex count was manually set to: " << maxVertexCount_ << "\n"; - } - else if(argument == "-octreeDepth" && argIndex < argc) - { - ++argIndex; - if (argIndex >= argc) - { - throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided."); - } - std::stringstream ss(argv[argIndex]); - ss >> treeDepth_; - if (ss.bad()) - { - throw OdmMeshingException("Argument '" + argument + "' has a bad value (wrong type)."); - } - log_ << "Octree depth was manually set to: " << treeDepth_ << "\n"; - } - else if(argument == "-solverDivide" && argIndex < argc) - { - ++argIndex; - if (argIndex >= argc) - { - throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided."); - } - std::stringstream ss(argv[argIndex]); - ss >> solverDivide_; - if (ss.bad()) - { - throw OdmMeshingException("Argument '" + argument + "' has a bad value (wrong type)."); - } - log_ << "Numerical solver divisions was manually set to: " << treeDepth_ << "\n"; - } - else if(argument == "-samplesPerNode" && argIndex < argc) - { - ++argIndex; - if (argIndex >= argc) - { - throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided."); - } - std::stringstream ss(argv[argIndex]); - ss >> samplesPerNode_; - if (ss.bad()) - { - throw OdmMeshingException("Argument '" + argument + "' has a bad value (wrong type)."); - } - log_ << "The number of samples per octree node was manually set to: " << samplesPerNode_ << "\n"; - } - else if(argument == "-inputFile" && argIndex < argc) - { - ++argIndex; - if (argIndex >= argc) - { - throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided."); - } - inputFile_ = std::string(argv[argIndex]); - std::ifstream testFile(inputFile_.c_str(), std::ios::binary); - if (!testFile.is_open()) - { - throw OdmMeshingException("Argument '" + argument + "' has a bad value. (file not accessible)"); - } - testFile.close(); - log_ << "Reading point cloud at: " << inputFile_ << "\n"; - } - else if(argument == "-outputFile" && argIndex < argc) - { - ++argIndex; - if (argIndex >= argc) - { - throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided."); - } - outputFile_ = std::string(argv[argIndex]); - std::ofstream testFile(outputFile_.c_str()); - if (!testFile.is_open()) - { - throw OdmMeshingException("Argument '" + argument + "' has a bad value."); - } - testFile.close(); - log_ << "Writing output to: " << outputFile_ << "\n"; - } - else if(argument == "-logFile" && argIndex < argc) - { - ++argIndex; - if (argIndex >= argc) - { - throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided."); - } - logFilePath_ = std::string(argv[argIndex]); - std::ofstream testFile(outputFile_.c_str()); - if (!testFile.is_open()) - { - throw OdmMeshingException("Argument '" + argument + "' has a bad value."); - } - testFile.close(); - log_ << "Writing log information to: " << logFilePath_ << "\n"; - } - else - { - printHelp(); - throw OdmMeshingException("Unrecognised argument '" + argument + "'"); - } - } -} - -void OdmMeshing::loadPoints() -{ - - if(pcl::io::loadPLYFile (inputFile_.c_str(), *points_.get()) == -1) { - throw OdmMeshingException("Error when reading points and normals from:\n" + inputFile_ + "\n"); - } - else - { - log_ << "Successfully loaded " << points_->size() << " points with corresponding normals from file.\n"; - } -} - -void OdmMeshing::printHelp() -{ - bool printInCoutPop = log_.isPrintingInCout(); - log_.setIsPrintingInCout(true); - - log_ << "OpenDroneMapMeshing.exe\n\n"; - - log_ << "Purpose:" << "\n"; - log_ << "Create a mesh from an oriented point cloud (points with normals) using the Poisson surface reconstruction method." << "\n"; - - log_ << "Usage:" << "\n"; - log_ << "The program requires a path to an input PLY point cloud file, all other input parameters are optional." << "\n\n"; - - log_ << "The following flags are available\n"; - log_ << "Call the program with flag \"-help\", or without parameters to print this message, or check any generated log file.\n"; - log_ << "Call the program with flag \"-verbose\", to print log messages in the standard output stream as well as in the log file.\n\n"; - - log_ << "Parameters are specified as: \"- \", (without <>), and the following parameters are configureable: " << "\n"; - log_ << "\"-inputFile \" (mandatory)" << "\n"; - log_ << "\"Input ascii ply file that must contain a point cloud with normals.\n\n"; - - log_ << "\"-outputFile \" (optional, default: odm_mesh.ply)" << "\n"; - log_ << "\"Target file in which the mesh is saved.\n\n"; - - log_ << "\"-logFile \" (optional, default: odm_meshing_log.txt)" << "\n"; - log_ << "\"Target file in which the mesh is saved.\n\n"; - - log_ << "\"-maxVertexCount \" (optional, default: 100,000)" << "\n"; - log_ << "Desired final vertex count (after decimation), set to 0 to disable decimation.\n\n"; - - log_ << "\"-treeDepth \" (optional, default: 0 (automatic))" << "\n"; - log_ << "Controls octree depth used for poisson reconstruction. Recommended values (9-11).\n" - << "Increasing the value on this parameter will raise initial vertex count." - << "If omitted or zero, the depth is calculated automatically from the input point count.\n\n"; - - log_ << "\"-samplesPerNode \" (optional, default: 1)" << "\n"; - log_ << "Average number of samples (points) per octree node. Increasing this value might help if data is very noisy.\n\n"; - - log_ << "\"-solverDivide \" (optional, default: 9)" << "\n"; - log_ << "Ocree depth at which the Laplacian equation is solved in the surface reconstruction step.\n"; - log_ << "Increasing this value increases computation times slightly but helps reduce memory usage.\n\n"; - - log_.setIsPrintingInCout(printInCoutPop); -} - -void OdmMeshing::createMesh() -{ - - // Attempt to calculate the depth of the tree if unspecified - if (treeDepth_ == 0) - { - treeDepth_ = calcTreeDepth(points_->size()); - } - - log_ << "Octree depth used for reconstruction is: " << treeDepth_ << "\n"; - log_ << "Estimated initial vertex count: " << pow(4, treeDepth_) << "\n\n"; - - meshCreator_->setDepth(treeDepth_); - meshCreator_->setSamplesPerNode(samplesPerNode_); - meshCreator_->setInputCloud(points_); - - // Guarantee manifold mesh. - meshCreator_->setManifold(true); - - // Begin reconstruction - meshCreator_->reconstruct(*mesh_.get()); - - log_ << "Reconstruction complete:\n"; - log_ << "Vertex count: " << mesh_->cloud.width << "\n"; - log_ << "Triangle count: " << mesh_->polygons.size() << "\n\n"; - -} - -void OdmMeshing::decimateMesh() -{ - if (maxVertexCount_ <= 0) - { - log_ << "Vertex count not specified, decimation cancelled.\n"; - return; - } - - if (maxVertexCount_ > mesh_->cloud.height*mesh_->cloud.width) - { - log_ << "Vertex count in mesh lower than initially generated mesh, unable to decimate.\n"; - return; - } - else - { - decimatedMesh_ = pcl::PolygonMeshPtr(new pcl::PolygonMesh); - - double reductionFactor = 1.0 - double(maxVertexCount_)/double(mesh_->cloud.height*mesh_->cloud.width); - - log_ << "Decimating mesh, removing " << reductionFactor*100 << " percent of vertices.\n"; - - pcl::MeshQuadricDecimationVTK decimator; - decimator.setInputMesh(mesh_); - decimator.setTargetReductionFactor(reductionFactor); - decimator.process(*decimatedMesh_.get()); - - log_ << "Decimation complete.\n"; - log_ << "Decimated vertex count: " << decimatedMesh_->cloud.width << "\n"; - log_ << "Decimated triangle count: " << decimatedMesh_->polygons.size() << "\n\n"; - - mesh_ = decimatedMesh_; - } -} - -int OdmMeshing::calcTreeDepth(size_t nPoints) -{ - // Assume points are located (roughly) in a plane. - double squareSide = std::sqrt(double(nPoints)); - - // Calculate octree depth such that if points were equally distributed in - // a quadratic plane, there would be at least 1 point per octree node. - int depth = 0; - while(std::pow(2,depth) < squareSide/2) - { - depth++; - } - return depth; -} - -void OdmMeshing::writePlyFile() -{ - log_ << "Saving mesh to file.\n"; - if (pcl::io::savePLYFile(outputFile_.c_str(), *mesh_.get()) == -1) { - throw OdmMeshingException("Error when saving mesh to file:\n" + outputFile_ + "\n"); - } - else - { - log_ << "Successfully wrote mesh to:\n" - << outputFile_ << "\n"; - } -} diff --git a/modules/odm_meshing/src/OdmMeshing.hpp b/modules/odm_meshing/src/OdmMeshing.hpp deleted file mode 100644 index 8e559989..00000000 --- a/modules/odm_meshing/src/OdmMeshing.hpp +++ /dev/null @@ -1,117 +0,0 @@ -#pragma once - -// STL -#include -#include - -// PCL -#include -#include -#include - -// Logging -#include "Logger.hpp" - -/*! - * \brief The OdmMeshing class is used to create a triangulated mesh using the Poisson method. - * The class reads an oriented point cloud (coordinates and normals) from a PLY ascii - * file and outputs the resulting welded manifold mesh on the form of an ASCII PLY-file. - * The class uses file read and write functions from pcl. - */ -class OdmMeshing -{ -public: - OdmMeshing(); - ~OdmMeshing(); - - /*! - * \brief run Runs the meshing functionality using the provided input arguments. - * For a list of accepted arguments, please see the main page documentation or - * call the program with parameter "-help". - * \param argc Application argument count. - * \param argv Argument values. - * \return 0 If successful. - */ - int run(int argc, char **argv); - -private: - - /*! - * \brief parseArguments Parses command line arguments. - * \param argc Application argument count. - * \param argv Argument values. - */ - void parseArguments(int argc, char** argv); - - /*! - * \brief createMesh Sets up the pcl::Poisson meshing class using provided arguments and calls - * it to start the meshing. - */ - void createMesh(); - - /*! - * \brief loadPoints Loads a PLY ascii file with points and normals from file. - */ - void loadPoints(); - - /*! - * \brief decimateMesh Performs post-processing on the form of quadric decimation to generate a mesh - * that has a higher density in areas with a lot of structure. - */ - void decimateMesh(); - - /*! - * \brief writePlyFile Writes the mesh to file on the Ply format. - */ - void writePlyFile(); - - /*! - * \brief printHelp Prints help, explaining usage. Can be shown by calling the program with argument: "-help". - */ - void printHelp(); - - /*! - * \brief calcTreeDepth Attepts to calculate the depth of the tree using the point cloud. - * The function makes the assumption points are located roughly in a plane - * (fairly reasonable for ortho-terrain photos) and tries to generate a mesh using - * an octree with an appropriate resolution. - * \param nPoints The total number of points in the input point cloud. - * \return The calcualated octree depth. - */ - int calcTreeDepth(size_t nPoints); - - Logger log_; /**< Logging object. */ - - pcl::Poisson::Ptr meshCreator_; /**< PCL poisson meshing class. */ - - pcl::PointCloud::Ptr points_; /**< Input point and normals. */ - pcl::PolygonMeshPtr mesh_; /**< PCL polygon mesh. */ - pcl::PolygonMeshPtr decimatedMesh_; /**< Decimated polygon mesh. */ - - std::string inputFile_; /**< Path to a file containing points and normals. */ - std::string outputFile_; /**< Path to the destination file. */ - std::string logFilePath_; /**< Path to the log file. */ - - unsigned int maxVertexCount_; /**< Desired output vertex count. */ - unsigned int treeDepth_; /**< Depth of octree used for reconstruction. */ - - double samplesPerNode_; /**< Samples per octree node.*/ - double solverDivide_; /**< Depth at which the Laplacian equation solver is run during surface estimation.*/ - double decimationFactor_; /**< Percentage of points to remove when decimating the mesh. */ -}; - -/*! - * \brief The OdmMeshingException class - */ -class OdmMeshingException : public std::exception -{ - -public: - OdmMeshingException() : message("Error in OdmMeshing") {} - OdmMeshingException(std::string msgInit) : message("Error in OdmMeshing:\n" + msgInit) {} - ~OdmMeshingException() throw() {} - virtual const char* what() const throw() {return message.c_str(); } - -private: - std::string message; /**< The error message **/ -}; diff --git a/modules/odm_meshing/src/main.cpp b/modules/odm_meshing/src/main.cpp deleted file mode 100644 index f99f20ce..00000000 --- a/modules/odm_meshing/src/main.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Insert license here. - -// Include meshing source code. -#include "OdmMeshing.hpp" - -/*! - * \mainpage main OpenDroneMap Meshing Module - * - * The OpenDroneMap Meshing Module generates a welded, manifold mesh using the Poisson - * surface reconstruction algorithm from any oriented point cloud (points with corresponding normals). - * - */ - -int main(int argc, char** argv) -{ - - OdmMeshing meshCreator; - return meshCreator.run(argc, argv); - -} diff --git a/opendm/config.py b/opendm/config.py index dec035c4..b4114ef6 100644 --- a/opendm/config.py +++ b/opendm/config.py @@ -245,7 +245,7 @@ def config(): metavar='', default=100000, type=int, - help=('The maximum vertex count of the output mesh ' + help=('The maximum vertex count of the output mesh. Applies to 2.5D mesh only. ' 'Default: %(default)s')) parser.add_argument('--mesh-octree-depth', @@ -263,15 +263,16 @@ def config(): help=('Number of points per octree node, recommended ' 'and default value: %(default)s')) - parser.add_argument('--mesh-solver-divide', - metavar='', - default=9, - type=int, - help=('Oct-tree depth at which the Laplacian equation ' - 'is solved in the surface reconstruction step. ' - 'Increasing this value increases computation ' - 'times slightly but helps reduce memory usage. ' - 'Default: %(default)s')) + parser.add_argument('--mesh-point-weight', + metavar='', + default=4, + type=float, + help=('This floating point value specifies the importance' + ' that interpolation of the point samples is given in the ' + 'formulation of the screened Poisson equation. The results ' + 'of the original (unscreened) Poisson Reconstruction can ' + 'be obtained by setting this value to 0.' + 'Default= %(default)s')) parser.add_argument('--mesh-neighbors', metavar='', diff --git a/opendm/context.py b/opendm/context.py index 9f7756b0..8812e91a 100644 --- a/opendm/context.py +++ b/opendm/context.py @@ -27,6 +27,8 @@ orb_slam2_path = os.path.join(superbuild_path, "src/orb_slam2") makescene_path = os.path.join(superbuild_path, 'src', 'elibs', 'mve', 'apps', 'makescene', 'makescene') #TODO: don't install in source smvs_path = os.path.join(superbuild_path, 'src', 'elibs', 'smvs', 'app', 'smvsrecon') +poisson_recon_path = os.path.join(superbuild_path, 'src', 'PoissonRecon', 'Bin', 'Linux', 'PoissonRecon') + # define mvstex path mvstex_path = os.path.join(superbuild_path, "install/bin/texrecon") diff --git a/scripts/odm_app.py b/scripts/odm_app.py index 98f24684..66fda204 100644 --- a/scripts/odm_app.py +++ b/scripts/odm_app.py @@ -59,7 +59,8 @@ class ODMApp(ecto.BlackBox): 'meshing': ODMeshingCell(max_vertex=p.args.mesh_size, oct_tree=p.args.mesh_octree_depth, samples=p.args.mesh_samples, - solver=p.args.mesh_solver_divide, + point_weight=p.args.mesh_point_weight, + max_concurrency=p.args.max_concurrency, verbose=p.args.verbose), 'texturing': ODMMvsTexCell(data_term=p.args.texturing_data_term, outlier_rem_type=p.args.texturing_outlier_removal_type, diff --git a/scripts/odm_meshing.py b/scripts/odm_meshing.py index 718a6b6c..a8754427 100644 --- a/scripts/odm_meshing.py +++ b/scripts/odm_meshing.py @@ -15,10 +15,8 @@ class ODMeshingCell(ecto.Cell): 'values are 8-12', 9) params.declare("samples", 'Number of points per octree node, recommended ' 'value: 1.0', 1) - params.declare("solver", 'Oct-tree depth at which the Laplacian equation ' - 'is solved in the surface reconstruction step. ' - 'Increasing this value increases computation ' - 'times slightly but helps reduce memory usage.', 9) + params.declare("point_weight", "specifies the importance that interpolation of the point samples is given in the formulation of the screened Poisson equation.", 4) + params.declare("max_concurrency", 'max threads', context.num_cores) params.declare("verbose", 'print additional messages to console', False) def declare_io(self, params, inputs, outputs): @@ -38,7 +36,7 @@ class ODMeshingCell(ecto.Cell): args = inputs.args tree = inputs.tree reconstruction = inputs.reconstruction - verbose = '-verbose' if self.params.verbose else '' + verbose = '--verbose' if self.params.verbose else '' # define paths and create working directories system.mkdir_p(tree.odm_meshing) @@ -62,22 +60,20 @@ class ODMeshingCell(ecto.Cell): log.ODM_DEBUG('Writing ODM Mesh file in: %s' % tree.odm_mesh) kwargs = { - 'bin': context.odm_modules_path, - 'outfile': tree.odm_mesh, - 'infile': infile, - 'log': tree.odm_meshing_log, - 'max_vertex': self.params.max_vertex, - 'oct_tree': self.params.oct_tree, - 'samples': self.params.samples, - 'solver': self.params.solver, - 'verbose': verbose + 'bin': context.poisson_recon_path, + 'outfile': tree.odm_mesh, + 'infile': infile, + 'oct_tree': self.params.oct_tree, + 'point_weight': self.params.point_weight, + 'threads': self.params.max_concurrency, + 'samples': self.params.samples, + 'verbose': verbose } - # run meshing binary - system.run('{bin}/odm_meshing -inputFile {infile} ' - '-outputFile {outfile} -logFile {log} ' - '-maxVertexCount {max_vertex} -octreeDepth {oct_tree} {verbose} ' - '-samplesPerNode {samples} -solverDivide {solver}'.format(**kwargs)) + system.run('{bin} --in {infile} --out {outfile} ' + '--depth {oct_tree} --pointWeight {point_weight} ' + '--linearFit --normals --density --samplesPerNode {samples} ' + '--threads {threads} {verbose}'.format(**kwargs)) else: log.ODM_WARNING('Found a valid ODM Mesh file in: %s' % tree.odm_mesh)