STL comes from 3D Systems’ StereoLithography Interface Specification (July 1988, revised October 1989), which defines an ASCII form and a binary form. The specification itself is not published online; this page follows the reprint of its rules in Marshall Burns’ Automated Fabrication (1993, section 6.5), and says where today’s files and readers depart from them.
Syntax
solid name
facet normal ni nj nk
outer loop
vertex v1x v1y v1z
vertex v2x v2y v2z
vertex v3x v3y v3z
endloop
endfacet
…the facet block repeated, one or more times…
endsolid name
| Keyword | Followed by | Meaning |
|---|---|---|
solid | An optional name, to the end of the line | Starts the file |
facet normal | Three numbers | Starts a triangle and gives its unit normal |
outer loop | Nothing | Starts the triangle’s list of corners |
vertex | Three numbers | One corner: x, y and z. Exactly three per loop |
endloop | Nothing | Ends the list of corners |
endfacet | Nothing | Ends the triangle |
endsolid | The same optional name | Ends the file |
The words outer loop suggest that a facet could have other loops, or
loops of more than three corners, but the specification describes only triangles, and
readers expect exactly one loop of three vertices per facet.
Rules of the specification
| Rule | In practice |
|---|---|
| Keywords are lower case. | Followed by almost all writers. |
facet normal and outer loop each contain one space; the keywords beginning end contain none. | Readers rely on it: endloop, not end loop. |
| Indentation is with spaces; tabs are not allowed. | Most readers accept any white space, including tabs and blank lines, between words and numbers, but never inside one. |
Numbers are single-precision floats in exponent form, such as 2.648000e-002. | Plain decimals such as 0.5 or 1 are written and read just as widely. |
| A normal coordinate may be negative; a vertex coordinate may not. The object lies in the all-positive octant, every vertex coordinate greater than zero. | No longer enforced: zero and negative coordinates are common today, as in the example below. |
| The file has no units; coordinates are in arbitrary units. | Unchanged. Programs ask, or assume millimetres. |
| Sorting facets by ascending z is recommended, not required, to help the slicer. | Rarely done. |
The name after solid is optional. When it is left out, some software
expects a space after solid anyway. The rest of that line is free text and
is sometimes used for the file name, the author or a date.
Facet orientation
Each facet is part of the boundary between the inside and the outside of the object, and the specification states which side is outside twice, in two ways that must agree: the normal points outwards, and the three vertices run anticlockwise when the object is seen from outside (the right-hand rule).
The normal should be a unit vector. Many programs write 0 0 0 and leave
the reader to compute the normal from the vertex order, and many readers ignore the
stored normal altogether. A file that gives both a correct normal and the right
vertex order works everywhere.
The vertex-to-vertex rule
Each triangle must share two vertices with each triangle next to it. A vertex of one triangle must never lie partway along the side of another. With the orientation rules this makes the surface closed: every edge belongs to exactly two facets, with no gaps, flipped facets or overlaps. Nothing in the syntax enforces it, which is why repair tools exist.
Each facet repeats its three vertices in full. The file has no shared vertex list, so a reader that needs the connections between facets has to find matching coordinates itself.
Example
solid tetrahedron
facet normal 0.000000e+000 0.000000e+000 -1.000000e+000
outer loop
vertex 0.000000e+000 0.000000e+000 0.000000e+000
vertex 0.000000e+000 1.000000e+000 0.000000e+000
vertex 1.000000e+000 0.000000e+000 0.000000e+000
endloop
endfacet
facet normal 0.000000e+000 -1.000000e+000 0.000000e+000
outer loop
vertex 0.000000e+000 0.000000e+000 0.000000e+000
vertex 1.000000e+000 0.000000e+000 0.000000e+000
vertex 0.000000e+000 0.000000e+000 1.000000e+000
endloop
endfacet
facet normal -1.000000e+000 0.000000e+000 0.000000e+000
outer loop
vertex 0.000000e+000 0.000000e+000 0.000000e+000
vertex 0.000000e+000 0.000000e+000 1.000000e+000
vertex 0.000000e+000 1.000000e+000 0.000000e+000
endloop
endfacet
facet normal 5.773503e-001 5.773503e-001 5.773503e-001
outer loop
vertex 1.000000e+000 0.000000e+000 0.000000e+000
vertex 0.000000e+000 1.000000e+000 0.000000e+000
vertex 0.000000e+000 0.000000e+000 1.000000e+000
endloop
endfacet
endsolid tetrahedron
Telling ASCII from binary
An ASCII file starts with solid, but so do some
binary files, whose free 80-byte header
happens to begin with that word. A reliable test reads the 32-bit count at offset 80 as
if the file were binary: if the file size is exactly 84 + 50 × count, it is binary.
Otherwise, finding facet and endsolid confirms ASCII.