Skip to content

FLAME

FLAME is a head model with shape, expression, neck, jaw, and eye controls.

Setup

FLAME requires registration at flame.is.tue.mpg.de.

body-models download flame

Or configure an existing file:

body-models set flame /path/to/FLAME_NEUTRAL.pkl

API

body_models.flame.numpy.FLAME

FLAME(*, model_path=None, rotation_type='axis_angle', simplify=1.0)

Bases: body_models.flame._model.FLAME

Skinned head model with shape and expression controls.

METHOD DESCRIPTION
apply_pose_correctives

Apply prepared pose correctives to identity-dependent rest vertices.

forward_points

Compute positions defined by a prepared vertex mapping.

forward_skeleton

Compute posed head joint transforms.

forward_vertices

Compute posed head vertices.

get_rest_pose

Construct canonical parameter defaults from :attr:parameter_spec.

joint_index

Resolve a common joint to this model's native joint index.

prepare_point_regressor

Preproject a vertex mapping and the model's linear identity bases.

prepare_identity

Precompute shape- and expression-dependent state.

prepare_pose

Precompute pose-dependent state for repeated forward passes.

ATTRIBUTE DESCRIPTION
common_joints

Common anatomical joints mapped to this model's native joint names.

has_face

bool(x) -> bool

has_hands

bool(x) -> bool

num_joints

Number of joints in the skeleton.

pose_joint_indices

Canonical joints whose local transforms are driven by each pose parameter.

runtime

Array runtime used by this model.

skinning_spec

Static topology, render-rig weights, and optional pose correctives.

symmetric_joints

Left/right joint pairs as (left_index, right_index), in joint order.

NUM_EXPR_COEFFS

int([x]) -> integer

NUM_HEAD_CONTROLS

int([x]) -> integer

NUM_JOINTS

int([x]) -> integer

NUM_SHAPE_COEFFS

int([x]) -> integer

common_joints property

common_joints

Common anatomical joints mapped to this model's native joint names.

has_face class-attribute

has_face = True

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

has_hands class-attribute

has_hands = False

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

num_joints property

num_joints

Number of joints in the skeleton.

pose_joint_indices property

pose_joint_indices

Canonical joints whose local transforms are driven by each pose parameter.

runtime property

runtime

Array runtime used by this model.

skinning_spec property

skinning_spec

Static topology, render-rig weights, and optional pose correctives.

symmetric_joints property

symmetric_joints

Left/right joint pairs as (left_index, right_index), in joint order.

Indices address the J axis of :meth:forward_skeleton outputs and cover the whole native skeleton, including joints outside the :class:Joint vocabulary. Unpaired joints lie on the midline. Pairs describe index correspondence only, not how to mirror a pose.

RAISES DESCRIPTION
ValueError

If a sided joint name has no counterpart.

NUM_EXPR_COEFFS class-attribute

NUM_EXPR_COEFFS = 100

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

int('0b100', base=0) 4

NUM_HEAD_CONTROLS class-attribute

NUM_HEAD_CONTROLS = 4

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

int('0b100', base=0) 4

NUM_JOINTS class-attribute

NUM_JOINTS = 5

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

int('0b100', base=0) 4

NUM_SHAPE_COEFFS class-attribute

NUM_SHAPE_COEFFS = 300

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal.

int('0b100', base=0) 4

apply_pose_correctives

apply_pose_correctives(*, identity, pose)

Apply prepared pose correctives to identity-dependent rest vertices.

Source code in src/body_models/_base.py
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
def apply_pose_correctives(
    self,
    *,
    identity: SkinningIdentity,
    pose: SkinningPose,
) -> Float[Array, "*batch V 3"]:
    """Apply prepared pose correctives to identity-dependent rest vertices."""
    vertices = identity["rest_vertices"]
    coefficients = pose.get("pose_coefficients")
    if coefficients is None:
        return vertices
    basis = self._corrective_basis
    if basis is None:
        raise RuntimeError("Prepared pose has corrective coefficients, but the model has no corrective basis.")
    return vertices + basis.apply(coefficients)

forward_points

forward_points(
    head_pose,
    *,
    point_regressor,
    head_rotation=None,
    shape=None,
    expression=None,
    identity=None,
    global_rotation=None,
    global_translation=None,
)

Compute positions defined by a prepared vertex mapping.

