This file documents the OOGL file types. For examples of these file types, look in /u/gcg/grap/data/.... Contents Conventions Common syntax File names Vertices Object references Object formats QUAD (List of quadrilaterals) MESH (Rectangularly-connected mesh) BBP/BEZuvn (List of Bezier surface patches) OFF/Lincoln (Polyhedra: polygons with shared vertices) VECT (List of points and lines) INST (Transformed Instance of another object) LIST (List of other objects) GROUP (Collection of 4x4 transformation matrices) Conventions Common syntax Most OOGL object file formats are free-format ASCII -- any amount of white space (blanks, tabs, newlines) may appear between tokens (numbers, key words, etc.). Line breaks are almost always insignificant, with a couple of exceptions as noted. Comments begin with # and continue to the end of the line; they're allowed anywhere a newline is. A binary format is also defined for many objects, but since nothing writes these binary files yet it's not described here. Typically an OOGL object will begin with a key word designating the object type, possibly with modifiers indicating presence of color information etc. In some formats the key word is optional, for compatibility with file formats defined elsewhere. Object type is then determined by guessing from the file suffix (if any) or from the data itself. Key words are case sensitive. Some have optional prefix letters indicating presence of color or other data; in this case the order of prefixes is significant, e.g. a CNMESH is valid but NCMESH is not. File naming When OOGL objects are read from disk files, the OOGL library uses the file suffix to guess at the file type. If the suffix is unrecognized, or if no suffix is available (e.g. for an object being read from a pipe, or embedded in another OOGL object), all known types of objects are tried in turn until one accepts the data as valid. For now, a suffix is considered a reliable hint. Putting a QUAD object in a file called "fred.mesh" is doomed to fail. Vertices A couple of objects share a style of representing vertices with optional per-vertex color, surface-normal and texture-space data. All vertices within an object have the same format, specified by the header key word. All data for a vertex is grouped together (as opposed to e.g. giving coordinates for all vertices, then colors for all vertices, and so on). The syntax is X Y Z (3-D floating-point vertex coordinates) followed by Nx Ny Nz (normalized 3-D surface-normal if present) followed by R G B A (4-component floating-point color if present, each component in range 0..1. The A (alpha) component represents opacity: 0 transparent, 1 opaque.) followed by U V W (3-component texture parameter; it's not clear how this is to be used, ask Pat Hanrahan) As mentioned above, values are separated by white space, and line breaks are immaterial. Object references Some object types allow references to other OOGL objects, which may appear literally in the data stream, be loaded from named disk files, or (eventually) be imported from shared memory or other message-passing mechanisms. The syntax for literally-included objects is { # left-brace = # equals sign: "literal OOGL object follows" # OOGL object in its usual form, so typically a # key word follows the '=' } # matching right-brace to mark the object's end For objects loaded from files, the form is { # left-brace < # less-than sign: "name of OOGL file follows" # pathname of file; may be enclosed in quotes } # matching right-brace Note that this isn't a general textual "include" mechanism; a complete OOGL object must appear in the referenced file. It's not well defined what the "current" directory is for filenames which don't begin with "/". At present it's relative to the current directory of the running program but might change so that, if file X/Y contains a reference { < "Z" }, we actually read file X/Z. For objects loaded from shared memory, the form will be { # left-brace @ # at sign: "name of exported object follows" -or- # name of object; may be quoted @ # or, name of the object and the message pool # it comes from, if not the default pool. } Again, white space and line breaks are insignificant. Object formats QUAD (collection of quadrilaterals) Conventional suffix: .quad Syntax: [C][N]QUAD -or- [C][N]POLY # Key word # 4*N vertices for some N ... The leading key word is [C][N]QUAD or [C][N]POLY, where the optional C and N prefixes indicate that each vertex includes colors and normals respectively. That is, these files begin with one of the words QUAD CQUAD NQUAD CNQUAD POLY CPOLY NPOLY CNPOLY (but not NCQUAD or NCPOLY). QUAD and POLY are synonymous; both forms are allowed just for compatibility with ChapReyes. Following the key word is an arbitrary number of groups of 4 vertices, each group describing a quadrilateral. See the Vertex syntax above. The object ends at end-of-file, or with a closebrace if incorporated into an object reference (see above). MESH (rectangularly-connected mesh) Conventional suffix: .mesh Syntax: [C][N][Z][U][u][v]MESH # Key word # Mesh dimensions # Nu*Nv vertices, in format specified # by initial key word ... ... ... ... The key word is [C][N][Z][U][u][v]MESH. The optional prefix characters mean: C Each vertex (see Vertices above) includes a 4-component color. N Each vertex includes a surface normal vector. Z Of the 3 vertex position values, only the Z component is present; X and Y are omitted, and assumed to equal the mesh (u,v) coordinate so X ranges from 0 .. (Nu-1), Y from 0 .. (Nv-1) where Nu and Nv are the mesh dimensions -- see below. U Each vertex includes a 3-component texture space parameter. u The mesh is wrapped in the u-direction, so the (0,v)'th vertex is connected to the (Nu-1,v)'th for all v. v The mesh is wrapped in the v-direction, so the (u,0)'th vertex is connected to the (u,Nv-1)'th for all u. Thus a u-wrapped or v-wrapped mesh is topologically a cylinder, while a uv-wrapped mesh is a torus. Note that the order of prefix characters is significant; a colored, u-wrapped mesh is a CuMESH not a uCmesh. Following the mesh header are integers Nu and Nv, the dimensions of the mesh. Then follow Nu*Nv vertices, each in the form given by the header. They appear in v-major order, i.e. if we name each vertex by (u,v) then the vertices appear in the order (0,0) (1,0) (2,0) (3,0) ... (Nu-1,0) (0,1) (1,1) (2,1) (3,1) ... (Nu-1,1) ... (0,Nv-1) ... (Nu-1,Nv-1) BBP and BEZ Conventional suffix: .bbp or .bez Either suffix may contain either type of patch. Syntax: [ST]BBP -or- [C]BEZ[_ST] # Nu, Nv are u- and v-direction # polynomial degrees in range 1..6 # Nd = # of dimensions: 3->3-D, 4->rational # Nu,Nv,Nd are each a single decimal digit. # BBP form implies Nu=Nv=Nd=3 so BBP = BEZ333. # Any number of patches follow the header # (Nu+1)*(Nv+1) patch control points # each 3 or 4 floats according to header ... ... ... ... # ST texture coordinates if mentioned in header # 4-component float (0..1) R G B A colors # for each patch corner if mentioned in header These formats represent collections of Bezier surface patches, of degrees up to 6, and with 3-D or 4-D (rational) vertices. The header keyword has the forms [ST]BBP or [C]BEZ[_ST] The "ST" prefix on BBP, or "_ST" suffix on BEZuvn, indicates that each patch includes four pairs of floating-point texture-space coordinates, one for each corner of the patch. The "C" prefix on BEZuvn indicates a colored patch, including four sets of four-component floating-point colors (red, green, blue, alpha) in the range 0..1, one color for each corner. and , each a single digit in the range 1..6, are the patch's polynomial degree in the u and v direction respectively. is the number of components in each patch vertex, and must be either "3" for 3-D or "4" for homogeneous coordinates, that is, rational patches. BBP patches are bicubic patches with 3-D vertices, so BBP = BEZ333 and STBBP = BEZ333_ST. Any number of patches follow the header. Each patch comprises a series of patch vertices, followed by optional (s,t) texture coordinates, followed by optional (r,g,b,a) colors. Each patch has (Nu+1)*(Nv+1) vertices in v-major order, so that if we designate a vertex by its control point indices (u,v) the order is (0,0) (1,0) (2,0) ... (Nu,0) (0,1) (1,1) (2,1) ... (Nu,1) ... (0,Nv) ... (Nu,Nv) with each vertex containing either 3 or 4 floating-point numbers as specified by the header. If the header calls for ST coordinates, four pairs of floating-point numbers follow: the texture-space coordinates for the (0,0), (Nu,0), (0,Nv), and (Nu,Nv) corners of the patch, respectively. If the header calls for colors, four four-component (red, green, blue, alpha) floating-point colors follow, one for each patch corner. The series of patches ends at end-of-file, or with a closebrace if incorporated in an object reference. OFF Conventional suffix: .off Syntax: OFF # Header keyword (optional) # NEdges not used or checked # Vertices ... # Faces # NV = # vertices on this face # V[0] ... V[NV-1]: vertex indices # in range 0..NVertices-1 ... ... # continues past # to end-of-line; may be 0 to 4 numbers # nothing: default # 1 integer: colormap index # 3 or 4 integers: RGB[A] values 0..255 # 3 or 4 floats: RGB[A] values 0..1 OFF files (named for "object file format") represent collections of planar polygons with possibly shared vertices, a convenient way to describe polyhedra. The polygons may be concave but there's no provision for polygons containing holes. An OFF file may begin with the keyword "OFF"; it's recommended but optional, as many existing files lack this keyword. Three ASCII integers follow: Current software does not use nor check ; it needn't be correct but must be present. The 3-D vertex coordinates follow: 3*Nvertices floating-point numbers. They're implicitly numbered 0 through . Following these are the face descriptions, typically written with one line per face. Each has the form ... [] Here is the number of vertices on this face, and through are indices into the list of vertices (in the range 0..). The optional may take several forms. Line breaks are significant here: the description begins after and ends with the end of the line (or the next # comment). A may be: nothing : the default color one integer : index into "the" colormap; see below three or four integers : RGB and possibly alpha values in the range 0..255 three or four floating-point numbers : RGB and possibly alpha values in the range 0..1 For the one-integer case, the colormap is currently read from /u/graphics/geom/data/cmap.fmap. Some better mechanism for supplying a colormap is likely someday. The meaning of "default color" varies. If no face of the object has a color, they all inherit the environment's default material color. If some but not all faces have colors, the default is gray (RGBA=.666). VECT Conventional suffix: .vect Syntax: VECT ... # number of vertices # in each polyline ... # number of colors supplied # in each polyline ... # All the vertices # (3*NVertices floats) ... # All the colors # (4*NColors floats, RGBA) VECT objects represent lists of polylines (strings of connected line segments, possibly closed). A degenerate polyline can be used to represent a point. A VECT file begins with the key word "VECT" and three integers: Here is the number of polylines in the file, the total number of vertices, and the number of colors as explained below. Next come integers Nv[0] Nv[1] Nv[2] ... Nv[] giving the number of vertices in each polyline. A negative number indicates a closed polyline; 1 denotes a single-pixel point. The sum (of the absolute values) of the Nv[i] must equal . Next come more integers Nc[i]: the number of colors in each polyline. Normally one of three values: 0 : No color is specified for this polyline. It's drawn in the same color as the previous polyline. 1 : A single color is specified. The entire polyline is drawn in that color. abs(Nv[i]) : Each vertex has a color. Either each segment is drawn in the corresponding color, or the colors are smoothly interpolated along the line segments, depending on the implementation. The sum of the Nc[i] must equal . Next come groups of 3 floating-point numbers: the coordinates of all the vertices. The first abs(Nv[0]) of them form the first polyline, the next abs(Nv[1]) form the second and so on. Finally groups of 4 floating-point numbers give red, green, blue and alpha (opacity) values. The first Nc[0] of them apply to the first polyline, and so on. INST No conventional suffix (yet). An INST applies a 4x4 transformation to another OOGL object. It begins with "INST" followed by these sections which may appear in any order: unit specifies the OOGL object to be instantiated. See the section on object references, above, for the syntax of a . transform <4x4 transformation matrix, i.e. 16 floating-point numbers> specifies the transformation to be applied to the instantiated object. The matrix is written such that, if p is a 4-element row vector representing homogeneous coordinates of a point (in the OOGL object before transformation), p' is the transformed point, and A is the 4x4 matrix, p' = p A Thus for a Euclidean transformation, the translation components appear in the fourth row (last four elements) of A. A's last column (4th, 8th, 12th and 16th elements) are typically 0, 0, 0, and 1 respectively. At some point this syntax will be extended. It should be possible to incorporate a transformation matrix from elsewhere, using the object reference syntax. GROUP Conventional suffix: .grp or .prj (.prj for "projective" matrices) Collection of 4x4 matrices, plus optional OOGL object. Syntax: GROUP # key word <4x4 matrix, 16 floats> ... # Any number of 4x4 matrices unit # optional section The OOGL object, if any, is instantiated under each of the given transformations. This is equivalent to a LIST of INST's, each referring to that same object, except that the object reference only needs to be written once, and the object is only stored once. Some programs -- notably MinneView -- accept a GROUP with no OOGL object, and use it to replicate their The GROUP syntax is liable to change. It might become a pure bundle of transformations, with no associated OOGL object. If so, the current replication functionality would be achieved with an INST plus separate GROUP object; something like: INST transform { < groupfile.grp } unit { < ooglobject } However this syntax doesn't currently work.