1519 lines
60 KiB
Plaintext
1519 lines
60 KiB
Plaintext
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
OFF - A 3D Object File Format
|
|||
|
|
|||
|
|
|||
|
Randi J. Rost
|
|||
|
6-November-1986
|
|||
|
Updated 12-October-1989
|
|||
|
|
|||
|
Digital Equipment Corporation
|
|||
|
Workstation Systems Engineering
|
|||
|
100 Hamilton Ave.
|
|||
|
Palo Alto, Ca. 94301
|
|||
|
|
|||
|
|
|||
|
This document describes the data format
|
|||
|
developed by WSE for the interchange and archiving
|
|||
|
of three-dimensional objects. This format, called
|
|||
|
OFF (for Object File Format), is general, flexi-
|
|||
|
ble, and extensible. It supports ASCII text ver-
|
|||
|
sions of objects for the purpose of interchange,
|
|||
|
and binary versions for efficiency of reading and
|
|||
|
writing. It is assumed that applications will
|
|||
|
develop their own, more efficient format for
|
|||
|
internal storage and operation on three-
|
|||
|
dimensional objects.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
_1. _I_n_t_r_o_d_u_c_t_i_o_n
|
|||
|
|
|||
|
One of the most time-consuming tasks in computer anima-
|
|||
|
tion projects is designing the 3D models that will be used.
|
|||
|
Many computer animation houses have found that owning a
|
|||
|
large number of databases makes it easier for them to take
|
|||
|
on new projects at a lower cost (time and $$$). The cost of
|
|||
|
initially creating an object can be amortized over the
|
|||
|
number of times it can be re-used. It is our intention to
|
|||
|
promote the use of OFF files within (and perhaps even out-
|
|||
|
side of) Digital in an effort to build up our collection of
|
|||
|
useful 3D models.
|
|||
|
|
|||
|
The file format itself is not limiting: OFF files can
|
|||
|
be used for a wide variety of object types. None of the
|
|||
|
"policy decisions" are hard-wired in the design of the file
|
|||
|
format, or in the support library routines that allow read-
|
|||
|
ing and writing of OFF files. Rather, the policy decisions
|
|||
|
have been left up to the designers since the format supports
|
|||
|
"generic" object definitions. We have developed specific
|
|||
|
conventions for objects that are defined by polygons for use
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 2 -
|
|||
|
|
|||
|
|
|||
|
within WSE, and we'd encourage others to adopt these conven-
|
|||
|
tions as well in order to promote the interchange of useful
|
|||
|
object data bases. The _d_x_m_o_d_e_l application (also developed
|
|||
|
by WSE) is an example of an application that permits reading
|
|||
|
and writing of OFF files.
|
|||
|
|
|||
|
This paper describes the Object File Format itself, the
|
|||
|
conventions we've adopted at WSE, and the library of support
|
|||
|
routines that can be used to read and write OFF files.
|
|||
|
|
|||
|
|
|||
|
_2. _D_e_s_i_g_n _G_o_a_l_s _a_n_d _N_o_n-_G_o_a_l_s
|
|||
|
|
|||
|
Design goals for the Object File Format include:
|
|||
|
|
|||
|
1) Simple. Simple cases should be simple. It should be
|
|||
|
possible to type in all the data required for a simple
|
|||
|
object (such as a cube) by hand.
|
|||
|
|
|||
|
2) Powerful. The Object File Format should be capable of
|
|||
|
accomodating complicated objects (many vertices,
|
|||
|
polygons, and a wide range of attributes).
|
|||
|
|
|||
|
3) Portable. ASCII text file representation required for
|
|||
|
portability across operating systems and hardware.
|
|||
|
This also allows operations on OFF files by familiar
|
|||
|
system utilities (text editors and the like).
|
|||
|
|
|||
|
4) Efficient. Binary text file representation required to
|
|||
|
allow efficient reading and writing of OFF files. It
|
|||
|
is assumed that reading/writing an object is a costly
|
|||
|
operation, but reading and writing ASCII data is just
|
|||
|
_t_o_o slow.
|
|||
|
|
|||
|
5) General. The format should address the general case of
|
|||
|
the three-dimensional object, not a single particular
|
|||
|
case.
|
|||
|
|
|||
|
6) Extensibile. Make sure the format can be easily
|
|||
|
extended to eventually support other primitives such as
|
|||
|
bezier patches.
|
|||
|
|
|||
|
7) No Favors. Avoid hard-wiring policy decisions.
|
|||
|
Rather, provide generic building blocks capable of sup-
|
|||
|
porting several styles and document a set of strongly
|
|||
|
encouraged conventions that we have adopted.
|
|||
|
|
|||
|
There are also things that were specifically non-goals in
|
|||
|
the design of the Object File Format.
|
|||
|
|
|||
|
1) Internal Format. The Object File Format is not
|
|||
|
intended to be forced upon applications as an internal
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 3 -
|
|||
|
|
|||
|
|
|||
|
format that must be used. Rather, it should be con-
|
|||
|
sidered a means for inputting and outputting object
|
|||
|
descriptions in a device-, language-, and operating
|
|||
|
system-independent format. Applications should feel
|
|||
|
free to develop and maintain the most useful/efficient
|
|||
|
data format they can, and only convert to/from OFF when
|
|||
|
input or output of a standardized object is desired.
|
|||
|
|
|||
|
2) Object Conventions. OFF conventions are documented
|
|||
|
only for objects in polygonal form at this point. It
|
|||
|
is anticipated that the Object File Format can be
|
|||
|
easily extended to handle bezier surface patches and
|
|||
|
other primitives in the future.
|
|||
|
|
|||
|
_3. _O_b_j_e_c_t_s
|
|||
|
|
|||
|
For the purposes of the Object File Format, we'll adopt
|
|||
|
a very general definition of an _o_b_j_e_c_t. An _o_b_j_e_c_t is simply
|
|||
|
a list of properties (name, description, author, copyright
|
|||
|
information, geometry data, colors, etc.)
|
|||
|
|
|||
|
The most important information about the object can be
|
|||
|
found in the _h_e_a_d_e_r _f_i_l_e for the object. The header file is
|
|||
|
always an ASCII text file that, by convention, is named
|
|||
|
_n_a_m_e.aoff where _n_a_m_e is the object name. See Appendix B for
|
|||
|
an example of an OFF object header file.
|
|||
|
|
|||
|
A few of these properties (name, description, author,
|
|||
|
copyright, type) are common to every type of 3D object and
|
|||
|
are considered standard properties. The standard properties
|
|||
|
are built into the routines that manipulate 3D objects. The
|
|||
|
rest of the properties may vary with the type of object, and
|
|||
|
so are defined by convention only.
|
|||
|
|
|||
|
The _n_a_m_e of an object is used to concisely describe the
|
|||
|
object itself. For example, we have objects named "x29",
|
|||
|
"banana" and "vw". By convention, this name also becomes
|
|||
|
the prefix for OFF data filenames when an object is read or
|
|||
|
written, so it is best to keep it fairly short.
|
|||
|
|
|||
|
The _d_e_s_c_r_i_p_t_i_o_n is used to more fully describe the
|
|||
|
object itself. It may contain the time and date of creation
|
|||
|
or more prose describing the object.
|
|||
|
|
|||
|
The _a_u_t_h_o_r should be the name of the person (or com-
|
|||
|
pany, or utility) that created the object. We should always
|
|||
|
try to give credit where credit is due. This field tells
|
|||
|
you who to thank for spiffy objects or whose cage to rattle
|
|||
|
when a problem with an OFF file is discovered.
|
|||
|
|
|||
|
The _c_o_p_y_r_i_g_h_t field contains information dealing with
|
|||
|
the distribution of the object data. Some object databases
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 4 -
|
|||
|
|
|||
|
|
|||
|
will be regarded by a company as proprietary. These objects
|
|||
|
should not be copied or distributed without consent. Other
|
|||
|
objects (vw, x29) were developed by companies or individuals
|
|||
|
and can be copied or used as long as the copyright notice
|
|||
|
appears and proper credit is given. Still other objects
|
|||
|
(cube, sphere, etc.) have been placed in the public domain.
|
|||
|
We have tried to be as careful as possible in preserving
|
|||
|
copyright and author information for the objects we have
|
|||
|
collected, but sometimes the information was lost or una-
|
|||
|
vailable. Be sure and honor copyright notices. If you
|
|||
|
don't, you (or your company) could end up in big trouble.
|
|||
|
|
|||
|
The _t_y_p_e field contains the type of the object. For
|
|||
|
now, only one type of object is supported: polygon objects.
|
|||
|
It is anticipated that polyline and surface patch-type
|
|||
|
objects will be supported in the future as well.
|
|||
|
|
|||
|
Also contained in the object header file are lines that
|
|||
|
describe the various properties of the object. Each line in
|
|||
|
the object header file that describes an attribute of the
|
|||
|
object other than a standard attribute must contain the pro-
|
|||
|
perty name, the property type, the data format and either a
|
|||
|
file name or a string containing default data, depending on
|
|||
|
the property type. Each of these four items is an ASCII
|
|||
|
string, separated by white space.
|
|||
|
|
|||
|
The _p_r_o_p_e_r_t_y _n_a_m_e uniquely describes the property.
|
|||
|
Property names for which we have defined conventions (see
|
|||
|
Appendix A) include geometry, polygon_colors, vertex_colors,
|
|||
|
back_faces, vertex_order, polygon_normals, vertex_normals,
|
|||
|
diffuse_coef, specular_coef, and specular_power.
|
|||
|
|
|||
|
OFF currently supports four _p_r_o_p_e_r_t_y _t_y_p_e_s: _d_e_f_a_u_l_t,
|
|||
|
_g_e_n_e_r_i_c, _i_n_d_e_x_e_d, and _i_n_d_e_x_e_d__p_o_l_y. If a property is indi-
|
|||
|
cated to be of type _d_e_f_a_u_l_t, the part of the line after the
|
|||
|
data format is assumed to contain some default data that
|
|||
|
will be applied to the entire object. For instance, it may
|
|||
|
make sense to give the entire object a default color and
|
|||
|
default diffuse and specular coefficients.
|
|||
|
|
|||
|
If the property type is either generic, indexed, or
|
|||
|
indexed_poly (described more fully below), the remainder of
|
|||
|
the line is taken to be a file name that can be opened and
|
|||
|
read to obtain the information for the property.
|
|||
|
|
|||
|
The data format indicates what type of data will be
|
|||
|
found on the remainder of the line if the property type is
|
|||
|
default, otherwise what kind of data will be found in the
|
|||
|
specified file. The data format is a string of characters
|
|||
|
(no spaces) that indicate the order and type of the data.
|
|||
|
Supported primitive data types are:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 5 -
|
|||
|
|
|||
|
|
|||
|
f - A number stored internally as a 32-bit floating point
|
|||
|
number
|
|||
|
|
|||
|
d - A number stored internally as a 64-bit double-precision
|
|||
|
floating point number
|
|||
|
|
|||
|
i - A number stored internally as a 32-bit integer value
|
|||
|
|
|||
|
h - A number stored internally as a 16-bit integer value
|
|||
|
|
|||
|
b - A number stored internally as an 8-bit integer value
|
|||
|
|
|||
|
s - A 32-bit pointer to a null-terminated string of charac-
|
|||
|
ters
|
|||
|
|
|||
|
If, for instance, you were interested in using 32-bit
|
|||
|
floating values for r, g, and b default color values, you
|
|||
|
might have a line in the object header file that reads
|
|||
|
|
|||
|
polygon_colors default fff 1.0 0.8 0.0
|
|||
|
|
|||
|
|
|||
|
It is important to understand that in all cases, the
|
|||
|
"string" (s) data primitive will indicate a pointer to a
|
|||
|
string that is stored internally in the data block for an
|
|||
|
object and not the string itself.
|
|||
|
|
|||
|
_4. _A_S_C_I_I _P_r_o_p_e_r_t_y _F_i_l_e_s
|
|||
|
|
|||
|
OFF supports ASCII text files as a way of providing for
|
|||
|
language-, hardware-, and operating system-independent
|
|||
|
object data files. The three types of data files currently
|
|||
|
supported by OFF are generic, indexed, and indexed_poly.
|
|||
|
|
|||
|
_4._1. _G_e_n_e_r_i_c _F_i_l_e_s
|
|||
|
|
|||
|
Generic files contain only a _c_o_u_n_t value followed by
|
|||
|
_c_o_u_n_t data items of the type specified by the data format.
|
|||
|
Each data item can be comprised of some combination of the
|
|||
|
primitive data types described in Section 3. Generic data
|
|||
|
files are useful for storing attributes which are unique at
|
|||
|
every vertex or polygon (such as color or normals).
|
|||
|
|
|||
|
String data items in ASCII generic files may not con-
|
|||
|
tain spaces or other white space. 8-bit integers must be
|
|||
|
listed in the range 0-255.
|
|||
|
|
|||
|
See Appendix D for an example of an ASCII generic data
|
|||
|
file.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 6 -
|
|||
|
|
|||
|
|
|||
|
_4._2. _I_n_d_e_x_e_d _F_i_l_e_s
|
|||
|
|
|||
|
Indexed files make use of a list of indices in order to
|
|||
|
reduce the amount of data required to store a property, and
|
|||
|
to provide a useful level of indirection. For instance,
|
|||
|
indexed files are commonly used to maintain per-polygon
|
|||
|
color information. If an object has just five colors, the
|
|||
|
indexed data file would contain the list of the five colors
|
|||
|
followed by an index from one to five for each of the
|
|||
|
polygons in the object. If an application maintains the
|
|||
|
indirection, it is possible for the user to easily select
|
|||
|
five different colors to be used on the model.
|
|||
|
|
|||
|
An indexed file begins with two integers separated by
|
|||
|
white space: the number of data items and the number of
|
|||
|
indices that will be provided. Following these two values
|
|||
|
is the list of data items that is to be used. Each data
|
|||
|
item in this list can be some combination of the primitive
|
|||
|
types described in Section 3. Following the data items is a
|
|||
|
list of indices each of which is a pointer to one of the
|
|||
|
items in the list of data items. The list of data items is
|
|||
|
assumed to begin starting at one, not zero.
|
|||
|
|
|||
|
|
|||
|
_4._3. _I_n_d_e_x_e_d__P_o_l_y _F_i_l_e_s
|
|||
|
|
|||
|
Indexed_poly files take advantage of a connectivity
|
|||
|
list to reduce the amount of information needed to store a
|
|||
|
list of polylines, polygons, or normals. The unique
|
|||
|
geometry items (e.g., vertices) are listed in the first part
|
|||
|
of the file. Following this list is a connectivity list.
|
|||
|
Each line in the connectivity list contains a _c_o_u_n_t value
|
|||
|
followed by _c_o_u_n_t indices (pointers) to information in the
|
|||
|
geometry list. (Items in the geometry list are indexed
|
|||
|
starting from one, not zero.)
|
|||
|
|
|||
|
The first line of an indexed_poly data file contains
|
|||
|
three integers, separated by white space. The first number
|
|||
|
on this line indicates the number of data items
|
|||
|
(vertices/normals) that follow, the second number indicates
|
|||
|
the number of polylines/polygons that follow the data list,
|
|||
|
and the third indicates the total number of edges that are
|
|||
|
contained in the polyline/polygon connectivity list.
|
|||
|
|
|||
|
String data items in ASCII indexed_poly files may not
|
|||
|
contain spaces or other white space. 8-bit integers must be
|
|||
|
listed in the range 0-255.
|
|||
|
|
|||
|
See Appendix C for an example of an ASCII indexed_poly
|
|||
|
file.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 7 -
|
|||
|
|
|||
|
|
|||
|
_5. _B_i_n_a_r_y _O_F_F _F_i_l_e_s
|
|||
|
|
|||
|
The same three types of data files described above are
|
|||
|
also supported in binary format. There are a few minor
|
|||
|
differences.
|
|||
|
|
|||
|
|
|||
|
_5._1. _G_e_n_e_r_i_c _F_i_l_e_s
|
|||
|
|
|||
|
Binary generic files begin with the first 32-bit word
|
|||
|
equal to OFF_GENERIC_MAGIC as defined in the include file
|
|||
|
_o_f_f._h. The second word in the file is the _c_o_u_n_t (number of
|
|||
|
data items in the file). Following the _c_o_u_n_t is the data
|
|||
|
itself.
|
|||
|
|
|||
|
The data format in the header file describes the primi-
|
|||
|
tives that make up each data item in the list. Within each
|
|||
|
data item, floats, doubles, 32-bit integers, and string
|
|||
|
pointers will all begin on a word boundary. 16-bit integers
|
|||
|
will all begin on a half-word boundary. Thus, if your data
|
|||
|
format for the data items in a generic data file is "bbb"
|
|||
|
(three byte values), each data item will be stored as three
|
|||
|
bytes followed by a null byte so that each data item will
|
|||
|
begin on a word boundary. Strings begin with a 32-bit _c_o_u_n_t
|
|||
|
followed by _c_o_u_n_t characters followed by a null character.
|
|||
|
The string is null-padded so it will end on a word boundary.
|
|||
|
|
|||
|
(It is assumed that for strings, the length will be
|
|||
|
read and then the necessary memory will be allocated and the
|
|||
|
string read in. This eliminates a problem with having
|
|||
|
variable-length data in the data files. Anyway, strings in
|
|||
|
files are really only there for symmetry with default
|
|||
|
values, where strings are really useful. The performance
|
|||
|
implications for files containing strings will probably be
|
|||
|
enough to prevent people from using them.)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
_5._2. _I_n_d_e_x_e_d _F_i_l_e_s
|
|||
|
|
|||
|
Binary indexed files begin with the first 32-bit word
|
|||
|
equal to OFF_INDEXED_MAGIC as defined in the include file
|
|||
|
_o_f_f._h. The second word in the file is the _c_o_u_n_t (number of
|
|||
|
data items in the file). The third word in the file is
|
|||
|
_n_u_m__i_n_d_i_c_e_s (number of indices in the index list).
|
|||
|
|
|||
|
Following these two integers is the data for the data
|
|||
|
item list. Each item in the data item list will begin on a
|
|||
|
word boundary. The data format in the header file describes
|
|||
|
the primitives that make up each data item in the list.
|
|||
|
Within each data item, floats, doubles, 32-bit integers, and
|
|||
|
string pointers will all begin on a word boundary. 16-bit
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 8 -
|
|||
|
|
|||
|
|
|||
|
integers will all begin on a half-word boundary. Thus, if
|
|||
|
your data format for the data items in an indexed data file
|
|||
|
is "bbb" (three byte values), each data item will be stored
|
|||
|
as three bytes followed by a null byte so that each data
|
|||
|
item will begin on a word boundary. Strings begin with a
|
|||
|
32-bit _c_o_u_n_t followed by _c_o_u_n_t characters followed by a null
|
|||
|
character. The string is null-padded so it will end on a
|
|||
|
word boundary.
|
|||
|
|
|||
|
Following the data item list is a list of index values.
|
|||
|
This list will also begin on a word boundary, however, the
|
|||
|
index values within this list are short integers and will be
|
|||
|
packed two to each 32-bit word.
|
|||
|
|
|||
|
|
|||
|
_5._3. _I_n_d_e_x_e_d__P_o_l_y _F_i_l_e_s
|
|||
|
|
|||
|
Binary indexed_poly files begin with the first 32-bit
|
|||
|
word equal to OFF_INDEXED_POLY_MAGIC as defined in the
|
|||
|
include file off.h. The second word is the number of data
|
|||
|
items in the vertex list (_n_p_t_s), the third word is the
|
|||
|
number of polylines/polygons in the list (_n_p_o_l_y_s), and the
|
|||
|
fourth word is the number of edges contained in the connec-
|
|||
|
tivity list (_n_c_o_n_n_e_c_t_s).
|
|||
|
|
|||
|
Starting at the fifth word in the file is a list of
|
|||
|
_n_p_t_s data items, followed by _n_p_o_l_y_s short integers contain-
|
|||
|
ing polyline/polygon vertex counts, followed by _n_c_o_n_n_e_c_t_s
|
|||
|
short integers which are indices into the array of data
|
|||
|
items. (This arrangement is slightly different than that
|
|||
|
used for indexed_poly files in ASCII format for efficiency
|
|||
|
reasons.)
|
|||
|
|
|||
|
The same restrictions that apply to the data types for
|
|||
|
generic binary files apply to indexed_poly binary files as
|
|||
|
well. In addition, the vertex count array which follows the
|
|||
|
geometry data in an indexed_poly file will always begin on a
|
|||
|
word boundary. The connectivity array that follows the ver-
|
|||
|
tex count array will not necessarily start on a word boun-
|
|||
|
dary, but will always begin _n_p_o_l_y_s * _s_i_z_e_o_f(_s_h_o_r_t) bytes
|
|||
|
after the start of the vertex count array.
|
|||
|
|
|||
|
|
|||
|
_6. _O_f_f._a _a_n_d _O_b_j_e_c_t_s._h
|
|||
|
|
|||
|
An include file and a library of routines has been pro-
|
|||
|
vided for UNIX/C programmers to more easily manipulate OFF
|
|||
|
files. The basic concepts of "reading" and "writing" OFF
|
|||
|
files are supported in this library of routines. The
|
|||
|
library is a software layer on top of the operating system
|
|||
|
file I/O interface, with special knowledge of OFF files.
|
|||
|
This subroutine library provides a mechanism for accessing
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 9 -
|
|||
|
|
|||
|
|
|||
|
the syntactical elements of an object file, but makes no
|
|||
|
attempt to understand the semantics. Higher level inter-
|
|||
|
faces can be layered on top.
|
|||
|
|
|||
|
The subroutine library refers to an object as a pointer
|
|||
|
to an _O_F_F_O_b_j_D_e_s_c. This structure contains a pointer to the
|
|||
|
first property in the property list. It is defined as fol-
|
|||
|
lows:
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
OFFProperty *FirstProp; /* Pointer to first property in list */
|
|||
|
} OFFObjDesc;
|
|||
|
|
|||
|
|
|||
|
The information that describes the object is contained
|
|||
|
in a linked list of property structures. The first such
|
|||
|
structure in the list is pointed at by an _O_F_F_O_b_j_D_e_s_c struc-
|
|||
|
ture. The property structures have the form:
|
|||
|
|
|||
|
typedef struct _OFFProp
|
|||
|
{
|
|||
|
char PropName[40];
|
|||
|
int PropType;
|
|||
|
char PropFileName[256];
|
|||
|
int PropCount;
|
|||
|
char DataFormat[40];
|
|||
|
char *PropData;
|
|||
|
struct _OFFProp *NextProp;
|
|||
|
} OFFProperty;
|
|||
|
|
|||
|
|
|||
|
_P_r_o_p_N_a_m_e contains a string defining one of the property
|
|||
|
types for which a convention has been defined. This
|
|||
|
includes the property names "name", "author", "description",
|
|||
|
"copyright", "comment", "geometry", "polygon_colors",
|
|||
|
"polygon_normal", etc. For a complete list of property
|
|||
|
names, see Appendix A. (The special attribute type "com-
|
|||
|
ment" is supported so that blank lines and comment lines can
|
|||
|
be preserved if an object file is read and then written.)
|
|||
|
|
|||
|
The _P_r_o_p_T_y_p_e field contains a value equal to
|
|||
|
_O_F_F__D_E_F_A_U_L_T__D_A_T_A, _O_F_F__G_E_N_E_R_I_C__D_A_T_A, _O_F_F__I_N_D_E_X_E_D__D_A_T_A, or
|
|||
|
_O_F_F__I_N_D_E_X_E_D__P_O_L_Y__D_A_T_A which defines the basic type for the
|
|||
|
property.
|
|||
|
|
|||
|
The _P_r_o_p_F_i_l_e_N_a_m_e is required if _P_r_o_p_T_y_p_e is something
|
|||
|
other than _O_F_F__D_E_F_A_U_L_T__D_A_T_A. It contains a string
|
|||
|
representing the name of the file to be read/written for
|
|||
|
this attribute. This file name should _n_o_t contain a path
|
|||
|
leading up to the file itself, only the actual file name.
|
|||
|
The object search path mechanism (see Section 7) should be
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 10 -
|
|||
|
|
|||
|
|
|||
|
used instead.
|
|||
|
|
|||
|
The _P_r_o_p_C_o_u_n_t indicates the actual number of data items
|
|||
|
associated with this particular attribute. After reading in
|
|||
|
an object, properties of type _O_F_F__D_E_F_A_U_L_T__D_A_T_A will have a
|
|||
|
_P_r_o_p_C_o_u_n_t of one, properties of type _O_F_F__G_E_N_E_R_I_C__D_A_T_A will
|
|||
|
have a _P_r_o_p_C_o_u_n_t equal to the number of generic data items
|
|||
|
in the list, properties of type _O_F_F__I_N_D_E_X_E_D__D_A_T_A will have a
|
|||
|
_P_r_o_p_C_o_u_n_t equal to the number of items in the data item
|
|||
|
list, and properties of type _O_F_F__I_N_D_E_X_E_D__P_O_L_Y__D_A_T_A will have
|
|||
|
a _P_r_o_p_C_o_u_n_t equal to the number of data items in the
|
|||
|
geometry list.
|
|||
|
|
|||
|
The _D_a_t_a_F_o_r_m_a_t field contains a string of characters
|
|||
|
corresponding to primitive data items. The composite type
|
|||
|
of the data for this property can then be deduced by looking
|
|||
|
at this field and applying the rules for padding to word and
|
|||
|
half-word boundaries.
|
|||
|
|
|||
|
The _P_r_o_p_D_a_t_a field contains a pointer to a block of
|
|||
|
memory containing the actual data for this property. This
|
|||
|
data will have the same data alignment restrictions as a
|
|||
|
binary file has, with the exception of strings. As strings
|
|||
|
are read in, memory is malloc'ed to hold them and a pointer
|
|||
|
to the string is stored in the appropriate field in the data
|
|||
|
list. This means that all primitive data types will have a
|
|||
|
fixed size and lengths and alignments can be computed more
|
|||
|
easily.
|
|||
|
|
|||
|
The _N_e_x_t_P_r_o_p field contains a pointer to the next pro-
|
|||
|
perty structure in the property list.
|
|||
|
|
|||
|
The routines contained in the subroutine library are
|
|||
|
defined below.
|
|||
|
|
|||
|
|
|||
|
#include "off.h"
|
|||
|
|
|||
|
int OFFReadObj(Obj, FileName)
|
|||
|
OFFObjDesc *Obj;
|
|||
|
char *FileName;
|
|||
|
|
|||
|
int OFFWriteObj(Obj, FileName, Directory, FileType);
|
|||
|
OFFObjDesc *Obj;
|
|||
|
char *FileName;
|
|||
|
char *Directory;
|
|||
|
int FileType;
|
|||
|
|
|||
|
void OFFPackObj(Obj)
|
|||
|
OFFObjDesc *Obj;
|
|||
|
|
|||
|
void OFFPackProperty(Property)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 11 -
|
|||
|
|
|||
|
|
|||
|
OFFProperty *Property;
|
|||
|
|
|||
|
int OFFReadGeneric(Property, FileName)
|
|||
|
OFFProperty *Property;
|
|||
|
char *FileName;
|
|||
|
|
|||
|
int OFFWriteGeneric(Property, FileName, FileType)
|
|||
|
OFFProperty *Property;
|
|||
|
char *FileName;
|
|||
|
int FileType;
|
|||
|
|
|||
|
int OFFReadIndexed(Property, FileName)
|
|||
|
OFFProperty *Property;
|
|||
|
char *FileName;
|
|||
|
|
|||
|
int OFFWriteIndexed(Property, FileName, FileType)
|
|||
|
OFFProperty *Property;
|
|||
|
char *FileName;
|
|||
|
int FileType;
|
|||
|
|
|||
|
int OFFReadIndexedPoly(Property, FileName)
|
|||
|
OFFProperty *Property;
|
|||
|
char *FileName;
|
|||
|
|
|||
|
int OFFWriteIndexedPoly(Property, FileName, FileType)
|
|||
|
OFFProperty *Property;
|
|||
|
char *FileName;
|
|||
|
int FileType;
|
|||
|
|
|||
|
OFFObjDesc *OFFCreateObj()
|
|||
|
|
|||
|
int OFFDestroyObj(Obj)
|
|||
|
OFFObjDesc *Obj;
|
|||
|
|
|||
|
OFFProperty *OFFAddProperty(Obj)
|
|||
|
OFFObjDesc *Obj;
|
|||
|
|
|||
|
int OFFRemoveProperty(Obj, PropertyName)
|
|||
|
OFFObjDesc *Obj;
|
|||
|
char *PropertyName;
|
|||
|
|
|||
|
int OFFFreeProperty(Property)
|
|||
|
OFFProperty *Property;
|
|||
|
|
|||
|
|
|||
|
_O_F_F_R_e_a_d_O_b_j will attempt to open the object header file
|
|||
|
named _F_i_l_e_N_a_m_e and read the object data it contains. A
|
|||
|
pointer to the constructed object structure will be returned
|
|||
|
in _O_b_j when the object has been read. An attempt will be
|
|||
|
made to open the specified file first as given, then con-
|
|||
|
catenated in turn with each of the directories specified by
|
|||
|
the environment search path variable _O_B_J__P_A_T_H. The property
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 12 -
|
|||
|
|
|||
|
|
|||
|
list for the object is built as the file is read. Upon
|
|||
|
return, the client need only traverse the property list and
|
|||
|
select the data it needs. This routine calls _O_F_F_R_e_a_d_G_e_n_e_r_i_c
|
|||
|
and _O_F_F_R_e_a_d_I_n_d_e_x_e_d_P_o_l_y in order to read associated data
|
|||
|
files. _O_F_F_R_e_a_d_O_b_j will return 0 if the read operation was
|
|||
|
successful, -1 otherwise.
|
|||
|
|
|||
|
_O_F_F_W_r_i_t_e_O_b_j will attempt to write the object pointed at
|
|||
|
by _O_b_j using the filename specified by _F_i_l_e_N_a_m_e. The file
|
|||
|
will be written in the directory indicated by _D_i_r_e_c_t_o_r_y. If
|
|||
|
_F_i_l_e_T_y_p_e is _O_F_F__A_S_C_I_I, the file will be written as an ASCII
|
|||
|
text OFF file. If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_A_R_Y, the file will be
|
|||
|
written as a binary OFF file. The property list for the
|
|||
|
object is traversed and each property of the object is writ-
|
|||
|
ten out in turn. This routine calls _O_F_F_W_r_i_t_e_G_e_n_e_r_i_c and
|
|||
|
_O_F_F_W_r_i_t_e_I_n_d_e_x_e_d_P_o_l_y in order to write associated data files.
|
|||
|
_O_F_F_W_r_i_t_e_O_b_j will return 0 if the write operation was suc-
|
|||
|
cessful, -1 otherwise.
|
|||
|
|
|||
|
_O_F_F_P_a_c_k_O_b_j attempts to _p_a_c_k the object pointed at by
|
|||
|
_O_b_j. Packing only applies to geometry and normals stored in
|
|||
|
indexed_polygon format. See _O_F_F_P_a_c_k_P_r_o_p_e_r_t_y below.
|
|||
|
|
|||
|
_O_F_F_P_a_c_k_P_r_o_p_e_r_t_y packs the property pointed at by _P_r_o_-
|
|||
|
_p_e_r_t_y. Packing can only be applied to indexed_polygon pro-
|
|||
|
perties with format ``fff''. (This is normally the case for
|
|||
|
geometry and normals properties.) Packing works by sharing
|
|||
|
common data (vertex or normal) values. Since each vertex
|
|||
|
and vertex normal of an object is usually shared by three or
|
|||
|
more polygons, this can save a great deal of space and
|
|||
|
rendering time. If _P_r_o_p_e_r_t_y could not be packed, it is not
|
|||
|
modified; otherwise the property data is changed in-place.
|
|||
|
|
|||
|
_O_F_F_R_e_a_d_G_e_n_e_r_i_c will read the generic data file named
|
|||
|
_F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains the full path name) into
|
|||
|
the property structure pointed at by _P_r_o_p_e_r_t_y. This routine
|
|||
|
will allocate the space it needs in order to read in the
|
|||
|
data. A pointer to this allocated data space will be stored
|
|||
|
in the _P_r_o_p_D_a_t_a field of the specified _p_r_o_p_e_r_t_y as described
|
|||
|
earlier. The entire object, including all allocated memory
|
|||
|
resources can later be deallocated by calling _O_F_F_D_e_s_t_r_o_y_O_b_j.
|
|||
|
This routine will not typically be called directly by appli-
|
|||
|
cations. _O_F_F_R_e_a_d_G_e_n_e_r_i_c will return 0 if the read operation
|
|||
|
was successful, -1 otherwise.
|
|||
|
|
|||
|
_O_F_F_W_r_i_t_e_G_e_n_e_r_i_c will write the generic data associated
|
|||
|
with _P_r_o_p_e_r_t_y into the file _F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains
|
|||
|
the full path name of the file to be written). If _F_i_l_e_T_y_p_e
|
|||
|
is _O_F_F__A_S_C_I_I, the file will be written as an ASCII text gen-
|
|||
|
eric data file. If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_A_R_Y, the file will be
|
|||
|
written as a binary generic data file. This routine will
|
|||
|
not typically be called directly by applications.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 13 -
|
|||
|
|
|||
|
|
|||
|
_O_F_F_W_r_i_t_e_G_e_n_e_r_i_c will return 0 if the write operation was
|
|||
|
successful, -1 otherwise.
|
|||
|
|
|||
|
_O_F_F_R_e_a_d_I_n_d_e_x_e_d will read the indexed data file named
|
|||
|
_F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains the full path name) into
|
|||
|
the property structure pointed at by _P_r_o_p_e_r_t_y. This routine
|
|||
|
will allocate the space it needs in order to read in the
|
|||
|
data. A pointer to this allocated data space will be stored
|
|||
|
in the _P_r_o_p_D_a_t_a field of the specified _p_r_o_p_e_r_t_y as described
|
|||
|
earlier. The entire object, including all allocated memory
|
|||
|
resources can later be deallocated by calling _O_F_F_D_e_s_t_r_o_y_O_b_j.
|
|||
|
This routine will not typically be called directly by appli-
|
|||
|
cations. _O_F_F_R_e_a_d_I_n_d_e_x_e_d will return 0 if the read operation
|
|||
|
was successful, -1 otherwise.
|
|||
|
|
|||
|
_O_F_F_W_r_i_t_e_I_n_d_e_x_e_d will write the indexed data associated
|
|||
|
with _P_r_o_p_e_r_t_y into the file _F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains
|
|||
|
the full path name of the file to be written). If _F_i_l_e_T_y_p_e
|
|||
|
is _O_F_F__A_S_C_I_I, the file will be written as an ASCII text
|
|||
|
indexed data file. If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_A_R_Y, the file will
|
|||
|
be written as a binary indexed data file. This routine will
|
|||
|
not typically be called directly by applications. _O_F_F_W_r_i_-
|
|||
|
_t_e_I_n_d_e_x_e_d will return 0 if the write operation was success-
|
|||
|
ful, -1 otherwise.
|
|||
|
|
|||
|
_O_F_F_R_e_a_d_I_n_d_e_x_e_d_P_o_l_y will read the indexed_poly data file
|
|||
|
named _F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains the full path name)
|
|||
|
into the property structure pointed at by _P_r_o_p_e_r_t_y. This
|
|||
|
routine will allocate the space it needs in order to read in
|
|||
|
the data. A pointer to this allocated data space will be
|
|||
|
stored in the _P_r_o_p_D_a_t_a field of the specified _p_r_o_p_e_r_t_y as
|
|||
|
described earlier. The entire object, including all allo-
|
|||
|
cated memory resources can later be deallocated by calling
|
|||
|
_O_F_F_D_e_s_t_r_o_y_O_b_j. This routine will not typically be called
|
|||
|
directly by applications. _O_F_F_R_e_a_d_I_n_d_e_x_e_d_P_o_l_y will return 0
|
|||
|
if the read operation was successful, -1 otherwise.
|
|||
|
|
|||
|
_O_F_F_W_r_i_t_e_I_n_d_e_x_e_d_P_o_l_y will write the indexed_poly data
|
|||
|
associated with _P_r_o_p_e_r_t_y into the file _F_i_l_e_N_a_m_e (here
|
|||
|
_F_i_l_e_N_a_m_e contains the full path name of the file to be writ-
|
|||
|
ten). If _F_i_l_e_T_y_p_e is _O_F_F__A_S_C_I_I, the file will be written as
|
|||
|
an ASCII text indexed_poly data file. If _F_i_l_e_T_y_p_e is
|
|||
|
_O_F_F__B_I_N_A_R_Y, the file will be written as a binary
|
|||
|
indexed_poly data file. This routine will not typically be
|
|||
|
called directly by applications. _O_F_F_W_r_i_t_e_I_n_d_e_x_e_d_P_o_l_y will
|
|||
|
return 0 if the write operation was successful, -1 other-
|
|||
|
wise.
|
|||
|
|
|||
|
_O_F_F_C_r_e_a_t_e_O_b_j allocates and initializes an _O_F_F_O_b_j_D_e_s_c
|
|||
|
structure A pointer to the newly-created structure is
|
|||
|
returned. The null pointer is returned if the operation was
|
|||
|
unsuccessful.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 14 -
|
|||
|
|
|||
|
|
|||
|
_O_F_F_D_e_s_t_r_o_y_O_b_j deallocates all memory resources associ-
|
|||
|
ated with the object pointed at by _O_b_j. It works by calling
|
|||
|
_O_F_F_F_r_e_e_P_r_o_p_e_r_t_y for each property in the property list for
|
|||
|
the specified object.
|
|||
|
|
|||
|
_O_F_F_A_d_d_P_r_o_p_e_r_t_y adds a property structure to the pro-
|
|||
|
perty list associated with the object pointed at by _O_b_j,
|
|||
|
initializes it, and returns a pointer to it. The null
|
|||
|
pointer is returned if the operation was unsuccessful.
|
|||
|
|
|||
|
_O_F_F_R_e_m_o_v_e_P_r_o_p_e_r_t_y deletes the named property from the
|
|||
|
object pointed at by _O_b_j. This routine returns -1 if the
|
|||
|
named property is not found in the property list for the
|
|||
|
specified object.
|
|||
|
|
|||
|
_O_F_F_F_r_e_e_P_r_o_p_e_r_t_y frees all the memory resources allo-
|
|||
|
cated to the property structure specified by _P_r_o_p_e_r_t_y as
|
|||
|
well as the property structure itself. This routine will
|
|||
|
not typically be called directly by applications.
|
|||
|
|
|||
|
_7. _O_b_j_e_c_t _S_e_a_r_c_h _P_a_t_h
|
|||
|
|
|||
|
It is important to avoid embedding path names in object
|
|||
|
files. When an object is transported to another system,
|
|||
|
chances are slim that the same directory structure will
|
|||
|
exist. The _O_F_F_R_e_a_d_O_b_j routine in libobj.a knows about an
|
|||
|
environment variable named _O_B_J__P_A_T_H that is used to overcome
|
|||
|
this problem.
|
|||
|
|
|||
|
When an object is read, an attempt is first made to
|
|||
|
open it in the current working directory. If that attempt
|
|||
|
fails, the directories specified in the _O_B_J__P_A_T_H environment
|
|||
|
variable are tried in turn until the file is successfully
|
|||
|
opened or the directory list is exhausted. _O_B_J__P_A_T_H con-
|
|||
|
tains a list of directories, separated by spaces, that are
|
|||
|
to be searched for the named objects.
|
|||
|
|
|||
|
The name of the directory where a successful open
|
|||
|
operation occurred is used for opening associated data files
|
|||
|
as well. This means that all of the data files for a par-
|
|||
|
ticular object must reside in the same directory.
|
|||
|
|
|||
|
It is hoped that in this way, users will be able to
|
|||
|
draw on one or more collections of "standard" objects in
|
|||
|
addition to their own private collections of objects.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 15 -
|
|||
|
|
|||
|
|
|||
|
_8. _A_p_p_e_n_d_i_x _A: _C_o_n_v_e_n_t_i_o_n_s _f_o_r _P_o_l_y_g_o_n_a_l _O_b_j_e_c_t_s
|
|||
|
|
|||
|
This list contains the conventions we have adopted for
|
|||
|
describing 3D polygonal objects which are defined in some
|
|||
|
three-dimensional model coordinate system. Items in regular
|
|||
|
type are string literal, printed as they would appear in an
|
|||
|
OFF file, and item in italics indicate data values that will
|
|||
|
vary from object to object. By convention, the header for
|
|||
|
an ASCII OFF file is suffixed with ".aoff" and the header
|
|||
|
for a binary OFF file is suffixed with ".off". There are
|
|||
|
two choices for how colors may be stored. If they are
|
|||
|
stored as generic data, the suffixes used are ".{b}pcol" for
|
|||
|
polygon colors and ".{b}vcol" for vertex colors. If they
|
|||
|
are stored as indexed data, the suffixes used are
|
|||
|
".{b}ipcol" and ".{b}ivcol".
|
|||
|
|
|||
|
|
|||
|
box; c|c|c|c|c|c l|l|l|l|l|l.
|
|||
|
Property Type Format Defaults ASCII
|
|||
|
filename Binary Filename =
|
|||
|
name ***** ***** _o_b_j_n_a_m_e ***** *****
|
|||
|
author ***** ***** _a_u_t_h_o_r ***** *****
|
|||
|
description ***** ***** _d_e_s_c_r_i_p_t_i_o_n ***** *****
|
|||
|
copyright ***** ***** _c_o_p_y_r_i_g_h_t ***** *****
|
|||
|
type ***** ***** polyline ***** *****
|
|||
|
***** ***** polygon ***** *****
|
|||
|
geometry indexed_poly fff ***** _n_a_m_e.geom _n_a_m_e.bgeom
|
|||
|
polygon_colors generic fff ***** _n_a_m_e.pcol _n_a_m_e.bpcol
|
|||
|
vertex_colors generic fff ***** _n_a_m_e.vcol _n_a_m_e.bvcol
|
|||
|
polygon_colors indexed fff ***** _n_a_m_e.ipcol _n_a_m_e.bipcol
|
|||
|
vertex_colors indexed fff ***** _n_a_m_e.ivcol _n_a_m_e.bivcol
|
|||
|
back_faces default s cull ***** *****
|
|||
|
display ***** *****
|
|||
|
reverse ***** *****
|
|||
|
vertex_order default s clockwise ***** *****
|
|||
|
counter-
|
|||
|
clockwise ***** *****
|
|||
|
counterclock-
|
|||
|
wise ***** *****
|
|||
|
polygon_normals generic fff ***** _n_a_m_e.pnorm _n_a_m_e.bpnorm
|
|||
|
vertex_normals generic fff ***** _n_a_m_e.vnorm _n_a_m_e.bvnorm
|
|||
|
diffuse_coef default f _v_a_l_u_e ***** *****
|
|||
|
specular_coef default f _v_a_l_u_e ***** *****
|
|||
|
specular_power default f _v_a_l_u_e ***** *****
|
|||
|
bounding_box default ffffff _v_a_l_u_e ***** *****
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 16 -
|
|||
|
|
|||
|
|
|||
|
_9. _A_p_p_e_n_d_i_x _B: _O_F_F _H_e_a_d_e_r _F_i_l_e _F_o_r _a _C_u_b_e (_c_u_b_e._a_o_f_f)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
; l l. name cube author Randi J. Rost
|
|||
|
description cube with sides of red, green, blue, cyan,
|
|||
|
yellow, magenta copyright public domain
|
|||
|
type polygon
|
|||
|
|
|||
|
|
|||
|
; l c c c l c c c l l l l. # Prop. data
|
|||
|
type format filename or default data
|
|||
|
#_______ _________ ______ ________________________
|
|||
|
|
|||
|
geometry indexed_poly fff cube.geom
|
|||
|
vertex_order default s clockwise
|
|||
|
polygon_colors generic fff cube.pcol
|
|||
|
back_faces default s cull
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 17 -
|
|||
|
|
|||
|
|
|||
|
_1_0. _A_p_p_e_n_d_i_x _C: _L_i_s_t_i_n_g _o_f _c_u_b_e._g_e_o_m
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
; nw(0.5i) nw(0.5i) nw(0.5i) nw(0.5i) nw(0.5i).
|
|||
|
8 6 24 -1.0 -1.0 1.0 -1.0 1.0 1.0
|
|||
|
1.0 1.0 1.0 1.0 -1.0 1.0 -1.0 -1.0 -1.0
|
|||
|
-1.0 1.0 -1.0 1.0 1.0 -1.0 1.0 -1.0 -
|
|||
|
1.0 4 1 2 3 4
|
|||
|
4 5 6 2 1
|
|||
|
4 3 2 6 7
|
|||
|
4 3 7 8 4
|
|||
|
4 1 4 8 5
|
|||
|
4 8 7 6 5
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 18 -
|
|||
|
|
|||
|
|
|||
|
_1_1. _A_p_p_e_n_d_i_x _D: _L_i_s_t_i_n_g _o_f _c_u_b_e._p_c_o_l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
; l s s nw(0.5i) nw(0.5i) nw(0.5i). 6 1.0
|
|||
|
0.0 0.0 0.0 1.0 0.0 0.0 0.0
|
|||
|
1.0 0.0 1.0 1.0 1.0 1.0 0.0 1.0
|
|||
|
0.0 1.0
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 19 -
|
|||
|
|
|||
|
|
|||
|
_1_2. _A_p_p_e_n_d_i_x _E: _L_i_s_t_i_n_g _o_f _o_f_f._h
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#define OFF_INDEXED_POLY_MAGIC 0xFEEDFEEDL
|
|||
|
#define OFF_GENERIC_MAGIC 0xBEEFBEEFL
|
|||
|
#define OFF_INDEXED_MAGIC 0xBADBADBAL
|
|||
|
|
|||
|
#define OFF_BIGSTR 256
|
|||
|
#define OFF_SMSTR 40
|
|||
|
|
|||
|
#define OFF_ASCII 0
|
|||
|
#define OFF_BINARY 1
|
|||
|
|
|||
|
|
|||
|
/* Types of data for object properties */
|
|||
|
|
|||
|
#define OFF_UNKNOWN_TYPE_DATA 0
|
|||
|
#define OFF_STANDARD_DATA 1
|
|||
|
#define OFF_COMMENT_DATA 2
|
|||
|
#define OFF_DEFAULT_DATA 3
|
|||
|
#define OFF_GENERIC_DATA 4
|
|||
|
#define OFF_INDEXED_POLY_DATA 5
|
|||
|
#define OFF_INDEXED_DATA 6
|
|||
|
|
|||
|
|
|||
|
typedef struct _OFFProp
|
|||
|
{
|
|||
|
char PropName[OFF_SMSTR]; /* Name of property (or attribute) */
|
|||
|
int PropType; /* Type of data for property */
|
|||
|
char PropFileName[OFF_BIGSTR];/* Name of file that has prop data */
|
|||
|
char DataFormat[OFF_SMSTR]; /* Pointer to property data format */
|
|||
|
int PropCount; /* Number of data items for property*/
|
|||
|
char *PropData; /* Pointer to property data */
|
|||
|
struct _OFFProp *NextProp; /* Pointer to next property in list */
|
|||
|
} OFFProperty;
|
|||
|
|
|||
|
typedef struct
|
|||
|
{
|
|||
|
OFFProperty *FirstProp; /* Pointer to first property in list*/
|
|||
|
} OFFObjDesc;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 20 -
|
|||
|
|
|||
|
|
|||
|
_1_3. _A_p_p_e_n_d_i_x _F: _D_a_t_a _S_t_r_u_c_t_u_r_e _F_o_r_m_a_t
|
|||
|
|
|||
|
The following diagram depicts some of the data struc-
|
|||
|
tures for the object _c_u_b_e._a_o_f_f after being read by
|
|||
|
_O_F_F_R_e_a_d_O_b_j() (or just prior to being written by _O_F_F_W_r_i_-
|
|||
|
_t_e_O_b_j()). move to 0.0, 14.5 Object: [ boxht
|
|||
|
= 0.3i; boxwid = 2.0i moveht = 0.3i; movewid = 0.0i
|
|||
|
down A: box "FirstProp" move
|
|||
|
up 0.3i; move right 2.0i down B: box
|
|||
|
]
|
|||
|
|
|||
|
move to 1.0, 13.0 Prop1: [ boxht = 0.3i;
|
|||
|
boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
|
|||
|
down A: box "PropName" down B:
|
|||
|
box "PropType" down C: box "PropFileName"
|
|||
|
down D: box "DataFormat" down
|
|||
|
E: box "PropCount" down F: box
|
|||
|
"PropData" down H: box "NextProp"
|
|||
|
move up 2.1i; move right 2.25i;
|
|||
|
boxht = 0.3i; boxwid = 3.0i moveht =
|
|||
|
0.3i; movewid = 0.0i down I: box "name"
|
|||
|
down J: box "OFF_STANDARD_DATA"
|
|||
|
down K: box "_n_u_l_l _s_t_r_i_n_g" down L:
|
|||
|
box "_n_u_l_l _s_t_r_i_n_g" down M: box "0"
|
|||
|
down N: box down O:
|
|||
|
box ]
|
|||
|
|
|||
|
move to 1.0, 10.0 Prop2: [ boxht = 0.3i;
|
|||
|
boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
|
|||
|
down A: box "PropName" down B:
|
|||
|
box "PropType" down C: box "PropFileName"
|
|||
|
down D: box "DataFormat" down
|
|||
|
E: box "PropCount" down F: box
|
|||
|
"PropData" down H: box "NextProp"
|
|||
|
move up 2.1i; move right 2.25i;
|
|||
|
boxht = 0.3i; boxwid = 3.0i moveht =
|
|||
|
0.3i; movewid = 0.0i down I: box "author"
|
|||
|
down J: box "OFF_STANDARD_DATA"
|
|||
|
down K: box "_n_u_l_l _s_t_r_i_n_g" down L:
|
|||
|
box "_n_u_l_l _s_t_r_i_n_g" down M: box "0"
|
|||
|
down N: box down O:
|
|||
|
box ]
|
|||
|
|
|||
|
move to 1.0, 7.0 Prop3: [ boxht = 0.3i;
|
|||
|
boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
|
|||
|
down A: box "PropName" down B:
|
|||
|
box "PropType" down C: box "PropFileName"
|
|||
|
down D: box "DataFormat" down
|
|||
|
E: box "PropCount" down F: box
|
|||
|
"PropData" down H: box "NextProp"
|
|||
|
move up 2.1i; move right 2.25i;
|
|||
|
boxht = 0.3i; boxwid = 3.0i moveht =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 21 -
|
|||
|
|
|||
|
|
|||
|
0.3i; movewid = 0.0i down I: box
|
|||
|
"geometry" down J: box
|
|||
|
"OFF_INDEXED_POLY_DATA" down K: box
|
|||
|
"cube.geom" down L: box "fff"
|
|||
|
down M: box "6" down N: box
|
|||
|
down O: box ]
|
|||
|
|
|||
|
move to 1.0, 4.0 Prop4: [ boxht = 0.3i;
|
|||
|
boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
|
|||
|
down A: box "PropName" down B:
|
|||
|
box "PropType" down C: box "PropFileName"
|
|||
|
down D: box "DataFormat" down
|
|||
|
E: box "PropCount" down F: box
|
|||
|
"PropData" down H: box "NextProp"
|
|||
|
move up 2.1i; move right 2.25i;
|
|||
|
boxht = 0.3i; boxwid = 3.0i moveht =
|
|||
|
0.3i; movewid = 0.0i down I: box
|
|||
|
"polygon_colors" down J: box
|
|||
|
"OFF_GENERIC_DATA" down K: box
|
|||
|
"cube.pcol" down L: box "fff"
|
|||
|
down M: box "6" down N: box
|
|||
|
down O: box ]
|
|||
|
|
|||
|
move to 1.0, 1.0 Prop5: [ boxht = 0.3i;
|
|||
|
boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
|
|||
|
down A: box "PropName" down B:
|
|||
|
box "PropType" down C: box "PropFileName"
|
|||
|
down D: box "DataFormat" down
|
|||
|
E: box "PropCount" down F: box
|
|||
|
"PropData" down H: box "NextProp"
|
|||
|
move up 2.1i; move right 2.25i;
|
|||
|
boxht = 0.3i; boxwid = 3.0i moveht =
|
|||
|
0.3i; movewid = 0.0i down I: box
|
|||
|
"back_faces" down J: box
|
|||
|
"OFF_DEFAULT_DATA" down K: box "_n_u_l_l
|
|||
|
_s_t_r_i_n_g" down L: box "s" down
|
|||
|
M: box "0" down N: box
|
|||
|
down O: box "_n_u_l_l _p_o_i_n_t_e_r" ]
|
|||
|
|
|||
|
line from Prop1.O.c to Prop1.O.c.x, (Prop1.s.y + Prop2.n.y)
|
|||
|
/ 2.0 line to 0.5, (Prop1.s.y + Prop2.n.y) / 2.0 line to
|
|||
|
0.5, Prop2.A.c.y arrow to Prop2.A.w
|
|||
|
|
|||
|
line from Prop2.O.c to Prop2.O.c.x, (Prop2.s.y + Prop3.n.y)
|
|||
|
/ 2.0 line to 0.5, (Prop2.s.y + Prop3.n.y) / 2.0 line dashed
|
|||
|
to 0.5, Prop3.A.c.y arrow to Prop3.A.w
|
|||
|
|
|||
|
line from Prop3.O.c to Prop3.O.c.x, (Prop3.s.y + Prop4.n.y)
|
|||
|
/ 2.0 line to 0.5, (Prop3.s.y + Prop4.n.y) / 2.0 line dashed
|
|||
|
to 0.5, Prop4.A.c.y arrow to Prop4.A.w
|
|||
|
|
|||
|
line from Prop4.O.c to Prop4.O.c.x, (Prop4.s.y + Prop5.n.y)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 22 -
|
|||
|
|
|||
|
|
|||
|
/ 2.0 line to 0.5, (Prop4.s.y + Prop5.n.y) / 2.0 line to
|
|||
|
0.5, Prop5.A.c.y arrow to Prop5.A.w
|
|||
|
|
|||
|
line from Object.B.c to Object.B.c.x, (Object.s.y +
|
|||
|
Prop1.n.y) / 2.0 line to 0.5, (Object.s.y + Prop1.n.y) / 2.0
|
|||
|
line to 0.5, Prop1.A.c.y arrow to Prop1.A.w
|
|||
|
|
|||
|
boxht = 0.3i; boxwid = 2.0i P1: box "cube" at Prop1.N.e.x +
|
|||
|
1.5i, Prop1.N.e.y arrow from Prop1.N.c to P1.w
|
|||
|
|
|||
|
P2: box "Randi J. Rost" at Prop2.N.e.x + 1.5i, Prop2.N.e.y
|
|||
|
arrow from Prop2.N.c to P2.w
|
|||
|
|
|||
|
P3: box " 8 6 24 -1.0 -1.0" at Prop3.N.e.x + 1.5i,
|
|||
|
Prop3.N.e.y P4: box " 1.0 -1.0 1.0 1.0 1.0" with .nw at
|
|||
|
P3.sw P5: box " 1.0 1.0 1.0 -1.0 1.0" with .nw at P4.sw
|
|||
|
P6: box "-1.0 -1.0 -1.0 -1.0 1.0" with .nw at P5.sw P7: box
|
|||
|
"-1.0 1.0 1.0 -1.0 1.0" with .nw at P6.sw P8: box "-1.0
|
|||
|
-1.0 4 4 4 4 4 4" with .nw at P7.sw P9: box "1 2 3 4
|
|||
|
5 6 2 1" with .nw at P8.sw Pa: box "3 2 6 7 3 7 8
|
|||
|
4" with .nw at P9.sw Pb: box "1 4 8 5 8 7 6 5" with
|
|||
|
.nw at Pa.sw arrow from Prop3.N.c to P3.w
|
|||
|
|
|||
|
Pc: box "6 1.0 0.0 0.0 0.0" at Prop4.N.e.x + 1.5i,
|
|||
|
Prop4.N.e.y Pd: box "1.0 0.0 0.0 0.0 1.0" with .nw at
|
|||
|
Pc.sw Pe: box "0.0 1.0 1.0 1.0 1.0" with .nw at Pd.sw
|
|||
|
Pf: box "0.0 1.0 0.0 1.0 " with .nw at Pe.sw arrow
|
|||
|
from Prop4.N.c to Pc.w
|
|||
|
|
|||
|
boxht = 0.3i; boxwid = 0.5i Pg: box at Prop5.N.e.x + 1.0i,
|
|||
|
Prop5.N.e.y Ph: box "cull" at Pg.e.x + 1.0i, Prop5.N.e.y
|
|||
|
arrow from Pg.c to Ph.w arrow from Prop5.N.c to Pg.w
|
|||
|
|
|||
|
"Object" at Object.A.n above
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 23 -
|
|||
|
|
|||
|
|
|||
|
_1_4. _A_c_k_n_o_w_l_e_d_g_e_m_e_n_t_s
|
|||
|
|
|||
|
OFF is a derivative of an object file format used at
|
|||
|
Ohio State University. Special thanks to Allen Akin of WSE
|
|||
|
for helpful ideas and suggestions. Thanks also to Jeff
|
|||
|
Friedberg of Digital's High-Performance Workstation (HPWS)
|
|||
|
group and Shaun Ho of WSE who also contributed to the
|
|||
|
design. Danny Shapiro of WSE provided suggestions for addi-
|
|||
|
tional enhancements and conventions.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
April 26, 1990
|
|||
|
|
|||
|
|
|||
|
|