Source code in src/body_models/flame/_model.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
def forward_points(
    self,
    head_pose: Float[Array, "*batch 4 N"] | Float[Array, "*batch 4 3 3"],
    *,
    point_regressor: PointRegressor,
    head_rotation: Float[Array, "*batch N"] | Float[Array, "*batch 3 3"] | None = None,
    shape: Float[Array, "*batch S"] | None = None,
    expression: Float[Array, "*batch E"] | None = None,
    identity: LinearIdentity | None = None,
    global_rotation: Float[Array, "*batch N"] | Float[Array, "*batch 3 3"] | None = None,
    global_translation: Float[Array, "*batch 3"] | None = None,
) -> Float[Array, "*batch K 3"]:
    """Compute positions defined by a prepared vertex mapping."""
    self._validate_identity_arguments(identity, shape=shape, expression=expression)
    if identity is not None:
        pose = self.prepare_pose(head_pose, head_rotation=head_rotation, identity=identity)
        return self._deform_points(point_regressor, identity, pose, global_rotation, global_translation)

    batch_shape = head_pose.shape[: -(self._num_rot_dims + 1)]
    resolved = self._resolve_identity_coefficients(batch_shape, shape=shape, expression=expression)
    skeleton_identity = self._prepare_skeleton_identity(*resolved)
    pose = self.prepare_pose(head_pose, head_rotation=head_rotation, identity=skeleton_identity)
    return self._deform_linear_points(
        point_regressor,
        resolved,
        pose,
        global_rotation,
        global_translation,
    )

forward_skeleton

forward_skeleton(
    head_pose,
    *,
    head_rotation=None,
    shape=None,
    expression=None,
    identity=None,
    global_rotation=None,
    global_translation=None,
    joint_indices=None,
)

Compute posed head joint transforms.

Source code in src/body_models/flame/_model.py
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def forward_skeleton(
    self,
    head_pose: Float[Array, "*batch 4 N"] | Float[Array, "*batch 4 3 3"],
    *,
    head_rotation: Float[Array, "*batch N"] | Float[Array, "*batch 3 3"] | None = None,
    shape: Float[Array, "*batch S"] | None = None,
    expression: Float[Array, "*batch E"] | None = None,
    identity: LinearIdentity | None = None,
    global_rotation: Float[Array, "*batch N"] | Float[Array, "*batch 3 3"] | None = None,
    global_translation: Float[Array, "*batch 3"] | None = None,
    joint_indices: Sequence[int] | None = None,
) -> Float[Array, "*batch 5 4 4"]:
    """Compute posed head joint transforms."""
    self._validate_identity_arguments(identity, shape=shape, expression=expression)
    if identity is None:
        batch_shape = head_pose.shape[: -(self._num_rot_dims + 1)]
        resolved = self._resolve_identity_coefficients(batch_shape, shape=shape, expression=expression)
        skeleton_identity = self._prepare_skeleton_identity(*resolved)
    else:
        skeleton_identity = identity

    skeleton = core.prepare_skeleton(
        self._runtime,
        self._assets.kinematic_tree,
        head_pose,
        head_rotation,
        self.rotation_type,
        local_joint_offsets=skeleton_identity["local_joint_offsets"],
        joint_indices=joint_indices,
    )
    return self._transform_skeleton(
        skeleton,
        global_rotation,
        global_translation,
    )

forward_vertices

forward_vertices(
    head_pose,
    *,
    head_rotation=None,
    shape=None,
    expression=None,
    identity=None,
    global_rotation=None,
    global_translation=None,
    vertex_indices=None,
)

Compute posed head vertices.

Source code in src/body_models/flame/_model.py
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def forward_vertices(
    self,
    head_pose: Float[Array, "*batch 4 N"] | Float[Array, "*batch 4 3 3"],
    *,
    head_rotation: Float[Array, "*batch N"] | Float[Array, "*batch 3 3"] | None = None,
    shape: Float[Array, "*batch S"] | None = None,
    expression: Float[Array, "*batch E"] | None = None,
    identity: LinearIdentity | None = None,
    global_rotation: Float[Array, "*batch N"] | Float[Array, "*batch 3 3"] | None = None,
    global_translation: Float[Array, "*batch 3"] | None = None,
    vertex_indices: Sequence[int] | None = None,
) -> Float[Array, "*batch V 3"]:
    """Compute posed head vertices."""
    self._validate_identity_arguments(identity, shape=shape, expression=expression)
    if identity is None:
        batch_shape = head_pose.shape[: -(self._num_rot_dims + 1)]
        resolved = self._resolve_identity_coefficients(batch_shape, shape=shape, expression=expression)
        identity = self.prepare_identity(*resolved)

    pose = self.prepare_pose(head_pose, head_rotation=head_rotation, identity=identity)
    return self._deform_vertices(
        identity,
        pose,
        global_rotation,
        global_translation,
        vertex_indices,
    )

