### Navigation

- index
- modules |
- next |
- previous |
- PyFFI 2.2.2 documentation »
- `pyffi` — Interfacing block structured files »
- `pyffi.formats` — File format interfaces »

# `pyffi.formats.tri` — TRI (.tri)

A .tri file contains facial expression data, that is, morphs for dynamic expressions such as smile, frown, and so on.

## Implementation

class `pyffi.formats.tri.``TriFormat`

  Bases: `pyffi.object_models.xml.FileFormat`

  This class implements the TRI format.

  `Data`

    alias of `Header`

  class `FileSignature`(**kwargs)

    Bases: `pyffi.object_models.xml.basic.BasicBase`

    Basic type which implements the header of a TRI file.

    `get_hash`(data=None)

      Return a hash value for this value.

      Returns: | An immutable object that can be used as a hash.

    `get_size`(data=None)

      Return number of bytes the header string occupies in a file.

      Returns: | Number of bytes.

    `read`(stream, data)

      Read header string from stream and check it.

      Parameters: | stream (file) – The stream to read from.

    `write`(stream, data)

      Write the header string to stream.

      Parameters: | stream (file) – The stream to write to.

  class `TriFormat.``Header`(template=None, argument=None, parent=None)

    Bases: `pyffi.formats.tri._Header`, `pyffi.object_models.Data`

    A class to contain the actual tri data.

    `add_modifier`(name=None, relative_vertices=None)

      Add a modifier.

    `add_morph`(name=None, relative_vertices=None)

      Add a morph.

    `inspect`(stream)

      Quickly checks if stream contains TRI data, and reads everything up to the arrays.

      Parameters: | stream (file) – The stream to inspect.

    `inspect_quick`(stream)

      Quickly checks if stream contains TRI data, by looking at the first 8 bytes. Reads the signature and the version.

      Parameters: | stream (file) – The stream to inspect.

    `read`(stream)

      Read a tri file.

      Parameters: | stream (`file`) – The stream from which to read.

    `write`(stream)

      Write a tri file.

      Parameters: | stream (`file`) – The stream to which to write.

  class `TriFormat.``ModifierRecord`(template=None, argument=None, parent=None)

    Bases: `pyffi.object_models.xml.struct_.StructBase`

    A modifier replaces the vertices from the base model(Header.vertices) with those in Header.modifier_vertices. Notethat Header.modifier_vertices counts up from the first modifieronwards. For example, if you were to take the 4th vertex to bemodified in the 2nd modifier and the size of the 1st modifierwas 10 vertices, then you would needHeader.modifier_vertices[14]. Therefore,Header.num_modifier_vertices =sum(modifier.num_vertices_to_modify for modifier inHeader.modifiers).

    `modifier_vertices`

      The actual modifier vertices (copied from Header.modifier_vertices).

    `name`

      Name of the Modifier.

    `vertices_to_modify`

      List of Vertices To Modify.

  class `TriFormat.``MorphRecord`(template=None, argument=None, parent=None)

    Bases: `pyffi.formats.tri._MorphRecord`, `builtins.object`

        >>> # create morph with 3 vertices.
        >>> morph = TriFormat.MorphRecord(argument=3)
        >>> morph.set_relative_vertices(
        ...     [(3, 5, 2), (1, 3, 2), (-9, 3, -1)])
        >>> # scale should be 9/32768.0 = 0.0002746...
        >>> morph.scale
        0.0002746...
        >>> for vert in morph.get_relative_vertices():
        ...     print([int(1000 * x + 0.5) for x in vert])
        [3000, 5000, 2000]
        [1000, 3000, 2000]
        [-8999, 3000, -999]

    `apply_scale`(scale)

      Apply scale factor to data.

          >>> # create morph with 3 vertices.
          >>> morph = TriFormat.MorphRecord(argument=3)
          >>> morph.set_relative_vertices(
          ...     [(3, 5, 2), (1, 3, 2), (-9, 3, -1)])
          >>> morph.apply_scale(2)
          >>> for vert in morph.get_relative_vertices():
          ...     print([int(1000 * x + 0.5) for x in vert])
          [6000, 10000, 4000]
          [2000, 6000, 4000]
          [-17999, 6000, -1999]

  class `TriFormat.``QuadFace`(template=None, argument=None, parent=None)

    Bases: `pyffi.object_models.xml.struct_.StructBase`

    Not used by the Oblivion engine as it’s tri based.

  `TriFormat.``byte`

    alias of `Byte`

  `TriFormat.``char`

    alias of `Char`

  `TriFormat.``float`

    alias of `Float`

  `TriFormat.``int`

    alias of `Int`

  `TriFormat.``short`

    alias of `Short`

  `TriFormat.``ubyte`

    alias of `UByte`

  `TriFormat.``uint`

    alias of `UInt`

  `TriFormat.``ushort`

    alias of `UShort`

  static `TriFormat.``version_number`(version_str)

    Converts version string into an integer.

    Parameters: | version_str (str) – The version string.
    Returns: | A version integer.

        >>> TriFormat.version_number('003')
        3
        >>> TriFormat.version_number('XXX')
        -1

## Regression tests

### Read a TRI file

    >>> # check and read tri file
    >>> stream = open('tests/tri/mmouthxivilai.tri', 'rb')
    >>> data = TriFormat.Data()
    >>> data.inspect(stream)
    >>> # do some stuff with header?
    >>> data.num_vertices
    89
    >>> data.num_tri_faces
    215
    >>> data.num_quad_faces
    0
    >>> data.num_uvs
    89
    >>> data.num_morphs
    18
    >>> data.read(stream)
    >>> print([str(morph.name.decode("ascii")) for morph in data.morphs])
    ['Fear', 'Surprise', 'Aah', 'BigAah', 'BMP', 'ChJSh', 'DST', 'Eee', 'Eh', 'FV', 'I', 'K', 'N', 'Oh', 'OohQ', 'R', 'Th', 'W']

### Parse all TRI files in a directory tree

    >>> for stream, data in TriFormat.walkData('tests/tri'):
    ...     print(stream.name)
    tests/tri/mmouthxivilai.tri

### Create an TRI file from scratch and write to file

    >>> data = TriFormat.Data()
    >>> from tempfile import TemporaryFile
    >>> stream = TemporaryFile()
    >>> data.write(stream)

### Navigation

- index
- modules |
- next |
- previous |
- PyFFI 2.2.2 documentation »
- `pyffi` — Interfacing block structured files »
- `pyffi.formats` — File format interfaces »