diff --git a/.github/workflows/build-python.yaml b/.github/workflows/build-python.yaml index b12c5d27..d5870fca 100644 --- a/.github/workflows/build-python.yaml +++ b/.github/workflows/build-python.yaml @@ -163,7 +163,6 @@ jobs: libopenmpt:x64-windows ` boost-mpi:x64-windows-static ` boost-thread:x64-windows-static ` - boost-filesystem:x64-windows-static ` boost-system:x64-windows-static ` boost-program-options:x64-windows-static ` boost-date-time:x64-windows-static ` @@ -185,7 +184,7 @@ jobs: if: ${{ steps.cache-boost.outputs.cache-hit != 'true' && runner.os == 'Linux' }} working-directory: ${{ env.BOOST_SRC_DIR }}/${{ env.BOOST_DIR }} run: | - ./bootstrap.sh --with-libraries=thread,filesystem,system,program_options,date_time,chrono --with-icu --prefix=${{ env.BOOST_INSTALL_PATH }} + ./bootstrap.sh --with-libraries=thread,system,program_options,date_time,chrono --with-icu --prefix=${{ env.BOOST_INSTALL_PATH }} ./b2 cxxflags=-fPIC cflags=-fPIC link=static install - name: Download source code libnabo ${{ env.LIBNABO_VERSION }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 0acebe37..5d93062b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,9 +126,9 @@ endif() #-------------------- # DEPENDENCY: boost #-------------------- -find_package(Boost REQUIRED COMPONENTS thread filesystem system program_options date_time) +find_package(Boost REQUIRED COMPONENTS thread system program_options date_time) if (Boost_MINOR_VERSION GREATER 47) - find_package(Boost REQUIRED COMPONENTS thread filesystem system program_options date_time chrono) + find_package(Boost REQUIRED COMPONENTS thread system program_options date_time chrono) endif () #-------------------- diff --git a/doc/LinkingProjects.md b/doc/LinkingProjects.md index f206490a..caafafcd 100644 --- a/doc/LinkingProjects.md +++ b/doc/LinkingProjects.md @@ -23,18 +23,18 @@ A working example of how to link to an external project can be found in [./examp ## Option 2: Using Eclipse -We will demonstrate how to create an Eclipse project containing a simple executable which depends on libpointmatcher. You must have [Eclipse CDT](http://www.eclipse.org/cdt/) installed to develop with libpointmatcher in Eclipse. +We will demonstrate how to create an Eclipse project containing a simple executable which depends on libpointmatcher. You must have [Eclipse CDT](http://www.eclipse.org/cdt/) installed to develop with libpointmatcher in Eclipse. -Create a new C++ project by clicking `File > New > C++ Project`. You can name your project "PointmatcherEclipseDemo" and in toolchains select the default toolchain for your system (most likely Linux GCC). Click `Finish` to add your project to your Eclipse workspace. +Create a new C++ project by clicking `File > New > C++ Project`. You can name your project "PointmatcherEclipseDemo" and in toolchains select the default toolchain for your system (most likely Linux GCC). Click `Finish` to add your project to your Eclipse workspace. -You must then configure the project by going to `Project > Properties > C/C++Build > Settings`. Navigate to `C++ Compiler > Includes` and add the libpointmatcher (e.g. ~/Libraries/libpointmatcher) and eigen (e.g. /usr/include/eigen3) include path to the `Include paths (-I)` list. Next, go to `C++ Linker/Libraries` and add the the following three dependencies to the "Libraries (-l)" list: +You must then configure the project by going to `Project > Properties > C/C++Build > Settings`. Navigate to `C++ Compiler > Includes` and add the libpointmatcher (e.g. ~/Libraries/libpointmatcher) and eigen (e.g. /usr/include/eigen3) include path to the `Include paths (-I)` list. Next, go to `C++ Linker/Libraries` and add the the following three dependencies to the "Libraries (-l)" list: * pointmatcher * boost_system * nabo Click `Ok` to save the configuration. Create a new source file by clicking `File > New > Source File` and name it "Demo.cpp". In this file you can type the following: - + ```cpp #include #include @@ -74,7 +74,6 @@ CONFIG += c++11 #QMAKE_LFLAGS += -mmacosx-version-min=10.7 LIBS += /usr/local/lib/libboost_thread-mt.dylib \ - /usr/local/lib/libboost_filesystem-mt.dylib \ /usr/local/lib/libboost_system-mt.dylib \ /usr/local/lib/libboost_program_options-mt.dylib \ /usr/local/lib/libboost_date_time-mt.dylib \ @@ -97,7 +96,7 @@ g++ -I/usr/local/include/pointmatcher -o myProgram.o -c myProgram.cpp You can then link to the pointmatcher library using: ```bash -g++ myProgram.o -o myProgram -lpointmatcher -lnabo -lboost_system -lyaml-cpp -lboost_filesystem -lrt +g++ myProgram.o -o myProgram -lpointmatcher -lnabo -lboost_system -lyaml-cpp -lrt ``` Nevertheless, it is always more convenient to use a builder such as CMake. diff --git a/evaluations/eval_solution.cpp b/evaluations/eval_solution.cpp index a4328ab1..1aa75210 100644 --- a/evaluations/eval_solution.cpp +++ b/evaluations/eval_solution.cpp @@ -44,8 +44,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include -#include #include #include #include @@ -55,7 +55,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace std; using namespace PointMatcherSupport; namespace po = boost::program_options; -namespace fs = boost::filesystem; +namespace fs = std::filesystem; namespace pt = boost::posix_time; typedef PointMatcher PM; diff --git a/examples/align_sequence.cpp b/examples/align_sequence.cpp index 9ea020fe..c7a6f4a7 100644 --- a/examples/align_sequence.cpp +++ b/examples/align_sequence.cpp @@ -38,9 +38,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include -#include -#include using namespace std; diff --git a/examples/build_map.cpp b/examples/build_map.cpp index 9df2a2b3..532b35f6 100644 --- a/examples/build_map.cpp +++ b/examples/build_map.cpp @@ -37,10 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pointmatcher/IO.h" #include #include -#include -#include -#include -#include +#include #include using namespace std; @@ -210,7 +207,7 @@ int main(int argc, char *argv[]) } stringstream outputFileNameIter; - outputFileNameIter << boost::filesystem::path(outputFileName).stem().c_str() << "_" << i << ".vtk"; + outputFileNameIter << std::filesystem::path(outputFileName).stem().c_str() << "_" << i << ".vtk"; mapCloud.save(outputFileNameIter.str()); } diff --git a/examples/compute_overlap.cpp b/examples/compute_overlap.cpp index a7fe923e..0a0c1a39 100644 --- a/examples/compute_overlap.cpp +++ b/examples/compute_overlap.cpp @@ -37,11 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pointmatcher/IO.h" #include #include -#include #include -#include -#include -#include #include using namespace std; diff --git a/examples/demo_Qt/demo.pro b/examples/demo_Qt/demo.pro index 1a3a9987..f067c73d 100644 --- a/examples/demo_Qt/demo.pro +++ b/examples/demo_Qt/demo.pro @@ -18,7 +18,6 @@ CONFIG += c++11 #QMAKE_LFLAGS += -mmacosx-version-min=10.7 LIBS += /usr/local/lib/libboost_thread-mt.dylib \ - /usr/local/lib/libboost_filesystem-mt.dylib \ /usr/local/lib/libboost_system-mt.dylib \ /usr/local/lib/libboost_program_options-mt.dylib \ /usr/local/lib/libboost_date_time-mt.dylib \ diff --git a/examples/demo_cmake/CMakeLists.txt b/examples/demo_cmake/CMakeLists.txt index 70526ee8..5603532b 100644 --- a/examples/demo_cmake/CMakeLists.txt +++ b/examples/demo_cmake/CMakeLists.txt @@ -7,7 +7,7 @@ project(convert) set(CMAKE_CXX_STANDARD 17) find_package(libpointmatcher REQUIRED) -find_package(Boost REQUIRED COMPONENTS filesystem) +find_package(Boost REQUIRED) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${libpointmatcher_INCLUDE_DIRS} ${Boost_INCLUDE_DIR}) diff --git a/examples/icp.cpp b/examples/icp.cpp index ab3f143d..8a30daba 100644 --- a/examples/icp.cpp +++ b/examples/icp.cpp @@ -36,8 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pointmatcher/PointMatcher.h" #include "pointmatcher/Bibliography.h" -#include "boost/filesystem.hpp" - #include #include #include diff --git a/examples/icp_advance_api.cpp b/examples/icp_advance_api.cpp index bcb8cf2f..21925e68 100644 --- a/examples/icp_advance_api.cpp +++ b/examples/icp_advance_api.cpp @@ -36,8 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pointmatcher/PointMatcher.h" #include "pointmatcher/Bibliography.h" -#include "boost/filesystem.hpp" - #include #include #include diff --git a/examples/icp_customized.cpp b/examples/icp_customized.cpp index c5f4d131..0b246efe 100644 --- a/examples/icp_customized.cpp +++ b/examples/icp_customized.cpp @@ -36,7 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pointmatcher/PointMatcher.h" #include #include -#include "boost/filesystem.hpp" using namespace std; diff --git a/examples/icp_simple.cpp b/examples/icp_simple.cpp index 895773de..ed2371f8 100644 --- a/examples/icp_simple.cpp +++ b/examples/icp_simple.cpp @@ -36,7 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "pointmatcher/PointMatcher.h" #include #include -#include "boost/filesystem.hpp" using namespace std; diff --git a/libpointmatcherConfig.cmake.in b/libpointmatcherConfig.cmake.in index 04061666..6de2c85f 100644 --- a/libpointmatcherConfig.cmake.in +++ b/libpointmatcherConfig.cmake.in @@ -7,9 +7,9 @@ include(CMakeFindDependencyMacro) find_dependency(libnabo REQUIRED) find_dependency(yaml-cpp REQUIRED) -find_package(Boost COMPONENTS thread filesystem system program_options date_time REQUIRED) +find_package(Boost COMPONENTS thread system program_options date_time REQUIRED) if (Boost_MINOR_VERSION GREATER 47) - find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono REQUIRED) + find_package(Boost COMPONENTS thread system program_options date_time chrono REQUIRED) endif () include(${CMAKE_CURRENT_LIST_DIR}/libpointmatcher-config.cmake) diff --git a/pointmatcher/IO.cpp b/pointmatcher/IO.cpp index 60b3d9e5..b9d3c455 100644 --- a/pointmatcher/IO.cpp +++ b/pointmatcher/IO.cpp @@ -45,9 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include "boost/algorithm/string.hpp" -#include "boost/filesystem.hpp" -#include "boost/filesystem/path.hpp" -#include "boost/filesystem/operations.hpp" +#include #include "boost/lexical_cast.hpp" #include "boost/foreach.hpp" @@ -93,7 +91,7 @@ static std::vector csvLineToVector(const char* line) CsvElements parseCsvWithHeader(const std::string& fileName) { validateFile(fileName); - + ifstream is(fileName.c_str()); unsigned elementCount=0; @@ -102,15 +100,15 @@ CsvElements parseCsvWithHeader(const std::string& fileName) bool firstLine(true); unsigned lineCount=0; - - string line; + + string line; while (safeGetLine(is, line)) { if(firstLine) { std::vector header = csvLineToVector(line.c_str()); - + elementCount = header.size(); for(unsigned int i = 0; i < elementCount; i++) { @@ -126,7 +124,7 @@ CsvElements parseCsvWithHeader(const std::string& fileName) { stringstream errorMsg; errorMsg << "Error at line " << lineCount+1 << ": expecting " << elementCount << " columns but read " << parsedLine.size() << " elements."; - throw runtime_error(errorMsg.str()); + throw runtime_error(errorMsg.str()); } for(unsigned int i = 0; i < parsedLine.size(); i++) @@ -135,7 +133,7 @@ CsvElements parseCsvWithHeader(const std::string& fileName) { if(i == (*it).second) { - data[(*it).first].push_back(parsedLine[i]); + data[(*it).first].push_back(parsedLine[i]); } } } @@ -143,9 +141,9 @@ CsvElements parseCsvWithHeader(const std::string& fileName) lineCount++; } - + // Use for debug - + //for(BOOST_AUTO(it,data.begin()); it!=data.end(); it++) //{ // cout << "--------------------------" << endl; @@ -155,7 +153,7 @@ CsvElements parseCsvWithHeader(const std::string& fileName) // // cout << (*it).second[i] << endl; // //} //} - + return data; } @@ -186,7 +184,7 @@ PointMatcherIO::FileInfoVector::FileInfoVector() @param fileName name of the CSV file @param dataPath path relative to which the point cloud CSV or VTK will be resolved @param configPath path relative to which the yaml configuration files will be resolved - + The first line of the CSV file must contain a header. The supported tags are: - reading: file name of the reading point cloud - reference: file name of the reference point cloud @@ -200,23 +198,15 @@ PointMatcherIO::FileInfoVector::FileInfoVector(const std::string& fileName, s { if (dataPath.empty()) { - #if BOOST_FILESYSTEM_VERSION >= 3 - dataPath = boost::filesystem::path(fileName).parent_path().string(); - #else - dataPath = boost::filesystem::path(fileName).parent_path().file_string(); - #endif + dataPath = std::filesystem::path(fileName).parent_path().string(); } if (configPath.empty()) { - #if BOOST_FILESYSTEM_VERSION >= 3 - configPath = boost::filesystem::path(fileName).parent_path().string(); - #else - configPath = boost::filesystem::path(fileName).parent_path().file_string(); - #endif + configPath = std::filesystem::path(fileName).parent_path().string(); } - + const CsvElements data = parseCsvWithHeader(fileName); - + // Look for transformations const bool found3dInitialTrans(findTransform(data, "iT", 3)); bool found2dInitialTrans(findTransform(data, "iT", 2)); @@ -226,7 +216,7 @@ PointMatcherIO::FileInfoVector::FileInfoVector(const std::string& fileName, s found2dInitialTrans = false; if (found3dGroundTruthTrans) found2dGroundTruthTrans = false; - + // Check for consistency if (found3dInitialTrans && found2dGroundTruthTrans) throw runtime_error("Initial transformation is in 3D but ground-truth is in 2D"); @@ -237,7 +227,7 @@ PointMatcherIO::FileInfoVector::FileInfoVector(const std::string& fileName, s throw runtime_error("Error transfering CSV to structure: The header should at least contain \"reading\"."); CsvElements::const_iterator referenceIt(data.find("reference")); CsvElements::const_iterator configIt(data.find("config")); - + // Load reading const std::vector& readingFileNames = readingIt->second; const unsigned lineCount = readingFileNames.size(); @@ -258,14 +248,14 @@ PointMatcherIO::FileInfoVector::FileInfoVector(const std::string& fileName, s for(unsigned line=0; line::FileInfoVector::FileInfoVector(const std::string& fileName, s info.groundTruthTransformation = getTransform(data, "gT", 3, line); if(found2dGroundTruthTrans) info.groundTruthTransformation = getTransform(data, "gT", 2, line); - + // Build the list this->push_back(info); } - + // Debug: Print the list /*for(unsigned i=0; i std::string PointMatcherIO::FileInfoVector::localToGlobalFileName(const std::string& parentPath, const std::string& fileName) { std::string globalFileName(fileName); - if (!boost::filesystem::exists(globalFileName)) + if (!std::filesystem::exists(globalFileName)) { - const boost::filesystem::path globalFilePath(boost::filesystem::path(parentPath) / boost::filesystem::path(fileName)); - #if BOOST_FILESYSTEM_VERSION >= 3 + const std::filesystem::path globalFilePath(std::filesystem::path(parentPath) / std::filesystem::path(fileName)); globalFileName = globalFilePath.string(); - #else - globalFileName = globalFilePath.file_string(); - #endif } validateFile(globalFileName); return globalFileName; @@ -354,19 +340,11 @@ template struct PointMatcherIO::FileInfoVector; //! Throw a runtime_error exception if fileName cannot be opened void PointMatcherSupport::validateFile(const std::string& fileName) { - boost::filesystem::path fullPath(fileName); + std::filesystem::path fullPath(fileName); ifstream ifs(fileName.c_str()); - if (!ifs.good() || !boost::filesystem::is_regular_file(fullPath)) - #if BOOST_FILESYSTEM_VERSION >= 3 - #if BOOST_VERSION >= 105000 - throw runtime_error(string("Cannot open file ") + boost::filesystem::absolute(fullPath).generic_string()); - #else - throw runtime_error(string("Cannot open file ") + boost::filesystem3::complete(fullPath).generic_string()); - #endif - #else - throw runtime_error(string("Cannot open file ") + boost::filesystem::complete(fullPath).native_file_string()); - #endif + if (!ifs.good() || !std::filesystem::is_regular_file(fullPath)) + throw runtime_error(string("Cannot open file ") + std::filesystem::absolute(fullPath).generic_string()); } @@ -374,24 +352,24 @@ void PointMatcherSupport::validateFile(const std::string& fileName) template typename PointMatcher::DataPoints PointMatcher::DataPoints::load(const std::string& fileName) { - const boost::filesystem::path path(fileName); + const std::filesystem::path path(fileName); if (path.has_extension()) { const string& ext(path.extension().string()); - if(boost::iequals(ext, ".vtk")) + if(ext == ".vtk") return PointMatcherIO::loadVTK(fileName); - else if(boost::iequals(ext, ".csv")) + else if(ext == ".csv") return PointMatcherIO::loadCSV(fileName); - else if(boost::iequals(ext, ".ply")) + else if(ext == ".ply") return PointMatcherIO::loadPLY(fileName); - else if(boost::iequals(ext, ".pcd")) + else if(ext == ".pcd") return PointMatcherIO::loadPCD(fileName); else throw runtime_error("loadAnyFormat(): Unknown extension \"" + ext + "\" for file \"" + fileName + "\", extension must be either \".vtk\", \".ply\", \".pcd\" or \".csv\""); } else { - throw runtime_error("loadAnyFormat(): Missing extension for file \"" + fileName + "\", extension must be either \".vtk\" or \".csv\""); + throw runtime_error("loadAnyFormat(): Missing extension for file \"" + fileName + "\", extension must be either \".vtk\", \".ply\", \".pcd\" or \".csv\""); } } @@ -403,19 +381,19 @@ PointMatcher::DataPoints PointMatcher::DataPoints::load(const st //! @brief Load comma separated values (csv) file //! @param fileName a string containing the path and the file name -//! +//! //! This loader has 3 behaviors since there is no official standard for //! csv files. A 2D or 3D point cloud will be created automatically if: //! - there is a header with columns named x, y and optionnaly z //! - there are only 2 or 3 columns in the file //! -//! Otherwise, the user is asked to enter column id manually which might +//! Otherwise, the user is asked to enter column id manually which might //! block automatic processing. template typename PointMatcher::DataPoints PointMatcherIO::loadCSV(const std::string& fileName) { ifstream ifs(fileName.c_str()); - + validateFile(fileName); return loadCSV(ifs); @@ -443,7 +421,7 @@ void PointMatcherIO::LabelGenerator::add(const std::string internalName) findLabel = true; break; } - + } if(!findLabel) @@ -550,13 +528,13 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is unsigned int csvRow = 0; bool hasHeader(false); bool firstLine(true); - + //count lines in the file is.unsetf(std::ios_base::skipws); unsigned int line_count = std::count( std::istream_iterator(is), - std::istream_iterator(), + std::istream_iterator(), '\n'); //reset the stream is.clear(); @@ -567,11 +545,11 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is string line; while (safeGetLine(is, line)) { - + // Skip empty lines if(line.empty()) break; - + // Look for text header unsigned int len = strspn(line.c_str(), " ,+-.1234567890Ee"); if(len != line.length()) @@ -604,7 +582,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is dim++; token = strtok_r(NULL, delimiters, &brkt); } - + if (!hasHeader) { // Check if it is a simple file with only coordinates @@ -628,7 +606,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is csvHeader.push_back(GenericInputHeader(os.str())); } - + // Overwrite with user inputs csvHeader[idX] = GenericInputHeader("x"); csvHeader[idY] = GenericInputHeader("y"); @@ -654,7 +632,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is int rowIdDescriptors = 0; int rowIdTime = 0; - + // Loop through all known external names (ordered list) for(size_t i=0; i::DataPoints PointMatcherIO::loadCSV(std::istream& is throw runtime_error(string("CSV parse error: encounter a type different from FEATURE, DESCRIPTOR and TIME. Implementation not supported. See the definition of 'enum PMPropTypes'")); break; } - + // we stop searching once we have a match break; } @@ -705,7 +683,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is rowIdDescriptors++; } } - + //3- RESERVE MEMORY if(hasHeader && line_count > 0) @@ -727,7 +705,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is char line_c[1024];//FIXME: this might be a problem for large files strcpy(line_c,line.c_str()); token = strtok_r(line_c, delimiters, &brkt); - + if(!(hasHeader && firstLine)) { // Parse a line @@ -740,11 +718,11 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is throw runtime_error( (boost::format("CSV parse error: at line %1%, too many elements to parse compare to the header number of columns (col=%2%).") % csvRow % csvHeader.size()).str()); } - + // Alias const int matrixRow = csvHeader[csvCol].matrixRowId; const int matrixCol = csvRow; - + switch (csvHeader[csvCol].matrixType) { case FEATURE: @@ -766,8 +744,8 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is token = strtok_r(NULL, delimiters, &brkt); csvCol++; } - - + + // Error check (not enough data) if(csvCol != (csvHeader.size())) { @@ -779,7 +757,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is } firstLine = false; - + } // 5- ASSEMBLE FINAL DATAPOINTS @@ -794,7 +772,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadCSV(std::istream& is if(times.rows() > 0) { loadedPoints.times = times; - loadedPoints.timeLabels = timeLabelGen.getLabels(); + loadedPoints.timeLabels = timeLabelGen.getLabels(); } // Ensure homogeous coordinates @@ -815,7 +793,7 @@ PointMatcher::DataPoints PointMatcherIO::loadCSV(const std::stri template void PointMatcher::DataPoints::save(const std::string& fileName, bool binary, unsigned precision) const { - const boost::filesystem::path path(fileName); + const std::filesystem::path path(fileName); if (path.has_extension()) { const string& ext(path.extension().string()); @@ -864,13 +842,13 @@ void PointMatcherIO::saveCSV(const DataPoints& data, std::ostream& os) const int pointCount(data.features.cols()); const int dimCount(data.features.rows()); const int descDimCount(data.descriptors.rows()); - + if (pointCount == 0) { LOG_WARNING_STREAM( "Warning, no points, doing nothing"); return; } - + // write header for (int i = 0; i < dimCount - 1; i++) { @@ -913,7 +891,7 @@ void PointMatcherIO::saveCSV(const DataPoints& data, std::ostream& os) } os << "\n"; } - + } template @@ -965,7 +943,7 @@ template typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is) { std::map labelledSplitTime; - + DataPoints loadedPoints; // parse header @@ -999,7 +977,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is int dim = 0; int pointCount = 0; string type; - + while (is >> fieldName) { // load features @@ -1093,7 +1071,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is } else if(!(type == "float" || type == "double")) throw runtime_error(string("Field " + fieldName + " is " + type + " but can only be of type double or float")); - + Matrix descriptor(dim, pointCount); readVtkData(type, isBinary, descriptor.transpose(), is); @@ -1114,7 +1092,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is // label name is >> name; - + bool isTimeSec = false; bool isTimeNsec = false; @@ -1124,14 +1102,14 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is isTimeSec = true; boost::algorithm::erase_last(name, "_splitTime_high32"); } - + if(boost::algorithm::ends_with(name, "_splitTime_low32")) { isTimeNsec = true; boost::algorithm::erase_last(name, "_splitTime_low32"); } - + bool skipLookupTable = false; bool isColorScalars = false; if(fieldName == "SCALARS") @@ -1164,10 +1142,10 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is else throw runtime_error(string("Unknown field name " + fieldName + ", expecting SCALARS, VECTORS, TENSORS, NORMALS or COLOR_SCALARS.")); - + safeGetLine(is, line); // remove rest of the parameter line including its line end; - + // Load time data if(isTimeSec || isTimeNsec) { @@ -1176,7 +1154,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is { safeGetLine(is, line); } - + typename std::map::iterator it; it = labelledSplitTime.find(name); @@ -1196,7 +1174,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is readVtkData(type, isBinary, labelledSplitTime[name].high32.transpose(), is); labelledSplitTime[name].isHigh32Found = true; } - + // Load nano seconds if(isTimeNsec) { @@ -1207,10 +1185,10 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is } else { - + Matrix descriptorData(dim, pointCount); - - if(isColorScalars && isBinary) + + if(isColorScalars && isBinary) { std::vector buffer(dim); for (int i = 0; i < pointCount; ++i){ @@ -1219,8 +1197,8 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is descriptorData(r, i) = buffer[r] / static_cast(255.0); } } - } - else + } + else { if(!(type == "float" || type == "double")) throw runtime_error(string("Field " + fieldName + " is " + type + " but can only be of type double or float.")); @@ -1246,7 +1224,7 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is { throw runtime_error(string("Missing time field representing the higher 32 bits. Expecting SCALARS with name " + it->first + "_splitTime_high32 in the VTK file.")); } - + if(it->second.isLow32Found == false) { throw runtime_error(string("Missing time field representing the lower 32 bits. Expecting SCALARS with name " + it->first + "_splitTime_low32 in the VTK file.")); @@ -1256,13 +1234,13 @@ typename PointMatcher::DataPoints PointMatcherIO::loadVTK(std::istream& is Int64Matrix timeData(1,pointCount); for(int i=0; isecond.high32.cols(); i++) { - + timeData(0,i) = (((std::int64_t) it->second.high32(0,i)) << 32) | ((std::int64_t) it->second.low32(0,i)); } loadedPoints.addTime(it->first, timeData); } - + return loadedPoints; } @@ -1277,7 +1255,7 @@ template void PointMatcherIO::saveVTK(const DataPoints& data, const std::string& fileName, bool binary, unsigned precision) { typedef typename InspectorsImpl::VTKFileInspector VTKInspector; - + Parametrizable::Parameters param; boost::assign::insert(param) ("baseFileName", ""); boost::assign::insert(param) ("writeBinary", toParam(binary)); @@ -1504,22 +1482,22 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPLY(std::istream& // Fetch vertex PLYElement* vertex = elements[0]; - + if(vertex->name != "vertex") { throw runtime_error(string("PLY parse error: vertex should be the first element defined.")); } - + // Fetch known features and descriptors const SupportedLabels & externalLabels = getSupportedExternalLabels(); - + int rowIdFeatures = 0; int rowIdDescriptors = 0; int rowIdTime= 0; - + LabelGenerator featLabelGen, descLabelGen, timeLabelGen; - + // Loop through all known external names (ordered list) for(size_t i=0; i::DataPoints PointMatcherIO::loadPLY(std::istream& } } } - + // loop through the remaining UNSUPPORTED labels and assigned them to a single descriptor row for(it_PLYProp it=vertex->properties.begin(); it!=vertex->properties.end(); ++it) { @@ -1641,7 +1619,7 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPLY(std::istream& /////////////////////////// // 5- ASSEMBLE FINAL DATAPOINTS - + DataPoints loadedPoints(features, featLabelGen.getLabels()); if (descriptors.rows() > 0) @@ -1653,10 +1631,10 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPLY(std::istream& if(times.rows() > 0) { loadedPoints.times = times; - loadedPoints.timeLabels = timeLabelGen.getLabels(); + loadedPoints.timeLabels = timeLabelGen.getLabels(); } - // Ensure homogeous coordinates + // Ensure homogeneous coordinates if(!loadedPoints.featureExists("pad")) { loadedPoints.addFeature("pad", Matrix::Ones(1,features.cols())); @@ -1745,9 +1723,9 @@ void PointMatcherIO::savePLY(const DataPoints& data, const std::string& template PointMatcherIO::PLYProperty::PLYProperty(const std::string& type, const std::string& name, const unsigned pos) : - name(name), - type(type), - pos(pos) + name(name), + type(type), + pos(pos) { if (plyPropTypeValid(type)) { @@ -1770,15 +1748,15 @@ PointMatcherIO::PLYProperty::PLYProperty(const std::string& type, template PointMatcherIO::PLYProperty::PLYProperty(const std::string& idx_type, const std::string& type, const std::string& name, const unsigned pos) : - name(name), - type(type), - idx_type(idx_type), + name(name), + type(type), + idx_type(idx_type), pos(pos) { - if (plyPropTypeValid(idx_type) && plyPropTypeValid(type)) + if (plyPropTypeValid(idx_type) && plyPropTypeValid(type)) { is_list = true; - } + } else { throw std::runtime_error( @@ -1887,7 +1865,7 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& 1- PARSE PCD HEADER 2- ASSIGN PCD PROPERTIES TO DATAPOINTS ROWS 3- Reserve memory for a DataPoints - 4- Parse PCD XXX to appropriate DataPoints cols and rows + 4- Parse PCD XXX to appropriate DataPoints cols and rows 5- Assemble final DataPoints PCD organisation: @@ -1945,19 +1923,19 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& else if (tokens[0] == "FIELDS") { header.properties.resize(tokens.size() - 1); - + for (size_t i = 1; i < tokens.size(); i++) { header.properties[i-1].field = tokens[i]; } - + } else if (tokens[0] == "SIZE") { if((tokens.size() - 1) != header.properties.size()) throw runtime_error("PCD Parse Error: number of elements for SIZE must be the same as FIELDS"); - + for (size_t i = 1; i < tokens.size(); i++) { const unsigned int size = boost::lexical_cast(tokens[i]); @@ -1978,7 +1956,7 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& if (type != 'I' && type != 'U' && type != 'F') throw runtime_error("PCD Parse Error: invalid TYPE, it must be 'I', 'U', or 'F'"); } - + } else if (tokens[0] == "COUNT") @@ -1986,13 +1964,13 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& if((tokens.size() - 1) != header.properties.size()) throw runtime_error("PCD Parse Error: number of elements for COUNT must be the same as FIELDS"); - + for (size_t i = 1; i < tokens.size(); i++) { const unsigned int count = boost::lexical_cast(tokens[i]); header.properties[i-1].count = count; } - + } else if (tokens[0] == "WIDTH") @@ -2000,12 +1978,12 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& try { header.width = boost::lexical_cast(tokens[1]); - } + } catch (boost::bad_lexical_cast&) { throw runtime_error("PCD Parse Error: invalid WIDTH"); } - + } else if (tokens[0] == "HEIGHT") @@ -2013,12 +1991,12 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& try { header.height= boost::lexical_cast(tokens[1]); - } + } catch (boost::bad_lexical_cast&) { throw runtime_error("PCD Parse Error: invalid HEIGHT"); } - + } else if (tokens[0] == "VIEWPOINT") @@ -2059,7 +2037,7 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& else if (tokens[0] == "DATA") { header.dataType= tokens[1]; - + if (header.dataType == "ascii") { // DATA is the last element of the header, we exit the loop @@ -2094,11 +2072,11 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& // Fetch known features and descriptors const SupportedLabels & externalLabels = getSupportedExternalLabels(); - + int rowIdFeatures = 0; int rowIdDescriptors = 0; int rowIdTime= 0; - + LabelGenerator featLabelGen, descLabelGen, timeLabelGen; // Loop through all known external names (ordered list) @@ -2150,7 +2128,7 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& } } } - + // loop through the remaining UNSUPPORTED labels and assigned them to a single descriptor row for(size_t i=0; i < header.properties.size(); i++) { @@ -2247,7 +2225,7 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& /////////////////////////// // 5- ASSEMBLE FINAL DATAPOINTS - + DataPoints loadedPoints(features, featLabelGen.getLabels()); if (descriptors.rows() > 0) @@ -2259,7 +2237,7 @@ typename PointMatcherIO::DataPoints PointMatcherIO::loadPCD(std::istream& if(times.rows() > 0) { loadedPoints.times = times; - loadedPoints.timeLabels = timeLabelGen.getLabels(); + loadedPoints.timeLabels = timeLabelGen.getLabels(); } // Ensure homogeous coordinates @@ -2366,6 +2344,3 @@ template void PointMatcherIO::savePCD(const DataPoints& data, const std::string& fileName, unsigned precision); template void PointMatcherIO::savePCD(const DataPoints& data, const std::string& fileName, unsigned precision); - - - diff --git a/utest/ui/IO.cpp b/utest/ui/IO.cpp index f640a011..a76d986e 100644 --- a/utest/ui/IO.cpp +++ b/utest/ui/IO.cpp @@ -418,7 +418,7 @@ class IOLoadSaveTest : public testing::Test virtual void TearDown() { - EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(testFileName))); + EXPECT_TRUE(std::filesystem::remove(std::filesystem::path(testFileName))); } diff --git a/utest/ui/Loggers.cpp b/utest/ui/Loggers.cpp index bb93c605..d2da3799 100644 --- a/utest/ui/Loggers.cpp +++ b/utest/ui/Loggers.cpp @@ -23,8 +23,8 @@ TEST(Loggers, FileLogger) fileLog.reset(); // The logger needs to release the files to allow them to be removed - EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(infoFileName))); - EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(warningFileName))); + EXPECT_TRUE(std::filesystem::remove(std::filesystem::path(infoFileName))); + EXPECT_TRUE(std::filesystem::remove(std::filesystem::path(warningFileName))); } TEST(Loggers, FileLoggerInfoToConsole) @@ -65,7 +65,7 @@ TEST(Loggers, FileLoggerInfoToFile) fileLog.reset(); // The logger needs to release the file to allow it to be removed - EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(infoFileName))); + EXPECT_TRUE(std::filesystem::remove(std::filesystem::path(infoFileName))); } TEST(Loggers, FileLoggerWarningToFile) @@ -84,5 +84,5 @@ TEST(Loggers, FileLoggerWarningToFile) fileLog.reset(); // The logger needs to release the file to allow it to be removed - EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(warningFileName))); + EXPECT_TRUE(std::filesystem::remove(std::filesystem::path(warningFileName))); } diff --git a/utest/ui/icp/GeneralTests.cpp b/utest/ui/icp/GeneralTests.cpp index fa332bae..538480f2 100644 --- a/utest/ui/icp/GeneralTests.cpp +++ b/utest/ui/icp/GeneralTests.cpp @@ -72,7 +72,7 @@ TEST(icpTest, icpTest) DP ref = DP::load(dataPath + "cloud.00000.vtk"); DP data = DP::load(dataPath + "cloud.00001.vtk"); - namespace fs = boost::filesystem; + namespace fs = std::filesystem; fs::path config_dir(dataPath + "icp_data"); EXPECT_TRUE( fs::exists(config_dir) && fs::is_directory(config_dir) ); @@ -85,7 +85,7 @@ TEST(icpTest, icpTest) // Load config file, and form ICP object PM::ICP icp; std::string config_file = d->path().string(); - if (fs::extension(config_file) != ".yaml") continue; + if (d->path().extension().string() != ".yaml") continue; std::ifstream ifs(config_file.c_str()); EXPECT_NO_THROW(icp.loadFromYaml(ifs)) << "This error was caused by the test file:" << endl << " " << config_file; @@ -174,7 +174,7 @@ TEST(icpTest, icpSingular) PM::ICP icp; std::string config_file = dataPath + "default-identity.yaml"; - EXPECT_TRUE(boost::filesystem::exists(config_file)); + EXPECT_TRUE(std::filesystem::exists(config_file)); std::ifstream ifs(config_file.c_str()); EXPECT_NO_THROW(icp.loadFromYaml(ifs)) << "This error was caused by the test file:" << endl << " " << config_file; @@ -198,7 +198,7 @@ TEST(icpTest, icpIdentity) PM::ICP icp; std::string config_file = dataPath + "default-identity.yaml"; - EXPECT_TRUE(boost::filesystem::exists(config_file)); + EXPECT_TRUE(std::filesystem::exists(config_file)); std::ifstream ifs(config_file.c_str()); EXPECT_NO_THROW(icp.loadFromYaml(ifs)) << "This error was caused by the test file:" << endl << " " << config_file; @@ -218,7 +218,7 @@ TEST(icpTest, similarityTransform) PM::ICP icp; std::string config_file = dataPath + "icp_data/defaultSimilarityPointToPointMinDistDataPointsFilter.yaml"; - EXPECT_TRUE(boost::filesystem::exists(config_file)); + EXPECT_TRUE(std::filesystem::exists(config_file)); std::ifstream ifs(config_file.c_str()); EXPECT_NO_THROW(icp.loadFromYaml(ifs)) << "This error was caused by the test file:" << endl << " " << config_file; diff --git a/utest/utest.h b/utest/utest.h index 8a011335..c20a88b9 100644 --- a/utest/utest.h +++ b/utest/utest.h @@ -8,9 +8,7 @@ #include #include -#include "boost/filesystem.hpp" -#include "boost/filesystem/path.hpp" -#include "boost/filesystem/operations.hpp" +#include typedef double NumericType; typedef PointMatcher PM;