get_rest_pose

get_rest_pose(*, batch_dims=(), dtype=None)

Construct canonical parameter defaults from :attr:parameter_spec.

PARAMETER DESCRIPTION
batch_dims

Leading batch dimensions.

TYPE: tuple[int, ...] DEFAULT: ()

dtype

Optional floating-point dtype.

TYPE: Any | None DEFAULT: None

RETURNS DESCRIPTION
dict[str, Float[Any, ...]]

Complete model parameters at rest.

Source code in src/body_models/_base.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
def get_rest_pose(
    self,
    *,
    batch_dims: tuple[int, ...] = (),
    dtype: Any | None = None,
) -> dict[str, Float[Array, "..."]]:
    """
    Construct canonical parameter defaults from :attr:`parameter_spec`.

    Args:
        batch_dims: Leading batch dimensions.
        dtype: Optional floating-point dtype.

    Returns:
        Complete model parameters at rest.
    """
    return {name: self._parameter_default(spec, batch_dims, dtype) for name, spec in self.parameter_spec.items()}

joint_index

joint_index(joint)

Resolve a common joint to this model's native joint index.

Source code in src/body_models/_base.py
173
174
175
176
177
178
179
180
181
def joint_index(self, joint: Joint) -> int:
    """Resolve a common joint to this model's native joint index."""
    if not isinstance(joint, Joint):
        raise TypeError("joint_index() expects a body_models.Joint; use joint_names.index(...) for native names.")
    try:
        native_name = self.common_joints[joint]
    except KeyError as exc:
        raise KeyError(f"{self.__class__.__name__} has no common joint {joint.value!r}") from exc
    return self.joint_names.index(native_name)

prepare_point_regressor

prepare_point_regressor(mapping)

Preproject a vertex mapping and the model's linear identity bases.

Source code in src/body_models/_linear_blendshape.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def prepare_point_regressor(
    self,
    mapping: Float[Array, "K V"],
) -> PointRegressor:
    """Preproject a vertex mapping and the model's linear identity bases."""
    regressor = super().prepare_point_regressor(mapping)
    xp = self._runtime.xp
    regressor["template"] = point_regression.project_vertex_values(
        regressor,
        self.rest_vertices,
        xp=xp,
    )
    regressor["identity_bases"] = tuple(
        point_regression.project_vertex_values(regressor, basis, xp=xp) for basis in self._point_identity_bases
    )
    return regressor

prepare_identity

prepare_identity(shape, expression)

Precompute shape- and expression-dependent state.

Source code in src/body_models/flame/_model.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def prepare_identity(
    self,
    shape: Float[Array, "*batch S"],
    expression: Float[Array, "*batch E"],
) -> LinearIdentity:
    """Precompute shape- and expression-dependent state."""
    return core.prepare_identity(
        xp=self._runtime.xp,
        v_template=self._assets.v_template,
        shapedirs=self._assets.shapedirs,
        exprdirs=self._assets.exprdirs,
        j_template=self._assets.j_template,
        j_shapedirs=self._assets.j_shapedirs,
        j_exprdirs=self._assets.j_exprdirs,
        parents=self._assets.kinematic_tree.parents,
        shape=shape,
        expression=expression,
    )

prepare_pose

prepare_pose(head_pose, *, head_rotation=None, identity)

Precompute pose-dependent state for repeated forward passes.

Source code in src/body_models/flame/_model.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
def prepare_pose(
    self,
    head_pose: Float[Array, "*batch 4 N"] | Float[Array, "*batch 4 3 3"],
    *,
    head_rotation: Float[Array, "*batch N"] | Float[Array, "*batch 3 3"] | None = None,
    identity: core.FlameSkeletonIdentity,
) -> SkinningPose:
    """Precompute pose-dependent state for repeated forward passes."""
    return core.prepare_pose(
        self._runtime,
        self._assets.kinematic_tree,
        head_pose=head_pose,
        head_rotation=head_rotation,
        rotation_type=self.rotation_type,
        local_joint_offsets=identity["local_joint_offsets"],
        rest_joints=identity["rest_joints"],
    )