=====================
Polyhedron attributes
=====================

**Attribute operations**

The following is the complete list of legal values for the attribute opcodes.  The format of the data depends on the opcode.

.. csv-table::

	"0x00", "OPT_TERMINATE"
	"0X01", "OPT_ALL_NORMALS_COMPRESSED"
	"0x02", "OPT_NORMALS_COMPRESSED"
	"0x03", "OPT_ALL_PARAMETERS_COMPRESSED"
	"0x04", "OPT_PARAMETERS_COMPRESSED"
	"0x05", "OPT_ALL_VFCOLORS"
	"0x06", "OPT_VERTEX_FCOLORS"
	"0x07", "OPT_ALL_VECOLORS"
	"0x08", "OPT_VERTEX_ECOLORS"
	"0x09", "OPT_ALL_VMCOLORS"
	"0x0A", "OPT_VERTEX_FINDICES"
	"0x0B", "OPT_ALL_VFINDICES"
	"0x0C", "OPT_VERTEX_FINDICES"
	"0x0D", "OPT_ALL_VEINDICES"
	"0x0E", "OPT_VERTEX_EINDICES"
	"0x0F", "OPT_ALL_VMINDICES"
	"0x10", "OPT_VERTEX_MINDICES"
	"0x11", "OPT_ALL_NORMALS"
	"0x12", "OPT_NORMALS"
	"0x13", "OPT_ALL_NORMALS_POLAR"
	"0x14", "OPT_NORMALS_POLAR"
	"0x15", "OPT_ALL_VMVISIBILITIES"
	"0x16", "OPT_VERTEX_MARKER_VISIBILITIES"
	"0x17", "OPT_ALL_VMSYMBOLS"
	"0x18", "OPT_VERTEX_MARKER_SYMBOLS"
	"0x19", "OPT_ALL_VMSIZES"
	"0x1A", "OPT_VERTEX_MARKER_SIZES"
	"0x1B", "OPT_ALL_PARAMETERS"
	"0x1C", "OPT_PARAMETERS"
	" ", "*break in sequence*"
	"0x21", "OPT_ALL_FACE_COLORS"
	"0x22", "OPT_FACE_COLORS"
	"0x23", "OPT_ALL_FACE_INDICES"
	"0x24", "OPT_FACE_INDICES"
	"0x25", "OPT_ALL_FACE_NORMALS"
	"0x26", "OPT_FACE_NORMALS"
	"0x27", "OPT_ALL_FACE_VISIBILITIES"
	"0x28", "OPT_FACE_VISIBILITIES"
	"0x29", "OPT_ALL_FACE_PATTERNS"
	"0x2A", "OPT_FACE_PATTERNS"
	" ", "*break in sequence*"
	"0x33", "OPT_FACE_REGIONS"
	" ", "*break in sequence*"
	"0x47", "OPT_ALL_EDGE_COLORS"
	"0x48", "OPT_EDGE_COLORS"
	"0x49", "OPT_ALL_EDGE_INDICES"
	"0x4A", "OPT_EDGE_INDICES"
	"0x4B", "OPT_ALL_EDGE_NORMALS_POLAR"
	"0x4C", "OPT_EDGE_NORMALS_POLAR"
	"0x4D", "OPT_ALL_EDGE_VISIBILITIES"
	"0x4E", "OPT_EDGE_VISIBILITIES"
	"0x4F", "OPT_ALL_EDGE_PATTERNS"
	"0x50", "OPT_EDGE_PATTERNS"
	"0x51", "OPT_ALL_EDGE_WEIGHTS"
	"0x52", "OPT_EDGE_WEIGHTS"
	" ", "*break in sequence*"
	"0x63", "OPT_POLYHEDRON_ATTRIBUTES"

:doc:`TKE_Shell </general/hsf/opcodes/TKE_Shell>` and :doc:`TKE_Mesh </general/hsf/opcodes/TKE_Mesh>` (a.k.a. polyhedra) *suboptions* and :doc:`TKE_PolyCylinder </general/hsf/opcodes/TKE_PolyCylinder>` *flags* have a bit to indicate the presence of "optionals" (a.k.a. attributes) on the faces, vertices, or edges.

If that bit is set,  There will be a list of one or more attribute operations followed by an ``OPT_TERMINATE``. Thus, the structure of this list is similar to a list of primitives in a segment, except that the opcodes and formats are specific to attributes.

The meaning of most of the attribute should be apparent from the name of the opcode. "Normals" are vertex normals. "Parameters" are texture coordinates bound to vertices. "Indices" are values for looking up into a previously defined color look-up table. Vertex colors and indices can affect marker, face or edge appearance, as specified with "vm", "ve", or "vf".  <p>

** Operations to define values everywhere

.. csv-table:

	"Values specified with compressed floats", " "
	"OPT_ALL_NORMALS_COMPRESSED", "float[3]"
	"OPT_ALL_VFCOLORS", "float[3]"
	"OPT_ALL_VECOLORS", "float[3]"
	"OPT_ALL_VMCOLORS", "float[3]"
	"OPT_ALL_VFINDICES", "float"
	"OPT_ALL_VEINDICES", "float"
	"OPT_ALL_VMINDICES", "float"
	"OPT_ALL_PARAMETERS_COMPRESSED", "float[** variable **]"
	"OPT_ALL_NORMALS_POLAR", "float[2]"
	"OPT_ALL_FACE_NORMALS_POLAR", "float[2]"
	"OPT_ALL_EDGE_NORMALS_POLAR", "float[2]"
	"OPT_ALL_FACE_COLORS", "float[3]"
	"OPT_ALL_FACE_INDICES", "float"
	"OPT_ALL_EDGE_COLORS", "float[3]"
	"OPT_ALL_EDGE_INDICES", "float"

**byte** operation,
**byte** compression_scheme,	
**byte** bits_per_sample,
**array of compressed floats** data

.. csv-table::

	"Values specified with uncompressed floats", " "
	"OPT_ALL_NORMALS", "float[3]"
	"OPT_ALL_VMARKER_SIZES", "float"
	"OPT_ALL_PARAMETERS", "float[\*\* variable \*\*]"
	"OPT_ALL_EDGE_WEIGHTS", "float"

**byte** operation,
[**byte** parameter width],
**array of floats** data
*note that the "parameter width" field, (which indicates the number of values on each vertex) is only used by ``OPT_ALL_PARAMETERS``*

.. csv-table::

	"Values specified with bytes", " "
	"OPT_ALL_VMSYMBOLS", "char"
	"OPT_ALL_VMVISIBILITIES", "char"
	"OPT_ALL_FACE_VISIBILITIES", "char"
	"OPT_ALL_EDGE_VISIBILITIES", "char"
	"OPT_ALL_FACE_PATTERNS", "char"
	"OPT_ALL_EDGE_PATTERNS", "char"

**byte** operation,
**byte** compression_scheme,	
**array of bytes** data

**Operations to define a subset of values**

.. csv-table::

	"Values specified with compressed floats", ""
	"OPT_NORMALS_COMPRESSED", "float[3]"
	"OPT_VERTEX_FCOLORS", "float[3]"
	"OPT_VERTEX_ECOLORS", "float[3]"
	"OPT_VERTEX_MCOLORS", "float[3]"
	"OPT_VERTEX_FINDICES", "float"
	"OPT_VERTEX_EINDICES", "float"
	"OPT_VERTEX_MINDICES", "float"
	"OPT_PARAMETERS_COMPRESSED", "float[ **variable** ]"
	"OPT_NORMALS_POLAR", "float[2]"
	"OPT_FACE_NORMALS_POLAR", "float[2]"
	"OPT_EDGE_NORMALS_POLAR", "float[2]"
	"OPT_FACE_COLORS", "float[3]"
	"OPT_FACE_INDICES", "float"
	"OPT_EDGE_COLORS", "float[3]"
	"OPT_EDGE_INDICES", "float"

**byte** operation,
**byte** compression_scheme,	
**byte** bits_per_sample,
**int** count,
**variable array ** indices (see <a href="#notes">notes</a>),
**array of compressed floats** data (see <a href="#aocf">below</a>)<P>

.. csv-table::

	"Values specified with uncompressed floats"
	"OPT_NORMALS", "float[3]"
	"OPT_PARAMETERS", "float[ **variable** ]"
	"OPT_VERTEX_MARKER_SIZES", "float"
	"OPT_EDGE_WEIGHTS", "float"

**byte** operation,
[**byte** parameter width],
**int** count,
**variable array ** indices (see <a href="#notes">notes</a>),
**array of floats** data

*note that the "parameter width" field, (which indicates the number of values on each vertex) is only used by ``OPT_ALL_PARAMETERS``*

.. csv-table::

	"Values specified with bytes", ""
	"OPT_VERTEX_MARKER_VISIBILITIES", "char"
	"OPT_FACE_VISIBILITIES", "char"
	"OPT_EDGE_VISIBILITIES", "char"
	"OPT_FACE_PATTERNS", "char"
	"OPT_EDGE_PATTERNS", "char"
	"OPT_VERTEX_MARKER_SYMBOLS", "char"

**byte** operation,
**byte** compression_scheme,	
**int** count,
**variable array ** indices
**array of bytes** data

In the above format, "count" specifies the number of values that are defined. "Indices" and is an array of size-dependent values.  They will be unsigned values that are 8-bit unsigned characters, 16-bit unsigned shorts, or 32-bit unsigned integers, rounded up from the number of bits required to store the point count (face count in the case of ``OPT_FACE_COLORS`` or ``OPT_FACE_INDICES``). "Data" is an array of unsigned values packed bitwise with no padding betweenentries whatsoever.

With this format, some of the values may be left undefined. They take on default or inherited values from elsewhere in a manner specific to the application and/or graphics system.

**Miscellaneous options**

.. csv-table::

	"OPT_FACE_REGIONS", "OPT_POLYHEDRON_ATTRIBUTES"

All are **variable** format, described below.


Notes
=====
	
The entire list is terminated with an ``OPT_TERMINATE`` opcode

**Array of compressed floats**

Points, normals, colors, color indices and parameters (a.k.a. texture coordinates) are all fundamentally arrays of floating point values.  Of those, all but points are given as part of the polyhedron optionals ("points" are defined as part of :doc:`TKE_Shell </general/hsf/opcodes/TKE_Shell>` and :doc:`TKE_Mesh </general/hsf/opcodes/TKE_Mesh>` which have links to this section for the definition of an "array of compressed floats"). The following schemes are currently defined:

.. csv-table::

	"1", "CS_TRIVIAL"
	"2", "CS_TRIVIAL_IMPLICIT (obsolete)"
	"3", "CS_REPULSE"
	
**CS_TRIVIAL**
If the value to be encoded has a variable number of dimensions (e.g. vertex parameters, a.k.a. texture coordinates). Under the ``CS_TRIVIAL`` scheme, the array consists of a minimum for each dimension, followed by a maximum for each dimension. All are encoded as 32-bit floats.  Next comes a packed array of raw data samples.  The initial bounding volume is omitted when possible:

* Normal vectors use {-1,-1,-1,1,1,1}
* Colors (by value, but not by index) use {0,0,0,1,1,1}
* Vertices, when the TK_Global_Quantization write flag is set, inherit the top-level global bounding box.

The bounding cuboid is linearly divided into 2 bits_per_sample equally spaced buckets. The samples field is then a packed array of samples in the order xyzxyz...xyz. The array is padded with bits set to 0 to align it to the next character, but no padding whatsoever exists between individual samples. Legal values for bits_per_sample allow for anything in the range from 2 to 31. For colors and normals, there is only one bounding cuboid possible, and are omitted. Normals use. Colors use.

**CS_TRIVIAL_IMPLICIT (obsolete)**
``CS_TRIVIAL_IMPLICIT`` differs from ``CS_TRIVIAL`` only in that the bounding cuboid is inferred from the nature of the data it is encoding. ``CS_TRIVIAL_IMPLICIT`` can be used only for normals, colors, parameters and colors-by-index.  Fornormals, the assumed bounding box is {-1,-1,-1,1,1,1}.  For the colors, the assumption is {0,0,0,1,1,1}. This compression scheme was deprecated because of the observation that the difference between ``CS_TRIVIAL`` and ``CS_TRIVIAL_IMPLICIT`` could be inferred from context.

**CS_REPULSE**
``CS_REPULSE`` is defined only for *bits_per_sample* values of 8 and 10.  A predefined set of unit vectors is hardcoded into both the reading and writing sides.  The bit-packed array of samples is interpreted as indices into this array of hardcoded unit vectors.  The last index in both the 8 and 10 bit versions is a reserved value that indicates that thenormal is not valid (left for the receiving end's graphics system to compute). For the definition of the predefined unit vectors, see :doc:`repulse_data`.

**Face regions - array of compresed Ints**

If face regions are defined, they are specified as one Int per face,which may then be compressed. The form of storage is defined by **Byte** compression_scheme which currently consists of two parts.

The upper part (compression_scheme & 0xF8) defines the storage size of all the following values:

.. csv-table::

	"0", "Int values are stored as Ints"
	"8", "Int values are stored as Bytes"
	"16", "Int values are stored as Words"

The lower part (compression_scheme & 0x07) defines the form of compression applied to the array of values:

.. csv-table::

	"0", "No compression. One region value per face."
	"1", "Sequential, zero based. A count is given indicating the number of distinct regions, folowed by *count* values indicating the number of faces in each successive region."
	"2", "Sequential, non-zero based. A count is given indicating the number of distinct regions, folowed by the first region index, and then *count* values indicating the number of faces in each successive region."
	"3", "Grouped faces. A count is given indicating the number of groups specified, followed by *count* pairs of region/length values"

For example, a cube defining regions for the faces as (0 0 0 0 1 1) could use scheme 1 to encode this as (2 4 2), another cube with regions (2 2 2 2 1 1) could use scheme 3 to produce (2 2 4 1 2).

Face region support was added in HSF format 7.05.

**Polyhedron attributes**

If polyhedron attributes are defined, they are attributes (such as color) which are set at the geometry level (as opposed
to the segment level or the face/edge/vertex level). They are stored as one or more normal attributes followed by a
``TKE_Termination`` opcode (distinct from the ``OPT_TERMINATE`` which is required when all optional fields are done).

Polyhedron attribute support was added in HSF format 7.05.
