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

Loading massive (10GB) ply files #2145

Closed
dakotabenjamin opened this issue Dec 11, 2017 · 21 comments
Closed

Loading massive (10GB) ply files #2145

dakotabenjamin opened this issue Dec 11, 2017 · 21 comments

Comments

@dakotabenjamin
Copy link
Contributor

dakotabenjamin commented Dec 11, 2017

Your Environment

  • Operating System and version: Ubuntu 16.04
  • Compiler: cmake 3.5.2 / make 4.1
  • PCL Version: 1.8.0
  • CPU: 16 cores / RAM: 118GB

Expected Behavior

pcl::io::LoadPLYFile should be able to handle large files without crashing.

Current Behavior

While trying to load a 10ish GB .ply point cloud using the following:

pcl::io::loadPLYFile<pcl::PointNormal> (inputFile_.c_str(), *points_.get())

I get a seg fault. Here's the gdb output:

Starting program: /home/dmb2/db-odm/build/bin/odm_meshing -inputFile /hdd/sanroque/opensfm/depthmaps/merged.ply -outputFile /hdd/sanroque/odm_meshing/odm_mesh.ply -logFile /hdd/sanroque/odm_meshing/odm_meshing_log.txt -maxVertexCount 1000000 -octreeDepth 9 -samplesPerNode 1.0 -solverDivide 12 -verbose
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff765b56d in void pcl::PLYReader::vertexScalarPropertyCallback<float>(float) () from /home/dmb2/db-odm/SuperBuild/install/lib/libpcl_io.so.1.8
(gdb) 

You can find the whole code source here: https://github.com/OpenDroneMap/OpenDroneMap/blob/master/modules/odm_meshing/src/OdmMeshing.cpp#L219

Possible Solution

I'm not exactly sure what the problem is, hoping y'all more experienced pcl devs can help

Code to Reproduce

You can find the isolated project here: https://github.com/dakotabenjamin/odm_meshing and follow the build instructions. I can share the large dataset privately.

Context

We are trying to scale up our photogrammetry software to be able to handle very large (5000+ image) datasets

@SergioRAgostinho
Copy link
Member

Thanks for submitting. This is gonna be fun to debug 😅 .

@SergioRAgostinho SergioRAgostinho added the needs: code review Specify why not closed/merged yet label Dec 11, 2017
@SergioRAgostinho
Copy link
Member

Ok first thing to try is to compile the current version of master and see if you have the same problem with it. I assume that is gonna be the same thing but we need to rule that one out early enough.

@SergioRAgostinho SergioRAgostinho added needs: author reply Specify why not closed/merged yet and removed needs: code review Specify why not closed/merged yet labels Dec 12, 2017
@dakotabenjamin
Copy link
Contributor Author

I can confirm that it still fails in the same way after building pcl from master. I will continue to follow any further instructions with this build.

@taketwo
Copy link
Member

taketwo commented Dec 15, 2017

What is the approximate number of points stored in this file?

@dakotabenjamin
Copy link
Contributor Author

from the header:

ply
format ascii 1.0
element vertex 184685009

@taketwo
Copy link
Member

taketwo commented Dec 15, 2017

And what is the type of the point cloud you are reading into? If it is more than 23 bytes, then this overflows:

cloud_->data.resize (cloud_->point_step * cloud_->width * cloud_->height);

@dakotabenjamin
Copy link
Contributor Author

dakotabenjamin commented Dec 15, 2017

By type, do you mean, pcl::PointNormal or the type of the numbers in the point cloud? Here's the rest of the head:

ply
format ascii 1.0
element vertex 184685009
property float x
property float y
property float z
property float nx
property float ny
property float nz
property uchar diffuse_red
property uchar diffuse_green
property uchar diffuse_blue
end_header
-14.8183 778.9617 25.9872 0.353 0.658 0.665 155 170 94
-14.9743 778.9879 25.9600 0.359 0.646 0.673 137 155 74
-24.4786 781.2566 25.7462 0.375 -0.056 0.925 126 144 48
-27.3715 784.1121 30.3645 0.386 -0.596 0.704 140 175 35

