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
[source]¶ Bases:
pyffi.object_models.xml.FileFormat
This class implements the EGM format.
-
class
Data
(version=2, num_vertices=0)[source]¶ Bases:
pyffi.object_models.Data
A class to contain the actual egm data.
-
get_detail_child_names
(edge_filter=(True, True))[source]¶ Generator which yields all child names of this item in the detail view.
Override this method if the node has children.
- Returns
Generator for detail tree child names.
- Return type
generator yielding
str
s
-
get_detail_child_nodes
(edge_filter=(True, True))[source]¶ Generator which yields all children of this item in the detail view (by default, all acyclic and active ones).
Override this method if the node has children.
- Parameters
edge_filter (
EdgeFilter
ortype(None)
) – The edge type to include.- Returns
Generator for detail tree child nodes.
- Return type
generator yielding
DetailNode
s
-
get_global_child_nodes
(edge_filter=(True, True))[source]¶ Generator which yields all children of this item in the global view, of given edge type (default is edges of type 0).
Override this method.
- Returns
Generator for global node children.
-
inspect
(stream)[source]¶ Quickly checks if stream contains EGM data, and reads the header.
- Parameters
stream (file) – The stream to inspect.
-
-
class
FileSignature
(**kwargs)[source]¶ Bases:
pyffi.object_models.xml.basic.BasicBase
Basic type which implements the header of a EGM file.
-
get_hash
(data=None)[source]¶ Return a hash value for this value.
- Returns
An immutable object that can be used as a hash.
-
get_size
(data=None)[source]¶ Return number of bytes the header string occupies in a file.
- Returns
Number of bytes.
-
-
class
FileVersion
(template=None, argument=None, parent=None)[source]¶ Bases:
pyffi.object_models.xml.basic.BasicBase
-
class
MorphRecord
(template=None, argument=None, parent=None)[source]¶ Bases:
pyffi.formats.egm._MorphRecord
,object
>>> # 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)[source]¶ 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]
-
-
byte
¶ alias of
pyffi.object_models.common.Byte
-
char
¶ alias of
pyffi.object_models.common.Char
-
float
¶ alias of
pyffi.object_models.common.Float
-
int
¶ alias of
pyffi.object_models.common.Int
-
short
¶ alias of
pyffi.object_models.common.Short
-
ubyte
¶ alias of
pyffi.object_models.common.UByte
-
uint
¶ alias of
pyffi.object_models.common.UInt
-
ushort
¶ alias of
pyffi.object_models.common.UShort
-
class
Regression tests¶
Read a EGM file¶
>>> # check and read egm file
>>> from os.path import dirname
>>> dirpath = __file__
>>> for i in range(4): #recurse up to root repo dir
... dirpath = dirname(dirpath)
>>> repo_root = dirpath
>>> format_root = os.path.join(repo_root, 'tests', 'formats', 'egm')
>>> file = os.path.join(format_root, 'mmouthxivilai.egm')
>>> stream = open(file, '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(format_root):
... try:
... # the replace call makes the doctest also pass on windows
... os_path = stream.name
... split = (os_path.split(os.sep))[-4:]
... rejoin = os.path.join(*split).replace(os.sep, "/")
... print("reading %s" % rejoin)
... except Exception:
... print(
... "Warning: read failed due corrupt file,"
... " corrupt format description, or bug.")
reading tests/formats/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)