PointCloudLibrary / pcl

Point Cloud Library (PCL)
https://pointclouds.org/
Other
9.8k stars 4.6k forks source link

IO PolygonMesh to PLY output cannot support large polygons #6087

Open mauricefallon opened 1 month ago

mauricefallon commented 1 month ago

Describe the bug

When writing a PolygonMesh with large polygons, PCL doesnt properly encode the size of the vertex lists.

Very specifically these lines use uchar to store the size of the polygon: https://github.com/PointCloudLibrary/pcl/blob/master/io/src/ply_io.cpp#L907C32-L907C51 https://github.com/PointCloudLibrary/pcl/blob/master/io/src/ply_io.cpp#L1520

When a polygon is bigger than 256 edges, this results in a ply file which cannot be read by PCL

This Possible Fix When a polygon contains a large polygon, the simple fix is to change: property list uchar int vertex_indices to property list uint int vertex_indices

PCL will then be able to read back in this ply file. However, meshlab (for comparison) cannot load this ply file. VTK can parse it.

Your Environment (please complete the following information):

mauricefallon commented 1 month ago

The existing header: ply format ascii 1.0 comment PCL generated element vertex 1257 property float x property float y property float z property uchar red property uchar green property uchar blue property float nx property float ny property float nz property float curvature element face 8 property list uchar int vertex_indices end_header

The header containing the fix:

ply format ascii 1.0 comment PCL generated element vertex 1257 property float x property float y property float z property uchar red property uchar green property uchar blue property float nx property float ny property float nz property float curvature element face 8 property list uint int vertex_indices end_header

mvieth commented 1 month ago

Interesting, I did not expect that someone would have faces with more than 255 vertices/edges. https://github.com/PointCloudLibrary/pcl/blob/master/io/src/ply_io.cpp#L907C32-L907C51 I think this line is actually irrelevant because it is for a pcl::PCLPointCloud2, not a pcl::PolygonMesh and stores no indices. I am not sure though why that line is written at all, probably for compatibility with some ply readers. However these lines would have to be adapted if uchar is changed to uint: https://github.com/PointCloudLibrary/pcl/blob/master/io/src/ply_io.cpp#L1707-L1713 (binary ply)

PCL will then be able to read back in this ply file. However, meshlab (for comparison) cannot load this ply file. VTK can parse it.

So the best approach probably is to check whether any face/polygon has more than 255 vertices, if yes use uint (and maybe print a warning), if not use uchar as before. Feel free to open a pull request.