@taketwo
Copy link
Member

taketwo commented Dec 15, 2017

I mean the point type, e.g. PointNormal.

@taketwo
Copy link
Member

taketwo commented Dec 15, 2017

Actually, having a closer look at what is going on, the data is first read into the PCLPointCloud2 which is a binary blob without associated type and only then converted to a typed point cloud. So what is relevant is the properties (number and size) stored in PLY file. In your case the total size of vertex properties is 27 bytes, thus we get overflow. Can you confirm this by adding a debug print statement near the line I posted? Or just try to fix the problem by casting to 64 bit numbers before multiplication.

@dakotabenjamin
Copy link
Contributor Author

I think this confirms:

Breakpoint 1, OdmMeshing::loadPoints (this=0x7fffffffdc60) at /home/dmb2/CLionProjects/odm_meshing/src/OdmMeshing.cpp:219
219	    if(pcl::io::loadPLYFile<pcl::PointNormal> (inputFile_.c_str(), *points_.get()) == -1) {

Breakpoint 2, pcl::io::loadPLYFile<pcl::PointNormal> (file_name="merged.ply", cloud=...) at /home/dmb2/db-odm/SuperBuild/install/include/pcl-1.8/pcl/io/ply_io.h:785
785	      return (p.read (file_name, cloud));

Breakpoint 3, pcl::PLYReader::read<pcl::PointNormal> (this=0x7fffffffd540, file_name="merged.ply", cloud=..., offset=0) at /home/dmb2/db-odm/SuperBuild/install/include/pcl-1.8/pcl/io/ply_io.h:208
208	                        ply_version, offset);

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff765816d in void pcl::PLYReader::vertexScalarPropertyCallback<float>(float) () from /home/dmb2/db-odm/SuperBuild/install/lib/libpcl_io.so.1.8

@dakotabenjamin
Copy link
Contributor Author

dakotabenjamin commented Dec 15, 2017

I apologize if I misunderstood your directive. I'm new to c++ and gdb in general. I'm still trying to get the debug print near that line

@SergioRAgostinho
Copy link
Member

Just print the result of the multiplication of point step * height * width into the terminal. The same statement that is used to resize the data vector.

@dakotabenjamin
Copy link
Contributor Author

(gdb) print cloud_->point_step * cloud_->width * cloud_->height
$1 = 876212956

@taketwo
Copy link
Member

taketwo commented Dec 15, 2017

Can you also print point step and cloud width?

@dakotabenjamin
Copy link
Contributor Author

dakotabenjamin commented Dec 15, 2017

(gdb) print cloud_->point_step
$2 = 28
(gdb) print cloud_->width
$3 = 184685009

@taketwo
Copy link
Member

taketwo commented Dec 15, 2017

So the problem is here indeed. We need to allocate 5171180252, but we allocate only 876212956. Please change the line 98 to:

cloud_->data.resize (static_cast<uint64_t>(cloud_->point_step) * cloud_->width * cloud_->height); 

@dakotabenjamin
Copy link
Contributor Author

It did load correctly! I ran into other issues, but those don't seem to be related to this issue.

I will implement the change as a patch in my own software, but will this be added into master as well?

@SergioRAgostinho
Copy link
Member

The idea was for you to submit a PR here and we commit the change.

@taketwo shouldn't we cast to size_t ?

@dakotabenjamin
Copy link
Contributor Author

I can do that. Let me know which type is best to use. I'll test both.

@taketwo
Copy link
Member

taketwo commented Dec 16, 2017

Yes, size_t is more appropriate.

@YouYue123
Copy link

YouYue123 commented Mar 4, 2018

This change is not working for me.

All of the points I read into memory are all in 0 value which means the actual parse is skipped somewhere because of the size

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants