home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FAQSYS18.ZIP / FAQS.DAT / OFF.DOC < prev    next >
Text File  |  1995-10-13  |  59KB  |  1,519 lines

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