6

I need to read PLY files (Stanford Triangle Format) with embedded texture for some purpose. I saw several specification of PLY files, but could not find a single source specifying the syntax for texture mapping. There seems to be so many libraries which reads PLY file, but most of them seems not to support texture (they just crashes; I tried 2-3 of them). Following is in the header for a ply file with texture:

ply
format binary_little_endian 1.0
comment TextureFile Parameterization.png
element vertex 50383               
property float x
property float y
property float z
property float nx
property float ny
property float nz
element face 99994               
property list uint8 int32 vertex_index
property list uint8 float texcoord
end_header

What I don't understand is the line property list uint8 float texcoord. Also the list corresponding to a face is

3 1247 1257 1279 6 0.09163 0.565323 0.109197 0.565733 0.10888 0.602539 6 9 0.992157 0.992157 0.992157 0.992157 0.992157 0.992157 0.992157 0.992157 0.992157`. 

What is this list; what is the format? While I understand that PLY gives you the opportunity to define your own properties for the elements, but the handling textures seems to be pretty much a standard and quite a few applications (like the popular Meshlab) seems to open textured PLY files using the above syntax.

I want to know what is the standard syntax followed for reading textured PLY files and if possible the source from where this information is found.

genpfault
  • 51,148
  • 11
  • 85
  • 139
krips89
  • 1,683
  • 4
  • 17
  • 32

2 Answers2

8

In PLY files faces often contain lists of values and these lists can vary in size. If it's a triangular face, expect three values, a quad = 4 and so on up to any arbitrary n-gon. A list is declared in a line like this:

property list uint8 int32 vertex_index

This is a list called 'vertex_index'. It will always consist of an 8-bit unsigned integer (that's the uint8) that is the size N, followed by N 32-bit integers (that's the int32).

In the example line this shows up right away:

3 1247 1257 1279

This says, here comes 3 values and then it gives you the three.

Now the second list is where the texture coordinates should be:

property list uint8 float texcoord

It's just like the first list in that the size comes first (as an unsigned byte) but this time it will be followed by a series of 32-bit floats instead of integers (makes sense for texture coordinates). The straightforward interpretation is that there will be a texture coordinate for each of the vertices listed in vertex_index. If we assume these are just 2d texture coordinates (a pretty safe assumption) we should expect to see the number 6 followed by 6 floating point values ... and we do:

6 0.09163 0.565323 0.109197 0.565733 0.10888 0.602539

These are the texture coordinates that correspond with the three vertices already listed.

Now, for a face, that should be it. I don't know what the stuff is on the rest of the line. According to your header the rest of the file should be binary so I don't know how you got it as a line of ascii text but the extra data on that line shouldn't be there (also according to the header which fully defines a face).

OllieBrown
  • 143
  • 8
  • Thanks for your answer, but the problem was interpreting the entire string `3 1247 1257 1279 6 0.09163 0.565323 0.109197 0.565733 0.10888 0.602539 6 9 0.992157 0.992157 0.992157 0.992157 0.992157 0.992157 0.992157 0.992157 0.992157` and not just half of it. What I learnt is there are no 'strict' rule for PLY and in fact you define your own rule and interpret it - that was the entire philosophy of PLY. Which is the reason the txt coordinates written by one software can be just different than others. – krips89 Mar 27 '15 at 15:51
  • 1
    Well and ultimately my response is that this string is NOT a proper PLY line. It violates the rules that the header sets up. PLY files are self-contained. The header describes what data you should expect in each line and then the lines follow. The line you are showing has more data than the header says it should. – OllieBrown Apr 02 '15 at 21:23
2

Let me add to @OllieBrown's response, as further info for anyone coming across this, that the format above uses per-face texture coordinates, also called wedge UVs. What this means is that if you are sharing vertices, there is a chance that a shared vertex(basically a vert index being used in multiple adjacent triangles), might have different UVs based on the triangle it takes part in. That usually happens when a vertex is on a UV seam or where UVs meet the texture borders. Typically that means duplicating vertices since GPUs require per-vertex attributes. So a shared vertex ends up as X vertices overlapping in space(where X is the number of triangles they are shared by), but have different UVs based on the triangle they take part in. One advantage to keeping data like that on disk is that since this is a text format, it reduces the amount of text you need, therefore reduced disk size. OBJ has that as well, although it keeps a flat UV array and uses indexing into that array instead, regardless of whether it's per-vertex or per-face UVs.

I also can't figure out what the 6 9 <9*0.992157> part is (although the 9 part seems like 3 vector3s which have the same value for all 3 axes), but Paul Bourke's code here has this description of the setup_other_props function:

/******************************************************************************
Make ready for "other" properties of an element-- those properties that
the user has not explicitly asked for, but that are to be stashed away
in a special structure to be carried along with the element's other
information.

Entry:
  plyfile - file identifier
  elem    - element for which we want to save away other properties
******************************************************************************/

void setup_other_props(PlyFile *plyfile, PlyElement *elem)

From what I understand, it's possible to keep data that are not part of the header, per element. These data are supposed to be kept and stored, but not interpreted for use in every application. Bourke's description of the format speaks about backwards compatibility with older software, so this might be a case of a custom format that only some applications understand but the extra info shouldn't hinder an older application that doesn't need them from understanding and/or rendering the content.

fcdt
  • 2,371
  • 5
  • 14
  • 26
NPatch
  • 66
  • 6