Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Point cloud loaders (LAS and TXT) #978

Draft
wants to merge 31 commits into
base: release-candidate
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
df9d559
add loaders for las and txt file format (point clouds)
Marina2468 Jul 25, 2022
9eccdfb
fix typo
Marina2468 Jul 25, 2022
afaa7d9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 26, 2022
5e396dd
remove compilation guards
Marina2468 Jul 26, 2022
faa0394
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 26, 2022
b478589
Update src/IO/AsciiPCLoader/asciipcloader.cpp
Marina2468 Jul 26, 2022
9e979c3
constructors set to default
Marina2468 Jul 26, 2022
d171d97
Merge branch 'pcloaders' of github.com:Marina2468/Radium-Engine into …
Marina2468 Jul 26, 2022
3573b19
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 26, 2022
814211f
Update src/IO/AsciiPCLoader/asciipcloader.cpp
Marina2468 Jul 26, 2022
bbf1404
Update src/IO/AsciiPCLoader/asciipcloader.cpp
Marina2468 Jul 26, 2022
1e49cd1
destructors set to default
Marina2468 Jul 26, 2022
2c53183
remove malloc
Marina2468 Jul 26, 2022
211b6f6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 26, 2022
c16169b
group log (remove code duplicate)
Marina2468 Jul 26, 2022
85c7236
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 26, 2022
5b6f991
update color and gps handling
Marina2468 Jul 26, 2022
6f9e1fa
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 26, 2022
c21c520
update to load all attribs as custom
Marina2468 Jul 26, 2022
c06f7a0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 26, 2022
c974425
update las loader
Marina2468 Jul 27, 2022
769a183
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 27, 2022
2a258b8
fix custom attribs reference issue
Marina2468 Jul 27, 2022
4b470bd
fix colors range
Marina2468 Jul 27, 2022
2f6cfde
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 27, 2022
1ded72e
remove properties' log
Marina2468 Jul 27, 2022
b361d35
Merge branch 'release-candidate' into pcloaders
Marina2468 Jul 27, 2022
d830798
add guards on read + improve char* to double cast
Marina2468 Jul 28, 2022
484848f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 28, 2022
c30f473
initialize to avoid warning
Marina2468 Jul 28, 2022
4fc2c2b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 203 additions & 0 deletions src/IO/AsciiPCLoader/asciipcloader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
#include <IO/AsciiPCLoader/asciipcloader.hpp>

#include <Core/Asset/FileData.hpp>
#include <Core/Utils/Attribs.hpp> //logs
#include <fstream>
#include <iostream>

using std::ifstream;
using std::make_unique;
using std::runtime_error;
using std::to_string;

const string trajExt( "txt" );

namespace Ra {
namespace IO {

AsciiPointCloudLoader::AsciiPointCloudLoader() {}
Marina2468 marked this conversation as resolved.
Show resolved Hide resolved

AsciiPointCloudLoader::~AsciiPointCloudLoader() {}
Marina2468 marked this conversation as resolved.
Show resolved Hide resolved

vector<string> AsciiPointCloudLoader::getFileExtensions() const {
return vector<string>( { "*." + 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::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<GeometryData>( "TRAJ_PC_" + to_string( ++id ), GeometryData::POINT_CLOUD );
Marina2468 marked this conversation as resolved.
Show resolved Hide resolved
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<unsigned long> spacepos;
unsigned long timepos, xpos, ypos, zpos;

if ( !getline( stream, line ) ) {
delete fileData;
LOG( logINFO ) << "file does not contain trajectory data format. aborting";
Marina2468 marked this conversation as resolved.
Show resolved Hide resolved
return nullptr;
}

timepos = line.find( "Time" );
Marina2468 marked this conversation as resolved.
Show resolved Hide resolved
xpos = line.find( " X" );
ypos = line.find( " Y" );
zpos = line.find( " Z" );

if ( timepos == string::npos ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid code duplication.
One option could be to test all positions at once, and throw a generic error message, e.g., ile does not contain mandatory properties (X, Y, Z, time). aborting

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*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this implementation, your loader can only load the x,y,z and time fields.
I would be better to load all the fields, then aggregate x,y,z, and add the position, and custom fields in the Radium datastructure.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated implementation to load all attributes as custom and aggregate x y z properties only

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<double> pointRecord;

auto& vertices = geometry->getGeometry().verticesWithLock();

// creating custom attrib for time record
auto handle = geometry->getGeometry().vertexAttribs().addAttrib<Scalar>( "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
41 changes: 41 additions & 0 deletions src/IO/AsciiPCLoader/asciipcloader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <Core/Asset/FileLoaderInterface.hpp>
#include <IO/RaIO.hpp>

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<string> 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
Loading