tinyply icon indicating copy to clipboard operation
tinyply copied to clipboard

Variable-length lists are not supported

Open bchretien opened this issue 7 years ago • 6 comments

Hi,

First of all thanks for the library. While testing it, I encountered the following issue.

The common use cases involve fixed-length lists for properties (e.g. faces made of 3 vertices), but the PLY format also supports variable lengths for the lists of each element, for example:

ply
format ascii 1.0
comment author: Greg Turk
comment object: another cube
element vertex 8
property float x
property float y
property float z
property uchar red                    { start of vertex color }
property uchar green
property uchar blue
element face 7
property list uchar int vertex_index  { number of vertices for each face }
element edge 5                        { five edges in object }
property int vertex1                  { index to first vertex of edge }
property int vertex2                  { index to second vertex }
property uchar red                    { start of edge color }
property uchar green
property uchar blue
end_header
0 0 0 255 0 0                         { start of vertex list }
0 0 1 255 0 0
0 1 1 255 0 0
0 1 0 255 0 0
1 0 0 0 0 255
1 0 1 0 0 255
1 1 1 0 0 255
1 1 0 0 0 255
3 0 1 2                               { start of face list, begin with a triangle }
3 0 2 3                               { another triangle }
4 7 6 5 4                             { now some quadrilaterals }
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
0 1 255 255 255                       { start of edge list, begin with white edge }
1 2 255 255 255
2 3 255 255 255
3 0 255 255 255
2 0 0 0 0                             { end with a single black line }

(example taken from Paul Bourke's personal page)

Here faces are described as both triangles and quadrilaterals, thus taking either 3 or 4 values. Apparently, this use case is not supported by tinyply yet, since these properties are serialized into a single vector, without keeping track of how many values are assigned to each element. We could also imagine cases where these lists can take any value (0 included).

Thus, for such cases, we might need to store the data in vector<vector<T>> (or vector<T> with an additional vector of offsets).

bchretien avatar Jan 16 '17 14:01 bchretien

Hah! Yes, you found some dirty laundry. I think the most practical, real-world example is a file that -- as you mention -- has tris and quads. The bad news is that adding support for this would probably require a re-write of both the API and internal parsing function.

ddiakopoulos avatar Jan 18 '17 23:01 ddiakopoulos

I managed to implement this feature: if the list length is set to 0, the property is treated as a variable-length list, stored as a std::vector<std::vector<T>>. I also added CMake support, and some basic tests. I can try to clean up things and make a PR for all of this if you're interested.

bchretien avatar Jan 19 '17 16:01 bchretien

👍 yes please!

ddiakopoulos avatar Jan 20 '17 00:01 ddiakopoulos

I'm still working on this, I fixed some more issues. For example, we might want to read face data only, thus skipping vertex elements entirely, which was not supported apparently.

bchretien avatar Jan 25 '17 17:01 bchretien

I also can't find an API to at least read the number of elements in a list, e.g. 3 for triangles and 4 for quadrics. Or do I miss something? If I expect all faces to be triangles, but they are quadrics, my application using tinyply crashes :-(

marnef avatar Jan 16 '20 11:01 marnef

Hi @marnef unfortunately this API doesn't exist on the master branch yet, but you can check out the variable-length branch if you need this feature.

ddiakopoulos avatar Jan 25 '20 20:01 ddiakopoulos