The PLY Format

The version 1.0 PLY format, also known as the Stanford Triangle Format, defines a flexible and systematic scheme for storing 3D data. The ASCII header specifies what data is in the file by defining "elements" each with a set of "properties." Many PLY files only have vertex and face data, however, it is possible to also include other data such as color information, vertex normals, or application-specific properties.

File Header

An example header (italicized text is comment):

| ply format binary_big_endian 1.0 element vertex 9200 property float x property float y property float z element face 18000 property list uchar int vertex_indices end_header | file ID specify data format and version define "vertex" element define "face" element data starts after this line

The file begins with "ply," identifying that it is a PLY file. The header must also include a format line with the syntax

| format <data format> <PLY version>

Supported data formats are "ascii" for data stored as text and "binary_little_endian" and "binary_big_endian" for binary data (where little/big endian refers to the byte ordering of multi-byte data). Element definitions begin with an "element" line followed by element property definitions

| element <element name> <number in file> property <data type> <property name 1> property <data type> <property name 2> property <data type> <property name 3> ...

For example, "element vertex 9200" defines an element "vertex" and specifies that 9200 vertices are stored in the file. Each element definition is followed by a list of properties of that element. There are two kinds of properties, scalar and list. A scalar property definition has the syntax

| property <data type> <property name>

where <data type> is

Name char uchar short ushort int uint float double
Type (8-bit) character (8-bit) unsigned character (16-bit) short integer (16-bit) unsigned short integer (32-bit) integer (32-bit) unsigned integer (32-bit) single-precision float (64-bit) double-precision float

For compatibility between systems, note that the number of bits in each data type must be consistent. A list type is stored with a count followed by a list of scalars. The definition syntax for a list property is

| property list <count data type> <data type> <property name>

For example, "property list uchar int vertex_index" defines vertex_index properties are stored starting with a byte count followed by integer values. This is useful for storing polygon connectivity as it has the flexibility to specify a variable number of vertex indices in each face.

The header can also include comments. The syntax for a comment is simply a line beginning with "comment" followed by a one-line comment:

| comment <comment text>

Comments can provide information about the data like the file's author, data description, data source, and other textual data.

Data

Following the header, the element data is stored as either ASCII or binary data (as specified by the format line in the header). After the header, the data is stored in the order the elements and properties were defined. First, all the data for the first element type is stored. In the example header, the first element type is "vertex" with 9200 vertices in the file, and with float properties "x," "y," and "z."

| float vertex[1].x float vertex[1].y float vertex[1].z float vertex[2].x float vertex[2].y float vertex[2].z ... float vertex[9200].x float vertex[9200].y float vertex[9200].z

In general, the properties data for each element is stored one element at a time.

| <property 1> <property 2> ... <property N> element[1] <property 1> <property 2> ... <property N> element[2] ...

The list type properties are stored beginning with a count and followed by a list of scalars. For example, the "face" element type has the list property "vertex_indices" with uchar count and int scalar type.

| uchar count int face[1].vertex_indices[1] int face[1].vertex_indices[2] int face[1].vertex_indices[3] ... int face[1].vertex_indices[count] uchar count int face[2].vertex_indices[1] int face[2].vertex_indices[2] int face[2].vertex_indices[3] ... int face[2].vertex_indices[count] ...

Example Files

Greg Turk uses these example in his article to explain the PLY format; find his article at University of Virginia or University of California, Irvine. The first simple example file below describes a unit cube with vertex and face data.

| ply format ascii 1.0 comment made by Greg Turk comment this file is a cube element vertex 8 property float x property float y property float z element face 6 property list uchar vertex_indices end_header 0 0 0 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 1 1 1 1 1 0 4 0 1 2 3 4 7 6 5 4 4 0 4 5 1 4 1 5 6 2 4 2 6 7 3 4 3 7 4 0 | file header data is in ASCII format define vertex elements, 8 vertices in file define face elements, 6 faces in file vertex data face data

A second example file extends the cube description, including vertex color data and edge elements.

| 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 red uchar property green uchar property blue uchar element face 7 property list uchar int vertex_indices element edge 5 property int vertex1 property int vertex2 property uchar red property uchar green property uchar blue end_header 0 0 0 255 0 0 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 3 0 2 3 4 7 6 5 4 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 1 2 255 255 255 2 3 255 255 255 3 0 255 255 255 2 0 0 0 0 | define vertex elements vertex color components define face elements define edge elements index of first vertex in edge index of second vertex edge color components vertex data face data edge data

Common Elements and Properties

While the PLY format has the flexibility to define many types of elements and properities, a common set of elements are understood between programs to communicate common 3D data types. Turk suggests elements and property names that programs should try to make standard.

| Element | Property | Data Type | Property Description
vertex | x y z | float float float | x,y,z coordinates
| nx ny nz | float float float | x,y,z components of normal
| red green blue alpha | uchar uchar uchar uchar | vertex color amount of transparency
| material_index | int | index to list of materials
face | vertex_indices | list of int | indices to vertices
| back_red back_green back_blue | uchar uchar uchar | backside color
edge | vertex1 vertex2 | int int | index to vertex index to other vertex
| crease_tag | uchar | crease in subdivision surface
material | red green blue alpha | uchar uchar uchar uchar | material color amount of transparency
| reflect_coeff refract_coeff refract_index extinct_coeff | float float float float | amount of light reflected amount of light transmitted index of refraction extinction coefficient

* - required "core" properties in red

For most applications, the minimum necessary information is vertex and face data. To make it easier for programs to interpret PLY files, the element properties listed in red should always be included. If there is no face data (as in the case of point-cloud data) the face element could be defined with an element count of zero. The other elements and properties are suggested names for often used information like material parameters and edge information.

More about PLY

Greg Turk's article on the PLY format
University of Virginia
University of California, Irvine

Source code for working with PLY files
Georgia Institute of Technology
Astrophysics Supercomputing Virtual Reality
RPly C library for the PLY file format

Viewers and Utilities for PLY files
3D Object Converter
Cyberware Plyview
Quick3D Viewer

Sample PLY files
The Stanford 3D Scanning Repository
Cyberware 3D Scan Samples
Simple PLY files
Large Geometric Models Archive

Written by Pascal Getreuer July 10, 2004