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

Conversation

Marina2468
Copy link

  • Please check if the PR fulfills these requirements
  • The commit message follows our guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

Be aware that the PR request cannot be accepted if it doesn't pass the Continuous Integration tests.

  • What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
    feature

  • What is the current behavior? (You can also link to an open issue here)
    no support in radium to load .las and .txt point clouds

  • What is the new behavior (if this is a feature change)?
    add file loaders for .las and .txt file formats

  • Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)
    no

  • Other information:

@nmellado nmellado added enhancement Type of issue/PR: enhancement IO Related to Ra::IO labels Jul 26, 2022
@nmellado nmellado changed the title Pcloaders Add Point cloud loaders (LAS and TXT) Jul 26, 2022
src/IO/filelist.cmake Outdated Show resolved Hide resolved
@nmellado nmellado self-assigned this Jul 26, 2022
@codecov
Copy link

codecov bot commented Jul 26, 2022

Codecov Report

Merging #978 (4fc2c2b) into release-candidate (edd1179) will decrease coverage by 0.37%.
The diff coverage is 0.00%.

@@                  Coverage Diff                  @@
##           release-candidate     #978      +/-   ##
=====================================================
- Coverage              39.93%   39.56%   -0.38%     
=====================================================
  Files                    345      349       +4     
  Lines                  22928    23146     +218     
=====================================================
  Hits                    9157     9157              
- Misses                 13771    13989     +218     
Impacted Files Coverage Δ
src/IO/AsciiPCLoader/asciipcloader.cpp 0.00% <0.00%> (ø)
src/IO/AsciiPCLoader/asciipcloader.hpp 0.00% <0.00%> (ø)
src/IO/LasLoader/lasloader.cpp 0.00% <0.00%> (ø)
src/IO/LasLoader/lasloader.hpp 0.00% <0.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us.

Copy link
Contributor

@nmellado nmellado left a comment

Choose a reason for hiding this comment

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

First round of reviews

src/IO/AsciiPCLoader/asciipcloader.cpp Outdated Show resolved Hide resolved
src/IO/AsciiPCLoader/asciipcloader.cpp Outdated Show resolved Hide resolved
src/IO/AsciiPCLoader/asciipcloader.cpp Show resolved Hide resolved
src/IO/AsciiPCLoader/asciipcloader.cpp Outdated Show resolved Hide resolved
src/IO/AsciiPCLoader/asciipcloader.cpp Outdated Show resolved Hide resolved
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

src/IO/LasLoader/lasloader.cpp Outdated Show resolved Hide resolved
src/IO/LasLoader/lasloader.cpp Outdated Show resolved Hide resolved
src/IO/LasLoader/lasloader.cpp Outdated Show resolved Hide resolved

// checking for colors
bool colors = false;
auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib<Ra::Core::Vector4>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Check if colors exist in file before adding them as vertexAttrib

Copy link
Contributor

Choose a reason for hiding this comment

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

Same for gps info

Copy link
Author

Choose a reason for hiding this comment

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

if they are not in file, i delete them at the end (lines 220-227)

Copy link
Contributor

Choose a reason for hiding this comment

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

This looks sub-optimal.
Can't you just move the attrib creation after the check ?

Copy link
Author

Choose a reason for hiding this comment

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

in that case I would need a temporary vector to store colors and gps_time in the data reading loop, and that is what we tried to avoid in the first place

Copy link
Contributor

@nmellado nmellado Jul 26, 2022

Choose a reason for hiding this comment

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

I don't think so.
You can call addAttrib at line 137, ie. when setting colors to true.
In fact you don't need the colors variable: you can only check if handle_color is valid, using
handle_color.idx().isValid()

See https://storm-irit.github.io/Radium-Engine/release-candidate/classRa_1_1Core_1_1Utils_1_1AttribHandle.html#af86250020bb2831ce80a811c17d3a6c5
and https://storm-irit.github.io/Radium-Engine/release-candidate/Index_8hpp_source.html

Copy link
Author

Choose a reason for hiding this comment

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

updated code to call findAttrib every iteration, please check if it's the suitable behaviour (i did not use idx()...)

