OFF is defined in the Geomview manual, as one of the object formats of its OOGL language. An OFF file describes a set of flat polygons that may share vertices. The polygons may be concave, but there is no way to give a polygon a hole. This page follows the manual’s OFF section and the general rules it shares with the other OOGL formats.
Layout
| Part | Syntax | Notes |
|---|---|---|
| Header keyword | [ST][C][N][4][n]OFF | Optional; see below |
| Dimension | Ndim | Present only with the n prefix |
| Counts | NVertices NFaces NEdges | Three integers. NEdges must be present but is neither used nor checked |
| Vertices | x y z and any extra data | NVertices of them, numbered from 0 in order |
| Faces | N v1 v2 … vN [colour] | NFaces of them, usually one per line |
Tokens, white space and comments
The text form is free-format ASCII: any amount of white space (spaces, tabs, line
breaks) may come between numbers and words. Line breaks matter in only one place, the
colour at the end of a face line. A # starts a comment that runs to the
end of the line, and a comment is allowed anywhere a line break is. Keywords are
case-sensitive: off is not a keyword.
Header keyword and prefixes
The keyword OFF is recommended but optional, because many existing files
lack it; a reader then recognises the file by its .off suffix or its
content. Prefix letters before OFF say what each vertex carries. When
several are used they must appear in the order below, so CNOFF is valid
and NCOFF is not recognised.
| Prefix | Adds to each vertex | Values |
|---|---|---|
ST | Texture coordinates | Two (s t) or three (s t u) |
C | A colour | Four floats, r g b a, each from 0 to 1; alpha 0 is transparent and 1 opaque |
N | A normal | Three floats, nx ny nz |
4 | A homogeneous coordinate | The position has one more value; see below |
n | A dimension of its own | A line with Ndim follows the keyword |
The letters are written in the reverse of the order in which the data appears in each
vertex. A STCN4OFF vertex holds the position, then the normal, then the
colour, then the texture coordinates. The manual allows two or three texture values
but does not say how a reader tells which; two is the usual case.
Vertices
All the data for one vertex is written together, and every vertex in a file has the same layout, set by the keyword. The position takes these forms:
| Keyword | Position values | Meaning |
|---|---|---|
OFF | 3 | x y z |
4OFF | 4 | x y z w, the last being the homogeneous component |
nOFF | Ndim | A point in Ndim dimensions |
4nOFF | Ndim + 1 | The first value is the homogeneous divisor, then the Ndim coordinates |
Without the 4 prefix, a 3D point has an implied homogeneous component of 1.
For N-dimensional vertices the manual says colours can be given as for 3D vertices,
but normals make no sense. The manual does not say how many values a normal would take
with the 4 or n prefix.
CNOFF
3 1 0
0 0 0 0 0 1 1 0 0 1
1 0 0 0 0 1 0 1 0 1
0 1 0 0 0 1 0 0 1 1
3 0 1 2
Faces
Each face gives its number of vertices, then that many vertex numbers in the range 0
to NVertices − 1, then an optional colour. The colour starts after the last
vertex number and ends at the end of the line or at a # comment, so it
must be on the same line as the face.
| Colour written as | Meaning |
|---|---|
| Nothing | The default colour |
| One integer | An index into a colour map, which Geomview reads from the file cmap.fmap in its data directory |
| Three or four integers | Red, green, blue and optionally alpha, each from 0 to 255 |
| Three or four floating-point numbers | Red, green, blue and optionally alpha, each from 0 to 1 |
The default colour depends on the rest of the file. If no face has a colour, every face takes the default material colour of the viewer. If some faces have colours and others do not, the others are grey, with red, green, blue and alpha all 0.666.
Geomview computes normals itself when the file gives none. They point towards the side from which the face’s vertices appear in anticlockwise order.
OFF BINARY
Writing the word BINARY after the keyword, as in OFF BINARY
or CNOFF BINARY, makes the rest of the file binary. The manual gives the
binary keyword as [ST][C][N][n]OFF BINARY, without the 4
prefix. The binary data starts at the byte after the first line feed following
BINARY; white space and one comment may come before that line feed. No
comments are possible inside the binary data.
| Value | Stored as |
|---|---|
| The three counts, each face’s vertex count and vertex numbers | 32-bit integer, big-endian |
| Positions, normals, vertex colours and texture coordinates | 32-bit IEEE 754 float, big-endian |
| Number of colour values after a face’s vertex numbers | 32-bit integer, big-endian: 0 for no colour, otherwise 1 to 4 |
| Face colour values | 32-bit float, big-endian; integers are not allowed here |
Big-endian means the most significant byte comes first. Unlike the text form, every
face carries a colour count, even when it is 0. The manual does not say how a binary
face with a single colour value, a colour map index, is to be read, nor whether the
Ndim of an nOFF BINARY file is written as text or as a
binary integer.
Worked example
A single triangle, with vertices at (0, 0, 0), (1, 0, 0) and (0, 1, 0) and no colour,
is 79 bytes in OFF BINARY.
00000000 4F 46 46 20 42 49 4E 41 52 59 0A 00 00 00 03 00 OFF BINARY......
00000010 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020 00 00 00 3F 80 00 00 00 00 00 00 00 00 00 00 00 ...?............
00000030 00 00 00 3F 80 00 00 00 00 00 00 00 00 00 03 00 ...?............
00000040 00 00 00 00 00 00 01 00 00 00 02 00 00 00 00 ...............
| Offset | Size | Type | Bytes | Meaning |
|---|---|---|---|---|
| 0 | 11 | Text | 4F 46 46 20 42 49 4E 41 52 59 0A | OFF BINARY and a line feed |
| 11 | 4 | int32 | 00 00 00 03 | NVertices = 3 |
| 15 | 4 | int32 | 00 00 00 01 | NFaces = 1 |
| 19 | 4 | int32 | 00 00 00 00 | NEdges = 0 |
| 23 | 12 | 3 × float32 | 00 00 00 00 × 3 | Vertex 0: 0.0, 0.0, 0.0 |
| 35 | 12 | 3 × float32 | 3F 80 00 00, 00 00 00 00 × 2 | Vertex 1: 1.0, 0.0, 0.0 |
| 47 | 12 | 3 × float32 | 00 00 00 00, 3F 80 00 00, 00 00 00 00 | Vertex 2: 0.0, 1.0, 0.0 |
| 59 | 4 | int32 | 00 00 00 03 | Face 0 has 3 vertices |
| 63 | 12 | 3 × int32 | 00 00 00 00, 00 00 00 01, 00 00 00 02 | Vertex numbers 0, 1 and 2 |
| 75 | 4 | int32 | 00 00 00 00 | No colour values follow |
The same face coloured opaque red would end with 00 00 00 04 and then the
floats 1.0, 0.0, 0.0 and 1.0: 3F 80 00 00 00 00 00 00 00 00 00 00 3F 80 00 00.