From df9d5598e169bd1a9db29d684689ba6832629e36 Mon Sep 17 00:00:00 2001 From: Linda ABLAOUI Date: Mon, 25 Jul 2022 10:09:15 +0200 Subject: [PATCH 01/28] add loaders for las and txt file format (point clouds) --- src/IO/AsciiPCLoader/asciipcloader.cpp | 200 ++++++++++++++++++++ src/IO/AsciiPCLoader/asciipcloader.hpp | 41 ++++ src/IO/CMakeLists.txt | 9 + src/IO/LasLoader/lasloader.cpp | 251 +++++++++++++++++++++++++ src/IO/LasLoader/lasloader.hpp | 45 +++++ src/IO/filelist.cmake | 14 ++ 6 files changed, 560 insertions(+) create mode 100644 src/IO/AsciiPCLoader/asciipcloader.cpp create mode 100644 src/IO/AsciiPCLoader/asciipcloader.hpp create mode 100644 src/IO/LasLoader/lasloader.cpp create mode 100644 src/IO/LasLoader/lasloader.hpp diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp new file mode 100644 index 00000000000..426d383cec4 --- /dev/null +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -0,0 +1,200 @@ +#include + +#include +#include //logs +#include +#include + +using std::to_string; +using std::runtime_error; +using std::ifstream; +using std::make_unique; + +const string trajExt("txt"); + +namespace Ra { +namespace IO { + + AsciiPointCloudLoader::AsciiPointCloudLoader () {} + + AsciiPointCloudLoader::~AsciiPointCloudLoader () {} + + vector AsciiPointCloudLoader::getFileExtensions () const { + return vector({"*." + trajExt}); + } + + bool AsciiPointCloudLoader::handleFileExtension (const string& extension) const { + return extension.compare(trajExt) == 0; + } + + Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile (const string& filename) { + using Ra::Core::Asset::GeometryData; + using Ra::Core::Asset::FileData; + using Ra::Core::Utils::logINFO; + using Ra::Core::Utils::logERROR; + + FileData* fileData = new Ra::Core::Asset::FileData(filename); + + if (!fileData->isInitialized()) { + delete fileData; + LOG(logINFO) << "Filedata could not be initialized"; + return nullptr; + } + + auto startTime = clock(); + // a unique name is required by the component messaging system + static int id = 0; + auto geometry = make_unique("TRAJ_PC_" + to_string(++id), GeometryData::POINT_CLOUD); + if (geometry == nullptr) { + LOG(logERROR) << "could not create geometry"; + return nullptr; + } + + geometry->setFrame(Ra::Core::Transform::Identity()); + + ifstream stream(filename); + if (!stream.is_open()) { + throw runtime_error("Could not open ifstream to path " + filename); + return nullptr; + } + else { + LOG(logINFO) << "---Beginning file loading---"; + } + + /*reading how data is arranged*/ + string line; + vector spacepos; + unsigned long timepos, xpos, ypos, zpos; + + if (!getline(stream, line)) { + delete fileData; + LOG(logINFO) << "file does not contain trajectory data format. aborting"; + return nullptr; + } + + timepos = line.find("Time"); + xpos = line.find(" X"); + ypos = line.find(" Y"); + zpos = line.find(" Z"); + + if (timepos == string::npos) { + delete fileData; + LOG(logINFO) << "file does not contain time property. aborting"; + return nullptr; + } + + if (xpos == string::npos) { + delete fileData; + LOG(logINFO) << "file does not contain X property. aborting"; + return nullptr; + } + + if (ypos == string::npos) { + delete fileData; + LOG(logINFO) << "file does not contain Y property. aborting"; + return nullptr; + } + + if (zpos == string::npos) { + delete fileData; + LOG(logINFO) << "file does not contain Z property. aborting"; + return nullptr; + } + + LOG(logINFO) << "Loading properties \"x\", \"y\", \"z\", \"time\"."; + + //skipping blank space + xpos++; ypos++; zpos++; + + /*retrieving x y z time attribut positions and column count*/ + int spacecount = 0; + for (size_t i = 0;i < line.length();++i) { + if (line[i] == ' ') { + spacepos.emplace_back(i); + spacecount++; + } + } + + for (int i = 0;i < spacecount;++i) { + if (timepos <= spacepos[i]) { + timepos = i; + break; + } + } + + for (int i = 0;i < spacecount;++i) { + if (xpos <= spacepos[i]) { + xpos = i; + break; + } + } + + for (int i = 0;i < spacecount;++i) { + if (ypos <= spacepos[i]) { + ypos = i; + break; + } + } + + for (int i = 0;i < spacecount;++i) { + if (zpos <= spacepos[i]) { + zpos = i; + break; + } + } + + vector pointRecord; + + auto& vertices = geometry->getGeometry().verticesWithLock(); + + //creating custom attrib for time record + auto handle = geometry->getGeometry().vertexAttribs().addAttrib("time"); + auto& attrib = geometry->getGeometry().vertexAttribs().getAttrib(handle); + auto& container = attrib.getDataWithLock(); + + /*recording data*/ + int i = 0; + double num; + while (stream >> num) { + pointRecord.emplace_back(num); + + //retrieving attributes from their position in line + if (i == spacecount) { + vertices.emplace_back(Scalar(pointRecord[xpos]), + Scalar(pointRecord[ypos]), + Scalar(pointRecord[zpos])); + container.emplace_back(Scalar(pointRecord[timepos])); + + pointRecord.clear(); + } + + i = (i + 1) % (spacecount + 1); + } + + stream.close(); + + geometry->getGeometry().verticesUnlock(); + geometry->getGeometry().vertexAttribs().unlock(handle); + + //finalizing + fileData->m_geometryData.clear(); + fileData->m_geometryData.reserve(1); + fileData->m_geometryData.push_back(move(geometry)); + + fileData->m_loadingTime = (clock() - startTime) / Scalar(CLOCKS_PER_SEC); + + LOG(logINFO) << "---File loading ended---"; + + fileData->displayInfo(); + + fileData->m_processed = true; + + return fileData; + } + + string AsciiPointCloudLoader::name () const { + return "Trajectory"; + } + +} //namespace IO +} //namespace Ra diff --git a/src/IO/AsciiPCLoader/asciipcloader.hpp b/src/IO/AsciiPCLoader/asciipcloader.hpp new file mode 100644 index 00000000000..b2b41454f9d --- /dev/null +++ b/src/IO/AsciiPCLoader/asciipcloader.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +using std::string; +using std::vector; + +namespace Ra { +namespace IO { + +class RA_IO_API AsciiPointCloudLoader : public Ra::Core::Asset::FileLoaderInterface { + public: + AsciiPointCloudLoader (); + + virtual ~AsciiPointCloudLoader (); + + vector getFileExtensions () const override; + bool handleFileExtension (const std::string& extension) const override; + + /** load vertices from .txt file + * + * load x, y, z and time from ASCII .txt file + * + * expected content in file: header line + data records + * + * header line content : attribute names separated by blanks ( ) + * + * example: Time X Y Z Roll Pitch Heading sdX sdY sdZ + * @note Although the header line can contain attributes other than coordinates and time, + * only these are loaded. X, Y, Z coordinates search in header line is case sensitive + * @param [in] filename file path + * @return nullptr if file opening, geometry creation fails + */ + Ra::Core::Asset::FileData* loadFile (const std::string& filename) override; + string name () const override; +}; + +} //namespace IO +} //namespace Ra + diff --git a/src/IO/CMakeLists.txt b/src/IO/CMakeLists.txt index 30469244143..dad30c5d4f0 100644 --- a/src/IO/CMakeLists.txt +++ b/src/IO/CMakeLists.txt @@ -7,6 +7,8 @@ option(RADIUM_IO_DEPRECATED "Provide deprecated loaders (to be removed without n option(RADIUM_IO_ASSIMP "Provide loaders based on Assimp library" ON) option(RADIUM_IO_TINYPLY "Provide loaders based on TinyPly library" ON) option(RADIUM_IO_VOLUMES "Provide loader for volume pvm file format" ON) +option(RADIUM_IO_LAS "Provide loader for las file format" OFF) +option(RADIUM_IO_ASCIIPC "Provide loader for point clouds in plain text (ascii) format" OFF) include(filelist.cmake) @@ -25,6 +27,13 @@ if(RADIUM_IO_TINYPLY) set_target_properties(${ra_io_target} PROPERTIES IO_HAS_TINYPLY ${RADIUM_IO_TINYPLY}) endif(RADIUM_IO_TINYPLY) +if(RADIUM_IO_LAS) + set_target_properties(${ra_io_target} PROPERTIES IO_HAS_LAS ${RADIUM_IO_LAS}) +endif(RADIUM_IO_LAS) +if(RADIUM_IO_ASCII) + set_target_properties(${ra_io_target} PROPERTIES IO_HAS_ASCIIPC ${RADIUM_IO_ASCIIPC}) +endif(RADIUM_IO_ASCII) + if(RADIUM_IO_ASSIMP) if(MSVC) if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp new file mode 100644 index 00000000000..419e8b474c6 --- /dev/null +++ b/src/IO/LasLoader/lasloader.cpp @@ -0,0 +1,251 @@ +#include + +#include +#include +#include + +using std::ifstream; +using std::ios; +using std::make_unique; +using std::to_string; +using std::runtime_error; + +const string lasExt("las"); + +namespace Ra { +namespace IO { + +LasLoader::LasLoader () {} + +LasLoader::~LasLoader () {} + +vector LasLoader::getFileExtensions () const { + return vector({"*." + lasExt}); +} + +bool LasLoader::handleFileExtension(const string& extension) const { + return extension.compare(lasExt) == 0; +} + +Ra::Core::Asset::FileData* LasLoader::loadFile (const string& filename) { + using Ra::Core::Asset::GeometryData; + using Ra::Core::Asset::FileData; + using Ra::Core::VectorArray; + using Ra::Core::Utils::logINFO; + using Ra::Core::Utils::logWARNING; + using Ra::Core::Utils::logERROR; + + FileData* fileData = new Ra::Core::Asset::FileData(filename); + + if (!fileData->isInitialized()) { + delete fileData; + LOG(logWARNING) << "Filedata could not be initialized"; + return nullptr; + } + + auto startTime = clock(); + // a unique name is required by the component messaging system + static int nameId = 0; + auto geometry = make_unique("LAS_PC_" + to_string(++nameId), GeometryData::POINT_CLOUD); + if (geometry == nullptr) { + LOG(logERROR) << "could not create geometry"; + return nullptr; + } + geometry->setFrame(Ra::Core::Transform::Identity()); + + ifstream stream(filename, ios::out | ios::binary); + + if (!stream.is_open()) { + throw runtime_error("Could not open binary ifstream to path " + filename ); + return nullptr; + } + else { + LOG(logINFO) << "---Beginning file loading---"; + } + + /*header part*/ + char buffer[48]; + + //reading minor version (needed to check data format) + stream.seekg(0); + stream.seekg(25); + stream.read(buffer, 1); + unsigned char minor = *(unsigned char*)buffer; + + if ((minor < 1) || (minor > 4)) { + delete fileData; + LOG(logERROR) << "LAS version 1." << (int)minor << " unsupported"; + return nullptr; + } + else { + LOG(logINFO) << "LAS version 1." << (int)minor; + } + + //reading distance from file start to first point record + stream.seekg(0); + stream.seekg(96); + stream.read(buffer, 4); + unsigned int offset = *(unsigned int*)buffer; + + //reading point data format + stream.seekg(0); + stream.seekg(104); + stream.read(buffer, 1); + unsigned char data_format = *(unsigned char*)buffer; + + if ((data_format < 0) + || (data_format > 3 && minor < 3) + || (data_format > 5 && minor == 3) + || (data_format > 6 && minor == 4)) { + delete fileData; + throw runtime_error("Corrupted file. Unvalid data format"); + return nullptr; + } + else { + LOG(logINFO) << "Data format " << (int)data_format; + LOG(logINFO) << "Loading properties \"x\", \"y\", \"z\","; + } + + //reading data record length (bytes) + stream.read(buffer, 2); + unsigned short data_len = *(unsigned short*)buffer; + + //reading total number of data records + stream.read(buffer, 4); + unsigned int nb_data = *(unsigned int*)buffer; + + //reading scales and offsets (used for computing coordinates) + stream.seekg(0); + stream.seekg(131); + stream.read(buffer, 48); + + double scale_x = *(double *)buffer; + double scale_y = *(double *)(buffer + 8); + double scale_z = *(double *)(buffer + 16); + double offset_x = *(double *)(buffer + 24); + double offset_y = *(double *)(buffer + 32); + double offset_z = *(double *)(buffer + 40); + + /*loading properties*/ + char* point = (char*)malloc(data_len * sizeof(char)); + + VectorArray& vertices = geometry->getGeometry().verticesWithLock(); + vertices.reserve(nb_data); + + //checking for colors + bool colors = false; + auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib( + Ra::Core::Geometry::getAttribName(Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR)); + VectorArray& color = geometry->getGeometry().vertexAttribs().getDataWithLock(handle_color); + if (data_format == 2 || data_format == 3 || (minor >= 3 && data_format == 5)) { + colors = true; + LOG(logINFO) << "\"red\", \"green\", \"blue\"."; + } + + //checking for GPS Time + bool gps_time = false; + auto handle_time = geometry->getGeometry().vertexAttribs().addAttrib("gps_time"); + VectorArray& time = geometry->getGeometry().vertexAttribs().getDataWithLock(handle_time); + if ((data_format == 1 ) + || (data_format == 3) + || ((minor > 2) && (data_format == 4)) + || ((minor > 2) && (data_format == 5)) + || ((minor == 4) && (data_format == 6))) { + gps_time = true; + LOG(logINFO) << "\"GPS time\"."; + } + + for (unsigned int i = 0;i < nb_data;++i) { + //positioning at point data location in file + int pos = offset + i * data_len; + stream.seekg(0); + stream.seekg(pos); + + //reading point data + stream.read(point, data_len); + + //extracting initial x y z coordinates + int ix; + int iy; + int iz; + + ix = *(int *)point; + iy = *(int *)(point + 4); + iz = *(int *)(point + 8); + + //computing actual coordinates + double x = (double) ix * scale_x + offset_x; + double y = (double) iy * scale_y + offset_y; + double z = (double) iz * scale_z + offset_z; + + //storing coordinates in vertices object + vertices.emplace_back(Scalar(x), Scalar(y), Scalar(z)); + + //computing colors if found + if (colors) { + unsigned short red, green, blue; + + if (data_format == 5 || data_format == 3) { + red = *(unsigned short*)(point + 28); + green = *(unsigned short*)(point + 30); + blue = *(unsigned short*)(point + 32); + } + else { + red = *(unsigned short*)(point + 20); + green = *(unsigned short*)(point + 22); + blue = *(unsigned short*)(point + 24); + } + + color.emplace_back(Scalar(red), Scalar(green), Scalar(blue), 1_ra); + } + + if (gps_time) { + //computing GPS time if found + if (data_format == 6) { + time.emplace_back()=(Scalar(*(double*)(point + 22))); + } + else { + time.emplace_back()=(Scalar(*(double*)(point + 20))); + } + } + } + stream.close(); + + geometry->getGeometry().verticesUnlock(); + geometry->getGeometry().vertexAttribs().unlock(handle_color); + geometry->getGeometry().vertexAttribs().unlock(handle_time); + + //removing colors if not found + if (!colors) { + geometry->getGeometry().vertexAttribs().removeAttrib(handle_color); + } + + //removing gps time if not found + if (!gps_time) { + geometry->getGeometry().vertexAttribs().removeAttrib(handle_time); + } + + free(point); + + //finalizing + fileData->m_geometryData.clear(); + fileData->m_geometryData.reserve(1); + fileData->m_geometryData.push_back(move(geometry)); + + fileData->m_loadingTime = (clock() - startTime) / Scalar(CLOCKS_PER_SEC); + + LOG(logINFO) << "---File loading ended---"; + + fileData->displayInfo(); + + fileData->m_processed = true; + + return fileData; +} + +string LasLoader::name () const { + return "LASer (.las)"; +} + +} //namespace IO +} //namespace Ra diff --git a/src/IO/LasLoader/lasloader.hpp b/src/IO/LasLoader/lasloader.hpp new file mode 100644 index 00000000000..1bfd0ee88d1 --- /dev/null +++ b/src/IO/LasLoader/lasloader.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include //AttribManager, logs +#include + +using std::string; +using std::vector; + +namespace Ra { +namespace IO { + +class RA_IO_API LasLoader : public Ra::Core::Asset::FileLoaderInterface { +public: + LasLoader (); + virtual ~LasLoader (); + + vector getFileExtensions () const override; + bool handleFileExtension (const std::string& extension) const override; + + /** load vertices from .las file + * + * load x, y, z point coordinates properties and; depending on + * data format parsed from header; red, green, blue and gps_time properties + * + * x, y, z coordinates are scaled according to scale and offset properties parsed + * from the file header + * + * support LAS specification version from 1.1 to 1.4 + * + * @note LAS specification lists other attributes that can be loaded + * for each point record (intensity, edge of flight line, scan direction, ...) however + * only the attributes mentionned above are loaded. See the official LAS specification + * for more details + * here + * @param [in] filename file path + * @return nullptr if file opening or geometry creation fails + */ + Ra::Core::Asset::FileData* loadFile (const std::string& filename) override; + string name () const override; +}; + +} //namespace IO +} //namespace Ra + diff --git a/src/IO/filelist.cmake b/src/IO/filelist.cmake index ee29da027be..f3cf88db5e3 100644 --- a/src/IO/filelist.cmake +++ b/src/IO/filelist.cmake @@ -62,3 +62,17 @@ if(RADIUM_IO_VOLUMES) list(APPEND io_headers VolumesLoader/pvmutils.hpp VolumesLoader/VolumeLoader.hpp) endif(RADIUM_IO_VOLUMES) + +if(RADIUM_IO_LAS) + list(APPEND io_sources LasLoader/lasloader.cpp) + + list(APPEND io_headers LasLoader/lasloader.hpp) + +endif(RADIUM_IO_LAS) + +if(RADIUM_IO_ASCIIPC) + list(APPEND io_sources AsciiPCLoader/asciipcloader.cpp) + + list(APPEND io_headers AsciiPCLoader/asciipcloader.hpp) + +endif(RADIUM_IO_ASCIIPC) From 9eccdfbefb64fc0729d14705bf685f045ebe0e1f Mon Sep 17 00:00:00 2001 From: Linda ABLAOUI Date: Mon, 25 Jul 2022 13:38:38 +0200 Subject: [PATCH 02/28] fix typo --- src/IO/LasLoader/lasloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 419e8b474c6..f876b9c2a74 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -202,10 +202,10 @@ Ra::Core::Asset::FileData* LasLoader::loadFile (const string& filename) { if (gps_time) { //computing GPS time if found if (data_format == 6) { - time.emplace_back()=(Scalar(*(double*)(point + 22))); + time.emplace_back(Scalar(*(double*)(point + 22))); } else { - time.emplace_back()=(Scalar(*(double*)(point + 20))); + time.emplace_back(Scalar(*(double*)(point + 20))); } } } From afaa7d906bc0bc798c7a6bfee49f76ae895e7b77 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 07:44:24 +0000 Subject: [PATCH 03/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/AsciiPCLoader/asciipcloader.cpp | 337 +++++++++++++------------ src/IO/AsciiPCLoader/asciipcloader.hpp | 58 ++--- src/IO/CMakeLists.txt | 10 +- src/IO/LasLoader/lasloader.cpp | 251 +++++++++--------- src/IO/LasLoader/lasloader.hpp | 25 +- src/IO/filelist.cmake | 8 +- 6 files changed, 343 insertions(+), 346 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 426d383cec4..5f1a9ab23b8 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -1,200 +1,203 @@ #include #include -#include //logs -#include +#include //logs #include +#include -using std::to_string; -using std::runtime_error; using std::ifstream; using std::make_unique; +using std::runtime_error; +using std::to_string; -const string trajExt("txt"); +const string trajExt( "txt" ); namespace Ra { namespace IO { - AsciiPointCloudLoader::AsciiPointCloudLoader () {} - - AsciiPointCloudLoader::~AsciiPointCloudLoader () {} - - vector AsciiPointCloudLoader::getFileExtensions () const { - return vector({"*." + trajExt}); - } - - bool AsciiPointCloudLoader::handleFileExtension (const string& extension) const { - return extension.compare(trajExt) == 0; - } - - Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile (const string& filename) { - using Ra::Core::Asset::GeometryData; - using Ra::Core::Asset::FileData; - using Ra::Core::Utils::logINFO; - using Ra::Core::Utils::logERROR; - - FileData* fileData = new Ra::Core::Asset::FileData(filename); - - if (!fileData->isInitialized()) { - delete fileData; - LOG(logINFO) << "Filedata could not be initialized"; - return nullptr; - } - - auto startTime = clock(); - // a unique name is required by the component messaging system - static int id = 0; - auto geometry = make_unique("TRAJ_PC_" + to_string(++id), GeometryData::POINT_CLOUD); - if (geometry == nullptr) { - LOG(logERROR) << "could not create geometry"; - return nullptr; - } +AsciiPointCloudLoader::AsciiPointCloudLoader() {} - geometry->setFrame(Ra::Core::Transform::Identity()); - - ifstream stream(filename); - if (!stream.is_open()) { - throw runtime_error("Could not open ifstream to path " + filename); - return nullptr; - } - else { - LOG(logINFO) << "---Beginning file loading---"; - } +AsciiPointCloudLoader::~AsciiPointCloudLoader() {} - /*reading how data is arranged*/ - string line; - vector spacepos; - unsigned long timepos, xpos, ypos, zpos; +vector AsciiPointCloudLoader::getFileExtensions() const { + return vector( { "*." + trajExt } ); +} - if (!getline(stream, line)) { - delete fileData; - LOG(logINFO) << "file does not contain trajectory data format. aborting"; - return nullptr; - } +bool AsciiPointCloudLoader::handleFileExtension( const string& extension ) const { + return extension.compare( trajExt ) == 0; +} - timepos = line.find("Time"); - xpos = line.find(" X"); - ypos = line.find(" Y"); - zpos = line.find(" Z"); - - if (timepos == string::npos) { - delete fileData; - LOG(logINFO) << "file does not contain time property. aborting"; - return nullptr; - } +Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filename ) { + using Ra::Core::Asset::FileData; + using Ra::Core::Asset::GeometryData; + using Ra::Core::Utils::logERROR; + using Ra::Core::Utils::logINFO; - if (xpos == string::npos) { - delete fileData; - LOG(logINFO) << "file does not contain X property. aborting"; - return nullptr; - } + FileData* fileData = new Ra::Core::Asset::FileData( filename ); - if (ypos == string::npos) { - delete fileData; - LOG(logINFO) << "file does not contain Y property. aborting"; - return nullptr; - } + if ( !fileData->isInitialized() ) { + delete fileData; + LOG( logINFO ) << "Filedata could not be initialized"; + return nullptr; + } - if (zpos == string::npos) { - delete fileData; - LOG(logINFO) << "file does not contain Z property. aborting"; - return nullptr; - } + auto startTime = clock(); + // a unique name is required by the component messaging system + static int id = 0; + auto geometry = + make_unique( "TRAJ_PC_" + to_string( ++id ), GeometryData::POINT_CLOUD ); + if ( geometry == nullptr ) { + LOG( logERROR ) << "could not create geometry"; + return nullptr; + } + + geometry->setFrame( Ra::Core::Transform::Identity() ); - LOG(logINFO) << "Loading properties \"x\", \"y\", \"z\", \"time\"."; + ifstream stream( filename ); + if ( !stream.is_open() ) { + throw runtime_error( "Could not open ifstream to path " + filename ); + return nullptr; + } + else { + LOG( logINFO ) << "---Beginning file loading---"; + } + + /*reading how data is arranged*/ + string line; + vector spacepos; + unsigned long timepos, xpos, ypos, zpos; + + if ( !getline( stream, line ) ) { + delete fileData; + LOG( logINFO ) << "file does not contain trajectory data format. aborting"; + return nullptr; + } - //skipping blank space - xpos++; ypos++; zpos++; + timepos = line.find( "Time" ); + xpos = line.find( " X" ); + ypos = line.find( " Y" ); + zpos = line.find( " Z" ); + + if ( timepos == string::npos ) { + delete fileData; + LOG( logINFO ) << "file does not contain time property. aborting"; + return nullptr; + } + + if ( xpos == string::npos ) { + delete fileData; + LOG( logINFO ) << "file does not contain X property. aborting"; + return nullptr; + } + + if ( ypos == string::npos ) { + delete fileData; + LOG( logINFO ) << "file does not contain Y property. aborting"; + return nullptr; + } - /*retrieving x y z time attribut positions and column count*/ - int spacecount = 0; - for (size_t i = 0;i < line.length();++i) { - if (line[i] == ' ') { - spacepos.emplace_back(i); - spacecount++; - } + if ( zpos == string::npos ) { + delete fileData; + LOG( logINFO ) << "file does not contain Z property. aborting"; + return nullptr; + } + + LOG( logINFO ) << "Loading properties \"x\", \"y\", \"z\", \"time\"."; + + // skipping blank space + xpos++; + ypos++; + zpos++; + + /*retrieving x y z time attribut positions and column count*/ + int spacecount = 0; + for ( size_t i = 0; i < line.length(); ++i ) { + if ( line[i] == ' ' ) { + spacepos.emplace_back( i ); + spacecount++; } + } - for (int i = 0;i < spacecount;++i) { - if (timepos <= spacepos[i]) { - timepos = i; - break; - } + for ( int i = 0; i < spacecount; ++i ) { + if ( timepos <= spacepos[i] ) { + timepos = i; + break; } + } - for (int i = 0;i < spacecount;++i) { - if (xpos <= spacepos[i]) { - xpos = i; - break; - } + for ( int i = 0; i < spacecount; ++i ) { + if ( xpos <= spacepos[i] ) { + xpos = i; + break; } + } - for (int i = 0;i < spacecount;++i) { - if (ypos <= spacepos[i]) { - ypos = i; - break; - } + for ( int i = 0; i < spacecount; ++i ) { + if ( ypos <= spacepos[i] ) { + ypos = i; + break; } + } + + for ( int i = 0; i < spacecount; ++i ) { + if ( zpos <= spacepos[i] ) { + zpos = i; + break; + } + } + + vector pointRecord; + + auto& vertices = geometry->getGeometry().verticesWithLock(); - for (int i = 0;i < spacecount;++i) { - if (zpos <= spacepos[i]) { - zpos = i; - break; - } + // creating custom attrib for time record + auto handle = geometry->getGeometry().vertexAttribs().addAttrib( "time" ); + auto& attrib = geometry->getGeometry().vertexAttribs().getAttrib( handle ); + auto& container = attrib.getDataWithLock(); + + /*recording data*/ + int i = 0; + double num; + while ( stream >> num ) { + pointRecord.emplace_back( num ); + + // retrieving attributes from their position in line + if ( i == spacecount ) { + vertices.emplace_back( Scalar( pointRecord[xpos] ), + Scalar( pointRecord[ypos] ), + Scalar( pointRecord[zpos] ) ); + container.emplace_back( Scalar( pointRecord[timepos] ) ); + + pointRecord.clear(); } - vector pointRecord; - - auto& vertices = geometry->getGeometry().verticesWithLock(); - - //creating custom attrib for time record - auto handle = geometry->getGeometry().vertexAttribs().addAttrib("time"); - auto& attrib = geometry->getGeometry().vertexAttribs().getAttrib(handle); - auto& container = attrib.getDataWithLock(); - - /*recording data*/ - int i = 0; - double num; - while (stream >> num) { - pointRecord.emplace_back(num); - - //retrieving attributes from their position in line - if (i == spacecount) { - vertices.emplace_back(Scalar(pointRecord[xpos]), - Scalar(pointRecord[ypos]), - Scalar(pointRecord[zpos])); - container.emplace_back(Scalar(pointRecord[timepos])); - - pointRecord.clear(); - } - - i = (i + 1) % (spacecount + 1); - } - - stream.close(); - - geometry->getGeometry().verticesUnlock(); - geometry->getGeometry().vertexAttribs().unlock(handle); - - //finalizing - fileData->m_geometryData.clear(); - fileData->m_geometryData.reserve(1); - fileData->m_geometryData.push_back(move(geometry)); - - fileData->m_loadingTime = (clock() - startTime) / Scalar(CLOCKS_PER_SEC); - - LOG(logINFO) << "---File loading ended---"; - - fileData->displayInfo(); - - fileData->m_processed = true; - - return fileData; - } - - string AsciiPointCloudLoader::name () const { - return "Trajectory"; + i = ( i + 1 ) % ( spacecount + 1 ); } - -} //namespace IO -} //namespace Ra + + stream.close(); + + geometry->getGeometry().verticesUnlock(); + geometry->getGeometry().vertexAttribs().unlock( handle ); + + // finalizing + fileData->m_geometryData.clear(); + fileData->m_geometryData.reserve( 1 ); + fileData->m_geometryData.push_back( move( geometry ) ); + + fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); + + LOG( logINFO ) << "---File loading ended---"; + + fileData->displayInfo(); + + fileData->m_processed = true; + + return fileData; +} + +string AsciiPointCloudLoader::name() const { + return "Trajectory"; +} + +} // namespace IO +} // namespace Ra diff --git a/src/IO/AsciiPCLoader/asciipcloader.hpp b/src/IO/AsciiPCLoader/asciipcloader.hpp index b2b41454f9d..57dfb18578e 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.hpp +++ b/src/IO/AsciiPCLoader/asciipcloader.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include using std::string; using std::vector; @@ -9,33 +9,33 @@ using std::vector; namespace Ra { namespace IO { -class RA_IO_API AsciiPointCloudLoader : public Ra::Core::Asset::FileLoaderInterface { - public: - AsciiPointCloudLoader (); - - virtual ~AsciiPointCloudLoader (); - - vector getFileExtensions () const override; - bool handleFileExtension (const std::string& extension) const override; - - /** load vertices from .txt file - * - * load x, y, z and time from ASCII .txt file - * - * expected content in file: header line + data records - * - * header line content : attribute names separated by blanks ( ) - * - * example: Time X Y Z Roll Pitch Heading sdX sdY sdZ - * @note Although the header line can contain attributes other than coordinates and time, - * only these are loaded. X, Y, Z coordinates search in header line is case sensitive - * @param [in] filename file path - * @return nullptr if file opening, geometry creation fails - */ - Ra::Core::Asset::FileData* loadFile (const std::string& filename) override; - string name () const override; +class RA_IO_API AsciiPointCloudLoader : public Ra::Core::Asset::FileLoaderInterface +{ + public: + AsciiPointCloudLoader(); + + virtual ~AsciiPointCloudLoader(); + + vector getFileExtensions() const override; + bool handleFileExtension( const std::string& extension ) const override; + + /** load vertices from .txt file + * + * load x, y, z and time from ASCII .txt file + * + * expected content in file: header line + data records + * + * header line content : attribute names separated by blanks ( ) + * + * example: Time X Y Z Roll Pitch Heading sdX sdY sdZ + * @note Although the header line can contain attributes other than coordinates and time, + * only these are loaded. X, Y, Z coordinates search in header line is case sensitive + * @param [in] filename file path + * @return nullptr if file opening, geometry creation fails + */ + Ra::Core::Asset::FileData* loadFile( const std::string& filename ) override; + string name() const override; }; -} //namespace IO -} //namespace Ra - +} // namespace IO +} // namespace Ra diff --git a/src/IO/CMakeLists.txt b/src/IO/CMakeLists.txt index dad30c5d4f0..40ed2166cc3 100644 --- a/src/IO/CMakeLists.txt +++ b/src/IO/CMakeLists.txt @@ -7,7 +7,7 @@ option(RADIUM_IO_DEPRECATED "Provide deprecated loaders (to be removed without n option(RADIUM_IO_ASSIMP "Provide loaders based on Assimp library" ON) option(RADIUM_IO_TINYPLY "Provide loaders based on TinyPly library" ON) option(RADIUM_IO_VOLUMES "Provide loader for volume pvm file format" ON) -option(RADIUM_IO_LAS "Provide loader for las file format" OFF) +option(RADIUM_IO_LAS "Provide loader for las file format" OFF) option(RADIUM_IO_ASCIIPC "Provide loader for point clouds in plain text (ascii) format" OFF) include(filelist.cmake) @@ -27,11 +27,11 @@ if(RADIUM_IO_TINYPLY) set_target_properties(${ra_io_target} PROPERTIES IO_HAS_TINYPLY ${RADIUM_IO_TINYPLY}) endif(RADIUM_IO_TINYPLY) -if(RADIUM_IO_LAS) - set_target_properties(${ra_io_target} PROPERTIES IO_HAS_LAS ${RADIUM_IO_LAS}) +if(RADIUM_IO_LAS) + set_target_properties(${ra_io_target} PROPERTIES IO_HAS_LAS ${RADIUM_IO_LAS}) endif(RADIUM_IO_LAS) -if(RADIUM_IO_ASCII) - set_target_properties(${ra_io_target} PROPERTIES IO_HAS_ASCIIPC ${RADIUM_IO_ASCIIPC}) +if(RADIUM_IO_ASCII) + set_target_properties(${ra_io_target} PROPERTIES IO_HAS_ASCIIPC ${RADIUM_IO_ASCIIPC}) endif(RADIUM_IO_ASCII) if(RADIUM_IO_ASSIMP) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index f876b9c2a74..2731e385fe1 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -1,240 +1,233 @@ #include #include -#include #include +#include using std::ifstream; using std::ios; using std::make_unique; -using std::to_string; using std::runtime_error; +using std::to_string; -const string lasExt("las"); +const string lasExt( "las" ); namespace Ra { namespace IO { -LasLoader::LasLoader () {} +LasLoader::LasLoader() {} -LasLoader::~LasLoader () {} +LasLoader::~LasLoader() {} -vector LasLoader::getFileExtensions () const { - return vector({"*." + lasExt}); +vector LasLoader::getFileExtensions() const { + return vector( { "*." + lasExt } ); } -bool LasLoader::handleFileExtension(const string& extension) const { - return extension.compare(lasExt) == 0; +bool LasLoader::handleFileExtension( const string& extension ) const { + return extension.compare( lasExt ) == 0; } -Ra::Core::Asset::FileData* LasLoader::loadFile (const string& filename) { - using Ra::Core::Asset::GeometryData; - using Ra::Core::Asset::FileData; +Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { using Ra::Core::VectorArray; + using Ra::Core::Asset::FileData; + using Ra::Core::Asset::GeometryData; + using Ra::Core::Utils::logERROR; using Ra::Core::Utils::logINFO; using Ra::Core::Utils::logWARNING; - using Ra::Core::Utils::logERROR; - FileData* fileData = new Ra::Core::Asset::FileData(filename); + FileData* fileData = new Ra::Core::Asset::FileData( filename ); - if (!fileData->isInitialized()) { + if ( !fileData->isInitialized() ) { delete fileData; - LOG(logWARNING) << "Filedata could not be initialized"; + LOG( logWARNING ) << "Filedata could not be initialized"; return nullptr; } auto startTime = clock(); // a unique name is required by the component messaging system static int nameId = 0; - auto geometry = make_unique("LAS_PC_" + to_string(++nameId), GeometryData::POINT_CLOUD); - if (geometry == nullptr) { - LOG(logERROR) << "could not create geometry"; + auto geometry = + make_unique( "LAS_PC_" + to_string( ++nameId ), GeometryData::POINT_CLOUD ); + if ( geometry == nullptr ) { + LOG( logERROR ) << "could not create geometry"; return nullptr; } - geometry->setFrame(Ra::Core::Transform::Identity()); + geometry->setFrame( Ra::Core::Transform::Identity() ); - ifstream stream(filename, ios::out | ios::binary); + ifstream stream( filename, ios::out | ios::binary ); - if (!stream.is_open()) { - throw runtime_error("Could not open binary ifstream to path " + filename ); + if ( !stream.is_open() ) { + throw runtime_error( "Could not open binary ifstream to path " + filename ); return nullptr; } else { - LOG(logINFO) << "---Beginning file loading---"; + LOG( logINFO ) << "---Beginning file loading---"; } /*header part*/ char buffer[48]; - //reading minor version (needed to check data format) - stream.seekg(0); - stream.seekg(25); - stream.read(buffer, 1); + // reading minor version (needed to check data format) + stream.seekg( 0 ); + stream.seekg( 25 ); + stream.read( buffer, 1 ); unsigned char minor = *(unsigned char*)buffer; - if ((minor < 1) || (minor > 4)) { + if ( ( minor < 1 ) || ( minor > 4 ) ) { delete fileData; - LOG(logERROR) << "LAS version 1." << (int)minor << " unsupported"; + LOG( logERROR ) << "LAS version 1." << (int)minor << " unsupported"; return nullptr; } else { - LOG(logINFO) << "LAS version 1." << (int)minor; + LOG( logINFO ) << "LAS version 1." << (int)minor; } - //reading distance from file start to first point record - stream.seekg(0); - stream.seekg(96); - stream.read(buffer, 4); + // reading distance from file start to first point record + stream.seekg( 0 ); + stream.seekg( 96 ); + stream.read( buffer, 4 ); unsigned int offset = *(unsigned int*)buffer; - //reading point data format - stream.seekg(0); - stream.seekg(104); - stream.read(buffer, 1); + // reading point data format + stream.seekg( 0 ); + stream.seekg( 104 ); + stream.read( buffer, 1 ); unsigned char data_format = *(unsigned char*)buffer; - if ((data_format < 0) - || (data_format > 3 && minor < 3) - || (data_format > 5 && minor == 3) - || (data_format > 6 && minor == 4)) { + if ( ( data_format < 0 ) || ( data_format > 3 && minor < 3 ) || + ( data_format > 5 && minor == 3 ) || ( data_format > 6 && minor == 4 ) ) { delete fileData; - throw runtime_error("Corrupted file. Unvalid data format"); + throw runtime_error( "Corrupted file. Unvalid data format" ); return nullptr; } else { - LOG(logINFO) << "Data format " << (int)data_format; - LOG(logINFO) << "Loading properties \"x\", \"y\", \"z\","; + LOG( logINFO ) << "Data format " << (int)data_format; + LOG( logINFO ) << "Loading properties \"x\", \"y\", \"z\","; } - //reading data record length (bytes) - stream.read(buffer, 2); + // reading data record length (bytes) + stream.read( buffer, 2 ); unsigned short data_len = *(unsigned short*)buffer; - //reading total number of data records - stream.read(buffer, 4); + // reading total number of data records + stream.read( buffer, 4 ); unsigned int nb_data = *(unsigned int*)buffer; - //reading scales and offsets (used for computing coordinates) - stream.seekg(0); - stream.seekg(131); - stream.read(buffer, 48); + // reading scales and offsets (used for computing coordinates) + stream.seekg( 0 ); + stream.seekg( 131 ); + stream.read( buffer, 48 ); - double scale_x = *(double *)buffer; - double scale_y = *(double *)(buffer + 8); - double scale_z = *(double *)(buffer + 16); - double offset_x = *(double *)(buffer + 24); - double offset_y = *(double *)(buffer + 32); - double offset_z = *(double *)(buffer + 40); + double scale_x = *(double*)buffer; + double scale_y = *(double*)( buffer + 8 ); + double scale_z = *(double*)( buffer + 16 ); + double offset_x = *(double*)( buffer + 24 ); + double offset_y = *(double*)( buffer + 32 ); + double offset_z = *(double*)( buffer + 40 ); /*loading properties*/ - char* point = (char*)malloc(data_len * sizeof(char)); + char* point = (char*)malloc( data_len * sizeof( char ) ); VectorArray& vertices = geometry->getGeometry().verticesWithLock(); - vertices.reserve(nb_data); + vertices.reserve( nb_data ); - //checking for colors - bool colors = false; + // checking for colors + bool colors = false; auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib( - Ra::Core::Geometry::getAttribName(Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR)); - VectorArray& color = geometry->getGeometry().vertexAttribs().getDataWithLock(handle_color); - if (data_format == 2 || data_format == 3 || (minor >= 3 && data_format == 5)) { + Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) ); + VectorArray& color = + geometry->getGeometry().vertexAttribs().getDataWithLock( handle_color ); + if ( data_format == 2 || data_format == 3 || ( minor >= 3 && data_format == 5 ) ) { colors = true; - LOG(logINFO) << "\"red\", \"green\", \"blue\"."; + LOG( logINFO ) << "\"red\", \"green\", \"blue\"."; } - //checking for GPS Time - bool gps_time = false; - auto handle_time = geometry->getGeometry().vertexAttribs().addAttrib("gps_time"); - VectorArray& time = geometry->getGeometry().vertexAttribs().getDataWithLock(handle_time); - if ((data_format == 1 ) - || (data_format == 3) - || ((minor > 2) && (data_format == 4)) - || ((minor > 2) && (data_format == 5)) - || ((minor == 4) && (data_format == 6))) { + // checking for GPS Time + bool gps_time = false; + auto handle_time = geometry->getGeometry().vertexAttribs().addAttrib( "gps_time" ); + VectorArray& time = + geometry->getGeometry().vertexAttribs().getDataWithLock( handle_time ); + if ( ( data_format == 1 ) || ( data_format == 3 ) || + ( ( minor > 2 ) && ( data_format == 4 ) ) || ( ( minor > 2 ) && ( data_format == 5 ) ) || + ( ( minor == 4 ) && ( data_format == 6 ) ) ) { gps_time = true; - LOG(logINFO) << "\"GPS time\"."; + LOG( logINFO ) << "\"GPS time\"."; } - for (unsigned int i = 0;i < nb_data;++i) { - //positioning at point data location in file + for ( unsigned int i = 0; i < nb_data; ++i ) { + // positioning at point data location in file int pos = offset + i * data_len; - stream.seekg(0); - stream.seekg(pos); + stream.seekg( 0 ); + stream.seekg( pos ); - //reading point data - stream.read(point, data_len); + // reading point data + stream.read( point, data_len ); - //extracting initial x y z coordinates + // extracting initial x y z coordinates int ix; int iy; int iz; - ix = *(int *)point; - iy = *(int *)(point + 4); - iz = *(int *)(point + 8); + ix = *(int*)point; + iy = *(int*)( point + 4 ); + iz = *(int*)( point + 8 ); - //computing actual coordinates - double x = (double) ix * scale_x + offset_x; - double y = (double) iy * scale_y + offset_y; - double z = (double) iz * scale_z + offset_z; + // computing actual coordinates + double x = (double)ix * scale_x + offset_x; + double y = (double)iy * scale_y + offset_y; + double z = (double)iz * scale_z + offset_z; - //storing coordinates in vertices object - vertices.emplace_back(Scalar(x), Scalar(y), Scalar(z)); + // storing coordinates in vertices object + vertices.emplace_back( Scalar( x ), Scalar( y ), Scalar( z ) ); - //computing colors if found - if (colors) { + // computing colors if found + if ( colors ) { unsigned short red, green, blue; - if (data_format == 5 || data_format == 3) { - red = *(unsigned short*)(point + 28); - green = *(unsigned short*)(point + 30); - blue = *(unsigned short*)(point + 32); + if ( data_format == 5 || data_format == 3 ) { + red = *(unsigned short*)( point + 28 ); + green = *(unsigned short*)( point + 30 ); + blue = *(unsigned short*)( point + 32 ); } else { - red = *(unsigned short*)(point + 20); - green = *(unsigned short*)(point + 22); - blue = *(unsigned short*)(point + 24); + red = *(unsigned short*)( point + 20 ); + green = *(unsigned short*)( point + 22 ); + blue = *(unsigned short*)( point + 24 ); } - color.emplace_back(Scalar(red), Scalar(green), Scalar(blue), 1_ra); + color.emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra ); } - if (gps_time) { - //computing GPS time if found - if (data_format == 6) { - time.emplace_back(Scalar(*(double*)(point + 22))); - } + if ( gps_time ) { + // computing GPS time if found + if ( data_format == 6 ) { time.emplace_back( Scalar( *(double*)( point + 22 ) ) ); } else { - time.emplace_back(Scalar(*(double*)(point + 20))); + time.emplace_back( Scalar( *(double*)( point + 20 ) ) ); } } } stream.close(); geometry->getGeometry().verticesUnlock(); - geometry->getGeometry().vertexAttribs().unlock(handle_color); - geometry->getGeometry().vertexAttribs().unlock(handle_time); + geometry->getGeometry().vertexAttribs().unlock( handle_color ); + geometry->getGeometry().vertexAttribs().unlock( handle_time ); - //removing colors if not found - if (!colors) { - geometry->getGeometry().vertexAttribs().removeAttrib(handle_color); - } + // removing colors if not found + if ( !colors ) { geometry->getGeometry().vertexAttribs().removeAttrib( handle_color ); } - //removing gps time if not found - if (!gps_time) { - geometry->getGeometry().vertexAttribs().removeAttrib(handle_time); - } + // removing gps time if not found + if ( !gps_time ) { geometry->getGeometry().vertexAttribs().removeAttrib( handle_time ); } - free(point); + free( point ); - //finalizing + // finalizing fileData->m_geometryData.clear(); - fileData->m_geometryData.reserve(1); - fileData->m_geometryData.push_back(move(geometry)); + fileData->m_geometryData.reserve( 1 ); + fileData->m_geometryData.push_back( move( geometry ) ); - fileData->m_loadingTime = (clock() - startTime) / Scalar(CLOCKS_PER_SEC); + fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); - LOG(logINFO) << "---File loading ended---"; + LOG( logINFO ) << "---File loading ended---"; fileData->displayInfo(); @@ -243,9 +236,9 @@ Ra::Core::Asset::FileData* LasLoader::loadFile (const string& filename) { return fileData; } -string LasLoader::name () const { +string LasLoader::name() const { return "LASer (.las)"; } -} //namespace IO -} //namespace Ra +} // namespace IO +} // namespace Ra diff --git a/src/IO/LasLoader/lasloader.hpp b/src/IO/LasLoader/lasloader.hpp index 1bfd0ee88d1..c1e1c2f72d5 100644 --- a/src/IO/LasLoader/lasloader.hpp +++ b/src/IO/LasLoader/lasloader.hpp @@ -10,13 +10,14 @@ using std::vector; namespace Ra { namespace IO { -class RA_IO_API LasLoader : public Ra::Core::Asset::FileLoaderInterface { -public: - LasLoader (); - virtual ~LasLoader (); +class RA_IO_API LasLoader : public Ra::Core::Asset::FileLoaderInterface +{ + public: + LasLoader(); + virtual ~LasLoader(); - vector getFileExtensions () const override; - bool handleFileExtension (const std::string& extension) const override; + vector getFileExtensions() const override; + bool handleFileExtension( const std::string& extension ) const override; /** load vertices from .las file * @@ -31,15 +32,15 @@ class RA_IO_API LasLoader : public Ra::Core::Asset::FileLoaderInterface { * @note LAS specification lists other attributes that can be loaded * for each point record (intensity, edge of flight line, scan direction, ...) however * only the attributes mentionned above are loaded. See the official LAS specification - * for more details + * for more details * here * @param [in] filename file path * @return nullptr if file opening or geometry creation fails */ - Ra::Core::Asset::FileData* loadFile (const std::string& filename) override; - string name () const override; + Ra::Core::Asset::FileData* loadFile( const std::string& filename ) override; + string name() const override; }; -} //namespace IO -} //namespace Ra - +} // namespace IO +} // namespace Ra diff --git a/src/IO/filelist.cmake b/src/IO/filelist.cmake index f3cf88db5e3..93c9d6c14ac 100644 --- a/src/IO/filelist.cmake +++ b/src/IO/filelist.cmake @@ -64,15 +64,15 @@ if(RADIUM_IO_VOLUMES) endif(RADIUM_IO_VOLUMES) if(RADIUM_IO_LAS) - list(APPEND io_sources LasLoader/lasloader.cpp) + list(APPEND io_sources LasLoader/lasloader.cpp) list(APPEND io_headers LasLoader/lasloader.hpp) - + endif(RADIUM_IO_LAS) if(RADIUM_IO_ASCIIPC) - list(APPEND io_sources AsciiPCLoader/asciipcloader.cpp) + list(APPEND io_sources AsciiPCLoader/asciipcloader.cpp) list(APPEND io_headers AsciiPCLoader/asciipcloader.hpp) - + endif(RADIUM_IO_ASCIIPC) From 5e396dd92cc31585ab34405f4222beb347ac20c7 Mon Sep 17 00:00:00 2001 From: Linda ABLAOUI Date: Tue, 26 Jul 2022 10:02:09 +0200 Subject: [PATCH 04/28] remove compilation guards --- src/IO/AsciiPCLoader/asciipcloader.cpp | 2 +- src/IO/CMakeLists.txt | 8 -------- src/IO/LasLoader/lasloader.cpp | 2 +- src/IO/filelist.cmake | 21 +++++++-------------- 4 files changed, 9 insertions(+), 24 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 5f1a9ab23b8..f8d8c08adc7 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include //logs diff --git a/src/IO/CMakeLists.txt b/src/IO/CMakeLists.txt index 40ed2166cc3..8c3ad1cbab9 100644 --- a/src/IO/CMakeLists.txt +++ b/src/IO/CMakeLists.txt @@ -7,8 +7,6 @@ option(RADIUM_IO_DEPRECATED "Provide deprecated loaders (to be removed without n option(RADIUM_IO_ASSIMP "Provide loaders based on Assimp library" ON) option(RADIUM_IO_TINYPLY "Provide loaders based on TinyPly library" ON) option(RADIUM_IO_VOLUMES "Provide loader for volume pvm file format" ON) -option(RADIUM_IO_LAS "Provide loader for las file format" OFF) -option(RADIUM_IO_ASCIIPC "Provide loader for point clouds in plain text (ascii) format" OFF) include(filelist.cmake) @@ -27,12 +25,6 @@ if(RADIUM_IO_TINYPLY) set_target_properties(${ra_io_target} PROPERTIES IO_HAS_TINYPLY ${RADIUM_IO_TINYPLY}) endif(RADIUM_IO_TINYPLY) -if(RADIUM_IO_LAS) - set_target_properties(${ra_io_target} PROPERTIES IO_HAS_LAS ${RADIUM_IO_LAS}) -endif(RADIUM_IO_LAS) -if(RADIUM_IO_ASCII) - set_target_properties(${ra_io_target} PROPERTIES IO_HAS_ASCIIPC ${RADIUM_IO_ASCIIPC}) -endif(RADIUM_IO_ASCII) if(RADIUM_IO_ASSIMP) if(MSVC) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 2731e385fe1..72f4e9d3ecf 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/IO/filelist.cmake b/src/IO/filelist.cmake index 93c9d6c14ac..cfa9dcfdc04 100644 --- a/src/IO/filelist.cmake +++ b/src/IO/filelist.cmake @@ -4,9 +4,14 @@ # ./generateFilelistForModule.sh IO # ---------------------------------------------------- -set(io_sources CameraLoader/CameraLoader.cpp) +set(io_sources CameraLoader/CameraLoader.cpp + AsciiPCLoader/asciipcloader.cpp + LasLoader/lasloader.cpp) -set(io_headers CameraLoader/CameraLoader.hpp RaIO.hpp) +set(io_headers CameraLoader/CameraLoader.hpp + LasLoader/lasloader.hpp + AsciiPCLoader/asciipcloader.hpp + RaIO.hpp) set(io_inlines) @@ -63,16 +68,4 @@ if(RADIUM_IO_VOLUMES) endif(RADIUM_IO_VOLUMES) -if(RADIUM_IO_LAS) - list(APPEND io_sources LasLoader/lasloader.cpp) - list(APPEND io_headers LasLoader/lasloader.hpp) - -endif(RADIUM_IO_LAS) - -if(RADIUM_IO_ASCIIPC) - list(APPEND io_sources AsciiPCLoader/asciipcloader.cpp) - - list(APPEND io_headers AsciiPCLoader/asciipcloader.hpp) - -endif(RADIUM_IO_ASCIIPC) From faa0394c3720d0566110cdc2d3d083de78c9a90c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 08:02:44 +0000 Subject: [PATCH 05/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/CMakeLists.txt | 1 - src/IO/filelist.cmake | 15 ++++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/IO/CMakeLists.txt b/src/IO/CMakeLists.txt index 8c3ad1cbab9..30469244143 100644 --- a/src/IO/CMakeLists.txt +++ b/src/IO/CMakeLists.txt @@ -25,7 +25,6 @@ if(RADIUM_IO_TINYPLY) set_target_properties(${ra_io_target} PROPERTIES IO_HAS_TINYPLY ${RADIUM_IO_TINYPLY}) endif(RADIUM_IO_TINYPLY) - if(RADIUM_IO_ASSIMP) if(MSVC) if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") diff --git a/src/IO/filelist.cmake b/src/IO/filelist.cmake index cfa9dcfdc04..4872ac65a01 100644 --- a/src/IO/filelist.cmake +++ b/src/IO/filelist.cmake @@ -4,14 +4,13 @@ # ./generateFilelistForModule.sh IO # ---------------------------------------------------- -set(io_sources CameraLoader/CameraLoader.cpp - AsciiPCLoader/asciipcloader.cpp - LasLoader/lasloader.cpp) +set(io_sources CameraLoader/CameraLoader.cpp AsciiPCLoader/asciipcloader.cpp + LasLoader/lasloader.cpp +) -set(io_headers CameraLoader/CameraLoader.hpp - LasLoader/lasloader.hpp - AsciiPCLoader/asciipcloader.hpp - RaIO.hpp) +set(io_headers CameraLoader/CameraLoader.hpp LasLoader/lasloader.hpp + AsciiPCLoader/asciipcloader.hpp RaIO.hpp +) set(io_inlines) @@ -67,5 +66,3 @@ if(RADIUM_IO_VOLUMES) list(APPEND io_headers VolumesLoader/pvmutils.hpp VolumesLoader/VolumeLoader.hpp) endif(RADIUM_IO_VOLUMES) - - From b4785893c9f1ac55f80461d9096bb0429bbd24a9 Mon Sep 17 00:00:00 2001 From: Linda Ablaoui <60941889+Marina2468@users.noreply.github.com> Date: Tue, 26 Jul 2022 12:10:37 +0200 Subject: [PATCH 06/28] Update src/IO/AsciiPCLoader/asciipcloader.cpp Co-authored-by: Nicolas Mellado --- src/IO/AsciiPCLoader/asciipcloader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index f8d8c08adc7..f4b6b54c647 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -73,6 +73,7 @@ Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filena return nullptr; } + // Find mandatory fields timepos = line.find( "Time" ); xpos = line.find( " X" ); ypos = line.find( " Y" ); From 9e979c3fa752faf3b9b59e49a522ce8d3e97fc92 Mon Sep 17 00:00:00 2001 From: Linda ABLAOUI Date: Tue, 26 Jul 2022 12:22:38 +0200 Subject: [PATCH 07/28] constructors set to default --- src/IO/AsciiPCLoader/asciipcloader.cpp | 2 -- src/IO/AsciiPCLoader/asciipcloader.hpp | 2 +- src/IO/LasLoader/lasloader.cpp | 2 -- src/IO/LasLoader/lasloader.hpp | 3 ++- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index f8d8c08adc7..65a85a032a0 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -15,8 +15,6 @@ const string trajExt( "txt" ); namespace Ra { namespace IO { -AsciiPointCloudLoader::AsciiPointCloudLoader() {} - AsciiPointCloudLoader::~AsciiPointCloudLoader() {} vector AsciiPointCloudLoader::getFileExtensions() const { diff --git a/src/IO/AsciiPCLoader/asciipcloader.hpp b/src/IO/AsciiPCLoader/asciipcloader.hpp index 57dfb18578e..f5dd19a0024 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.hpp +++ b/src/IO/AsciiPCLoader/asciipcloader.hpp @@ -12,7 +12,7 @@ namespace IO { class RA_IO_API AsciiPointCloudLoader : public Ra::Core::Asset::FileLoaderInterface { public: - AsciiPointCloudLoader(); + AsciiPointCloudLoader() = default; virtual ~AsciiPointCloudLoader(); diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 72f4e9d3ecf..27dc9425972 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -15,8 +15,6 @@ const string lasExt( "las" ); namespace Ra { namespace IO { -LasLoader::LasLoader() {} - LasLoader::~LasLoader() {} vector LasLoader::getFileExtensions() const { diff --git a/src/IO/LasLoader/lasloader.hpp b/src/IO/LasLoader/lasloader.hpp index c1e1c2f72d5..8c214e9af43 100644 --- a/src/IO/LasLoader/lasloader.hpp +++ b/src/IO/LasLoader/lasloader.hpp @@ -13,7 +13,8 @@ namespace IO { class RA_IO_API LasLoader : public Ra::Core::Asset::FileLoaderInterface { public: - LasLoader(); + LasLoader() = default; + virtual ~LasLoader(); vector getFileExtensions() const override; From 3573b19656bb70bd24e532407d76c28fb1870a14 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:24:30 +0000 Subject: [PATCH 08/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/LasLoader/lasloader.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/LasLoader/lasloader.hpp b/src/IO/LasLoader/lasloader.hpp index 8c214e9af43..feaa95aa4a0 100644 --- a/src/IO/LasLoader/lasloader.hpp +++ b/src/IO/LasLoader/lasloader.hpp @@ -14,7 +14,7 @@ class RA_IO_API LasLoader : public Ra::Core::Asset::FileLoaderInterface { public: LasLoader() = default; - + virtual ~LasLoader(); vector getFileExtensions() const override; From 814211f37bfc826dbb478d993d66345ffcd1637f Mon Sep 17 00:00:00 2001 From: Linda Ablaoui <60941889+Marina2468@users.noreply.github.com> Date: Tue, 26 Jul 2022 12:25:38 +0200 Subject: [PATCH 09/28] Update src/IO/AsciiPCLoader/asciipcloader.cpp Co-authored-by: Nicolas Mellado --- src/IO/AsciiPCLoader/asciipcloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 843e475c8be..1f33f023462 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -67,7 +67,7 @@ Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filena if ( !getline( stream, line ) ) { delete fileData; - LOG( logINFO ) << "file does not contain trajectory data format. aborting"; + LOG( logINFO ) << "file does not contain data format. aborting"; return nullptr; } From bbf14045e3add5b9090d29532c444e3901885500 Mon Sep 17 00:00:00 2001 From: Linda Ablaoui <60941889+Marina2468@users.noreply.github.com> Date: Tue, 26 Jul 2022 12:25:46 +0200 Subject: [PATCH 10/28] Update src/IO/AsciiPCLoader/asciipcloader.cpp Co-authored-by: Nicolas Mellado --- src/IO/AsciiPCLoader/asciipcloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 1f33f023462..696af98cc94 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -43,7 +43,7 @@ Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filena // a unique name is required by the component messaging system static int id = 0; auto geometry = - make_unique( "TRAJ_PC_" + to_string( ++id ), GeometryData::POINT_CLOUD ); + make_unique( "PC_" + to_string( ++id ), GeometryData::POINT_CLOUD ); if ( geometry == nullptr ) { LOG( logERROR ) << "could not create geometry"; return nullptr; From 1e49cd1077dde56be5244372d35c35c571fc6e3d Mon Sep 17 00:00:00 2001 From: Linda ABLAOUI Date: Tue, 26 Jul 2022 12:37:02 +0200 Subject: [PATCH 11/28] destructors set to default --- src/IO/AsciiPCLoader/asciipcloader.cpp | 2 -- src/IO/AsciiPCLoader/asciipcloader.hpp | 3 +-- src/IO/LasLoader/lasloader.cpp | 2 -- src/IO/LasLoader/lasloader.hpp | 3 +-- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 843e475c8be..a06b946b5e0 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -15,8 +15,6 @@ const string trajExt( "txt" ); namespace Ra { namespace IO { -AsciiPointCloudLoader::~AsciiPointCloudLoader() {} - vector AsciiPointCloudLoader::getFileExtensions() const { return vector( { "*." + trajExt } ); } diff --git a/src/IO/AsciiPCLoader/asciipcloader.hpp b/src/IO/AsciiPCLoader/asciipcloader.hpp index f5dd19a0024..72385ac38d9 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.hpp +++ b/src/IO/AsciiPCLoader/asciipcloader.hpp @@ -13,8 +13,7 @@ class RA_IO_API AsciiPointCloudLoader : public Ra::Core::Asset::FileLoaderInterf { public: AsciiPointCloudLoader() = default; - - virtual ~AsciiPointCloudLoader(); + virtual ~AsciiPointCloudLoader() = default; vector getFileExtensions() const override; bool handleFileExtension( const std::string& extension ) const override; diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 27dc9425972..6e56d6d790c 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -15,8 +15,6 @@ const string lasExt( "las" ); namespace Ra { namespace IO { -LasLoader::~LasLoader() {} - vector LasLoader::getFileExtensions() const { return vector( { "*." + lasExt } ); } diff --git a/src/IO/LasLoader/lasloader.hpp b/src/IO/LasLoader/lasloader.hpp index 8c214e9af43..da36f2cc797 100644 --- a/src/IO/LasLoader/lasloader.hpp +++ b/src/IO/LasLoader/lasloader.hpp @@ -14,8 +14,7 @@ class RA_IO_API LasLoader : public Ra::Core::Asset::FileLoaderInterface { public: LasLoader() = default; - - virtual ~LasLoader(); + virtual ~LasLoader() = default; vector getFileExtensions() const override; bool handleFileExtension( const std::string& extension ) const override; From 211b6f6ec66846526aa7f148b5c685969ecc7bcd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:51:31 +0000 Subject: [PATCH 12/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/AsciiPCLoader/asciipcloader.hpp | 2 +- src/IO/LasLoader/lasloader.cpp | 28 +++++++++++++------------- src/IO/LasLoader/lasloader.hpp | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.hpp b/src/IO/AsciiPCLoader/asciipcloader.hpp index 72385ac38d9..cbcd0bde553 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.hpp +++ b/src/IO/AsciiPCLoader/asciipcloader.hpp @@ -12,7 +12,7 @@ namespace IO { class RA_IO_API AsciiPointCloudLoader : public Ra::Core::Asset::FileLoaderInterface { public: - AsciiPointCloudLoader() = default; + AsciiPointCloudLoader() = default; virtual ~AsciiPointCloudLoader() = default; vector getFileExtensions() const override; diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index cab604029d5..0bbbde6a9aa 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -90,8 +90,8 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { stream.read( buffer, 1 ); unsigned char data_format = *(unsigned char*)buffer; - if ( ( data_format > 3 && minor < 3 ) || - ( data_format > 5 && minor == 3 ) || ( data_format > 6 && minor == 4 ) ) { + if ( ( data_format > 3 && minor < 3 ) || ( data_format > 5 && minor == 3 ) || + ( data_format > 6 && minor == 4 ) ) { delete fileData; throw runtime_error( "Corrupted file. Unvalid data format" ); return nullptr; @@ -114,15 +114,15 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { stream.seekg( 131 ); stream.read( buffer, 48 ); - double scale_x = *(reinterpret_cast(buffer)); - double scale_y = *(reinterpret_cast(buffer + 8)); - double scale_z = *(reinterpret_cast(buffer + 16)); - double offset_x = *(reinterpret_cast(buffer + 24)); - double offset_y = *(reinterpret_cast(buffer + 32)); - double offset_z = *(reinterpret_cast(buffer + 40)); + double scale_x = *( reinterpret_cast( buffer ) ); + double scale_y = *( reinterpret_cast( buffer + 8 ) ); + double scale_z = *( reinterpret_cast( buffer + 16 ) ); + double offset_x = *( reinterpret_cast( buffer + 24 ) ); + double offset_y = *( reinterpret_cast( buffer + 32 ) ); + double offset_z = *( reinterpret_cast( buffer + 40 ) ); /*loading properties*/ - vector point ( data_len ); + vector point( data_len ); VectorArray& vertices = geometry->getGeometry().verticesWithLock(); vertices.reserve( nb_data ); @@ -194,13 +194,13 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { color.emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra ); } - if (gps_time) { - //computing GPS time if found - if (data_format == 6) { - time.emplace_back(Scalar(*reinterpret_cast(point.data() + 22))); + if ( gps_time ) { + // computing GPS time if found + if ( data_format == 6 ) { + time.emplace_back( Scalar( *reinterpret_cast( point.data() + 22 ) ) ); } else { - time.emplace_back(Scalar(*reinterpret_cast(point.data() + 20))); + time.emplace_back( Scalar( *reinterpret_cast( point.data() + 20 ) ) ); } } } diff --git a/src/IO/LasLoader/lasloader.hpp b/src/IO/LasLoader/lasloader.hpp index da36f2cc797..fef0dedd849 100644 --- a/src/IO/LasLoader/lasloader.hpp +++ b/src/IO/LasLoader/lasloader.hpp @@ -13,7 +13,7 @@ namespace IO { class RA_IO_API LasLoader : public Ra::Core::Asset::FileLoaderInterface { public: - LasLoader() = default; + LasLoader() = default; virtual ~LasLoader() = default; vector getFileExtensions() const override; From c16169b031171c76cd2eae38aa8d64ec7871b807 Mon Sep 17 00:00:00 2001 From: Linda Ablaoui <60941889+Marina2468@users.noreply.github.com> Date: Tue, 26 Jul 2022 13:07:40 +0200 Subject: [PATCH 13/28] group log (remove code duplicate) --- src/IO/AsciiPCLoader/asciipcloader.cpp | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 7bd239a18f8..0d266dcb265 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -75,27 +75,10 @@ Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filena ypos = line.find( " Y" ); zpos = line.find( " Z" ); - if ( timepos == string::npos ) { + if (( timepos == string::npos ) || ( xpos == string::npos ) + || ( ypos == string::npos ) || ( zpos == string::npos )) { delete fileData; - LOG( logINFO ) << "file does not contain time property. aborting"; - return nullptr; - } - - if ( xpos == string::npos ) { - delete fileData; - LOG( logINFO ) << "file does not contain X property. aborting"; - return nullptr; - } - - if ( ypos == string::npos ) { - delete fileData; - LOG( logINFO ) << "file does not contain Y property. aborting"; - return nullptr; - } - - if ( zpos == string::npos ) { - delete fileData; - LOG( logINFO ) << "file does not contain Z property. aborting"; + LOG( logINFO ) << "file does not contain mandatory properties (X, Y, Z, time). aborting"; return nullptr; } From 85c7236b7b12e64169d53bc369733afd7409e71c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 11:07:58 +0000 Subject: [PATCH 14/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/AsciiPCLoader/asciipcloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 0d266dcb265..8e339466657 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -75,8 +75,8 @@ Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filena ypos = line.find( " Y" ); zpos = line.find( " Z" ); - if (( timepos == string::npos ) || ( xpos == string::npos ) - || ( ypos == string::npos ) || ( zpos == string::npos )) { + if ( ( timepos == string::npos ) || ( xpos == string::npos ) || ( ypos == string::npos ) || + ( zpos == string::npos ) ) { delete fileData; LOG( logINFO ) << "file does not contain mandatory properties (X, Y, Z, time). aborting"; return nullptr; From 5b6f9911366406a328017adc0bce9b40f17ca324 Mon Sep 17 00:00:00 2001 From: Linda Ablaoui <60941889+Marina2468@users.noreply.github.com> Date: Tue, 26 Jul 2022 14:31:27 +0200 Subject: [PATCH 15/28] update color and gps handling --- src/IO/LasLoader/lasloader.cpp | 223 ++++++++++++++++----------------- 1 file changed, 110 insertions(+), 113 deletions(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 0bbbde6a9aa..96184880aa9 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -24,208 +24,205 @@ bool LasLoader::handleFileExtension( const string& extension ) const { } Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { - using Ra::Core::VectorArray; - using Ra::Core::Asset::FileData; using Ra::Core::Asset::GeometryData; - using Ra::Core::Utils::logERROR; + using Ra::Core::Asset::FileData; + using Ra::Core::VectorArray; using Ra::Core::Utils::logINFO; using Ra::Core::Utils::logWARNING; + using Ra::Core::Utils::logERROR; - FileData* fileData = new Ra::Core::Asset::FileData( filename ); + FileData* fileData = new Ra::Core::Asset::FileData(filename); - if ( !fileData->isInitialized() ) { + if (!fileData->isInitialized()) { delete fileData; - LOG( logWARNING ) << "Filedata could not be initialized"; + LOG(logWARNING) << "Filedata could not be initialized"; return nullptr; } auto startTime = clock(); // a unique name is required by the component messaging system static int nameId = 0; - auto geometry = - make_unique( "LAS_PC_" + to_string( ++nameId ), GeometryData::POINT_CLOUD ); - if ( geometry == nullptr ) { - LOG( logERROR ) << "could not create geometry"; + auto geometry = make_unique("LAS_PC_" + to_string(++nameId), GeometryData::POINT_CLOUD); + if (geometry == nullptr) { + LOG(logERROR) << "could not create geometry"; return nullptr; } - geometry->setFrame( Ra::Core::Transform::Identity() ); + geometry->setFrame(Ra::Core::Transform::Identity()); - ifstream stream( filename, ios::out | ios::binary ); + ifstream stream(filename, ios::out | ios::binary); - if ( !stream.is_open() ) { - throw runtime_error( "Could not open binary ifstream to path " + filename ); + if (!stream.is_open()) { + throw runtime_error("Could not open binary ifstream to path " + filename ); return nullptr; } else { - LOG( logINFO ) << "---Beginning file loading---"; + LOG(logINFO) << "---Beginning file loading---"; } /*header part*/ char buffer[48]; - // reading minor version (needed to check data format) - stream.seekg( 0 ); - stream.seekg( 25 ); - stream.read( buffer, 1 ); + //reading minor version (needed to check data format) + stream.seekg(0); + stream.seekg(25); + stream.read(buffer, 1); unsigned char minor = *(unsigned char*)buffer; - if ( ( minor < 1 ) || ( minor > 4 ) ) { + if ((minor < 1) || (minor > 4)) { delete fileData; - LOG( logERROR ) << "LAS version 1." << (int)minor << " unsupported"; + LOG(logERROR) << "LAS version 1." << (int)minor << " unsupported"; return nullptr; } else { - LOG( logINFO ) << "LAS version 1." << (int)minor; + LOG(logINFO) << "LAS version 1." << (int)minor; } - // reading distance from file start to first point record - stream.seekg( 0 ); - stream.seekg( 96 ); - stream.read( buffer, 4 ); + //reading distance from file start to first point record + stream.seekg(0); + stream.seekg(96); + stream.read(buffer, 4); unsigned int offset = *(unsigned int*)buffer; - // reading point data format - stream.seekg( 0 ); - stream.seekg( 104 ); - stream.read( buffer, 1 ); + //reading point data format + stream.seekg(0); + stream.seekg(104); + stream.read(buffer, 1); unsigned char data_format = *(unsigned char*)buffer; - if ( ( data_format > 3 && minor < 3 ) || ( data_format > 5 && minor == 3 ) || - ( data_format > 6 && minor == 4 ) ) { + if ((data_format < 0) + || (data_format > 3 && minor < 3) + || (data_format > 5 && minor == 3) + || (data_format > 6 && minor == 4)) { delete fileData; - throw runtime_error( "Corrupted file. Unvalid data format" ); + throw runtime_error("Corrupted file. Unvalid data format"); return nullptr; } else { - LOG( logINFO ) << "Data format " << (int)data_format; - LOG( logINFO ) << "Loading properties \"x\", \"y\", \"z\","; + LOG(logINFO) << "Data format " << (int)data_format; + LOG(logINFO) << "Loading properties \"x\", \"y\", \"z\","; } - // reading data record length (bytes) - stream.read( buffer, 2 ); + //reading data record length (bytes) + stream.read(buffer, 2); unsigned short data_len = *(unsigned short*)buffer; - // reading total number of data records - stream.read( buffer, 4 ); + //reading total number of data records + stream.read(buffer, 4); unsigned int nb_data = *(unsigned int*)buffer; - // reading scales and offsets (used for computing coordinates) - stream.seekg( 0 ); - stream.seekg( 131 ); - stream.read( buffer, 48 ); + //reading scales and offsets (used for computing coordinates) + stream.seekg(0); + stream.seekg(131); + stream.read(buffer, 48); - double scale_x = *( reinterpret_cast( buffer ) ); - double scale_y = *( reinterpret_cast( buffer + 8 ) ); - double scale_z = *( reinterpret_cast( buffer + 16 ) ); - double offset_x = *( reinterpret_cast( buffer + 24 ) ); - double offset_y = *( reinterpret_cast( buffer + 32 ) ); - double offset_z = *( reinterpret_cast( buffer + 40 ) ); + double scale_x = *(reinterpret_cast(buffer)); + double scale_y = *(reinterpret_cast(buffer + 8)); + double scale_z = *(reinterpret_cast(buffer + 16)); + double offset_x = *(reinterpret_cast(buffer + 24)); + double offset_y = *(reinterpret_cast(buffer + 32)); + double offset_z = *(reinterpret_cast(buffer + 40)); /*loading properties*/ - vector point( data_len ); + vector point (data_len); VectorArray& vertices = geometry->getGeometry().verticesWithLock(); - vertices.reserve( nb_data ); - - // checking for colors - bool colors = false; - auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib( - Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) ); - VectorArray& color = - geometry->getGeometry().vertexAttribs().getDataWithLock( handle_color ); - if ( data_format == 2 || data_format == 3 || ( minor >= 3 && data_format == 5 ) ) { + vertices.reserve(nb_data); + + //checking for colors + bool colors = false; + if (data_format == 2 || data_format == 3 || (minor >= 3 && data_format == 5)) { + auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib( + Ra::Core::Geometry::getAttribName(Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR)); colors = true; - LOG( logINFO ) << "\"red\", \"green\", \"blue\"."; + LOG(logINFO) << "\"red\", \"green\", \"blue\"."; } - // checking for GPS Time - bool gps_time = false; - auto handle_time = geometry->getGeometry().vertexAttribs().addAttrib( "gps_time" ); - VectorArray& time = - geometry->getGeometry().vertexAttribs().getDataWithLock( handle_time ); - if ( ( data_format == 1 ) || ( data_format == 3 ) || - ( ( minor > 2 ) && ( data_format == 4 ) ) || ( ( minor > 2 ) && ( data_format == 5 ) ) || - ( ( minor == 4 ) && ( data_format == 6 ) ) ) { + //checking for GPS Time + bool gps_time = false; + if ((data_format == 1 ) + || (data_format == 3) + || ((minor > 2) && (data_format == 4)) + || ((minor > 2) && (data_format == 5)) + || ((minor == 4) && (data_format == 6))) { + auto handle_time = geometry->getGeometry().vertexAttribs().addAttrib("gps_time"); gps_time = true; - LOG( logINFO ) << "\"GPS time\"."; + LOG(logINFO) << "\"GPS time\"."; } - for ( unsigned int i = 0; i < nb_data; ++i ) { - // positioning at point data location in file + for (unsigned int i = 0;i < nb_data;++i) { + //positioning at point data location in file int pos = offset + i * data_len; - stream.seekg( 0 ); - stream.seekg( pos ); + stream.seekg(0); + stream.seekg(pos); - // reading point data - stream.read( point.data(), data_len ); + //reading point data + stream.read(point.data(), data_len); - // extracting initial x y z coordinates + //extracting initial x y z coordinates int ix; int iy; int iz; - ix = *(int*)point.data(); - iy = *(int*)( point.data() + 4 ); - iz = *(int*)( point.data() + 8 ); + ix = *(int *)(point.data()); + iy = *(int *)(point.data() + 4); + iz = *(int *)(point.data() + 8); - // computing actual coordinates - double x = (double)ix * scale_x + offset_x; - double y = (double)iy * scale_y + offset_y; - double z = (double)iz * scale_z + offset_z; + //computing actual coordinates + double x = (double) ix * scale_x + offset_x; + double y = (double) iy * scale_y + offset_y; + double z = (double) iz * scale_z + offset_z; - // storing coordinates in vertices object - vertices.emplace_back( Scalar( x ), Scalar( y ), Scalar( z ) ); + //storing coordinates in vertices object + vertices.emplace_back(Scalar(x), Scalar(y), Scalar(z)); - // computing colors if found - if ( colors ) { + //computing colors if found + if (colors) { unsigned short red, green, blue; - if ( data_format == 5 || data_format == 3 ) { - red = *(unsigned short*)( point.data() + 28 ); - green = *(unsigned short*)( point.data() + 30 ); - blue = *(unsigned short*)( point.data() + 32 ); + if (data_format == 5 || data_format == 3) { + red = *(unsigned short*)(point.data() + 28); + green = *(unsigned short*)(point.data() + 30); + blue = *(unsigned short*)(point.data() + 32); } else { - red = *(unsigned short*)( point.data() + 20 ); - green = *(unsigned short*)( point.data() + 22 ); - blue = *(unsigned short*)( point.data() + 24 ); + red = *(unsigned short*)(point.data() + 20); + green = *(unsigned short*)(point.data() + 22); + blue = *(unsigned short*)(point.data() + 24); } - color.emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra ); + auto handle_colors = geometry->getGeometry().vertexAttribs().findAttrib( + Ra::Core::Geometry::getAttribName(Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR)); + geometry->getGeometry().vertexAttribs().getDataWithLock(handle_colors).emplace_back(Scalar(red), Scalar(green), Scalar(blue), 1_ra); + geometry->getGeometry().vertexAttribs().unlock(handle_colors); } - if ( gps_time ) { - // computing GPS time if found - if ( data_format == 6 ) { - time.emplace_back( Scalar( *reinterpret_cast( point.data() + 22 ) ) ); + if (gps_time) { + //computing GPS time if found + auto handle_time = geometry->getGeometry().vertexAttribs().findAttrib("gps_time"); + auto& time = geometry->getGeometry().vertexAttribs().getDataWithLock(handle_time); + if (data_format == 6) { + time.emplace_back(Scalar(*reinterpret_cast(point.data() + 22))); } else { - time.emplace_back( Scalar( *reinterpret_cast( point.data() + 20 ) ) ); + time.emplace_back(Scalar(*reinterpret_cast(point.data() + 20))); } + geometry->getGeometry().vertexAttribs().unlock(handle_time); } } stream.close(); geometry->getGeometry().verticesUnlock(); - geometry->getGeometry().vertexAttribs().unlock( handle_color ); - geometry->getGeometry().vertexAttribs().unlock( handle_time ); - - // removing colors if not found - if ( !colors ) { geometry->getGeometry().vertexAttribs().removeAttrib( handle_color ); } - - // removing gps time if not found - if ( !gps_time ) { geometry->getGeometry().vertexAttribs().removeAttrib( handle_time ); } point.clear(); - // finalizing + //finalizing fileData->m_geometryData.clear(); - fileData->m_geometryData.reserve( 1 ); - fileData->m_geometryData.push_back( move( geometry ) ); + fileData->m_geometryData.reserve(1); + fileData->m_geometryData.push_back(move(geometry)); - fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); + fileData->m_loadingTime = (clock() - startTime) / Scalar(CLOCKS_PER_SEC); - LOG( logINFO ) << "---File loading ended---"; + LOG(logINFO) << "---File loading ended---"; fileData->displayInfo(); From 6f9e1faf4512886d7471dde9c969107867839cae Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 12:32:38 +0000 Subject: [PATCH 16/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/LasLoader/lasloader.cpp | 217 +++++++++++++++++---------------- 1 file changed, 110 insertions(+), 107 deletions(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 96184880aa9..09260c4014c 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -24,189 +24,192 @@ bool LasLoader::handleFileExtension( const string& extension ) const { } Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { - using Ra::Core::Asset::GeometryData; - using Ra::Core::Asset::FileData; using Ra::Core::VectorArray; + using Ra::Core::Asset::FileData; + using Ra::Core::Asset::GeometryData; + using Ra::Core::Utils::logERROR; using Ra::Core::Utils::logINFO; using Ra::Core::Utils::logWARNING; - using Ra::Core::Utils::logERROR; - FileData* fileData = new Ra::Core::Asset::FileData(filename); + FileData* fileData = new Ra::Core::Asset::FileData( filename ); - if (!fileData->isInitialized()) { + if ( !fileData->isInitialized() ) { delete fileData; - LOG(logWARNING) << "Filedata could not be initialized"; + LOG( logWARNING ) << "Filedata could not be initialized"; return nullptr; } auto startTime = clock(); // a unique name is required by the component messaging system static int nameId = 0; - auto geometry = make_unique("LAS_PC_" + to_string(++nameId), GeometryData::POINT_CLOUD); - if (geometry == nullptr) { - LOG(logERROR) << "could not create geometry"; + auto geometry = + make_unique( "LAS_PC_" + to_string( ++nameId ), GeometryData::POINT_CLOUD ); + if ( geometry == nullptr ) { + LOG( logERROR ) << "could not create geometry"; return nullptr; } - geometry->setFrame(Ra::Core::Transform::Identity()); + geometry->setFrame( Ra::Core::Transform::Identity() ); - ifstream stream(filename, ios::out | ios::binary); + ifstream stream( filename, ios::out | ios::binary ); - if (!stream.is_open()) { - throw runtime_error("Could not open binary ifstream to path " + filename ); + if ( !stream.is_open() ) { + throw runtime_error( "Could not open binary ifstream to path " + filename ); return nullptr; } else { - LOG(logINFO) << "---Beginning file loading---"; + LOG( logINFO ) << "---Beginning file loading---"; } /*header part*/ char buffer[48]; - //reading minor version (needed to check data format) - stream.seekg(0); - stream.seekg(25); - stream.read(buffer, 1); + // reading minor version (needed to check data format) + stream.seekg( 0 ); + stream.seekg( 25 ); + stream.read( buffer, 1 ); unsigned char minor = *(unsigned char*)buffer; - if ((minor < 1) || (minor > 4)) { + if ( ( minor < 1 ) || ( minor > 4 ) ) { delete fileData; - LOG(logERROR) << "LAS version 1." << (int)minor << " unsupported"; + LOG( logERROR ) << "LAS version 1." << (int)minor << " unsupported"; return nullptr; } else { - LOG(logINFO) << "LAS version 1." << (int)minor; + LOG( logINFO ) << "LAS version 1." << (int)minor; } - //reading distance from file start to first point record - stream.seekg(0); - stream.seekg(96); - stream.read(buffer, 4); + // reading distance from file start to first point record + stream.seekg( 0 ); + stream.seekg( 96 ); + stream.read( buffer, 4 ); unsigned int offset = *(unsigned int*)buffer; - //reading point data format - stream.seekg(0); - stream.seekg(104); - stream.read(buffer, 1); + // reading point data format + stream.seekg( 0 ); + stream.seekg( 104 ); + stream.read( buffer, 1 ); unsigned char data_format = *(unsigned char*)buffer; - if ((data_format < 0) - || (data_format > 3 && minor < 3) - || (data_format > 5 && minor == 3) - || (data_format > 6 && minor == 4)) { + if ( ( data_format < 0 ) || ( data_format > 3 && minor < 3 ) || + ( data_format > 5 && minor == 3 ) || ( data_format > 6 && minor == 4 ) ) { delete fileData; - throw runtime_error("Corrupted file. Unvalid data format"); + throw runtime_error( "Corrupted file. Unvalid data format" ); return nullptr; } else { - LOG(logINFO) << "Data format " << (int)data_format; - LOG(logINFO) << "Loading properties \"x\", \"y\", \"z\","; + LOG( logINFO ) << "Data format " << (int)data_format; + LOG( logINFO ) << "Loading properties \"x\", \"y\", \"z\","; } - //reading data record length (bytes) - stream.read(buffer, 2); + // reading data record length (bytes) + stream.read( buffer, 2 ); unsigned short data_len = *(unsigned short*)buffer; - //reading total number of data records - stream.read(buffer, 4); + // reading total number of data records + stream.read( buffer, 4 ); unsigned int nb_data = *(unsigned int*)buffer; - //reading scales and offsets (used for computing coordinates) - stream.seekg(0); - stream.seekg(131); - stream.read(buffer, 48); + // reading scales and offsets (used for computing coordinates) + stream.seekg( 0 ); + stream.seekg( 131 ); + stream.read( buffer, 48 ); - double scale_x = *(reinterpret_cast(buffer)); - double scale_y = *(reinterpret_cast(buffer + 8)); - double scale_z = *(reinterpret_cast(buffer + 16)); - double offset_x = *(reinterpret_cast(buffer + 24)); - double offset_y = *(reinterpret_cast(buffer + 32)); - double offset_z = *(reinterpret_cast(buffer + 40)); + double scale_x = *( reinterpret_cast( buffer ) ); + double scale_y = *( reinterpret_cast( buffer + 8 ) ); + double scale_z = *( reinterpret_cast( buffer + 16 ) ); + double offset_x = *( reinterpret_cast( buffer + 24 ) ); + double offset_y = *( reinterpret_cast( buffer + 32 ) ); + double offset_z = *( reinterpret_cast( buffer + 40 ) ); /*loading properties*/ - vector point (data_len); + vector point( data_len ); VectorArray& vertices = geometry->getGeometry().verticesWithLock(); - vertices.reserve(nb_data); + vertices.reserve( nb_data ); - //checking for colors + // checking for colors bool colors = false; - if (data_format == 2 || data_format == 3 || (minor >= 3 && data_format == 5)) { + if ( data_format == 2 || data_format == 3 || ( minor >= 3 && data_format == 5 ) ) { auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib( - Ra::Core::Geometry::getAttribName(Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR)); + Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) ); colors = true; - LOG(logINFO) << "\"red\", \"green\", \"blue\"."; + LOG( logINFO ) << "\"red\", \"green\", \"blue\"."; } - //checking for GPS Time + // checking for GPS Time bool gps_time = false; - if ((data_format == 1 ) - || (data_format == 3) - || ((minor > 2) && (data_format == 4)) - || ((minor > 2) && (data_format == 5)) - || ((minor == 4) && (data_format == 6))) { - auto handle_time = geometry->getGeometry().vertexAttribs().addAttrib("gps_time"); - gps_time = true; - LOG(logINFO) << "\"GPS time\"."; + if ( ( data_format == 1 ) || ( data_format == 3 ) || + ( ( minor > 2 ) && ( data_format == 4 ) ) || ( ( minor > 2 ) && ( data_format == 5 ) ) || + ( ( minor == 4 ) && ( data_format == 6 ) ) ) { + auto handle_time = geometry->getGeometry().vertexAttribs().addAttrib( "gps_time" ); + gps_time = true; + LOG( logINFO ) << "\"GPS time\"."; } - for (unsigned int i = 0;i < nb_data;++i) { - //positioning at point data location in file + for ( unsigned int i = 0; i < nb_data; ++i ) { + // positioning at point data location in file int pos = offset + i * data_len; - stream.seekg(0); - stream.seekg(pos); + stream.seekg( 0 ); + stream.seekg( pos ); - //reading point data - stream.read(point.data(), data_len); + // reading point data + stream.read( point.data(), data_len ); - //extracting initial x y z coordinates + // extracting initial x y z coordinates int ix; int iy; int iz; - ix = *(int *)(point.data()); - iy = *(int *)(point.data() + 4); - iz = *(int *)(point.data() + 8); + ix = *(int*)( point.data() ); + iy = *(int*)( point.data() + 4 ); + iz = *(int*)( point.data() + 8 ); - //computing actual coordinates - double x = (double) ix * scale_x + offset_x; - double y = (double) iy * scale_y + offset_y; - double z = (double) iz * scale_z + offset_z; + // computing actual coordinates + double x = (double)ix * scale_x + offset_x; + double y = (double)iy * scale_y + offset_y; + double z = (double)iz * scale_z + offset_z; - //storing coordinates in vertices object - vertices.emplace_back(Scalar(x), Scalar(y), Scalar(z)); + // storing coordinates in vertices object + vertices.emplace_back( Scalar( x ), Scalar( y ), Scalar( z ) ); - //computing colors if found - if (colors) { + // computing colors if found + if ( colors ) { unsigned short red, green, blue; - if (data_format == 5 || data_format == 3) { - red = *(unsigned short*)(point.data() + 28); - green = *(unsigned short*)(point.data() + 30); - blue = *(unsigned short*)(point.data() + 32); + if ( data_format == 5 || data_format == 3 ) { + red = *(unsigned short*)( point.data() + 28 ); + green = *(unsigned short*)( point.data() + 30 ); + blue = *(unsigned short*)( point.data() + 32 ); } else { - red = *(unsigned short*)(point.data() + 20); - green = *(unsigned short*)(point.data() + 22); - blue = *(unsigned short*)(point.data() + 24); + red = *(unsigned short*)( point.data() + 20 ); + green = *(unsigned short*)( point.data() + 22 ); + blue = *(unsigned short*)( point.data() + 24 ); } - auto handle_colors = geometry->getGeometry().vertexAttribs().findAttrib( - Ra::Core::Geometry::getAttribName(Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR)); - geometry->getGeometry().vertexAttribs().getDataWithLock(handle_colors).emplace_back(Scalar(red), Scalar(green), Scalar(blue), 1_ra); - geometry->getGeometry().vertexAttribs().unlock(handle_colors); + auto handle_colors = + geometry->getGeometry().vertexAttribs().findAttrib( + Ra::Core::Geometry::getAttribName( + Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) ); + geometry->getGeometry() + .vertexAttribs() + .getDataWithLock( handle_colors ) + .emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra ); + geometry->getGeometry().vertexAttribs().unlock( handle_colors ); } - if (gps_time) { - //computing GPS time if found - auto handle_time = geometry->getGeometry().vertexAttribs().findAttrib("gps_time"); - auto& time = geometry->getGeometry().vertexAttribs().getDataWithLock(handle_time); - if (data_format == 6) { - time.emplace_back(Scalar(*reinterpret_cast(point.data() + 22))); + if ( gps_time ) { + // computing GPS time if found + auto handle_time = + geometry->getGeometry().vertexAttribs().findAttrib( "gps_time" ); + auto& time = geometry->getGeometry().vertexAttribs().getDataWithLock( handle_time ); + if ( data_format == 6 ) { + time.emplace_back( Scalar( *reinterpret_cast( point.data() + 22 ) ) ); } else { - time.emplace_back(Scalar(*reinterpret_cast(point.data() + 20))); + time.emplace_back( Scalar( *reinterpret_cast( point.data() + 20 ) ) ); } - geometry->getGeometry().vertexAttribs().unlock(handle_time); + geometry->getGeometry().vertexAttribs().unlock( handle_time ); } } stream.close(); @@ -215,14 +218,14 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { point.clear(); - //finalizing + // finalizing fileData->m_geometryData.clear(); - fileData->m_geometryData.reserve(1); - fileData->m_geometryData.push_back(move(geometry)); + fileData->m_geometryData.reserve( 1 ); + fileData->m_geometryData.push_back( move( geometry ) ); - fileData->m_loadingTime = (clock() - startTime) / Scalar(CLOCKS_PER_SEC); + fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); - LOG(logINFO) << "---File loading ended---"; + LOG( logINFO ) << "---File loading ended---"; fileData->displayInfo(); From c21c5204578197e727f1e1c4fb4c2d89491fbb80 Mon Sep 17 00:00:00 2001 From: Marina2468 Date: Tue, 26 Jul 2022 21:56:35 +0200 Subject: [PATCH 17/28] update to load all attribs as custom --- src/IO/AsciiPCLoader/asciipcloader.cpp | 276 +++++++++++++------------ src/IO/AsciiPCLoader/asciipcloader.hpp | 19 +- 2 files changed, 154 insertions(+), 141 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 8e339466657..9fd8fa68727 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -10,173 +10,179 @@ using std::make_unique; using std::runtime_error; using std::to_string; -const string trajExt( "txt" ); +const string asciiExt( "txt" ); namespace Ra { namespace IO { vector AsciiPointCloudLoader::getFileExtensions() const { - return vector( { "*." + trajExt } ); + return vector( { "*." + asciiExt } ); } bool AsciiPointCloudLoader::handleFileExtension( const string& extension ) const { - return extension.compare( trajExt ) == 0; + return extension.compare( asciiExt ) == 0; } -Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filename ) { - using Ra::Core::Asset::FileData; - using Ra::Core::Asset::GeometryData; - using Ra::Core::Utils::logERROR; - using Ra::Core::Utils::logINFO; - - FileData* fileData = new Ra::Core::Asset::FileData( filename ); - - if ( !fileData->isInitialized() ) { - delete fileData; - LOG( logINFO ) << "Filedata could not be initialized"; - return nullptr; - } - - auto startTime = clock(); - // a unique name is required by the component messaging system - static int id = 0; - auto geometry = - make_unique( "PC_" + to_string( ++id ), GeometryData::POINT_CLOUD ); - if ( geometry == nullptr ) { - LOG( logERROR ) << "could not create geometry"; - return nullptr; - } - - geometry->setFrame( Ra::Core::Transform::Identity() ); - - ifstream stream( filename ); - if ( !stream.is_open() ) { - throw runtime_error( "Could not open ifstream to path " + filename ); - return nullptr; - } - else { - LOG( logINFO ) << "---Beginning file loading---"; - } - - /*reading how data is arranged*/ - string line; - vector spacepos; - unsigned long timepos, xpos, ypos, zpos; - - if ( !getline( stream, line ) ) { - delete fileData; - LOG( logINFO ) << "file does not contain data format. aborting"; - return nullptr; - } - - // Find mandatory fields - timepos = line.find( "Time" ); - xpos = line.find( " X" ); - ypos = line.find( " Y" ); - zpos = line.find( " Z" ); - - if ( ( timepos == string::npos ) || ( xpos == string::npos ) || ( ypos == string::npos ) || - ( zpos == string::npos ) ) { - delete fileData; - LOG( logINFO ) << "file does not contain mandatory properties (X, Y, Z, time). aborting"; - return nullptr; - } - - LOG( logINFO ) << "Loading properties \"x\", \"y\", \"z\", \"time\"."; - - // skipping blank space - xpos++; - ypos++; - zpos++; - - /*retrieving x y z time attribut positions and column count*/ - int spacecount = 0; - for ( size_t i = 0; i < line.length(); ++i ) { - if ( line[i] == ' ' ) { - spacepos.emplace_back( i ); - spacecount++; +Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile (const string& filename) { + using Ra::Core::Asset::GeometryData; + using Ra::Core::Asset::FileData; + using Ra::Core::Utils::logINFO; + using Ra::Core::Utils::logERROR; + + FileData* fileData = new Ra::Core::Asset::FileData(filename); + + if (!fileData->isInitialized()) { + delete fileData; + LOG(logINFO) << "Filedata could not be initialized"; + return nullptr; + } + + auto startTime = clock(); + // a unique name is required by the component messaging system + static int id = 0; + auto geometry = make_unique("TRAJ_PC_" + to_string(++id), GeometryData::POINT_CLOUD); + if (geometry == nullptr) { + LOG(logERROR) << "could not create geometry"; + return nullptr; } - } - for ( int i = 0; i < spacecount; ++i ) { - if ( timepos <= spacepos[i] ) { - timepos = i; - break; + geometry->setFrame(Ra::Core::Transform::Identity()); + + ifstream stream(filename); + if (!stream.is_open()) { + throw runtime_error("Could not open ifstream to path " + filename); + return nullptr; + } + else { + LOG(logINFO) << "---Beginning file loading---"; } - } - for ( int i = 0; i < spacecount; ++i ) { - if ( xpos <= spacepos[i] ) { - xpos = i; - break; - } - } + /*reading how data is arranged*/ + string line; - for ( int i = 0; i < spacecount; ++i ) { - if ( ypos <= spacepos[i] ) { - ypos = i; - break; + if (!getline(stream, line)) { + delete fileData; + LOG(logINFO) << "file does not contain trajectory data format. aborting"; + return nullptr; } - } - for ( int i = 0; i < spacecount; ++i ) { - if ( zpos <= spacepos[i] ) { - zpos = i; - break; + //retrieving all properties from header line + std::stringstream words (line); + vector tokens; + string temp; + while (words >> temp) { tokens.emplace_back(temp); }; + + //making sure X, Y, Z and Time properties are found + int xpos = -1, ypos = -1, zpos = -1, timepos = -1; + for (size_t i = 0;i < tokens.size();++i) { + if (xpos == -1) { + if (tokens[i].compare("X") == 0) { + xpos = i; + } + } + if (ypos == -1) { + if (tokens[i].compare("Y") == 0) { + ypos = i; + } + } + if (zpos == -1) { + if (tokens[i].compare("Z") == 0) { + zpos = i; + } + } + if (timepos == -1) { + if (tokens[i].compare("Time") == 0) { + timepos = i; + } + } } - } - - vector pointRecord; - - auto& vertices = geometry->getGeometry().verticesWithLock(); - - // creating custom attrib for time record - auto handle = geometry->getGeometry().vertexAttribs().addAttrib( "time" ); - auto& attrib = geometry->getGeometry().vertexAttribs().getAttrib( handle ); - auto& container = attrib.getDataWithLock(); - - /*recording data*/ - int i = 0; - double num; - while ( stream >> num ) { - pointRecord.emplace_back( num ); - // retrieving attributes from their position in line - if ( i == spacecount ) { - vertices.emplace_back( Scalar( pointRecord[xpos] ), - Scalar( pointRecord[ypos] ), - Scalar( pointRecord[zpos] ) ); - container.emplace_back( Scalar( pointRecord[timepos] ) ); + LOG(logINFO) << xpos << " " << ypos << " " << zpos << " " << timepos; - pointRecord.clear(); + if ((xpos == -1) || (ypos == -1) || (zpos == -1) || (timepos == -1)) { + delete fileData; + LOG(logERROR) << "file does not contain mandatory properties (X, Y, Z, Time). aborting"; + return nullptr; + } + else { + LOG(logINFO) << "loading properties: "; + string info = ""; + for (size_t i = 0;i < tokens.size();++i) { + if (i % 4 == 3) { + LOG(logINFO) << info << tokens[i]; + info = ""; + } + else { + info += tokens[i] + ", "; + } + } } - i = ( i + 1 ) % ( spacecount + 1 ); - } - - stream.close(); + Ra::Core::VectorArray& vertices = geometry->getGeometry().verticesWithLock(); + + // creating custom attrib for time record + auto handle = geometry->getGeometry().vertexAttribs().addAttrib( "time" ); + auto& attrib = geometry->getGeometry().vertexAttribs().getAttrib( handle ); + auto& time = attrib.getDataWithLock(); + + //creating custom attribs for all other properties + vector> attribs; + for (size_t i = 0;i < tokens.size();++i) { + //skipping mandatory attribs + if (((int)i == xpos) || ((int)i == ypos) || ((int)i == zpos) || ((int)i == timepos)) { continue; } + auto handle2 = geometry->getGeometry().vertexAttribs().addAttrib( tokens[i] ); + auto& attrib2 = geometry->getGeometry().vertexAttribs().getAttrib( handle2 ); + attribs.emplace_back( attrib2.getDataWithLock() ); + } - geometry->getGeometry().verticesUnlock(); - geometry->getGeometry().vertexAttribs().unlock( handle ); + /*recording data*/ + vector pointRecord; + int i = 0; + double num; + while (stream >> num) { + pointRecord.emplace_back(num); + + if (i == (int)(tokens.size() - 1)) { + vertices.emplace_back(Scalar(pointRecord[xpos]), Scalar(pointRecord[ypos]), Scalar(pointRecord[zpos])); + time.emplace_back(Scalar(pointRecord[timepos])); + size_t k = 0; + for (size_t j = 0;j < tokens.size();++j) { + if (((int)j == xpos) || ((int)j == ypos) || ((int)j == zpos) || ((int)j == timepos)) { continue; } + attribs[k].emplace_back(Scalar(pointRecord[j])); + ++k; + } + pointRecord.clear(); + } + i = (i + 1) % tokens.size(); + } + stream.close(); + + geometry->getGeometry().verticesUnlock(); + geometry->getGeometry().vertexAttribs().unlock(handle); + for (size_t i = 0;i < tokens.size();++i) { + if (((int)i == xpos) || ((int)i == ypos) || ((int)i == zpos) || ((int)i == timepos)) { continue; } + auto handle2 = geometry->getGeometry().vertexAttribs().findAttrib( tokens[i] ); + geometry->getGeometry().vertexAttribs().unlock(handle2); + } - // finalizing - fileData->m_geometryData.clear(); - fileData->m_geometryData.reserve( 1 ); - fileData->m_geometryData.push_back( move( geometry ) ); + // finalizing + fileData->m_geometryData.clear(); + fileData->m_geometryData.reserve( 1 ); + fileData->m_geometryData.push_back( move( geometry ) ); - fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); + fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); - LOG( logINFO ) << "---File loading ended---"; + LOG( logINFO ) << "---File loading ended---"; - fileData->displayInfo(); + fileData->displayInfo(); - fileData->m_processed = true; + fileData->m_processed = true; - return fileData; + return fileData; } string AsciiPointCloudLoader::name() const { - return "Trajectory"; + return "Plain Text (ASCII)"; } } // namespace IO diff --git a/src/IO/AsciiPCLoader/asciipcloader.hpp b/src/IO/AsciiPCLoader/asciipcloader.hpp index cbcd0bde553..69ebfd44052 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.hpp +++ b/src/IO/AsciiPCLoader/asciipcloader.hpp @@ -18,19 +18,26 @@ class RA_IO_API AsciiPointCloudLoader : public Ra::Core::Asset::FileLoaderInterf vector getFileExtensions() const override; bool handleFileExtension( const std::string& extension ) const override; - /** load vertices from .txt file - * - * load x, y, z and time from ASCII .txt file + /** load vertices properties from ASCII .txt file * * expected content in file: header line + data records * * header line content : attribute names separated by blanks ( ) * * example: Time X Y Z Roll Pitch Heading sdX sdY sdZ - * @note Although the header line can contain attributes other than coordinates and time, - * only these are loaded. X, Y, Z coordinates search in header line is case sensitive + * + * X, Y, Z and Time properties (case sensitive) are mandatory + * for file loading. Failure to find any of these properties + * results in file reading failure + * + * X, Y, Z properties are aggregated in geometry vertex array, + * while all other properties are loaded as custom attribs in + * Radium + * + * @todo add aggregation for normals/colors * @param [in] filename file path - * @return nullptr if file opening, geometry creation fails + * @return nullptr if file opening fails, geometry creation + * fails or one of the mandatory properties is not found */ Ra::Core::Asset::FileData* loadFile( const std::string& filename ) override; string name() const override; From c06f7a0f0ab48f611ab906908129e674329fa31f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 19:57:27 +0000 Subject: [PATCH 18/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/AsciiPCLoader/asciipcloader.cpp | 284 +++++++++++++------------ src/IO/AsciiPCLoader/asciipcloader.hpp | 2 +- 2 files changed, 146 insertions(+), 140 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 9fd8fa68727..3c72246fae3 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -23,162 +23,168 @@ bool AsciiPointCloudLoader::handleFileExtension( const string& extension ) const return extension.compare( asciiExt ) == 0; } -Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile (const string& filename) { - using Ra::Core::Asset::GeometryData; - using Ra::Core::Asset::FileData; - using Ra::Core::Utils::logINFO; - using Ra::Core::Utils::logERROR; - - FileData* fileData = new Ra::Core::Asset::FileData(filename); - - if (!fileData->isInitialized()) { - delete fileData; - LOG(logINFO) << "Filedata could not be initialized"; - return nullptr; - } - - auto startTime = clock(); - // a unique name is required by the component messaging system - static int id = 0; - auto geometry = make_unique("TRAJ_PC_" + to_string(++id), GeometryData::POINT_CLOUD); - if (geometry == nullptr) { - LOG(logERROR) << "could not create geometry"; - return nullptr; +Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filename ) { + using Ra::Core::Asset::FileData; + using Ra::Core::Asset::GeometryData; + using Ra::Core::Utils::logERROR; + using Ra::Core::Utils::logINFO; + + FileData* fileData = new Ra::Core::Asset::FileData( filename ); + + if ( !fileData->isInitialized() ) { + delete fileData; + LOG( logINFO ) << "Filedata could not be initialized"; + return nullptr; + } + + auto startTime = clock(); + // a unique name is required by the component messaging system + static int id = 0; + auto geometry = + make_unique( "TRAJ_PC_" + to_string( ++id ), GeometryData::POINT_CLOUD ); + if ( geometry == nullptr ) { + LOG( logERROR ) << "could not create geometry"; + return nullptr; + } + + geometry->setFrame( Ra::Core::Transform::Identity() ); + + ifstream stream( filename ); + if ( !stream.is_open() ) { + throw runtime_error( "Could not open ifstream to path " + filename ); + return nullptr; + } + else { + LOG( logINFO ) << "---Beginning file loading---"; + } + + /*reading how data is arranged*/ + string line; + + if ( !getline( stream, line ) ) { + delete fileData; + LOG( logINFO ) << "file does not contain trajectory data format. aborting"; + return nullptr; + } + + // retrieving all properties from header line + std::stringstream words( line ); + vector tokens; + string temp; + while ( words >> temp ) { + tokens.emplace_back( temp ); + }; + + // making sure X, Y, Z and Time properties are found + int xpos = -1, ypos = -1, zpos = -1, timepos = -1; + for ( size_t i = 0; i < tokens.size(); ++i ) { + if ( xpos == -1 ) { + if ( tokens[i].compare( "X" ) == 0 ) { xpos = i; } } - - geometry->setFrame(Ra::Core::Transform::Identity()); - - ifstream stream(filename); - if (!stream.is_open()) { - throw runtime_error("Could not open ifstream to path " + filename); - return nullptr; - } - else { - LOG(logINFO) << "---Beginning file loading---"; + if ( ypos == -1 ) { + if ( tokens[i].compare( "Y" ) == 0 ) { ypos = i; } } - - /*reading how data is arranged*/ - string line; - - if (!getline(stream, line)) { - delete fileData; - LOG(logINFO) << "file does not contain trajectory data format. aborting"; - return nullptr; - } - - //retrieving all properties from header line - std::stringstream words (line); - vector tokens; - string temp; - while (words >> temp) { tokens.emplace_back(temp); }; - - //making sure X, Y, Z and Time properties are found - int xpos = -1, ypos = -1, zpos = -1, timepos = -1; - for (size_t i = 0;i < tokens.size();++i) { - if (xpos == -1) { - if (tokens[i].compare("X") == 0) { - xpos = i; - } - } - if (ypos == -1) { - if (tokens[i].compare("Y") == 0) { - ypos = i; - } - } - if (zpos == -1) { - if (tokens[i].compare("Z") == 0) { - zpos = i; - } - } - if (timepos == -1) { - if (tokens[i].compare("Time") == 0) { - timepos = i; - } - } + if ( zpos == -1 ) { + if ( tokens[i].compare( "Z" ) == 0 ) { zpos = i; } } - - LOG(logINFO) << xpos << " " << ypos << " " << zpos << " " << timepos; - - if ((xpos == -1) || (ypos == -1) || (zpos == -1) || (timepos == -1)) { - delete fileData; - LOG(logERROR) << "file does not contain mandatory properties (X, Y, Z, Time). aborting"; - return nullptr; + if ( timepos == -1 ) { + if ( tokens[i].compare( "Time" ) == 0 ) { timepos = i; } } - else { - LOG(logINFO) << "loading properties: "; - string info = ""; - for (size_t i = 0;i < tokens.size();++i) { - if (i % 4 == 3) { - LOG(logINFO) << info << tokens[i]; - info = ""; - } - else { - info += tokens[i] + ", "; - } + } + + LOG( logINFO ) << xpos << " " << ypos << " " << zpos << " " << timepos; + + if ( ( xpos == -1 ) || ( ypos == -1 ) || ( zpos == -1 ) || ( timepos == -1 ) ) { + delete fileData; + LOG( logERROR ) << "file does not contain mandatory properties (X, Y, Z, Time). aborting"; + return nullptr; + } + else { + LOG( logINFO ) << "loading properties: "; + string info = ""; + for ( size_t i = 0; i < tokens.size(); ++i ) { + if ( i % 4 == 3 ) { + LOG( logINFO ) << info << tokens[i]; + info = ""; + } + else { + info += tokens[i] + ", "; } } - - Ra::Core::VectorArray& vertices = geometry->getGeometry().verticesWithLock(); - - // creating custom attrib for time record - auto handle = geometry->getGeometry().vertexAttribs().addAttrib( "time" ); - auto& attrib = geometry->getGeometry().vertexAttribs().getAttrib( handle ); - auto& time = attrib.getDataWithLock(); - - //creating custom attribs for all other properties - vector> attribs; - for (size_t i = 0;i < tokens.size();++i) { - //skipping mandatory attribs - if (((int)i == xpos) || ((int)i == ypos) || ((int)i == zpos) || ((int)i == timepos)) { continue; } - auto handle2 = geometry->getGeometry().vertexAttribs().addAttrib( tokens[i] ); - auto& attrib2 = geometry->getGeometry().vertexAttribs().getAttrib( handle2 ); - attribs.emplace_back( attrib2.getDataWithLock() ); + } + + Ra::Core::VectorArray& vertices = geometry->getGeometry().verticesWithLock(); + + // creating custom attrib for time record + auto handle = geometry->getGeometry().vertexAttribs().addAttrib( "time" ); + auto& attrib = geometry->getGeometry().vertexAttribs().getAttrib( handle ); + auto& time = attrib.getDataWithLock(); + + // creating custom attribs for all other properties + vector> attribs; + for ( size_t i = 0; i < tokens.size(); ++i ) { + // skipping mandatory attribs + if ( ( (int)i == xpos ) || ( (int)i == ypos ) || ( (int)i == zpos ) || + ( (int)i == timepos ) ) { + continue; } - - /*recording data*/ - vector pointRecord; - int i = 0; - double num; - while (stream >> num) { - pointRecord.emplace_back(num); - - if (i == (int)(tokens.size() - 1)) { - vertices.emplace_back(Scalar(pointRecord[xpos]), Scalar(pointRecord[ypos]), Scalar(pointRecord[zpos])); - time.emplace_back(Scalar(pointRecord[timepos])); - size_t k = 0; - for (size_t j = 0;j < tokens.size();++j) { - if (((int)j == xpos) || ((int)j == ypos) || ((int)j == zpos) || ((int)j == timepos)) { continue; } - attribs[k].emplace_back(Scalar(pointRecord[j])); - ++k; + auto handle2 = geometry->getGeometry().vertexAttribs().addAttrib( tokens[i] ); + auto& attrib2 = geometry->getGeometry().vertexAttribs().getAttrib( handle2 ); + attribs.emplace_back( attrib2.getDataWithLock() ); + } + + /*recording data*/ + vector pointRecord; + int i = 0; + double num; + while ( stream >> num ) { + pointRecord.emplace_back( num ); + + if ( i == (int)( tokens.size() - 1 ) ) { + vertices.emplace_back( Scalar( pointRecord[xpos] ), + Scalar( pointRecord[ypos] ), + Scalar( pointRecord[zpos] ) ); + time.emplace_back( Scalar( pointRecord[timepos] ) ); + size_t k = 0; + for ( size_t j = 0; j < tokens.size(); ++j ) { + if ( ( (int)j == xpos ) || ( (int)j == ypos ) || ( (int)j == zpos ) || + ( (int)j == timepos ) ) { + continue; } - pointRecord.clear(); + attribs[k].emplace_back( Scalar( pointRecord[j] ) ); + ++k; } - i = (i + 1) % tokens.size(); + pointRecord.clear(); } - stream.close(); - - geometry->getGeometry().verticesUnlock(); - geometry->getGeometry().vertexAttribs().unlock(handle); - for (size_t i = 0;i < tokens.size();++i) { - if (((int)i == xpos) || ((int)i == ypos) || ((int)i == zpos) || ((int)i == timepos)) { continue; } - auto handle2 = geometry->getGeometry().vertexAttribs().findAttrib( tokens[i] ); - geometry->getGeometry().vertexAttribs().unlock(handle2); + i = ( i + 1 ) % tokens.size(); + } + stream.close(); + + geometry->getGeometry().verticesUnlock(); + geometry->getGeometry().vertexAttribs().unlock( handle ); + for ( size_t i = 0; i < tokens.size(); ++i ) { + if ( ( (int)i == xpos ) || ( (int)i == ypos ) || ( (int)i == zpos ) || + ( (int)i == timepos ) ) { + continue; } + auto handle2 = geometry->getGeometry().vertexAttribs().findAttrib( tokens[i] ); + geometry->getGeometry().vertexAttribs().unlock( handle2 ); + } - // finalizing - fileData->m_geometryData.clear(); - fileData->m_geometryData.reserve( 1 ); - fileData->m_geometryData.push_back( move( geometry ) ); + // finalizing + fileData->m_geometryData.clear(); + fileData->m_geometryData.reserve( 1 ); + fileData->m_geometryData.push_back( move( geometry ) ); - fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); + fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); - LOG( logINFO ) << "---File loading ended---"; + LOG( logINFO ) << "---File loading ended---"; - fileData->displayInfo(); + fileData->displayInfo(); - fileData->m_processed = true; + fileData->m_processed = true; - return fileData; + return fileData; } string AsciiPointCloudLoader::name() const { diff --git a/src/IO/AsciiPCLoader/asciipcloader.hpp b/src/IO/AsciiPCLoader/asciipcloader.hpp index 69ebfd44052..69c0022dfd6 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.hpp +++ b/src/IO/AsciiPCLoader/asciipcloader.hpp @@ -36,7 +36,7 @@ class RA_IO_API AsciiPointCloudLoader : public Ra::Core::Asset::FileLoaderInterf * * @todo add aggregation for normals/colors * @param [in] filename file path - * @return nullptr if file opening fails, geometry creation + * @return nullptr if file opening fails, geometry creation * fails or one of the mandatory properties is not found */ Ra::Core::Asset::FileData* loadFile( const std::string& filename ) override; From c97442530808308b984654fada0bd9370891bfd9 Mon Sep 17 00:00:00 2001 From: Marina2468 Date: Wed, 27 Jul 2022 08:24:30 +0200 Subject: [PATCH 19/28] update las loader --- src/IO/LasLoader/lasloader.cpp | 82 +++++++++++++++++----------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 09260c4014c..1e9151115a1 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -127,23 +127,25 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { VectorArray& vertices = geometry->getGeometry().verticesWithLock(); vertices.reserve( nb_data ); - // checking for colors - bool colors = false; - if ( data_format == 2 || data_format == 3 || ( minor >= 3 && data_format == 5 ) ) { - auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib( - Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) ); - colors = true; - LOG( logINFO ) << "\"red\", \"green\", \"blue\"."; + //checking for colors + Ra::Core::Utils::AttribHandle< Ra::Core::Vector4 > handle_color; + Ra::Core::VectorArray< Ra::Core::Vector4 > colors; + if (data_format == 2 || data_format == 3 || (minor >= 3 && data_format == 5)) { + handle_color = geometry->getGeometry().vertexAttribs().addAttrib( + Ra::Core::Geometry::getAttribName(Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR)); + LOG(logINFO) << "\"red\", \"green\", \"blue\"."; } - // checking for GPS Time - bool gps_time = false; - if ( ( data_format == 1 ) || ( data_format == 3 ) || - ( ( minor > 2 ) && ( data_format == 4 ) ) || ( ( minor > 2 ) && ( data_format == 5 ) ) || - ( ( minor == 4 ) && ( data_format == 6 ) ) ) { - auto handle_time = geometry->getGeometry().vertexAttribs().addAttrib( "gps_time" ); - gps_time = true; - LOG( logINFO ) << "\"GPS time\"."; + //checking for GPS Time + Ra::Core::Utils::AttribHandle< Scalar > handle_time; + Ra::Core::VectorArray< Scalar > gps_time; + if ((data_format == 1 ) + || (data_format == 3) + || ((minor > 2) && (data_format == 4)) + || ((minor > 2) && (data_format == 5)) + || ((minor == 4) && (data_format == 6))) { + handle_time = geometry->getGeometry().vertexAttribs().addAttrib("gps_time"); + LOG(logINFO) << "\"GPS time\"."; } for ( unsigned int i = 0; i < nb_data; ++i ) { @@ -172,44 +174,32 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { // storing coordinates in vertices object vertices.emplace_back( Scalar( x ), Scalar( y ), Scalar( z ) ); - // computing colors if found - if ( colors ) { + // loading colors if found + if (handle_color.idx().isValid()) { unsigned short red, green, blue; - if ( data_format == 5 || data_format == 3 ) { - red = *(unsigned short*)( point.data() + 28 ); - green = *(unsigned short*)( point.data() + 30 ); - blue = *(unsigned short*)( point.data() + 32 ); + if (data_format == 5 || data_format == 3) { + red = *(unsigned short*)(point.data() + 28); + green = *(unsigned short*)(point.data() + 30); + blue = *(unsigned short*)(point.data() + 32); } else { - red = *(unsigned short*)( point.data() + 20 ); - green = *(unsigned short*)( point.data() + 22 ); - blue = *(unsigned short*)( point.data() + 24 ); + red = *(unsigned short*)(point.data() + 20); + green = *(unsigned short*)(point.data() + 22); + blue = *(unsigned short*)(point.data() + 24); } - auto handle_colors = - geometry->getGeometry().vertexAttribs().findAttrib( - Ra::Core::Geometry::getAttribName( - Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) ); - geometry->getGeometry() - .vertexAttribs() - .getDataWithLock( handle_colors ) - .emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra ); - geometry->getGeometry().vertexAttribs().unlock( handle_colors ); + colors.emplace_back(Scalar(red), Scalar(green), Scalar(blue), 1_ra); } - if ( gps_time ) { - // computing GPS time if found - auto handle_time = - geometry->getGeometry().vertexAttribs().findAttrib( "gps_time" ); - auto& time = geometry->getGeometry().vertexAttribs().getDataWithLock( handle_time ); - if ( data_format == 6 ) { - time.emplace_back( Scalar( *reinterpret_cast( point.data() + 22 ) ) ); + if (handle_time.idx().isValid()) { + // loading GPS time if found + if (data_format == 6) { + gps_time.emplace_back(Scalar(*reinterpret_cast(point.data() + 22))); } else { - time.emplace_back( Scalar( *reinterpret_cast( point.data() + 20 ) ) ); + gps_time.emplace_back(Scalar(*reinterpret_cast(point.data() + 20))); } - geometry->getGeometry().vertexAttribs().unlock( handle_time ); } } stream.close(); @@ -218,6 +208,14 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { point.clear(); + if (handle_color.idx().isValid()) { + geometry->getGeometry().vertexAttribs().getAttrib(handle_color).setData(colors); + } + if (handle_time.idx().isValid()) { + geometry->getGeometry().vertexAttribs().getAttrib(handle_time).setData(gps_time); + } + + // finalizing fileData->m_geometryData.clear(); fileData->m_geometryData.reserve( 1 ); From 769a1839fe05c9dd840d8d493b179959272a4f0c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 27 Jul 2022 06:27:41 +0000 Subject: [PATCH 20/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/LasLoader/lasloader.cpp | 65 ++++++++++++++++------------------ 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 1e9151115a1..e93e3324ce6 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -127,25 +127,23 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { VectorArray& vertices = geometry->getGeometry().verticesWithLock(); vertices.reserve( nb_data ); - //checking for colors - Ra::Core::Utils::AttribHandle< Ra::Core::Vector4 > handle_color; - Ra::Core::VectorArray< Ra::Core::Vector4 > colors; - if (data_format == 2 || data_format == 3 || (minor >= 3 && data_format == 5)) { + // checking for colors + Ra::Core::Utils::AttribHandle handle_color; + Ra::Core::VectorArray colors; + if ( data_format == 2 || data_format == 3 || ( minor >= 3 && data_format == 5 ) ) { handle_color = geometry->getGeometry().vertexAttribs().addAttrib( - Ra::Core::Geometry::getAttribName(Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR)); - LOG(logINFO) << "\"red\", \"green\", \"blue\"."; + Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) ); + LOG( logINFO ) << "\"red\", \"green\", \"blue\"."; } - //checking for GPS Time - Ra::Core::Utils::AttribHandle< Scalar > handle_time; - Ra::Core::VectorArray< Scalar > gps_time; - if ((data_format == 1 ) - || (data_format == 3) - || ((minor > 2) && (data_format == 4)) - || ((minor > 2) && (data_format == 5)) - || ((minor == 4) && (data_format == 6))) { - handle_time = geometry->getGeometry().vertexAttribs().addAttrib("gps_time"); - LOG(logINFO) << "\"GPS time\"."; + // checking for GPS Time + Ra::Core::Utils::AttribHandle handle_time; + Ra::Core::VectorArray gps_time; + if ( ( data_format == 1 ) || ( data_format == 3 ) || + ( ( minor > 2 ) && ( data_format == 4 ) ) || ( ( minor > 2 ) && ( data_format == 5 ) ) || + ( ( minor == 4 ) && ( data_format == 6 ) ) ) { + handle_time = geometry->getGeometry().vertexAttribs().addAttrib( "gps_time" ); + LOG( logINFO ) << "\"GPS time\"."; } for ( unsigned int i = 0; i < nb_data; ++i ) { @@ -175,30 +173,30 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { vertices.emplace_back( Scalar( x ), Scalar( y ), Scalar( z ) ); // loading colors if found - if (handle_color.idx().isValid()) { + if ( handle_color.idx().isValid() ) { unsigned short red, green, blue; - if (data_format == 5 || data_format == 3) { - red = *(unsigned short*)(point.data() + 28); - green = *(unsigned short*)(point.data() + 30); - blue = *(unsigned short*)(point.data() + 32); + if ( data_format == 5 || data_format == 3 ) { + red = *(unsigned short*)( point.data() + 28 ); + green = *(unsigned short*)( point.data() + 30 ); + blue = *(unsigned short*)( point.data() + 32 ); } else { - red = *(unsigned short*)(point.data() + 20); - green = *(unsigned short*)(point.data() + 22); - blue = *(unsigned short*)(point.data() + 24); + red = *(unsigned short*)( point.data() + 20 ); + green = *(unsigned short*)( point.data() + 22 ); + blue = *(unsigned short*)( point.data() + 24 ); } - colors.emplace_back(Scalar(red), Scalar(green), Scalar(blue), 1_ra); + colors.emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra ); } - if (handle_time.idx().isValid()) { + if ( handle_time.idx().isValid() ) { // loading GPS time if found - if (data_format == 6) { - gps_time.emplace_back(Scalar(*reinterpret_cast(point.data() + 22))); + if ( data_format == 6 ) { + gps_time.emplace_back( Scalar( *reinterpret_cast( point.data() + 22 ) ) ); } else { - gps_time.emplace_back(Scalar(*reinterpret_cast(point.data() + 20))); + gps_time.emplace_back( Scalar( *reinterpret_cast( point.data() + 20 ) ) ); } } } @@ -208,14 +206,13 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { point.clear(); - if (handle_color.idx().isValid()) { - geometry->getGeometry().vertexAttribs().getAttrib(handle_color).setData(colors); + if ( handle_color.idx().isValid() ) { + geometry->getGeometry().vertexAttribs().getAttrib( handle_color ).setData( colors ); } - if (handle_time.idx().isValid()) { - geometry->getGeometry().vertexAttribs().getAttrib(handle_time).setData(gps_time); + if ( handle_time.idx().isValid() ) { + geometry->getGeometry().vertexAttribs().getAttrib( handle_time ).setData( gps_time ); } - // finalizing fileData->m_geometryData.clear(); fileData->m_geometryData.reserve( 1 ); From 2a258b8b7311cf7201f04f0486ffc181d1d4e165 Mon Sep 17 00:00:00 2001 From: Marina2468 Date: Wed, 27 Jul 2022 12:33:33 +0200 Subject: [PATCH 21/28] fix custom attribs reference issue --- src/IO/AsciiPCLoader/asciipcloader.cpp | 263 +++++++++++-------------- 1 file changed, 120 insertions(+), 143 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index 3c72246fae3..b8dfe51cc02 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -24,167 +24,144 @@ bool AsciiPointCloudLoader::handleFileExtension( const string& extension ) const } Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filename ) { - using Ra::Core::Asset::FileData; using Ra::Core::Asset::GeometryData; - using Ra::Core::Utils::logERROR; - using Ra::Core::Utils::logINFO; - - FileData* fileData = new Ra::Core::Asset::FileData( filename ); - - if ( !fileData->isInitialized() ) { - delete fileData; - LOG( logINFO ) << "Filedata could not be initialized"; - return nullptr; - } - - auto startTime = clock(); - // a unique name is required by the component messaging system - static int id = 0; - auto geometry = - make_unique( "TRAJ_PC_" + to_string( ++id ), GeometryData::POINT_CLOUD ); - if ( geometry == nullptr ) { - LOG( logERROR ) << "could not create geometry"; - return nullptr; - } - - geometry->setFrame( Ra::Core::Transform::Identity() ); - - ifstream stream( filename ); - if ( !stream.is_open() ) { - throw runtime_error( "Could not open ifstream to path " + filename ); - return nullptr; - } - else { - LOG( logINFO ) << "---Beginning file loading---"; - } - - /*reading how data is arranged*/ - string line; - - if ( !getline( stream, line ) ) { - delete fileData; - LOG( logINFO ) << "file does not contain trajectory data format. aborting"; - return nullptr; - } - - // retrieving all properties from header line - std::stringstream words( line ); - vector tokens; - string temp; - while ( words >> temp ) { - tokens.emplace_back( temp ); - }; - - // making sure X, Y, Z and Time properties are found - int xpos = -1, ypos = -1, zpos = -1, timepos = -1; - for ( size_t i = 0; i < tokens.size(); ++i ) { - if ( xpos == -1 ) { - if ( tokens[i].compare( "X" ) == 0 ) { xpos = i; } + using Ra::Core::Asset::FileData; + using Ra::Core::Utils::logINFO; + using Ra::Core::Utils::logERROR; + + FileData* fileData = new Ra::Core::Asset::FileData(filename); + + if (!fileData->isInitialized()) { + delete fileData; + LOG(logINFO) << "Filedata could not be initialized"; + return nullptr; + } + + auto startTime = clock(); + // a unique name is required by the component messaging system + static int id = 0; + auto geometry = make_unique("TRAJ_PC_" + to_string(++id), GeometryData::POINT_CLOUD); + if (geometry == nullptr) { + LOG(logERROR) << "could not create geometry"; + return nullptr; } - if ( ypos == -1 ) { - if ( tokens[i].compare( "Y" ) == 0 ) { ypos = i; } - } - if ( zpos == -1 ) { - if ( tokens[i].compare( "Z" ) == 0 ) { zpos = i; } + + geometry->setFrame(Ra::Core::Transform::Identity()); + + ifstream stream(filename); + if (!stream.is_open()) { + throw runtime_error("Could not open ifstream to path " + filename); + return nullptr; + } + else { + LOG(logINFO) << "---Beginning file loading---"; } - if ( timepos == -1 ) { - if ( tokens[i].compare( "Time" ) == 0 ) { timepos = i; } + + /*reading how data is arranged*/ + string line; + + if (!std::getline(stream, line)) { + delete fileData; + LOG(logINFO) << "file does not contain ascii data format. aborting"; + return nullptr; } - } - - LOG( logINFO ) << xpos << " " << ypos << " " << zpos << " " << timepos; - - if ( ( xpos == -1 ) || ( ypos == -1 ) || ( zpos == -1 ) || ( timepos == -1 ) ) { - delete fileData; - LOG( logERROR ) << "file does not contain mandatory properties (X, Y, Z, Time). aborting"; - return nullptr; - } - else { - LOG( logINFO ) << "loading properties: "; - string info = ""; - for ( size_t i = 0; i < tokens.size(); ++i ) { - if ( i % 4 == 3 ) { - LOG( logINFO ) << info << tokens[i]; - info = ""; + + //retrieving all properties from header line + std::stringstream words (line); + vector tokens; + string temp; + while (words >> temp) { tokens.emplace_back(temp); }; + + //making sure X, Y, Z and Time properties are found + int xpos = -1, ypos = -1, zpos = -1; + for (size_t i = 0;i < tokens.size();++i) { + string token = tokens[i]; + if (xpos == -1) { + if (token.compare("X") == 0) { + xpos = i; + } } - else { - info += tokens[i] + ", "; + if (ypos == -1) { + if (token.compare("Y") == 0) { + ypos = i; + } + } + if (zpos == -1) { + if (token.compare("Z") == 0) { + zpos = i; + } } } - } - - Ra::Core::VectorArray& vertices = geometry->getGeometry().verticesWithLock(); - - // creating custom attrib for time record - auto handle = geometry->getGeometry().vertexAttribs().addAttrib( "time" ); - auto& attrib = geometry->getGeometry().vertexAttribs().getAttrib( handle ); - auto& time = attrib.getDataWithLock(); - - // creating custom attribs for all other properties - vector> attribs; - for ( size_t i = 0; i < tokens.size(); ++i ) { - // skipping mandatory attribs - if ( ( (int)i == xpos ) || ( (int)i == ypos ) || ( (int)i == zpos ) || - ( (int)i == timepos ) ) { - continue; + + if ((xpos == -1) || (ypos == -1) || (zpos == -1)) { + delete fileData; + LOG(logERROR) << "file does not contain mandatory properties (X, Y, Z, Time). aborting"; + return nullptr; } - auto handle2 = geometry->getGeometry().vertexAttribs().addAttrib( tokens[i] ); - auto& attrib2 = geometry->getGeometry().vertexAttribs().getAttrib( handle2 ); - attribs.emplace_back( attrib2.getDataWithLock() ); - } - - /*recording data*/ - vector pointRecord; - int i = 0; - double num; - while ( stream >> num ) { - pointRecord.emplace_back( num ); - - if ( i == (int)( tokens.size() - 1 ) ) { - vertices.emplace_back( Scalar( pointRecord[xpos] ), - Scalar( pointRecord[ypos] ), - Scalar( pointRecord[zpos] ) ); - time.emplace_back( Scalar( pointRecord[timepos] ) ); - size_t k = 0; - for ( size_t j = 0; j < tokens.size(); ++j ) { - if ( ( (int)j == xpos ) || ( (int)j == ypos ) || ( (int)j == zpos ) || - ( (int)j == timepos ) ) { - continue; + else { + LOG(logINFO) << "loading properties: "; + string info = ""; + for (size_t i = 0;i < tokens.size();++i) { + if (i % 4 == 3) { + LOG(logINFO) << info << tokens[i]; + info = ""; + } + else { + info += tokens[i] + ", "; } - attribs[k].emplace_back( Scalar( pointRecord[j] ) ); - ++k; } - pointRecord.clear(); } - i = ( i + 1 ) % tokens.size(); - } - stream.close(); - - geometry->getGeometry().verticesUnlock(); - geometry->getGeometry().vertexAttribs().unlock( handle ); - for ( size_t i = 0; i < tokens.size(); ++i ) { - if ( ( (int)i == xpos ) || ( (int)i == ypos ) || ( (int)i == zpos ) || - ( (int)i == timepos ) ) { - continue; + + Ra::Core::VectorArray& vertices = geometry->getGeometry().verticesWithLock(); + + //creating custom attribs for all other properties + vector> attribs; + attribs.reserve(tokens.size() - 3); + + for (size_t i = 0;i < tokens.size();++i) { + //skipping mandatory attribs + if (((int)i == xpos) || ((int)i == ypos) || ((int)i == zpos)) { continue; } + attribs.emplace_back(geometry->getGeometry().vertexAttribs().addAttrib( tokens[i] )); } - auto handle2 = geometry->getGeometry().vertexAttribs().findAttrib( tokens[i] ); - geometry->getGeometry().vertexAttribs().unlock( handle2 ); - } - // finalizing - fileData->m_geometryData.clear(); - fileData->m_geometryData.reserve( 1 ); - fileData->m_geometryData.push_back( move( geometry ) ); + /*recording data*/ + vector pointRecord; + int i = 0; + double num; + while (stream >> num) { + pointRecord.emplace_back(num); + + if (i == (int)(tokens.size() - 1)) { + vertices.emplace_back(Scalar(pointRecord[xpos]), Scalar(pointRecord[ypos]), Scalar(pointRecord[zpos])); + size_t k = 0; + for (size_t j = 0;j < tokens.size();++j) { + if (((int)j == xpos) || ((int)j == ypos) || ((int)j == zpos)) { continue; } + geometry->getGeometry().vertexAttribs().getDataWithLock(attribs[k]).emplace_back(Scalar(pointRecord[j])); + geometry->getGeometry().vertexAttribs().unlock(attribs[k]); + ++k; + } + pointRecord.clear(); + } + i = (i + 1) % tokens.size(); + } + stream.close(); + + geometry->getGeometry().verticesUnlock(); + + // finalizing + fileData->m_geometryData.clear(); + fileData->m_geometryData.reserve( 1 ); + fileData->m_geometryData.push_back( move( geometry ) ); - fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); + fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); - LOG( logINFO ) << "---File loading ended---"; + LOG( logINFO ) << "---File loading ended---"; - fileData->displayInfo(); + fileData->displayInfo(); - fileData->m_processed = true; + fileData->m_processed = true; - return fileData; + return fileData; } string AsciiPointCloudLoader::name() const { From 4b470bdcb3cfa488cfeea7105839ce982966eb70 Mon Sep 17 00:00:00 2001 From: Marina2468 Date: Wed, 27 Jul 2022 12:33:56 +0200 Subject: [PATCH 22/28] fix colors range --- src/IO/LasLoader/lasloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index e93e3324ce6..4b05d76d444 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -187,7 +187,7 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { blue = *(unsigned short*)( point.data() + 24 ); } - colors.emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra ); + colors.emplace_back(Scalar(red) / 65536_ra, Scalar(green) / 65536_ra, Scalar(blue) / 65536_ra, 1_ra); } if ( handle_time.idx().isValid() ) { From 2f6cfde80ebb79400cc1aaca10faa0e307ad8b7e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 27 Jul 2022 10:47:16 +0000 Subject: [PATCH 23/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/AsciiPCLoader/asciipcloader.cpp | 247 +++++++++++++------------ src/IO/LasLoader/lasloader.cpp | 5 +- 2 files changed, 129 insertions(+), 123 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index b8dfe51cc02..bc7c758abf8 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -24,144 +24,147 @@ bool AsciiPointCloudLoader::handleFileExtension( const string& extension ) const } Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filename ) { + using Ra::Core::Asset::FileData; using Ra::Core::Asset::GeometryData; - using Ra::Core::Asset::FileData; - using Ra::Core::Utils::logINFO; - using Ra::Core::Utils::logERROR; - - FileData* fileData = new Ra::Core::Asset::FileData(filename); - - if (!fileData->isInitialized()) { - delete fileData; - LOG(logINFO) << "Filedata could not be initialized"; - return nullptr; - } - - auto startTime = clock(); - // a unique name is required by the component messaging system - static int id = 0; - auto geometry = make_unique("TRAJ_PC_" + to_string(++id), GeometryData::POINT_CLOUD); - if (geometry == nullptr) { - LOG(logERROR) << "could not create geometry"; - return nullptr; + using Ra::Core::Utils::logERROR; + using Ra::Core::Utils::logINFO; + + FileData* fileData = new Ra::Core::Asset::FileData( filename ); + + if ( !fileData->isInitialized() ) { + delete fileData; + LOG( logINFO ) << "Filedata could not be initialized"; + return nullptr; + } + + auto startTime = clock(); + // a unique name is required by the component messaging system + static int id = 0; + auto geometry = + make_unique( "TRAJ_PC_" + to_string( ++id ), GeometryData::POINT_CLOUD ); + if ( geometry == nullptr ) { + LOG( logERROR ) << "could not create geometry"; + return nullptr; + } + + geometry->setFrame( Ra::Core::Transform::Identity() ); + + ifstream stream( filename ); + if ( !stream.is_open() ) { + throw runtime_error( "Could not open ifstream to path " + filename ); + return nullptr; + } + else { + LOG( logINFO ) << "---Beginning file loading---"; + } + + /*reading how data is arranged*/ + string line; + + if ( !std::getline( stream, line ) ) { + delete fileData; + LOG( logINFO ) << "file does not contain ascii data format. aborting"; + return nullptr; + } + + // retrieving all properties from header line + std::stringstream words( line ); + vector tokens; + string temp; + while ( words >> temp ) { + tokens.emplace_back( temp ); + }; + + // making sure X, Y, Z and Time properties are found + int xpos = -1, ypos = -1, zpos = -1; + for ( size_t i = 0; i < tokens.size(); ++i ) { + string token = tokens[i]; + if ( xpos == -1 ) { + if ( token.compare( "X" ) == 0 ) { xpos = i; } } - - geometry->setFrame(Ra::Core::Transform::Identity()); - - ifstream stream(filename); - if (!stream.is_open()) { - throw runtime_error("Could not open ifstream to path " + filename); - return nullptr; - } - else { - LOG(logINFO) << "---Beginning file loading---"; + if ( ypos == -1 ) { + if ( token.compare( "Y" ) == 0 ) { ypos = i; } } - - /*reading how data is arranged*/ - string line; - - if (!std::getline(stream, line)) { - delete fileData; - LOG(logINFO) << "file does not contain ascii data format. aborting"; - return nullptr; + if ( zpos == -1 ) { + if ( token.compare( "Z" ) == 0 ) { zpos = i; } } - - //retrieving all properties from header line - std::stringstream words (line); - vector tokens; - string temp; - while (words >> temp) { tokens.emplace_back(temp); }; - - //making sure X, Y, Z and Time properties are found - int xpos = -1, ypos = -1, zpos = -1; - for (size_t i = 0;i < tokens.size();++i) { - string token = tokens[i]; - if (xpos == -1) { - if (token.compare("X") == 0) { - xpos = i; - } + } + + if ( ( xpos == -1 ) || ( ypos == -1 ) || ( zpos == -1 ) ) { + delete fileData; + LOG( logERROR ) << "file does not contain mandatory properties (X, Y, Z, Time). aborting"; + return nullptr; + } + else { + LOG( logINFO ) << "loading properties: "; + string info = ""; + for ( size_t i = 0; i < tokens.size(); ++i ) { + if ( i % 4 == 3 ) { + LOG( logINFO ) << info << tokens[i]; + info = ""; } - if (ypos == -1) { - if (token.compare("Y") == 0) { - ypos = i; - } - } - if (zpos == -1) { - if (token.compare("Z") == 0) { - zpos = i; - } - } - } - - if ((xpos == -1) || (ypos == -1) || (zpos == -1)) { - delete fileData; - LOG(logERROR) << "file does not contain mandatory properties (X, Y, Z, Time). aborting"; - return nullptr; - } - else { - LOG(logINFO) << "loading properties: "; - string info = ""; - for (size_t i = 0;i < tokens.size();++i) { - if (i % 4 == 3) { - LOG(logINFO) << info << tokens[i]; - info = ""; - } - else { - info += tokens[i] + ", "; - } + else { + info += tokens[i] + ", "; } } - - Ra::Core::VectorArray& vertices = geometry->getGeometry().verticesWithLock(); - - //creating custom attribs for all other properties - vector> attribs; - attribs.reserve(tokens.size() - 3); - - for (size_t i = 0;i < tokens.size();++i) { - //skipping mandatory attribs - if (((int)i == xpos) || ((int)i == ypos) || ((int)i == zpos)) { continue; } - attribs.emplace_back(geometry->getGeometry().vertexAttribs().addAttrib( tokens[i] )); - } - - /*recording data*/ - vector pointRecord; - int i = 0; - double num; - while (stream >> num) { - pointRecord.emplace_back(num); - - if (i == (int)(tokens.size() - 1)) { - vertices.emplace_back(Scalar(pointRecord[xpos]), Scalar(pointRecord[ypos]), Scalar(pointRecord[zpos])); - size_t k = 0; - for (size_t j = 0;j < tokens.size();++j) { - if (((int)j == xpos) || ((int)j == ypos) || ((int)j == zpos)) { continue; } - geometry->getGeometry().vertexAttribs().getDataWithLock(attribs[k]).emplace_back(Scalar(pointRecord[j])); - geometry->getGeometry().vertexAttribs().unlock(attribs[k]); - ++k; - } - pointRecord.clear(); + } + + Ra::Core::VectorArray& vertices = geometry->getGeometry().verticesWithLock(); + + // creating custom attribs for all other properties + vector> attribs; + attribs.reserve( tokens.size() - 3 ); + + for ( size_t i = 0; i < tokens.size(); ++i ) { + // skipping mandatory attribs + if ( ( (int)i == xpos ) || ( (int)i == ypos ) || ( (int)i == zpos ) ) { continue; } + attribs.emplace_back( + geometry->getGeometry().vertexAttribs().addAttrib( tokens[i] ) ); + } + + /*recording data*/ + vector pointRecord; + int i = 0; + double num; + while ( stream >> num ) { + pointRecord.emplace_back( num ); + + if ( i == (int)( tokens.size() - 1 ) ) { + vertices.emplace_back( Scalar( pointRecord[xpos] ), + Scalar( pointRecord[ypos] ), + Scalar( pointRecord[zpos] ) ); + size_t k = 0; + for ( size_t j = 0; j < tokens.size(); ++j ) { + if ( ( (int)j == xpos ) || ( (int)j == ypos ) || ( (int)j == zpos ) ) { continue; } + geometry->getGeometry() + .vertexAttribs() + .getDataWithLock( attribs[k] ) + .emplace_back( Scalar( pointRecord[j] ) ); + geometry->getGeometry().vertexAttribs().unlock( attribs[k] ); + ++k; } - i = (i + 1) % tokens.size(); + pointRecord.clear(); } - stream.close(); + i = ( i + 1 ) % tokens.size(); + } + stream.close(); - geometry->getGeometry().verticesUnlock(); + geometry->getGeometry().verticesUnlock(); - // finalizing - fileData->m_geometryData.clear(); - fileData->m_geometryData.reserve( 1 ); - fileData->m_geometryData.push_back( move( geometry ) ); + // finalizing + fileData->m_geometryData.clear(); + fileData->m_geometryData.reserve( 1 ); + fileData->m_geometryData.push_back( move( geometry ) ); - fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); + fileData->m_loadingTime = ( clock() - startTime ) / Scalar( CLOCKS_PER_SEC ); - LOG( logINFO ) << "---File loading ended---"; + LOG( logINFO ) << "---File loading ended---"; - fileData->displayInfo(); + fileData->displayInfo(); - fileData->m_processed = true; + fileData->m_processed = true; - return fileData; + return fileData; } string AsciiPointCloudLoader::name() const { diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 4b05d76d444..d0758ff7422 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -187,7 +187,10 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { blue = *(unsigned short*)( point.data() + 24 ); } - colors.emplace_back(Scalar(red) / 65536_ra, Scalar(green) / 65536_ra, Scalar(blue) / 65536_ra, 1_ra); + colors.emplace_back( Scalar( red ) / 65536_ra, + Scalar( green ) / 65536_ra, + Scalar( blue ) / 65536_ra, + 1_ra ); } if ( handle_time.idx().isValid() ) { From 1ded72e98c6e4b0a8218e99b8f383c2caee7145f Mon Sep 17 00:00:00 2001 From: Marina2468 Date: Wed, 27 Jul 2022 13:14:57 +0200 Subject: [PATCH 24/28] remove properties' log --- src/IO/AsciiPCLoader/asciipcloader.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/IO/AsciiPCLoader/asciipcloader.cpp b/src/IO/AsciiPCLoader/asciipcloader.cpp index bc7c758abf8..c199e267d00 100644 --- a/src/IO/AsciiPCLoader/asciipcloader.cpp +++ b/src/IO/AsciiPCLoader/asciipcloader.cpp @@ -95,19 +95,6 @@ Ra::Core::Asset::FileData* AsciiPointCloudLoader::loadFile( const string& filena LOG( logERROR ) << "file does not contain mandatory properties (X, Y, Z, Time). aborting"; return nullptr; } - else { - LOG( logINFO ) << "loading properties: "; - string info = ""; - for ( size_t i = 0; i < tokens.size(); ++i ) { - if ( i % 4 == 3 ) { - LOG( logINFO ) << info << tokens[i]; - info = ""; - } - else { - info += tokens[i] + ", "; - } - } - } Ra::Core::VectorArray& vertices = geometry->getGeometry().verticesWithLock(); From d83079835d0cae279f601d9ec2c2ee293a871f75 Mon Sep 17 00:00:00 2001 From: Marina2468 Date: Thu, 28 Jul 2022 17:59:26 +0200 Subject: [PATCH 25/28] add guards on read + improve char* to double cast --- src/IO/LasLoader/lasloader.cpp | 73 ++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index d0758ff7422..eea931d487e 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -23,6 +23,13 @@ bool LasLoader::handleFileExtension( const string& extension ) const { return extension.compare( lasExt ) == 0; } +double readDouble (const char* buffer) { + double res; + char* converter = reinterpret_cast(&res); + std::copy(buffer, buffer + sizeof(double), converter); + return res; +} + Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { using Ra::Core::VectorArray; using Ra::Core::Asset::FileData; @@ -66,7 +73,11 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { // reading minor version (needed to check data format) stream.seekg( 0 ); stream.seekg( 25 ); - stream.read( buffer, 1 ); + if ( !stream.read( buffer, 1 ) ) { + delete fileData; + throw runtime_error( "Could not read minor version" ); + return nullptr; + } unsigned char minor = *(unsigned char*)buffer; if ( ( minor < 1 ) || ( minor > 4 ) ) { @@ -81,16 +92,24 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { // reading distance from file start to first point record stream.seekg( 0 ); stream.seekg( 96 ); - stream.read( buffer, 4 ); + if ( !stream.read( buffer, 4 ) ) { + delete fileData; + throw runtime_error( "Could not read offset to point records" ); + return nullptr; + } unsigned int offset = *(unsigned int*)buffer; // reading point data format stream.seekg( 0 ); stream.seekg( 104 ); - stream.read( buffer, 1 ); + if ( !stream.read( buffer, 1 ) ) { + delete fileData; + throw runtime_error( "Could not read data format" ); + return nullptr; + } unsigned char data_format = *(unsigned char*)buffer; - if ( ( data_format < 0 ) || ( data_format > 3 && minor < 3 ) || + if ( ( data_format > 3 && minor < 3 ) || ( data_format > 5 && minor == 3 ) || ( data_format > 6 && minor == 4 ) ) { delete fileData; throw runtime_error( "Corrupted file. Unvalid data format" ); @@ -102,31 +121,42 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { } // reading data record length (bytes) - stream.read( buffer, 2 ); + if ( !stream.read( buffer, 2 ) ) { + delete fileData; + throw runtime_error( "Could not read point record length" ); + return nullptr; + } unsigned short data_len = *(unsigned short*)buffer; // reading total number of data records - stream.read( buffer, 4 ); + if ( !stream.read( buffer, 4 ) ) { + delete fileData; + throw runtime_error( "Could not read number of point records" ); + return nullptr; + } unsigned int nb_data = *(unsigned int*)buffer; // reading scales and offsets (used for computing coordinates) stream.seekg( 0 ); stream.seekg( 131 ); - stream.read( buffer, 48 ); + if ( !stream.read( buffer, 48 ) ) { + delete fileData; + throw runtime_error( "Could not read scale and offset fields" ); + return nullptr; + } - double scale_x = *( reinterpret_cast( buffer ) ); - double scale_y = *( reinterpret_cast( buffer + 8 ) ); - double scale_z = *( reinterpret_cast( buffer + 16 ) ); - double offset_x = *( reinterpret_cast( buffer + 24 ) ); - double offset_y = *( reinterpret_cast( buffer + 32 ) ); - double offset_z = *( reinterpret_cast( buffer + 40 ) ); + double scale_x = readDouble( buffer ); + double scale_y = readDouble( buffer + 8 ); + double scale_z = readDouble( buffer + 16 ); + double offset_x = readDouble( buffer + 24 ); + double offset_y = readDouble( buffer + 32 ); + double offset_z = readDouble( buffer + 40 ); /*loading properties*/ vector point( data_len ); VectorArray& vertices = geometry->getGeometry().verticesWithLock(); vertices.reserve( nb_data ); - // checking for colors Ra::Core::Utils::AttribHandle handle_color; Ra::Core::VectorArray colors; @@ -153,7 +183,11 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { stream.seekg( pos ); // reading point data - stream.read( point.data(), data_len ); + if ( !stream.read( point.data(), data_len ) ) { + delete fileData; + throw runtime_error( "Could not read point record " + to_string(i) ); + return nullptr; + } // extracting initial x y z coordinates int ix; @@ -164,7 +198,7 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { iy = *(int*)( point.data() + 4 ); iz = *(int*)( point.data() + 8 ); - // computing actual coordinates + // scaling to obtain actual coordinates double x = (double)ix * scale_x + offset_x; double y = (double)iy * scale_y + offset_y; double z = (double)iz * scale_z + offset_z; @@ -196,19 +230,18 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { if ( handle_time.idx().isValid() ) { // loading GPS time if found if ( data_format == 6 ) { - gps_time.emplace_back( Scalar( *reinterpret_cast( point.data() + 22 ) ) ); + gps_time.emplace_back( Scalar( readDouble( point.data() + 22 ) ) ); } else { - gps_time.emplace_back( Scalar( *reinterpret_cast( point.data() + 20 ) ) ); + gps_time.emplace_back( Scalar( readDouble( point.data() + 20 ) ) ); } } } stream.close(); + point.clear(); geometry->getGeometry().verticesUnlock(); - point.clear(); - if ( handle_color.idx().isValid() ) { geometry->getGeometry().vertexAttribs().getAttrib( handle_color ).setData( colors ); } From 484848f468a852b25e6381ad932f654409524962 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 28 Jul 2022 16:03:37 +0000 Subject: [PATCH 26/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/LasLoader/lasloader.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index eea931d487e..b17bd9ea9cb 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -23,10 +23,10 @@ bool LasLoader::handleFileExtension( const string& extension ) const { return extension.compare( lasExt ) == 0; } -double readDouble (const char* buffer) { +double readDouble( const char* buffer ) { double res; - char* converter = reinterpret_cast(&res); - std::copy(buffer, buffer + sizeof(double), converter); + char* converter = reinterpret_cast( &res ); + std::copy( buffer, buffer + sizeof( double ), converter ); return res; } @@ -109,8 +109,8 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { } unsigned char data_format = *(unsigned char*)buffer; - if ( ( data_format > 3 && minor < 3 ) || - ( data_format > 5 && minor == 3 ) || ( data_format > 6 && minor == 4 ) ) { + if ( ( data_format > 3 && minor < 3 ) || ( data_format > 5 && minor == 3 ) || + ( data_format > 6 && minor == 4 ) ) { delete fileData; throw runtime_error( "Corrupted file. Unvalid data format" ); return nullptr; @@ -185,7 +185,7 @@ Ra::Core::Asset::FileData* LasLoader::loadFile( const string& filename ) { // reading point data if ( !stream.read( point.data(), data_len ) ) { delete fileData; - throw runtime_error( "Could not read point record " + to_string(i) ); + throw runtime_error( "Could not read point record " + to_string( i ) ); return nullptr; } From c30f4737c9dae96499f7ff4d115b846eb0a48da7 Mon Sep 17 00:00:00 2001 From: Linda Ablaoui <60941889+Marina2468@users.noreply.github.com> Date: Thu, 28 Jul 2022 21:07:13 +0200 Subject: [PATCH 27/28] initialize to avoid warning --- src/IO/LasLoader/lasloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index b17bd9ea9cb..7340eb72c4e 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -24,7 +24,7 @@ bool LasLoader::handleFileExtension( const string& extension ) const { } double readDouble( const char* buffer ) { - double res; + double res = 0; char* converter = reinterpret_cast( &res ); std::copy( buffer, buffer + sizeof( double ), converter ); return res; From 4fc2c2bb159a35fde33587317d2e2c1086b01b46 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 28 Jul 2022 19:07:32 +0000 Subject: [PATCH 28/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/IO/LasLoader/lasloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/LasLoader/lasloader.cpp b/src/IO/LasLoader/lasloader.cpp index 7340eb72c4e..f17bb02c380 100644 --- a/src/IO/LasLoader/lasloader.cpp +++ b/src/IO/LasLoader/lasloader.cpp @@ -24,7 +24,7 @@ bool LasLoader::handleFileExtension( const string& extension ) const { } double readDouble( const char* buffer ) { - double res = 0; + double res = 0; char* converter = reinterpret_cast( &res ); std::copy( buffer, buffer + sizeof( double ), converter ); return res;