Comment on lines 131 to 135
bool colors = false;
if ( data_format == 2 || data_format == 3 || ( minor >= 3 && data_format == 5 ) ) {
auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib<Ra::Core::Vector4>(
Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) );
colors = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
bool colors = false;
if ( data_format == 2 || data_format == 3 || ( minor >= 3 && data_format == 5 ) ) {
auto handle_color = geometry->getGeometry().vertexAttribs().addAttrib<Ra::Core::Vector4>(
Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) );
colors = true;
Ra::Core::Utils::AttribHandle< Ra::Core::Vector4 > handle_color;
if ( data_format == 2 || data_format == 3 || ( minor >= 3 && data_format == 5 ) ) {
handle_color = geometry->getGeometry().vertexAttribs().addAttrib<Ra::Core::Vector4>(
Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) );

vertices.emplace_back( Scalar( x ), Scalar( y ), Scalar( z ) );

// computing colors if found
if ( colors ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if ( colors ) {
if ( handle_colors.idx().isValid() ) {

Comment on lines 190 to 193
auto handle_colors =
geometry->getGeometry().vertexAttribs().findAttrib<Ra::Core::Vector4>(
Ra::Core::Geometry::getAttribName(
Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
auto handle_colors =
geometry->getGeometry().vertexAttribs().findAttrib<Ra::Core::Vector4>(
Ra::Core::Geometry::getAttribName(
Ra::Core::Geometry::MeshAttrib::VERTEX_COLOR ) );

Comment on lines 194 to 198
geometry->getGeometry()
.vertexAttribs()
.getDataWithLock( handle_colors )
.emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra );
geometry->getGeometry().vertexAttribs().unlock( handle_colors );
Copy link
Contributor

Choose a reason for hiding this comment

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

It will be more efficient to look for the attrib only once.
Note that you can do

            auto& attr =  geometry->getGeometry(). getAttrib( handle_colors );

I think that I now understand why you need your temporary arrays, my bad.
So:

  • use temporary std::vector for colors (and other attributes)
  • after reading, copy them using geometry->getGeometry(). getAttrib( handle_colors ).setData().

Copy link
Author

Choose a reason for hiding this comment

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

updated

src/IO/AsciiPCLoader/asciipcloader.cpp Outdated Show resolved Hide resolved
src/IO/AsciiPCLoader/asciipcloader.cpp Outdated Show resolved Hide resolved
( (int)i == timepos ) ) {
continue;
}
auto handle2 = geometry->getGeometry().vertexAttribs().findAttrib<Scalar>( tokens[i] );
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess it would be better to store the handle in an array, it would be easier to lock/unlock.

Copy link
Author

Choose a reason for hiding this comment

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

updated

*
* example: Time X Y Z Roll Pitch Heading sdX sdY sdZ
*
* X, Y, Z and Time properties (case sensitive) are mandatory
Copy link
Contributor

Choose a reason for hiding this comment

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

I am wondering if we could relax the constraint on the time field: it could be useful to load point-clouds with xyz coordinates, even if we don't have the time field.

Copy link
Author

Choose a reason for hiding this comment

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

done. now only position properties are mandatory

blue = *(unsigned short*)( point.data() + 24 );
}

colors.emplace_back( Scalar( red ), Scalar( green ), Scalar( blue ), 1_ra );
Copy link
Contributor

Choose a reason for hiding this comment

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

As you can see here https://storm-irit.github.io/Radium-Engine/release-candidate/classRa_1_1Core_1_1Utils_1_1ColorBase.html
Colors have values between 0 and 1.
As you cast unsigned short to float, you will always have values > 1.

Copy link
Author

Choose a reason for hiding this comment

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

so do I need to perform a division by 2¹⁶?

Copy link
Contributor

Choose a reason for hiding this comment

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

You need to be sure what is the maximum value in practice. Usually it is 255.

Copy link
Author

Choose a reason for hiding this comment

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

it says in the specification that color channels are coded on 16 bits and that it should always be normalized to be so

src/IO/LasLoader/lasloader.hpp Show resolved Hide resolved
@dlyr dlyr marked this pull request as draft January 18, 2023 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Type of issue/PR: enhancement IO Related to Ra::IO
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants