pyffi.formats.egm — EGM (.egm)

An .egm file contains facial shape modifiers, that is, morphs that modify static properties of the face, such as nose size, chin shape, and so on.

Implementation

class pyffi.formats.egm.EgmFormat

Bases: pyffi.object_models.xml.FileFormat

This class implements the EGM format.

class Data(version=2, num_vertices=0)

Bases: pyffi.object_models.Data

A class to contain the actual egm data.

add_asym_morph()

Add an asymmetric morph, and return it.

add_sym_morph()

Add a symmetric morph, and return it.

apply_scale(scale)

Apply scale factor to all morphs.

inspect(stream)

Quickly checks if stream contains EGM data, and reads the header.

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

Quickly checks if stream contains EGM data, and gets the version, by looking at the first 8 bytes.

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

Read a egm file.

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

Write a egm file.

Parameters:stream (file) – The stream to which to write.
class EgmFormat.FileSignature(**kwargs)

Bases: pyffi.object_models.xml.basic.BasicBase

Basic type which implements the header of a EGM 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 EgmFormat.MorphRecord(template=None, argument=None, parent=None)

Bases: pyffi.formats.egm._MorphRecord

>>> # create morph with 3 vertices.
>>> morph = EgmFormat.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 = EgmFormat.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]
EgmFormat.byte

alias of Byte

EgmFormat.char

alias of Char

EgmFormat.float

alias of Float

EgmFormat.int

alias of Int

EgmFormat.short

alias of Short

EgmFormat.ubyte

alias of UByte

EgmFormat.uint

alias of UInt

EgmFormat.ushort

alias of UShort

static EgmFormat.version_number(version_str)

Converts version string into an integer.

Parameters:version_str (str) – The version string.
Returns:A version integer.
>>> EgmFormat.version_number('002')
2
>>> EgmFormat.version_number('XXX')
-1

Regression tests

Read a EGM file

>>> # check and read egm file
>>> stream = open('tests/egm/mmouthxivilai.egm', 'rb')
>>> data = EgmFormat.Data()
>>> data.inspect_quick(stream)
>>> data.version
2
>>> data.inspect(stream)
>>> data.header.num_vertices
89
>>> data.header.num_sym_morphs
50
>>> data.header.num_asym_morphs
30
>>> data.header.time_date_stamp
2001060901
>>> data.read(stream)
>>> data.sym_morphs[0].vertices[0].x
17249

Parse all EGM files in a directory tree

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

Create an EGM file from scratch and write to file

>>> data = EgmFormat.Data(num_vertices=10)
>>> data.header.num_vertices
10
>>> morph = data.add_sym_morph()
>>> len(morph.vertices)
10
>>> morph.scale = 0.4
>>> morph.vertices[0].z = 123
>>> morph.vertices[9].x = -30000
>>> morph = data.add_asym_morph()
>>> morph.scale = 2.3
>>> morph.vertices[3].z = -5
>>> morph.vertices[4].x = 99
>>> from tempfile import TemporaryFile
>>> stream = TemporaryFile()
>>> data.write(stream)