home *** CD-ROM | disk | FTP | other *** search
/ Avalon - 3D Objects & Resources / Avalon.iso / frmtspcs / off.txt < prev    next >
Text File  |  1995-01-01  |  60KB  |  1,641 lines

  1.                            OFF - A 3D Object File Format
  2.  
  3.  
  4.                                    Randi J. Rost
  5.                                   6-November-1986
  6.                               Updated 12-October-1989
  7.  
  8.                            Digital Equipment Corporation
  9.                           Workstation Systems Engineering
  10.                                  100 Hamilton Ave.
  11.                                 Palo Alto, Ca. 94301
  12.  
  13.  
  14.                       This  document  describes  the  data   format
  15.                  developed by WSE for the interchange and archiving
  16.                  of three-dimensional objects.  This format, called
  17.                  OFF  (for  Object File Format), is general, flexi-
  18.                  ble, and extensible.  It supports ASCII text  ver-
  19.                  sions  of  objects for the purpose of interchange,
  20.                  and binary versions for efficiency of reading  and
  21.                  writing.   It  is  assumed  that applications will
  22.                  develop  their  own,  more  efficient  format  for
  23.                  internal   storage   and   operation   on   three-
  24.                  dimensional objects.
  25.  
  26.  
  27.  
  28.  
  29.             _1.  _I_n_t_r_o_d_u_c_t_i_o_n
  30.  
  31.                  One of the most time-consuming tasks in computer anima-
  32.             tion  projects is designing the 3D models that will be used.
  33.             Many computer animation houses  have  found  that  owning  a
  34.             large  number  of databases makes it easier for them to take
  35.             on new projects at a lower cost (time and $$$).  The cost of
  36.             initially  creating  an  object  can  be  amortized over the
  37.             number of times it can be re-used.  It is our  intention  to
  38.             promote  the  use of OFF files within (and perhaps even out-
  39.             side of) Digital in an effort to build up our collection  of
  40.             useful 3D models.
  41.  
  42.                  The file format itself is not limiting:  OFF files  can
  43.             be  used  for  a  wide variety of object types.  None of the
  44.             "policy decisions" are hard-wired in the design of the  file
  45.             format,  or in the support library routines that allow read-
  46.             ing and writing of OFF files.  Rather, the policy  decisions
  47.             have been left up to the designers since the format supports
  48.             "generic" object definitions.  We  have  developed  specific
  49.             conventions for objects that are defined by polygons for use
  50.  
  51.  
  52.  
  53.  
  54.                                    April 26, 1990
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.                                        - 2 -
  62.  
  63.  
  64.             within WSE, and we'd encourage others to adopt these conven-
  65.             tions  as well in order to promote the interchange of useful
  66.             object data bases.  The _d_x_m_o_d_e_l application (also   
  67. developed
  68.             by WSE) is an example of an application that permits reading
  69.             and writing of OFF files.
  70.  
  71.                  This paper describes the Object File Format itself, the
  72.             conventions we've adopted at WSE, and the library of support
  73.             routines that can be used to read and write OFF files.
  74.  
  75.  
  76.             _2.  _D_e_s_i_g_n _G_o_a_l_s _a_n_d _N_o_n-_G_o_a_ 
  77. l_s
  78.  
  79.             Design goals for the Object File Format include:
  80.  
  81.             1)   Simple.  Simple cases should be simple.  It  should  be
  82.                  possible  to type in all the data required for a simple
  83.                  object (such as a cube) by hand.
  84.  
  85.             2)   Powerful.  The Object File Format should be capable  of
  86.                  accomodating   complicated   objects   (many  vertices,
  87.                  polygons, and a wide range of attributes).
  88.  
  89.             3)   Portable.  ASCII text file representation required  for
  90.                  portability  across  operating  systems  and  hardware.
  91.                  This also allows operations on OFF  files  by  familiar
  92.                  system utilities (text editors and the like).
  93.  
  94.             4)   Efficient.  Binary text file representation required to
  95.                  allow  efficient  reading and writing of OFF files.  It
  96.                  is assumed that reading/writing an object is  a  costly
  97.                  operation,  but  reading and writing ASCII data is just
  98.                  _t_o_o slow.
  99.  
  100.             5)   General.  The format should address the general case of
  101.                  the  three-dimensional  object, not a single particular
  102.                  case.
  103.  
  104.             6)   Extensibile.   Make  sure  the  format  can  be  easily
  105.                  extended to eventually support other primitives such as
  106.                  bezier patches.
  107.  
  108.             7)   No  Favors.   Avoid   hard-wiring   policy   decisions.
  109.                  Rather, provide generic building blocks capable of sup-
  110.                  porting several styles and document a set  of  strongly
  111.                  encouraged conventions that we have adopted.
  112.  
  113.             There are also things that were  specifically  non-goals  in
  114.             the design of the Object File Format.
  115.  
  116.             1)   Internal  Format.   The  Object  File  Format  is   not
  117.                  intended  to be forced upon applications as an internal
  118.  
  119.  
  120.  
  121.  
  122.                                    April 26, 1990
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.                                        - 3 -
  130.  
  131.  
  132.                  format that must be used.  Rather, it  should  be  con-
  133.                  sidered  a  means  for  inputting and outputting object
  134.                  descriptions in a  device-,  language-,  and  operating
  135.                  system-independent  format.   Applications  should feel
  136.                  free to develop and maintain the most  useful/efficient
  137.                  data format they can, and only convert to/from OFF when
  138.                  input or output of a standardized object is desired.
  139.  
  140.             2)   Object Conventions.   OFF  conventions  are  documented
  141.                  only  for  objects in polygonal form at this point.  It
  142.                  is anticipated that  the  Object  File  Format  can  be
  143.                  easily  extended  to  handle bezier surface patches and
  144.                  other primitives in the future.
  145.  
  146.             _3.  _O_b_j_e_c_t_s
  147.  
  148.                  For the purposes of the Object File Format, we'll adopt
  149.             a very general definition of an _o_b_j_e_c_t.  An _o_b_j_e_c_ 
  150. t is simply
  151.             a list of properties (name, description,  author,  copyright
  152.             information, geometry data, colors, etc.)
  153.  
  154.                  The most important information about the object can  be
  155.             found in the _h_e_a_d_e_r _f_i_l_e for the object.  The header  
  156. file is
  157.             always an ASCII text file  that,  by  convention,  is  named
  158.             _n_a_m_e.aoff where _n_a_m_e is the object name.  See Appendix B  
  159. for
  160.             an example of an OFF object header file.
  161.  
  162.                  A few of these properties (name,  description,  author,
  163.             copyright,  type)  are common to every type of 3D object and
  164.             are considered standard properties.  The standard properties
  165.             are built into the routines that manipulate 3D objects.  The
  166.             rest of the properties may vary with the type of object, and
  167.             so are defined by convention only.
  168.  
  169.                  The _n_a_m_e of an object is used to concisely describe the
  170.             object  itself.   For  example, we have objects named "x29",
  171.             "banana" and "vw".  By convention, this  name  also  becomes
  172.             the  prefix for OFF data filenames when an object is read or
  173.             written, so it is best to keep it fairly short.
  174.  
  175.                  The _d_e_s_c_r_i_p_t_i_o_n is used  to  more  fully   
  176. describe  the
  177.             object itself.  It may contain the time and date of creation
  178.             or more prose describing the object.
  179.  
  180.                  The _a_u_t_h_o_r should be the name of the  person  (or  com-
  181.             pany, or utility) that created the object.  We should always
  182.             try to give credit where credit is due.   This  field  tells
  183.             you  who to thank for spiffy objects or whose cage to rattle
  184.             when a problem with an OFF file is discovered.
  185.  
  186.                  The _c_o_p_y_r_i_g_h_t field contains information  dealing   
  187. with
  188.             the  distribution of the object data.  Some object databases
  189.  
  190.  
  191.  
  192.  
  193.                                    April 26, 1990
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.                                        - 4 -
  201.  
  202.  
  203.             will be regarded by a company as proprietary.  These objects
  204.             should  not be copied or distributed without consent.  Other
  205.             objects (vw, x29) were developed by companies or individuals
  206.             and  can  be  copied or used as long as the copyright notice
  207.             appears and proper credit is  given.   Still  other  objects
  208.             (cube,  sphere, etc.) have been placed in the public domain.
  209.             We have tried to be as careful  as  possible  in  preserving
  210.             copyright  and  author  information  for the objects we have
  211.             collected, but sometimes the information was  lost  or  una-
  212.             vailable.   Be  sure  and  honor  copyright notices.  If you
  213.             don't, you (or your company) could end up in big trouble.
  214.  
  215.                  The _t_y_p_e field contains the type of  the  object.   For
  216.             now,  only one type of object is supported: polygon objects.
  217.             It is  anticipated  that  polyline  and  surface  patch-type
  218.             objects will be supported in the future as well.
  219.  
  220.                  Also contained in the object header file are lines that
  221.             describe the various properties of the object.  Each line in
  222.             the object header file that describes an  attribute  of  the
  223.             object other than a standard attribute must contain the pro-
  224.             perty name, the property type, the data format and either  a
  225.             file  name or a string containing default data, depending on
  226.             the property type.  Each of these four  items  is  an  ASCII
  227.             string, separated by white space.
  228.  
  229.                  The _p_r_o_p_e_r_t_y  _n_a_m_e  uniquely  describes  the   
  230. property.
  231.             Property  names  for  which we have defined conventions (see
  232.             Appendix A) include geometry, polygon_colors, vertex_colors,
  233.             back_faces,  vertex_order,  polygon_normals, vertex_normals,
  234.             diffuse_coef, specular_coef, and specular_power.
  235.  
  236.                  OFF currently supports four  _p_r_o_p_e_r_t_y  _t_y_p_e_ 
  237. s:  _d_e_f_a_u_l_t,
  238.             _g_e_n_e_r_i_c,  _i_n_d_e_x_e_d, and _i_n_d_e_x_e_ 
  239. d__p_o_l_y.  If a property is indi-
  240.             cated to be of type _d_e_f_a_u_l_t, the part of the line after   
  241. the
  242.             data  format  is  assumed  to contain some default data that
  243.             will be applied to the entire object.  For instance, it  may
  244.             make  sense  to  give  the entire object a default color and
  245.             default diffuse and specular coefficients.
  246.  
  247.                  If the property type is  either  generic,  indexed,  or
  248.             indexed_poly  (described more fully below), the remainder of
  249.             the line is taken to be a file name that can be  opened  and
  250.             read to obtain the information for the property.
  251.  
  252.                  The data format indicates what type  of  data  will  be
  253.             found  on  the remainder of the line if the property type is
  254.             default, otherwise what kind of data will be  found  in  the
  255.             specified  file.   The data format is a string of characters
  256.             (no spaces) that indicate the order and type  of  the  data.
  257.             Supported primitive data types are:
  258.  
  259.  
  260.  
  261.  
  262.  
  263.                                    April 26, 1990
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.                                        - 5 -
  271.  
  272.  
  273.             f -  A number stored internally as a 32-bit  floating  point
  274.                  number
  275.  
  276.             d -  A number stored internally as a 64-bit double-precision
  277.                  floating point number
  278.  
  279.             i -  A number stored internally as a 32-bit integer value
  280.  
  281.             h -  A number stored internally as a 16-bit integer value
  282.  
  283.             b -  A number stored internally as an 8-bit integer value
  284.  
  285.             s -  A 32-bit pointer to a null-terminated string of charac-
  286.                  ters
  287.  
  288.                  If, for instance, you were interested in  using  32-bit
  289.             floating  values  for  r, g, and b default color values, you
  290.             might have a line in the object header file that reads
  291.  
  292.                     polygon_colors   default   fff   1.0   0.8   0.0
  293.  
  294.  
  295.                  It is important to understand that in  all  cases,  the
  296.             "string"  (s)  data  primitive  will indicate a pointer to a
  297.             string that is stored internally in the data  block  for  an
  298.             object and not the string itself.
  299.  
  300.             _4.  _A_S_C_I_I _P_r_o_p_e_r_t_y _F_i_l_e_s
  301.  
  302.                  OFF supports ASCII text files as a way of providing for
  303.             language-,   hardware-,   and  operating  system-independent
  304.             object data files.  The three types of data files  currently
  305.             supported by OFF are generic, indexed, and indexed_poly.
  306.  
  307.             _4._1.  _G_e_n_e_r_i_c _F_i_l_e_s
  308.  
  309.                  Generic files contain only a _c_o_u_n_t  value  followed  by
  310.             _c_o_u_n_t  data  items of the type specified by the data format.
  311.             Each data item can be comprised of some combination  of  the
  312.             primitive  data  types described in Section 3.  Generic data
  313.             files are useful for storing attributes which are unique  at
  314.             every vertex or polygon (such as color or normals).
  315.  
  316.                  String data items in ASCII generic files may  not  con-
  317.             tain  spaces  or  other white space.  8-bit integers must be
  318.             listed in the range 0-255.
  319.  
  320.                  See Appendix D for an example of an ASCII generic  data
  321.             file.
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.                                    April 26, 1990
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.                                        - 6 -
  337.  
  338.  
  339.             _4._2.  _I_n_d_e_x_e_d _F_i_l_e_s
  340.  
  341.                  Indexed files make use of a list of indices in order to
  342.             reduce  the amount of data required to store a property, and
  343.             to provide a useful level  of  indirection.   For  instance,
  344.             indexed  files  are  commonly  used  to maintain per-polygon
  345.             color information.  If an object has just five  colors,  the
  346.             indexed  data file would contain the list of the five colors
  347.             followed by an index from  one  to  five  for  each  of  the
  348.             polygons  in  the  object.   If an application maintains the
  349.             indirection, it is possible for the user  to  easily  select
  350.             five different colors to be used on the model.
  351.  
  352.                  An indexed file begins with two integers  separated  by
  353.             white  space:  the  number  of  data items and the number of
  354.             indices that will be provided.  Following these  two  values
  355.             is  the  list  of  data items that is to be used.  Each data
  356.             item in this list can be some combination of  the  primitive
  357.             types described in Section 3.  Following the data items is a
  358.             list of indices each of which is a pointer  to  one  of  the
  359.             items  in the list of data items.  The list of data items is
  360.             assumed to begin starting at one, not zero.
  361.  
  362.  
  363.             _4._3.  _I_n_d_e_x_e_d__P_o_l_y _F_i_l_e_s
  364.  
  365.                  Indexed_poly files take  advantage  of  a  connectivity
  366.             list  to  reduce the amount of information needed to store a
  367.             list  of  polylines,  polygons,  or  normals.   The   unique
  368.             geometry items (e.g., vertices) are listed in the first part
  369.             of the file.  Following this list is  a  connectivity  list.
  370.             Each  line  in  the connectivity list contains a _c_o_u_n_t value
  371.             followed by _c_o_u_n_t indices (pointers) to information  in  the
  372.             geometry  list.   (Items  in  the  geometry list are indexed
  373.             starting from one, not zero.)
  374.  
  375.                  The first line of an indexed_poly  data  file  contains
  376.             three  integers, separated by white space.  The first number
  377.             on  this  line  indicates   the   number   of   data   items
  378.             (vertices/normals)  that follow, the second number indicates
  379.             the number of polylines/polygons that follow the data  list,
  380.             and  the  third indicates the total number of edges that are
  381.             contained in the polyline/polygon connectivity list.
  382.  
  383.                  String data items in ASCII indexed_poly files  may  not
  384.             contain spaces or other white space.  8-bit integers must be
  385.             listed in the range 0-255.
  386.  
  387.                  See Appendix C for an example of an ASCII  indexed_poly
  388.             file.
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.                                    April 26, 1990
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.                                        - 7 -
  403.  
  404.  
  405.             _5.  _B_i_n_a_r_y _O_F_F _F_i_l_e_s
  406.  
  407.                  The same three types of data files described above  are
  408.             also  supported  in  binary  format.   There are a few minor
  409.             differences.
  410.  
  411.  
  412.             _5._1.  _G_e_n_e_r_i_c _F_i_l_e_s
  413.  
  414.                  Binary generic files begin with the first  32-bit  word
  415.             equal  to  OFF_GENERIC_MAGIC  as defined in the include file
  416.             _o_f_f._h.  The second word in the file is the _c_o_u_n_t  
  417. (number  of
  418.             data  items  in  the file).  Following the _c_o_u_n_t is the data
  419.             itself.
  420.  
  421.                  The data format in the header file describes the primi-
  422.             tives  that make up each data item in the list.  Within each
  423.             data item, floats,  doubles,  32-bit  integers,  and  string
  424.             pointers will all begin on a word boundary.  16-bit integers
  425.             will all begin on a half-word boundary.  Thus, if your  data
  426.             format  for  the  data items in a generic data file is "bbb"
  427.             (three byte values), each data item will be stored as  three
  428.             bytes  followed  by  a null byte so that each data item will
  429.             begin on a word boundary.  Strings begin with a 32-bit _c_o_u_n_t
  430.             followed  by  _c_o_u_n_t characters followed by a null character.
  431.             The string is null-padded so it will end on a word boundary.
  432.  
  433.                  (It is assumed that for strings,  the  length  will  be
  434.             read and then the necessary memory will be allocated and the
  435.             string read in.   This  eliminates  a  problem  with  having
  436.             variable-length  data in the data files.  Anyway, strings in
  437.             files are  really  only  there  for  symmetry  with  default
  438.             values,  where  strings  are really useful.  The performance
  439.             implications for files containing strings will  probably  be
  440.             enough to prevent people from using them.)
  441.  
  442.  
  443.  
  444.             _5._2.  _I_n_d_e_x_e_d _F_i_l_e_s
  445.  
  446.                  Binary indexed files begin with the first  32-bit  word
  447.             equal  to  OFF_INDEXED_MAGIC  as defined in the include file
  448.             _o_f_f._h.  The second word in the file is the _c_o_u_n_t  
  449. (number  of
  450.             data  items  in  the  file).   The third word in the file is
  451.             _n_u_m__i_n_d_i_c_e_s (number of indices in the index list).
  452.  
  453.                  Following these two integers is the data for  the  data
  454.             item  list.  Each item in the data item list will begin on a
  455.             word boundary.  The data format in the header file describes
  456.             the  primitives  that  make  up  each data item in the list.
  457.             Within each data item, floats, doubles, 32-bit integers, and
  458.             string  pointers  will all begin on a word boundary.  16-bit
  459.  
  460.  
  461.  
  462.  
  463.                                    April 26, 1990
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.                                        - 8 -
  471.  
  472.  
  473.             integers will all begin on a half-word boundary.   Thus,  if
  474.             your  data format for the data items in an indexed data file
  475.             is "bbb" (three byte values), each data item will be  stored
  476.             as  three  bytes  followed  by a null byte so that each data
  477.             item will begin on a word boundary.  Strings  begin  with  a
  478.             32-bit _c_o_u_n_t followed by _c_o_u_n_t characters followed by  
  479. a null
  480.             character.  The string is null-padded so it will  end  on  a
  481.             word boundary.
  482.  
  483.                  Following the data item list is a list of index values.
  484.             This  list  will also begin on a word boundary, however, the
  485.             index values within this list are short integers and will be
  486.             packed two to each 32-bit word.
  487.  
  488.  
  489.             _5._3.  _I_n_d_e_x_e_d__P_o_l_y _F_i_l_e_s
  490.  
  491.                  Binary indexed_poly files begin with the  first  32-bit
  492.             word  equal  to  OFF_INDEXED_POLY_MAGIC  as  defined  in the
  493.             include file off.h.  The second word is the number  of  data
  494.             items  in  the  vertex  list  (_n_p_t_s),  the third word is the
  495.             number of polylines/polygons in the list (_n_p_o_l_y_s),  and  the
  496.             fourth  word is the number of edges contained in the connec-
  497.             tivity list (_n_c_o_n_n_e_c_t_s).
  498.  
  499.                  Starting at the fifth word in the file  is  a  list  of
  500.             _n_p_t_s  data items, followed by _n_p_o_l_y_s short integers  
  501. contain-
  502.             ing polyline/polygon vertex counts,  followed  by  _n_c_o_n_n_e_c_ 
  503. t_s
  504.             short  integers  which  are  indices  into the array of data
  505.             items.  (This arrangement is slightly  different  than  that
  506.             used  for  indexed_poly files in ASCII format for efficiency
  507.             reasons.)
  508.  
  509.                  The same restrictions that apply to the data types  for
  510.             generic  binary  files apply to indexed_poly binary files as
  511.             well.  In addition, the vertex count array which follows the
  512.             geometry data in an indexed_poly file will always begin on a
  513.             word boundary.  The connectivity array that follows the ver-
  514.             tex  count  array will not necessarily start on a word boun-
  515.             dary, but will always begin  _n_p_o_l_y_s  *  _s_i_z_e_o_f(_ 
  516. s_h_o_r_t)  bytes
  517.             after the start of the vertex count array.
  518.  
  519.  
  520.             _6.  _O_f_f._a _a_n_d _O_b_j_e_c_t_s._h
  521.  
  522.                  An include file and a library of routines has been pro-
  523.             vided  for  UNIX/C programmers to more easily manipulate OFF
  524.             files.  The basic concepts of "reading"  and  "writing"  OFF
  525.             files  are  supported  in  this  library  of  routines.  The
  526.             library is a software layer on top of the  operating  system
  527.             file  I/O  interface,  with  special knowledge of OFF files.
  528.             This subroutine library provides a mechanism  for  accessing
  529.  
  530.  
  531.  
  532.  
  533.                                    April 26, 1990
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.                                        - 9 -
  541.  
  542.  
  543.             the  syntactical  elements  of  an object file, but makes no
  544.             attempt to understand the semantics.   Higher  level  inter-
  545.             faces can be layered on top.
  546.  
  547.                  The subroutine library refers to an object as a pointer
  548.             to  an _O_F_F_O_b_j_D_e_s_c.  This structure contains a pointer  
  549. to the
  550.             first property in the property list.  It is defined as  fol-
  551.             lows:
  552.  
  553.                     typedef struct
  554.                         {
  555.                         OFFProperty *FirstProp;     /* Pointer to first property in  
  556. list */
  557.                         } OFFObjDesc;
  558.  
  559.  
  560.                  The information that describes the object is  contained
  561.             in  a  linked  list  of property structures.  The first such
  562.             structure in the list is pointed at by an _O_F_F_O_b_j_D_e_s_c   
  563. struc-
  564.             ture.  The property structures have the form:
  565.  
  566.                     typedef struct _OFFProp
  567.                         {
  568.                         char        PropName[40];
  569.                         int         PropType;
  570.                         char        PropFileName[256];
  571.                         int         PropCount;
  572.                         char        DataFormat[40];
  573.                         char        *PropData;
  574.                         struct _OFFProp *NextProp;
  575.                         } OFFProperty;
  576.  
  577.  
  578.                  _P_r_o_p_N_a_m_e contains a string defining one of the  
  579. property
  580.             types  for  which  a  convention  has  been  defined.   This
  581.             includes the property names "name", "author", "description",
  582.             "copyright",    "comment",   "geometry",   "polygon_colors",
  583.             "polygon_normal", etc.  For  a  complete  list  of  property
  584.             names,  see  Appendix  A.  (The special attribute type "com-
  585.             ment" is supported so that blank lines and comment lines can
  586.             be preserved if an object file is read and then written.)
  587.  
  588.                  The  _P_r_o_p_T_y_p_e  field  contains   a   value   equal    
  589. to
  590.             _O_F_F__D_E_F_A_U_L_T__D_A_T_A,   _O_F_F__G_E_N_E_ 
  591. R_I_C__D_A_T_A,  _O_F_F__I_N_D_E_X_E_D__D_A_T_A,  or
  592.             _O_F_F__I_N_D_E_X_E_D__P_O_L_Y__D_A_T_A which defines  
  593. the basic type  for  the
  594.             property.
  595.  
  596.                  The _P_r_o_p_F_i_l_e_N_a_m_e is required if _P_r_o_ 
  597. p_T_y_p_e  is  something
  598.             other   than   _O_F_F__D_E_F_A_U_L_T__D_A_T_A.    It    
  599. contains  a  string
  600.             representing the name of the file  to  be  read/written  for
  601.             this  attribute.   This  file name should _n_o_t contain a path
  602.             leading up to the file itself, only the  actual  file  name.
  603.             The  object  search path mechanism (see Section 7) should be
  604.  
  605.  
  606.  
  607.  
  608.                                    April 26, 1990
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.                                        - 10 -
  616.  
  617.  
  618.             used instead.
  619.  
  620.                  The _P_r_o_p_C_o_u_n_t indicates the actual number of data  
  621. items
  622.             associated with this particular attribute.  After reading in
  623.             an object, properties of type _O_F_F__D_E_F_A_U_L_T__D_A_T_ 
  624. A will  have  a
  625.             _P_r_o_p_C_o_u_n_t  of  one, properties of type _O_F_F__G_ 
  626. E_N_E_R_I_C__D_A_T_A will
  627.             have a _P_r_o_p_C_o_u_n_t equal to the number of generic  data   
  628. items
  629.             in the list, properties of type _O_F_F__I_N_D_E_X_E_D__D_A_ 
  630. T_A will have a
  631.             _P_r_o_p_C_o_u_n_t equal to the number of  items  in  the  data   
  632. item
  633.             list, and properties of type _O_F_F__I_N_D_E_X_E_D__P_O_L_ 
  634. Y__D_A_T_A will have
  635.             a _P_r_o_p_C_o_u_n_t equal  to  the  number  of  data  items  in   
  636. the
  637.             geometry list.
  638.  
  639.                  The _D_a_t_a_F_o_r_m_a_t field contains a  string  of   
  640. characters
  641.             corresponding  to  primitive data items.  The composite type
  642.             of the data for this property can then be deduced by looking
  643.             at this field and applying the rules for padding to word and
  644.             half-word boundaries.
  645.  
  646.                  The _P_r_o_p_D_a_t_a field contains a pointer  to  a  block   
  647. of
  648.             memory  containing  the actual data for this property.  This
  649.             data will have the same data  alignment  restrictions  as  a
  650.             binary  file has, with the exception of strings.  As strings
  651.             are read in, memory is malloc'ed to hold them and a  pointer
  652.             to the string is stored in the appropriate field in the data
  653.             list.  This means that all primitive data types will have  a
  654.             fixed  size  and lengths and alignments can be computed more
  655.             easily.
  656.  
  657.                  The _N_e_x_t_P_r_o_p field contains a pointer to the next   
  658. pro-
  659.             perty structure in the property list.
  660.  
  661.                  The routines contained in the  subroutine  library  are
  662.             defined below.
  663.  
  664.  
  665.             #include "off.h"
  666.  
  667.             int OFFReadObj(Obj, FileName)
  668.                     OFFObjDesc *Obj;
  669.                     char *FileName;
  670.  
  671.             int OFFWriteObj(Obj, FileName, Directory, FileType);
  672.                     OFFObjDesc *Obj;
  673.                     char *FileName;
  674.                     char *Directory;
  675.                     int FileType;
  676.  
  677.             void OFFPackObj(Obj)
  678.                     OFFObjDesc *Obj;
  679.  
  680.             void OFFPackProperty(Property)
  681.  
  682.  
  683.  
  684.  
  685.                                    April 26, 1990
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.                                        - 11 -
  693.  
  694.  
  695.                     OFFProperty *Property;
  696.  
  697.             int OFFReadGeneric(Property, FileName)
  698.                     OFFProperty *Property;
  699.                     char *FileName;
  700.  
  701.             int OFFWriteGeneric(Property, FileName, FileType)
  702.                     OFFProperty *Property;
  703.                     char *FileName;
  704.                     int FileType;
  705.  
  706.             int OFFReadIndexed(Property, FileName)
  707.                     OFFProperty *Property;
  708.                     char *FileName;
  709.  
  710.             int OFFWriteIndexed(Property, FileName, FileType)
  711.                     OFFProperty *Property;
  712.                     char *FileName;
  713.                     int FileType;
  714.  
  715.             int OFFReadIndexedPoly(Property, FileName)
  716.                     OFFProperty *Property;
  717.                     char *FileName;
  718.  
  719.             int OFFWriteIndexedPoly(Property, FileName, FileType)
  720.                     OFFProperty *Property;
  721.                     char *FileName;
  722.                     int FileType;
  723.  
  724.             OFFObjDesc *OFFCreateObj()
  725.  
  726.             int OFFDestroyObj(Obj)
  727.                     OFFObjDesc *Obj;
  728.  
  729.             OFFProperty *OFFAddProperty(Obj)
  730.                     OFFObjDesc *Obj;
  731.  
  732.             int OFFRemoveProperty(Obj, PropertyName)
  733.                     OFFObjDesc *Obj;
  734.                     char *PropertyName;
  735.  
  736.             int OFFFreeProperty(Property)
  737.                     OFFProperty *Property;
  738.  
  739.  
  740.                  _O_F_F_R_e_a_d_O_b_j will attempt to open the object  
  741. header  file
  742.             named  _F_i_l_e_N_a_m_e  and  read  the  object data it contains.   
  743. A
  744.             pointer to the constructed object structure will be returned
  745.             in  _O_b_j  when  the object has been read.  An attempt will be
  746.             made to open the specified file first as  given,  then  con-
  747.             catenated  in turn with each of the directories specified by
  748.             the environment search path variable _O_B_J__P_A_T_H.  The  
  749. property
  750.  
  751.  
  752.  
  753.  
  754.                                    April 26, 1990
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.                                        - 12 -
  762.  
  763.  
  764.             list  for  the  object  is  built as the file is read.  Upon
  765.             return, the client need only traverse the property list  and
  766.             select the data it needs.  This routine calls _O_F_F_R_e_a_d_G_ 
  767. e_n_e_r_i_c
  768.             and _O_F_F_R_e_a_d_I_n_d_e_x_e_d_P_o_l_y in  order  to   
  769. read  associated  data
  770.             files.   _O_F_F_R_e_a_d_O_b_j  will return 0 if the read  
  771. operation was
  772.             successful, -1 otherwise.
  773.  
  774.                  _O_F_F_W_r_i_t_e_O_b_j will attempt to write the object  
  775. pointed at
  776.             by  _O_b_j  using the filename specified by _F_i_l_e_N_a_m_e.   
  777. The file
  778.             will be written in the directory indicated by _D_i_r_e_c_t_o_r_ 
  779. y.  If
  780.             _F_i_l_e_T_y_p_e  is _O_F_F__A_S_C_I_I, the file will be  
  781. written as an ASCII
  782.             text OFF file.  If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_A_R_ 
  783. Y, the file will  be
  784.             written  as  a  binary  OFF file.  The property list for the
  785.             object is traversed and each property of the object is writ-
  786.             ten  out  in  turn.   This routine calls _O_F_F_W_r_i_t_e_G_e_ 
  787. n_e_r_i_c and
  788.             _O_F_F_W_r_i_t_e_I_n_d_e_x_e_d_P_o_l_y in order to  
  789. write associated data files.
  790.             _O_F_F_W_r_i_t_e_O_b_j  will  return  0 if the write operation  
  791. was suc-
  792.             cessful, -1 otherwise.
  793.  
  794.                  _O_F_F_P_a_c_k_O_b_j attempts to _p_a_c_k the object   
  795. pointed  at  by
  796.             _O_b_j.  Packing only applies to geometry and normals stored in
  797.             indexed_polygon format.  See _O_F_F_P_a_c_k_P_r_o_p_e_r_t_ 
  798. y below.
  799.  
  800.                  _O_F_F_P_a_c_k_P_r_o_p_e_r_t_y packs the property  
  801. pointed at  by  _P_r_o_-
  802.             _p_e_r_t_y.   Packing can only be applied to indexed_polygon pro-
  803.             perties with format ``fff''.  (This is normally the case for
  804.             geometry  and  normals properties.) Packing works by sharing
  805.             common data (vertex or normal) values.   Since  each  vertex
  806.             and vertex normal of an object is usually shared by three or
  807.             more polygons, this can save  a  great  deal  of  space  and
  808.             rendering  time.  If _P_r_o_p_e_r_t_y could not be packed, it is  
  809. not
  810.             modified; otherwise the property data is changed in-place.
  811.  
  812.                  _O_F_F_R_e_a_d_G_e_n_e_r_i_c will read the generic   
  813. data  file  named
  814.             _F_i_l_e_N_a_m_e  (here  _F_i_l_e_N_a_m_e  contains the  
  815. full path name) into
  816.             the property structure pointed at by _P_r_o_p_e_r_t_y.  This  
  817. routine
  818.             will  allocate  the  space  it needs in order to read in the
  819.             data.  A pointer to this allocated data space will be stored
  820.             in the _P_r_o_p_D_a_t_a field of the specified _p_r_o_p_e_ 
  821. r_t_y as described
  822.             earlier.  The entire object, including all allocated  memory
  823.             resources can later be deallocated by calling _O_F_F_D_e_s_t_r_ 
  824. o_y_O_b_j.
  825.             This routine will not typically be called directly by appli-
  826.             cations.  _O_F_F_R_e_a_d_G_e_n_e_r_i_c will return 0 if the  
  827. read operation
  828.             was successful, -1 otherwise.
  829.  
  830.                  _O_F_F_W_r_i_t_e_G_e_n_e_r_i_c will write the generic  
  831. data  associated
  832.             with _P_r_o_p_e_r_t_y into the file _F_i_l_e_N_a_m_e  
  833. (here _F_i_l_e_N_a_m_e contains
  834.             the full path name of the file to be written).  If  _F_i_l_e_T_y_ 
  835. p_e
  836.             is _O_F_F__A_S_C_I_I, the file will be written as an ASCII text  
  837. gen-
  838.             eric data file.  If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_A_ 
  839. R_Y, the file will be
  840.             written  as  a  binary generic data file.  This routine will
  841.             not  typically   be   called   directly   by   applications.
  842.  
  843.  
  844.  
  845.  
  846.                                    April 26, 1990
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.                                        - 13 -
  854.  
  855.  
  856.             _O_F_F_W_r_i_t_e_G_e_n_e_r_i_c  will  return  0  if the  
  857. write operation was
  858.             successful, -1 otherwise.
  859.  
  860.                  _O_F_F_R_e_a_d_I_n_d_e_x_e_d will read the indexed   
  861. data  file  named
  862.             _F_i_l_e_N_a_m_e  (here  _F_i_l_e_N_a_m_e  contains the  
  863. full path name) into
  864.             the property structure pointed at by _P_r_o_p_e_r_t_y.  This  
  865. routine
  866.             will  allocate  the  space  it needs in order to read in the
  867.             data.  A pointer to this allocated data space will be stored
  868.             in the _P_r_o_p_D_a_t_a field of the specified _p_r_o_p_e_ 
  869. r_t_y as described
  870.             earlier.  The entire object, including all allocated  memory
  871.             resources can later be deallocated by calling _O_F_F_D_e_s_t_r_ 
  872. o_y_O_b_j.
  873.             This routine will not typically be called directly by appli-
  874.             cations.  _O_F_F_R_e_a_d_I_n_d_e_x_e_d will return 0 if the  
  875. read operation
  876.             was successful, -1 otherwise.
  877.  
  878.                  _O_F_F_W_r_i_t_e_I_n_d_e_x_e_d will write the indexed  
  879. data  associated
  880.             with _P_r_o_p_e_r_t_y into the file _F_i_l_e_N_a_m_e  
  881. (here _F_i_l_e_N_a_m_e contains
  882.             the full path name of the file to be written).  If  _F_i_l_e_T_y_ 
  883. p_e
  884.             is  _O_F_F__A_S_C_I_I,  the  file  will  be written as an ASCII  
  885. text
  886.             indexed data file.  If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_ 
  887. A_R_Y, the file will
  888.             be written as a binary indexed data file.  This routine will
  889.             not typically be called directly by  applications.   _O_F_F_W_r_i_ 
  890. -
  891.             _t_e_I_n_d_e_x_e_d  will return 0 if the write operation was  
  892. success-
  893.             ful, -1 otherwise.
  894.  
  895.                  _O_F_F_R_e_a_d_I_n_d_e_x_e_d_P_o_l_y will read the  
  896. indexed_poly data file
  897.             named  _F_i_l_e_N_a_m_e  (here _F_i_l_e_N_a_m_e contains  
  898. the full path name)
  899.             into the property structure pointed at  by  _P_r_o_p_e_r_t_y.    
  900. This
  901.             routine will allocate the space it needs in order to read in
  902.             the data.  A pointer to this allocated data  space  will  be
  903.             stored  in  the  _P_r_o_p_D_a_t_a field of the specified _p_r_ 
  904. o_p_e_r_t_y as
  905.             described earlier.  The entire object, including  all  allo-
  906.             cated  memory  resources can later be deallocated by calling
  907.             _O_F_F_D_e_s_t_r_o_y_O_b_j.  This routine will not   
  908. typically  be  called
  909.             directly  by applications.  _O_F_F_R_e_a_d_I_n_d_e_x_e_d_ 
  910. P_o_l_y will return 0
  911.             if the read operation was successful, -1 otherwise.
  912.  
  913.                  _O_F_F_W_r_i_t_e_I_n_d_e_x_e_d_P_o_l_y will write   
  914. the  indexed_poly  data
  915.             associated  with  _P_r_o_p_e_r_t_y  into  the  file  _F_i_l_ 
  916. e_N_a_m_e  (here
  917.             _F_i_l_e_N_a_m_e contains the full path name of the file to be  
  918. writ-
  919.             ten).  If _F_i_l_e_T_y_p_e is _O_F_F__A_S_C_I_I, the file  
  920. will be written as
  921.             an ASCII  text  indexed_poly  data  file.   If  _F_i_l_e_T_y_p_e   
  922. is
  923.             _O_F_F__B_I_N_A_R_Y,   the   file   will   be  written  as  a   
  924. binary
  925.             indexed_poly data file.  This routine will not typically  be
  926.             called  directly  by applications.  _O_F_F_W_r_i_t_e_I_n_d_e_ 
  927. x_e_d_P_o_l_y will
  928.             return 0 if the write operation was  successful,  -1  other-
  929.             wise.
  930.  
  931.                  _O_F_F_C_r_e_a_t_e_O_b_j allocates and  initializes  an   
  932. _O_F_F_O_b_j_D_e_s_c
  933.             structure  A  pointer  to  the  newly-created  structure  is
  934.             returned.  The null pointer is returned if the operation was
  935.             unsuccessful.
  936.  
  937.  
  938.  
  939.  
  940.                                    April 26, 1990
  941.  
  942.  
  943.  
  944.  
  945.  
  946.  
  947.                                        - 14 -
  948.  
  949.  
  950.                  _O_F_F_D_e_s_t_r_o_y_O_b_j deallocates all memory  
  951. resources  associ-
  952.             ated with the object pointed at by _O_b_j.  It works by calling
  953.             _O_F_F_F_r_e_e_P_r_o_p_e_r_t_y for each property in the  
  954. property  list  for
  955.             the specified object.
  956.  
  957.                  _O_F_F_A_d_d_P_r_o_p_e_r_t_y adds a property structure   
  958. to  the  pro-
  959.             perty  list  associated  with  the object pointed at by _O_b_j,
  960.             initializes it, and returns  a  pointer  to  it.   The  null
  961.             pointer is returned if the operation was unsuccessful.
  962.  
  963.                  _O_F_F_R_e_m_o_v_e_P_r_o_p_e_r_t_y deletes the  
  964. named property  from  the
  965.             object  pointed  at  by _O_b_j.  This routine returns -1 if the
  966.             named property is not found in the  property  list  for  the
  967.             specified object.
  968.  
  969.                  _O_F_F_F_r_e_e_P_r_o_p_e_r_t_y frees all the  memory   
  970. resources  allo-
  971.             cated  to  the  property  structure specified by _P_r_o_p_e_r_t_y  
  972. as
  973.             well as the property structure itself.   This  routine  will
  974.             not typically be called directly by applications.
  975.  
  976.             _7.  _O_b_j_e_c_t _S_e_a_r_c_h _P_a_t_h
  977.  
  978.                  It is important to avoid embedding path names in object
  979.             files.   When  an  object  is transported to another system,
  980.             chances are slim that  the  same  directory  structure  will
  981.             exist.   The  _O_F_F_R_e_a_d_O_b_j  routine in libobj.a knows  
  982. about an
  983.             environment variable named _O_B_J__P_A_T_H that is used to  
  984. overcome
  985.             this problem.
  986.  
  987.                  When an object is read, an attempt  is  first  made  to
  988.             open  it  in the current working directory.  If that attempt
  989.             fails, the directories specified in the _O_B_J__P_A_T_H  
  990. environment
  991.             variable  are  tried  in turn until the file is successfully
  992.             opened or the directory list is  exhausted.   _O_B_J__P_A_T_H   
  993. con-
  994.             tains  a  list of directories, separated by spaces, that are
  995.             to be searched for the named objects.
  996.  
  997.                  The name of  the  directory  where  a  successful  open
  998.             operation occurred is used for opening associated data files
  999.             as well.  This means that all of the data files for  a  par-
  1000.             ticular object must reside in the same directory.
  1001.  
  1002.                  It is hoped that in this way, users  will  be  able  to
  1003.             draw  on  one  or  more collections of "standard" objects in
  1004.             addition to their own private collections of objects.
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.                                    April 26, 1990
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.                                        - 15 -
  1024.  
  1025.  
  1026.             _8.  _A_p_p_e_n_d_i_x _A: _C_o_n_v_e_n_t_i_o_n_s _ 
  1027. f_o_r _P_o_l_y_g_o_n_a_l _O_b_j_e_c_t_s
  1028.  
  1029.                  This list contains the conventions we have adopted  for
  1030.             describing  3D  polygonal  objects which are defined in some
  1031.             three-dimensional model coordinate system.  Items in regular
  1032.             type  are string literal, printed as they would appear in an
  1033.             OFF file, and item in italics indicate data values that will
  1034.             vary  from  object to object.  By convention, the header for
  1035.             an ASCII OFF file is suffixed with ".aoff"  and  the  header
  1036.             for  a  binary  OFF file is suffixed with ".off".  There are
  1037.             two choices for how colors  may  be  stored.   If  they  are
  1038.             stored as generic data, the suffixes used are ".{b}pcol" for
  1039.             polygon colors and ".{b}vcol" for vertex  colors.   If  they
  1040.             are   stored   as   indexed  data,  the  suffixes  used  are
  1041.             ".{b}ipcol" and ".{b}ivcol".
  1042.  
  1043.  
  1044.             box;                c|c|c|c|c|c                 l|l|l|l|l|l.
  1045.             Property        Type    Format  Defaults        ASCII
  1046.             filename  Binary                 Filename                  =
  1047.             name    *****   *****   _o_b_j_n_a_m_e *****   *****
  1048.             author  *****   *****   _a_u_t_h_o_r  *****   *****
  1049.             description     *****   *****   _d_e_s_c_r_i_p_t_i_o_n      
  1050. *****   *****
  1051.             copyright       *****   *****   _c_o_p_y_r_i_g_h_t       *****    
  1052. *****
  1053.             type    *****   *****   polyline        *****   *****
  1054.                     *****   *****   polygon *****   *****
  1055.             geometry        indexed_poly    fff     *****   _n_a_m_e.geom       _ 
  1056. n_a_m_e.bgeom
  1057.             polygon_colors  generic fff     *****   _n_a_m_e.pcol       _n_a_ 
  1058. m_e.bpcol
  1059.             vertex_colors   generic fff     *****   _n_a_m_e.vcol       _n_a_ 
  1060. m_e.bvcol
  1061.             polygon_colors  indexed fff     *****   _n_a_m_e.ipcol      _n_a_ 
  1062. m_e.bipcol
  1063.             vertex_colors   indexed fff     *****   _n_a_m_e.ivcol      _n_a_ 
  1064. m_e.bivcol
  1065.             back_faces      default s       cull    *****   *****
  1066.                                     display *****   *****
  1067.                                     reverse *****   *****
  1068.             vertex_order    default s       clockwise       *****   *****
  1069.                                     counter-
  1070.             clockwise       *****   *****
  1071.                                     counterclock-
  1072.             wise        *****   *****
  1073.             polygon_normals generic fff     *****   _n_a_m_e.pnorm      _n_a_ 
  1074. m_e.bpnorm
  1075.             vertex_normals  generic fff     *****   _n_a_m_e.vnorm      _n_a_ 
  1076. m_e.bvnorm
  1077.             diffuse_coef    default f       _v_a_l_u_e   *****   *****
  1078.             specular_coef   default f       _v_a_l_u_e   *****   *****
  1079.             specular_power  default f       _v_a_l_u_e   *****   *****
  1080.             bounding_box    default ffffff  _v_a_l_u_e   *****   *****
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.                                    April 26, 1990
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099.                                        - 16 -
  1100.  
  1101.  
  1102.             _9.  _A_p_p_e_n_d_i_x _B: _O_F_F _H_e_a_d_e_r _F_i_ 
  1103. l_e _F_o_r _a _C_u_b_e (_c_u_b_e._a_o_f_f)
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.             ;    l    l.     name    cube    author  Randi    J.    Rost
  1113.             description     cube  with  sides of red, green, blue, cyan,
  1114.             yellow,      magenta      copyright       public      domain
  1115.             type    polygon
  1116.  
  1117.  
  1118.             ;  l  c  c  c  l  c  c  c   l   l   l   l.    #   Prop. data
  1119.             type       format  filename       or       default      data
  1120.             #_______        _________       ______  ________________________
  1121.  
  1122.             geometry        indexed_poly    fff     cube.geom
  1123.             vertex_order    default s       clockwise
  1124.             polygon_colors  generic fff     cube.pcol
  1125.             back_faces      default s       cull
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.                                    April 26, 1990
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.                                        - 17 -
  1167.  
  1168.  
  1169.             _1_0.  _A_p_p_e_n_d_i_x _C: _L_i_s_t_i_n_g _o_f _c_ 
  1170. u_b_e._g_e_o_m
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.             ;   nw(0.5i)   nw(0.5i)    nw(0.5i)    nw(0.5i)    nw(0.5i).
  1180.             8       6       24  -1.0    -1.0    1.0  -1.0    1.0     1.0
  1181.             1.0     1.0     1.0 1.0     -1.0    1.0 -1.0    -1.0    -1.0
  1182.             -1.0    1.0     -1.0  1.0     1.0     -1.0 1.0     -1.0    -
  1183.             1.0                        4       1       2       3       4
  1184.             4       5       6       2       1
  1185.             4       3       2       6       7
  1186.             4       3       7       8       4
  1187.             4       1       4       8       5
  1188.             4       8       7       6       5
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.                                    April 26, 1990
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.                                        - 18 -
  1234.  
  1235.  
  1236.             _1_1.  _A_p_p_e_n_d_i_x _D: _L_i_s_t_i_n_g _o_f _c_ 
  1237. u_b_e._p_c_o_l
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.             ; l s s nw(0.5i) nw(0.5i)  nw(0.5i).   6                 1.0
  1247.             0.0         0.0  0.0         1.0         0.0  0.0        0.0
  1248.             1.0 0.0        1.0        1.0 1.0        1.0        0.0  1.0
  1249.             0.0        1.0
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271.  
  1272.  
  1273.  
  1274.  
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.  
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.                                    April 26, 1990
  1294.  
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.                                        - 19 -
  1301.  
  1302.  
  1303.             _1_2.  _A_p_p_e_n_d_i_x _E: _L_i_s_t_i_n_g _o_f _o_ 
  1304. f_f._h
  1305.  
  1306.  
  1307.  
  1308.             #define OFF_INDEXED_POLY_MAGIC  0xFEEDFEEDL
  1309.             #define OFF_GENERIC_MAGIC       0xBEEFBEEFL
  1310.             #define OFF_INDEXED_MAGIC       0xBADBADBAL
  1311.  
  1312.             #define OFF_BIGSTR              256
  1313.             #define OFF_SMSTR               40
  1314.  
  1315.             #define OFF_ASCII               0
  1316.             #define OFF_BINARY              1
  1317.  
  1318.  
  1319.             /* Types of data for object properties  */
  1320.  
  1321.             #define OFF_UNKNOWN_TYPE_DATA   0
  1322.             #define OFF_STANDARD_DATA       1
  1323.             #define OFF_COMMENT_DATA        2
  1324.             #define OFF_DEFAULT_DATA        3
  1325.             #define OFF_GENERIC_DATA        4
  1326.             #define OFF_INDEXED_POLY_DATA   5
  1327.             #define OFF_INDEXED_DATA        6
  1328.  
  1329.  
  1330.             typedef struct _OFFProp
  1331.                 {
  1332.                 char        PropName[OFF_SMSTR];     /* Name of property (or  
  1333. attribute)  */
  1334.                 int         PropType;                /* Type of data for property         
  1335. */
  1336.                 char        PropFileName[OFF_BIGSTR];/* Name of file that has prop  
  1337. data  */
  1338.                 char        DataFormat[OFF_SMSTR];   /* Pointer to property data  
  1339. format  */
  1340.                 int         PropCount;               /* Number of data items for  
  1341. property*/
  1342.                 char        *PropData;               /* Pointer to property data          
  1343. */
  1344.                 struct _OFFProp *NextProp;           /* Pointer to next property in  
  1345. list */
  1346.                 } OFFProperty;
  1347.  
  1348.             typedef struct
  1349.                 {
  1350.                 OFFProperty *FirstProp;              /* Pointer to first property in  
  1351. list*/
  1352.                 } OFFObjDesc;
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.  
  1368.                                    April 26, 1990
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.                                        - 20 -
  1376.  
  1377.  
  1378.             _1_3.  _A_p_p_e_n_d_i_x _F: _D_a_t_a _S_t_r_u_c_t_ 
  1379. u_r_e _F_o_r_m_a_t
  1380.  
  1381.                  The following diagram depicts some of the  data  struc-
  1382.             tures   for   the  object  _c_u_b_e._a_o_f_f  after  being  read   
  1383. by
  1384.             _O_F_F_R_e_a_d_O_b_j() (or just prior  to  being  written  by   
  1385. _O_F_F_W_r_i_-
  1386.             _t_e_O_b_j()).  move to 0.0, 14.5 Object:         [         boxht
  1387.             = 0.3i; boxwid = 2.0i         moveht = 0.3i; movewid =  0.0i
  1388.                         down          A: box "FirstProp"            move
  1389.             up 0.3i; move right  2.0i              down          B:  box
  1390.                     ]
  1391.  
  1392.             move to 1.0, 13.0 Prop1:          [          boxht  =  0.3i;
  1393.             boxwid = 1.5i         moveht = 0.3i; movewid = 0.0i
  1394.             down         A: box "PropName"              down          B:
  1395.             box "PropType"            down         C: box "PropFileName"
  1396.                        down         D: box "DataFormat"             down
  1397.                     E:  box  "PropCount"             down         F: box
  1398.             "PropData"              down           H:   box   "NextProp"
  1399.                         move  up  2.1i;              move  right  2.25i;
  1400.                        boxht = 0.3i; boxwid = 3.0i             moveht  =
  1401.             0.3i;  movewid  = 0.0i            down         I: box "name"
  1402.                        down         J: box "OFF_STANDARD_DATA"
  1403.             down         K: box "_n_u_l_l _s_t_r_i_n_g"            down          
  1404. L:
  1405.             box  "_n_u_l_l  _s_t_r_i_n_g"              down          M:   
  1406. box   "0"
  1407.                         down          N:  box            down         O:
  1408.             box         ]
  1409.  
  1410.             move to 1.0, 10.0 Prop2:          [          boxht  =  0.3i;
  1411.             boxwid = 1.5i         moveht = 0.3i; movewid = 0.0i
  1412.             down         A: box "PropName"              down          B:
  1413.             box "PropType"            down         C: box "PropFileName"
  1414.                        down         D: box "DataFormat"             down
  1415.                     E:  box  "PropCount"             down         F: box
  1416.             "PropData"              down           H:   box   "NextProp"
  1417.                         move  up  2.1i;              move  right  2.25i;
  1418.                        boxht = 0.3i; boxwid = 3.0i             moveht  =
  1419.             0.3i; movewid = 0.0i            down         I: box "author"
  1420.                        down         J: box "OFF_STANDARD_DATA"
  1421.             down         K: box "_n_u_l_l _s_t_r_i_n_g"            down          
  1422. L:
  1423.             box  "_n_u_l_l  _s_t_r_i_n_g"              down          M:   
  1424. box   "0"
  1425.                         down          N:  box            down         O:
  1426.             box         ]
  1427.  
  1428.             move to 1.0, 7.0  Prop3:          [          boxht  =  0.3i;
  1429.             boxwid = 1.5i         moveht = 0.3i; movewid = 0.0i
  1430.             down         A: box "PropName"              down          B:
  1431.             box "PropType"            down         C: box "PropFileName"
  1432.                        down         D: box "DataFormat"             down
  1433.                     E:  box  "PropCount"             down         F: box
  1434.             "PropData"              down           H:   box   "NextProp"
  1435.                         move  up  2.1i;              move  right  2.25i;
  1436.                        boxht = 0.3i; boxwid = 3.0i             moveht  =
  1437.  
  1438.  
  1439.  
  1440.  
  1441.                                    April 26, 1990
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.                                        - 21 -
  1449.  
  1450.  
  1451.             0.3i;   movewid   =  0.0i              down          I:  box
  1452.             "geometry"                     down              J:      box
  1453.             "OFF_INDEXED_POLY_DATA"                down          K:  box
  1454.             "cube.geom"            down         L:  box  "fff"
  1455.             down          M:  box  "6"              down          N: box
  1456.                        down         O: box         ]
  1457.  
  1458.             move to 1.0, 4.0  Prop4:          [          boxht  =  0.3i;
  1459.             boxwid = 1.5i         moveht = 0.3i; movewid = 0.0i
  1460.             down         A: box "PropName"              down          B:
  1461.             box "PropType"            down         C: box "PropFileName"
  1462.                        down         D: box "DataFormat"             down
  1463.                     E:  box  "PropCount"             down         F: box
  1464.             "PropData"              down           H:   box   "NextProp"
  1465.                         move  up  2.1i;              move  right  2.25i;
  1466.                        boxht = 0.3i; boxwid = 3.0i             moveht  =
  1467.             0.3i;   movewid   =  0.0i              down          I:  box
  1468.             "polygon_colors"                  down            J:     box
  1469.             "OFF_GENERIC_DATA"                  down            K:   box
  1470.             "cube.pcol"            down         L:  box  "fff"
  1471.             down          M:  box  "6"              down          N: box
  1472.                        down         O: box         ]
  1473.  
  1474.             move to 1.0, 1.0  Prop5:          [          boxht  =  0.3i;
  1475.             boxwid = 1.5i         moveht = 0.3i; movewid = 0.0i
  1476.             down         A: box "PropName"              down          B:
  1477.             box "PropType"            down         C: box "PropFileName"
  1478.                        down         D: box "DataFormat"             down
  1479.                     E:  box  "PropCount"             down         F: box
  1480.             "PropData"              down           H:   box   "NextProp"
  1481.                         move  up  2.1i;              move  right  2.25i;
  1482.                        boxht = 0.3i; boxwid = 3.0i             moveht  =
  1483.             0.3i;   movewid   =  0.0i              down          I:  box
  1484.             "back_faces"                    down             J:      box
  1485.             "OFF_DEFAULT_DATA"              down          K:  box  "_n_u_l_l
  1486.             _s_t_r_i_n_g"            down         L: box "s"              down
  1487.                     M:  box  "0"            down         N: box
  1488.             down         O: box "_n_u_l_l _p_o_i_n_t_e_r"         ]
  1489.  
  1490.             line from Prop1.O.c to Prop1.O.c.x, (Prop1.s.y +  Prop2.n.y)
  1491.             /  2.0  line  to  0.5, (Prop1.s.y + Prop2.n.y) / 2.0 line to
  1492.             0.5, Prop2.A.c.y arrow to Prop2.A.w
  1493.  
  1494.             line from Prop2.O.c to Prop2.O.c.x, (Prop2.s.y +  Prop3.n.y)
  1495.             / 2.0 line to 0.5, (Prop2.s.y + Prop3.n.y) / 2.0 line dashed
  1496.             to 0.5, Prop3.A.c.y arrow to Prop3.A.w
  1497.  
  1498.             line from Prop3.O.c to Prop3.O.c.x, (Prop3.s.y +  Prop4.n.y)
  1499.             / 2.0 line to 0.5, (Prop3.s.y + Prop4.n.y) / 2.0 line dashed
  1500.             to 0.5, Prop4.A.c.y arrow to Prop4.A.w
  1501.  
  1502.             line from Prop4.O.c to Prop4.O.c.x, (Prop4.s.y +  Prop5.n.y)
  1503.  
  1504.  
  1505.  
  1506.  
  1507.                                    April 26, 1990
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.                                        - 22 -
  1515.  
  1516.  
  1517.             /  2.0  line  to  0.5, (Prop4.s.y + Prop5.n.y) / 2.0 line to
  1518.             0.5, Prop5.A.c.y arrow to Prop5.A.w
  1519.  
  1520.             line  from  Object.B.c  to   Object.B.c.x,   (Object.s.y   +
  1521.             Prop1.n.y) / 2.0 line to 0.5, (Object.s.y + Prop1.n.y) / 2.0
  1522.             line to 0.5, Prop1.A.c.y arrow to Prop1.A.w
  1523.  
  1524.             boxht = 0.3i; boxwid = 2.0i P1: box "cube" at Prop1.N.e.x  +
  1525.             1.5i, Prop1.N.e.y arrow from Prop1.N.c to P1.w
  1526.  
  1527.             P2: box "Randi J. Rost" at Prop2.N.e.x +  1.5i,  Prop2.N.e.y
  1528.             arrow from Prop2.N.c to P2.w
  1529.  
  1530.             P3: box "  8    6    24 -1.0 -1.0" at  Prop3.N.e.x  +  1.5i,
  1531.             Prop3.N.e.y  P4:  box " 1.0 -1.0  1.0  1.0  1.0" with .nw at
  1532.             P3.sw P5: box " 1.0  1.0  1.0 -1.0  1.0" with .nw  at  P4.sw
  1533.             P6: box "-1.0 -1.0 -1.0 -1.0  1.0" with .nw at P5.sw P7: box
  1534.             "-1.0  1.0  1.0 -1.0  1.0" with .nw at P6.sw P8:  box  "-1.0
  1535.             -1.0  4  4  4 4  4  4" with .nw at P7.sw P9: box "1  2  3  4
  1536.             5  6  2  1" with .nw at P8.sw Pa: box "3  2  6  7  3   7   8
  1537.             4"  with  .nw at P9.sw Pb: box "1  4  8  5  8  7  6  5" with
  1538.             .nw at Pa.sw arrow from Prop3.N.c to P3.w
  1539.  
  1540.             Pc: box "6    1.0  0.0  0.0  0.0"  at  Prop4.N.e.x  +  1.5i,
  1541.             Prop4.N.e.y  Pd:  box  "1.0  0.0  0.0  0.0  1.0" with .nw at
  1542.             Pc.sw Pe: box "0.0  1.0  1.0  1.0  1.0" with  .nw  at  Pd.sw
  1543.             Pf:  box  "0.0   1.0  0.0  1.0     " with .nw at Pe.sw arrow
  1544.             from Prop4.N.c to Pc.w
  1545.  
  1546.             boxht = 0.3i; boxwid = 0.5i Pg: box at Prop5.N.e.x  +  1.0i,
  1547.             Prop5.N.e.y  Ph:  box  "cull"  at Pg.e.x + 1.0i, Prop5.N.e.y
  1548.             arrow from Pg.c to Ph.w arrow from Prop5.N.c to Pg.w
  1549.  
  1550.             "Object" at Object.A.n above
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.  
  1561.  
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573.                                    April 26, 1990
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.                                        - 23 -
  1581.  
  1582.  
  1583.             _1_4.  _A_c_k_n_o_w_l_e_d_g_e_m_e_n_t_s
  1584.  
  1585.                  OFF is a derivative of an object file  format  used  at
  1586.             Ohio  State University.  Special thanks to Allen Akin of WSE
  1587.             for helpful ideas  and  suggestions.  Thanks  also  to  Jeff
  1588.             Friedberg  of  Digital's High-Performance Workstation (HPWS)
  1589.             group and Shaun Ho  of  WSE  who  also  contributed  to  the
  1590.             design.  Danny Shapiro of WSE provided suggestions for addi-
  1591.             tional enhancements and conventions.
  1592.  
  1593.  
  1594.  
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.  
  1602.  
  1603.  
  1604.  
  1605.  
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.  
  1626.  
  1627.  
  1628.  
  1629.  
  1630.  
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.                                    April 26, 1990
  1640.  
  1641.