Stanford PLY#

.ply read + write lazy: binary only

Summary of the specification#

PLY — the Stanford Triangle Format — stores a mesh as a list of named elements, typically vertex and face, each declared in an ASCII header along with its property names and scalar types. The body that follows is either ASCII text or a packed binary block in the byte order the header names. Because the header is self-describing, PLY can carry arbitrary per-vertex and per-face attributes: colours, normals, confidence, intensity.

Specification at a glance#

magic / header

ply, then format ascii | binary_little_endian | binary_big_endian 1.0

structure

element <name> <count> declarations, each followed by its property lines

scalar types

char uchar short ushort int uint float double, plus list <count-type> <item-type>

faces

property list uchar int vertex_indices — 0-based, arbitrary polygon size

comments

comment lines anywhere in the header; obj_info for producer metadata

published by

Greg Turk, Stanford University

Reading#

import polyxios as px

mesh = px.read("model.ply")
mesh.vertices          # (n, 3)
mesh.element_types     # element groups found in the file

Binary bodies can be memory-mapped instead of loaded:

mesh = px.read("big.ply", lazy=True)

Writing#

px.write(mesh, "out.ply")

Format-specific options:

Option

Default

Effect

binary

False

Write a packed binary body instead of ASCII.

endian

"little"

Byte order of the binary body; “big” emits binary_big_endian.

Quirks worth knowing#

  • Vertex properties beyond x/y/z — colour, normals, confidence, intensity — are preserved as named vertex attributes rather than dropped.

  • Lazy loading applies to binary bodies only; an ASCII file must be parsed in full before any value is available.

  • Index widths are checked against the declared vertex count, so a mesh too large for the header’s list type raises instead of truncating.

See also

Supported formats — the full format table.