1 | The PLY Polygon File Format |
---|
2 | --------------------------- |
---|
3 | |
---|
4 | Introduction |
---|
5 | ------------ |
---|
6 | |
---|
7 | This document presents the PLY polygon file format, a format for storing |
---|
8 | graphical objects that are described as a collection of polygons. Our goal is |
---|
9 | to provide a format that is simple and easy to implement but that is general |
---|
10 | enough to be useful for a wide range of models. The file format has two |
---|
11 | sub-formats: an ASCII representation for easily getting started, and a binary |
---|
12 | version for compact storage and for rapid saving and loading. We hope that |
---|
13 | this format will promote the exchange of graphical object between programs and |
---|
14 | also between groups of people. |
---|
15 | |
---|
16 | Overview |
---|
17 | -------- |
---|
18 | |
---|
19 | Anyone who has worked in the field of computer graphics for even a short |
---|
20 | time knows about the bewildering array of storage formats for graphical |
---|
21 | objects. It seems as though every programmer creates a new file format for |
---|
22 | nearly every new programming project. The way out of this morass of |
---|
23 | formats is to create a single file format that is both flexible enough to |
---|
24 | anticipate future needs and that is simple enough so as not to drive away |
---|
25 | potential users. Once such a format is defined, a suite of utilities (both |
---|
26 | procedures and entire programs) can be written that are centered around this |
---|
27 | format. Each new utility that is added to the suite can leverage off the power |
---|
28 | of the others. |
---|
29 | |
---|
30 | The PLY format describes an object as a collection of vertices, faces and |
---|
31 | other elements, along with properties such as color and normal direction that |
---|
32 | can be attached to these elements. A PLY file contains the description of |
---|
33 | exactly one object. Sources of such objects include: hand-digitized objects, |
---|
34 | polygon objects from modeling programs, range data, triangles from marching |
---|
35 | cubes (isosurfaces from volume data), terrain data, radiosity models. |
---|
36 | Properties that might be stored with the object include: color, surface |
---|
37 | normals, texture coordinates, transparency, range data confidence, and |
---|
38 | different properties for the front and back of a polygon. |
---|
39 | |
---|
40 | The PLY format is NOT intended to be a general scene description |
---|
41 | language, a shading language or a catch-all modeling format. This means |
---|
42 | that it includes no transformation matrices, object instantiation, modeling |
---|
43 | hierarchies, or object sub-parts. It does not include parametric patches, |
---|
44 | quadric surfaces, constructive solid geometry operations, triangle strips, |
---|
45 | polygons with holes, or texture descriptions (not to be confused with texture |
---|
46 | coordinates, which it does support!). |
---|
47 | |
---|
48 | A typical PLY object definition is simply a list of (x,y,z) triples for |
---|
49 | vertices and a list of faces that are described by indices into the list of |
---|
50 | vertices. Most PLY files include this core information. Vertices and faces |
---|
51 | are two examples of "elements", and the bulk of a PLY file is its list of |
---|
52 | elements. Each element in a given file has a fixed number of "properties" that |
---|
53 | are specified for each element. The typical information in a PLY file contains |
---|
54 | just two elements, the (x,y,z) triples for vertices and the vertex indices for |
---|
55 | each face. Applications can create new properties that are attached to |
---|
56 | elements of an object. For example, the properties red, green and blue are |
---|
57 | commonly associated with vertex elements. New properties are added in such a |
---|
58 | way that old programs do not break when these new properties are encountered. |
---|
59 | Properties that are not understood by a program can either be carried along |
---|
60 | uninterpreted or can be discarded. In addition, one can create a new element |
---|
61 | type and define the properties associated with this element. Examples of new |
---|
62 | elements are edges, cells (lists of pointers to faces) and materials (ambient, |
---|
63 | diffuse and specular colors and coefficients). New elements can also be |
---|
64 | carried along or discarded by programs that do not understand them. |
---|
65 | |
---|
66 | File Structure |
---|
67 | -------------- |
---|
68 | |
---|
69 | This is the structure of a typical PLY file: |
---|
70 | |
---|
71 | Header |
---|
72 | Vertex List |
---|
73 | Face List |
---|
74 | (lists of other elements) |
---|
75 | |
---|
76 | The header is a series of carraige-return terminated lines of text that |
---|
77 | describe the remainder of the file. The header includes a description of each |
---|
78 | element type, including the element's name (e.g. "edge"), how many such |
---|
79 | elements are in the object, and a list of the various properties associated |
---|
80 | with the element. The header also tells whether the file is binary or ASCII. |
---|
81 | Following the header is one list of elements for each element type, presented |
---|
82 | in the order described in the header. |
---|
83 | |
---|
84 | Below is the complete ASCII description for a cube. The header of a binary |
---|
85 | version of the same object would differ only in substituting the word |
---|
86 | "binary_little_endian" or "binary_big_endian" for the word "ascii". The |
---|
87 | comments in brackets are NOT part of the file, they are annotations to this |
---|
88 | example. Comments in files are ordinary keyword-identified lines that begin |
---|
89 | with the word "comment". |
---|
90 | |
---|
91 | ply |
---|
92 | format ascii 1.0 { ascii/binary, format version number } |
---|
93 | comment made by Greg Turk { comments keyword specified, like all lines } |
---|
94 | comment this file is a cube |
---|
95 | element vertex 8 { define "vertex" element, 8 of them in file } |
---|
96 | property float x { vertex contains float "x" coordinate } |
---|
97 | property float y { y coordinate is also a vertex property } |
---|
98 | property float z { z coordinate, too } |
---|
99 | element face 6 { there are 6 "face" elements in the file } |
---|
100 | property list uchar int vertex_index { "vertex_indices" is a list of ints } |
---|
101 | end_header { delimits the end of the header } |
---|
102 | 0 0 0 { start of vertex list } |
---|
103 | 0 0 1 |
---|
104 | 0 1 1 |
---|
105 | 0 1 0 |
---|
106 | 1 0 0 |
---|
107 | 1 0 1 |
---|
108 | 1 1 1 |
---|
109 | 1 1 0 |
---|
110 | 4 0 1 2 3 { start of face list } |
---|
111 | 4 7 6 5 4 |
---|
112 | 4 0 4 5 1 |
---|
113 | 4 1 5 6 2 |
---|
114 | 4 2 6 7 3 |
---|
115 | 4 3 7 4 0 |
---|
116 | |
---|
117 | This example demonstrates the basic components of the header. Each part |
---|
118 | of the header is a carraige-return terminated ASCII string that begins with a |
---|
119 | keyword. Even the start and end of the header ("ply<cr>" and |
---|
120 | "end_header<cr>") are in this form. The characters "ply<cr>" must be the |
---|
121 | first four characters of the file, since they serve as the fileÕs magic number. |
---|
122 | Following the start of the header is the keyword "format" and a specification |
---|
123 | of either ASCII or binary format, followed by a version number. Next is the |
---|
124 | description of each of the elements in the polygon file, and within each |
---|
125 | element description is the specification of the properties. Then generic |
---|
126 | element description has this form: |
---|
127 | |
---|
128 | element <element-name> <number-in-file> |
---|
129 | property <data-type> <property-name-1> |
---|
130 | property <data-type> <property-name-2> |
---|
131 | property <data-type> <property-name-3> |
---|
132 | ... |
---|
133 | |
---|
134 | The properties listed after an "element" line define both the data type of the |
---|
135 | property and also the order in which the property appears for each element. |
---|
136 | There are two kinds of data types a property may have: scalar and list. Here |
---|
137 | is a list of the scalar data types a property may have: |
---|
138 | |
---|
139 | name type number of bytes |
---|
140 | --------------------------------------- |
---|
141 | char character 1 |
---|
142 | uchar unsigned character 1 |
---|
143 | short short integer 2 |
---|
144 | ushort unsigned short integer 2 |
---|
145 | int integer 4 |
---|
146 | uint unsigned integer 4 |
---|
147 | float single-precision float 4 |
---|
148 | double double-precision float 8 |
---|
149 | |
---|
150 | These byte counts are important and must not vary across implementations in |
---|
151 | order for these files to be portable. There is a special form of property |
---|
152 | definitions that uses the list data type: |
---|
153 | |
---|
154 | property list <numerical-type> <numerical-type> <property-name> |
---|
155 | |
---|
156 | An example of this is from the cube file above: |
---|
157 | |
---|
158 | property list uchar int vertex_index |
---|
159 | |
---|
160 | This means that the property "vertex_index" contains first an unsigned char |
---|
161 | telling how many indices the property contains, followed by a list containing |
---|
162 | that many integers. Each integer in this variable-length list is an index to |
---|
163 | a vertex. |
---|
164 | |
---|
165 | Another Example |
---|
166 | --------------- |
---|
167 | |
---|
168 | Here is another cube definition: |
---|
169 | |
---|
170 | ply |
---|
171 | format ascii 1.0 |
---|
172 | comment author: Greg Turk |
---|
173 | comment object: another cube |
---|
174 | element vertex 8 |
---|
175 | property float x |
---|
176 | property float y |
---|
177 | property float z |
---|
178 | property red uchar { start of vertex color } |
---|
179 | property green uchar |
---|
180 | property blue uchar |
---|
181 | element face 7 |
---|
182 | property list uchar int vertex_index { number of vertices for each face } |
---|
183 | element edge 5 { five edges in object } |
---|
184 | property int vertex1 { index to first vertex of edge } |
---|
185 | property int vertex2 { index to second vertex } |
---|
186 | property uchar red { start of edge color } |
---|
187 | property uchar green |
---|
188 | property uchar blue |
---|
189 | end_header |
---|
190 | 0 0 0 255 0 0 { start of vertex list } |
---|
191 | 0 0 1 255 0 0 |
---|
192 | 0 1 1 255 0 0 |
---|
193 | 0 1 0 255 0 0 |
---|
194 | 1 0 0 0 0 255 |
---|
195 | 1 0 1 0 0 255 |
---|
196 | 1 1 1 0 0 255 |
---|
197 | 1 1 0 0 0 255 |
---|
198 | 3 0 1 2 { start of face list, begin with a triangle } |
---|
199 | 3 0 2 3 { another triangle } |
---|
200 | 4 7 6 5 4 { now some quadrilaterals } |
---|
201 | 4 0 4 5 1 |
---|
202 | 4 1 5 6 2 |
---|
203 | 4 2 6 7 3 |
---|
204 | 4 3 7 4 0 |
---|
205 | 0 1 255 255 255 { start of edge list, begin with white edge } |
---|
206 | 1 2 255 255 255 |
---|
207 | 2 3 255 255 255 |
---|
208 | 3 0 255 255 255 |
---|
209 | 2 0 0 0 0 { end with a single black line } |
---|
210 | |
---|
211 | This file specifies a red, green and blue value for each vertex. To |
---|
212 | illustrate the variable-length nature of vertex_index, the first two faces of |
---|
213 | the object are triangles instead of a single square. This means that the |
---|
214 | number of faces in the object is 7. This object also contains a list of |
---|
215 | edges. Each edge contains two pointers to the vertices that delinate the |
---|
216 | edge. Each edge also has a color. The five edges defined above were |
---|
217 | specified so as to highlight the two triangles in the file. The first four |
---|
218 | edges are white, and they surround the two triangles. The final edge is |
---|
219 | black, and it is the edge that separates the triangles. |
---|
220 | |
---|
221 | User-Defined Elements |
---|
222 | --------------------- |
---|
223 | |
---|
224 | The examples above showed the use of three elements: vertices, faces and |
---|
225 | edges. The PLY format allows users to define their own elements as well. |
---|
226 | The format for defining a new element is exactly the same as for vertices, |
---|
227 | faces and edges. Here is the section of a header that defines a material |
---|
228 | property: |
---|
229 | |
---|
230 | element material 6 |
---|
231 | property ambient_red uchar { ambient color } |
---|
232 | property ambient_green uchar |
---|
233 | property ambient_blue uchar |
---|
234 | property ambient_coeff float |
---|
235 | property diffuse_red uchar { diffuse color } |
---|
236 | property diffuse_green uchar |
---|
237 | property diffuse_blue uchar |
---|
238 | property diffuse_coeff float |
---|
239 | property specular_red uchar { specular color } |
---|
240 | property specular_green uchar |
---|
241 | property specular_blue uchar |
---|
242 | property specular_coeff float |
---|
243 | property specular_power float { Phong power } |
---|
244 | |
---|
245 | These lines would appear in the header directly after the specification of |
---|
246 | vertices, faces and edges. If we want each vertex to have a material |
---|
247 | specification, we might add this line to the end of the properties for a |
---|
248 | vertex: |
---|
249 | |
---|
250 | property material_index int |
---|
251 | |
---|
252 | This integer is now an index into the list of materials contained in the file. |
---|
253 | It may be tempting for the author of a new application to invent several new |
---|
254 | elements to be stored in PLY files. This practice should be kept to a |
---|
255 | minimum. Much better is to try adapting common elements (vertices, faces, |
---|
256 | edges, materials) to new uses, so that other programs that understand these |
---|
257 | elements might be useful in manipulating these adapted elements. Take, for |
---|
258 | example, an application that describes molecules as collections of spheres and |
---|
259 | cylinders. It would be tempting define sphere and cylinder elements for the |
---|
260 | PLY files containing the molecules. If, however, we use the vertex and edge |
---|
261 | elements for this purpose (adding the radius property to each), we can make |
---|
262 | use of programs that manipulate and display vertices and edges. Clearly one |
---|
263 | should not create special elements for triangles and quadrilaterals, but |
---|
264 | instead use the face element. What if a program does not know the adjacency |
---|
265 | between faces and vertices (so-called unshared vertices)? This is where each |
---|
266 | triangle (say) is purely a collection of three positions in space, with no |
---|
267 | notion whether some triangles have common vertices. This is a fairly common |
---|
268 | situation. Assuming there are N triangles in a given object, then 3N vertices |
---|
269 | should be written to the file, followed by N faces that simply connect up |
---|
270 | these vertices. We anticipate that a utility will be written that converts |
---|
271 | between unshared and shared vertex files. |
---|
272 | |
---|
273 | Object Information |
---|
274 | ------------------ |
---|
275 | |
---|
276 | |
---|
277 | Interface Routines |
---|
278 | ------------------ |
---|
279 | |
---|
280 | This section describes a set of C routines that make it easy to read and write |
---|
281 | PLY polygon files. Both binary and ASCII files can be written with almost |
---|
282 | identical procedure calls. There are simple mechanisms for allowing a program |
---|
283 | to carry along information about an object even if the program doesn't |
---|
284 | explicitly know about all the types of elements and properties in a file. |
---|
285 | |
---|
286 | Writing Files |
---|
287 | ------------- |
---|
288 | |
---|
289 | Whether reading or writing a PLY file, there is one data structure that |
---|
290 | is associated with a given file, and that is the "PlyFile" data type. |
---|
291 | To write a file, we call the routine "ply_write": |
---|
292 | |
---|
293 | PlyFile *ply_write (FILE *fp, /* pointer to file for writing */ |
---|
294 | int nelems, /* number of elements in file */ |
---|
295 | char **elem_names, /* list of element names */ |
---|
296 | int file_type) /* binary or ascii? */ |
---|
297 | |
---|
298 | This routine returns a pointer to a structure of type PlyFile which will |
---|
299 | be used later to refer to the file. "ply_write" is called with a pointer |
---|
300 | to a file that we have opened for writing, the number of |
---|
301 | |
---|
302 | |
---|
303 | |
---|
304 | General Utilities |
---|
305 | ----------------- |
---|
306 | |
---|
307 | rescale |
---|
308 | center of mass |
---|
309 | compute vertex normals |
---|
310 | polygon editor |
---|
311 | polygon display |
---|
312 | create platonic and archemidean polyhedra |
---|
313 | truncate, stellate, dual, snub |
---|
314 | laplacian smoothing |
---|
315 | mesh simplification |
---|
316 | conversion to and from PLY files |
---|
317 | shared <-> unshared vertices |
---|
318 | split arbitrary polygons into triangles |
---|
319 | find connected components |
---|
320 | refine a subdivision surface |
---|
321 | strip away some properties and/or elements of a PLY file |
---|
322 | create new properties with default values |
---|
323 | combine multiple polygonal objects into one |
---|
324 | re-map values of properties into new ranges (like [0,255] into [0,1]) |
---|
325 | re-name properties |
---|
326 | orient the faces of an object so that adjacent faces are consistant |
---|
327 | |
---|
328 | Pre-Defined Elements and Properties |
---|
329 | ----------------------------------- |
---|
330 | |
---|
331 | Although the PLY format allows arbitrary new elements and properties, the |
---|
332 | biggest benefit of using the format is for communication between programs. |
---|
333 | These programs should understand a common set of elements and properties. |
---|
334 | To that end, we present suggestions for the names and types of a number of |
---|
335 | properties. |
---|
336 | |
---|
337 | The suggestions for properties are broken down into three separate lists. The |
---|
338 | first of these lists contain the two elements (vertex and face) and the |
---|
339 | associated four properties that ALL programs that use PLY files should |
---|
340 | understand. These four properties (x, y, z, vertex_index) comprise the |
---|
341 | minimal information that any polygon file should contain. Writing a program |
---|
342 | that expects these four properties is trivial, thus making it easy for a |
---|
343 | program to accept any PLY file that contains these "core" properties. The |
---|
344 | second list describes further properties that are likely to be used often. |
---|
345 | The final set are some suggestions for properties that some applications may |
---|
346 | desire. |
---|
347 | |
---|
348 | Core List (required) |
---|
349 | -------------------- |
---|
350 | |
---|
351 | Element: vertex |
---|
352 | x float x coordinate |
---|
353 | y float y coordinate |
---|
354 | z float z coordinate |
---|
355 | Element: face |
---|
356 | vertex_index list of int indices to vertices |
---|
357 | |
---|
358 | Second List (often used) |
---|
359 | ------------------------ |
---|
360 | |
---|
361 | Element: vertex |
---|
362 | nx float x component of normal |
---|
363 | ny float y component of normal |
---|
364 | nz float z component of normal |
---|
365 | red uchar red part of color |
---|
366 | green uchar green part of color |
---|
367 | blue uchar blue part of color |
---|
368 | alpha uchar amount of transparency |
---|
369 | material_index int index to list of materials |
---|
370 | Element: face |
---|
371 | Element: edge |
---|
372 | vertex1 int index to vertex |
---|
373 | vertex2 int other index to vertex |
---|
374 | Element: material |
---|
375 | red uchar red part of color |
---|
376 | green uchar green part of color |
---|
377 | blue uchar blue part of color |
---|
378 | alpha uchar amount of transparency |
---|
379 | reflect_coeff float amount of light reflected |
---|
380 | refract_coeff float amount of light transmitted |
---|
381 | refract_index float index of refraction |
---|
382 | extinct_coeff float extinction coefficient |
---|
383 | |
---|
384 | Third List (suggested extensions) |
---|
385 | --------------------------------- |
---|
386 | |
---|
387 | Element: vertex |
---|
388 | face_index list of int indices to faces |
---|
389 | vertex_index list of int indices to vertices |
---|
390 | edge_index list of int indices to edges |
---|
391 | radius float for spheres |
---|
392 | Element: face |
---|
393 | back_red uchar color of backside |
---|
394 | back_green uchar |
---|
395 | back_blue uchar |
---|
396 | Element: edge |
---|
397 | face1 int index to face |
---|
398 | face2 int other index to face |
---|
399 | radius float for cylinders |
---|
400 | crease_tag uchar crease in subdivision surface |
---|
401 | Element: material |
---|
402 | Element: cell examples: tetrahedra, cubes |
---|
403 | face_index list of int indices to faces |
---|
404 | vertex_index list of int indices to vertices |
---|
405 | edge_index list of int indices to edges |
---|
406 | |
---|
407 | |
---|