cutan.expression.provider¶
The expression provider: authored leaves + dialogue sugar → per-axis curves (an#98).
The face solver in the cutout compiler sums contributors per (node,
property) at compile time. It gets those contributors from an
ExpressionProvider — the seam an audio- or vision-driven source
plugs into later. The default provider composes, for one entity of one shot:
every
expressionleaf action (flattened out of the shot’s composition tree with its absolute times);the dialogue sugar: a line’s
[emotion]becomes an expression over the line, in memory only — never written intoshot.actionsor the scenes store, or the md writer would emit the emotion twice.
Each span ramps its intensity in and out over blend seconds (0 = cut);
two overlapping spans cross-fade because the sum is additive. Curves are
sampled per frame, so the solver and this module agree on time by
construction.
>>> from an.ir.schema import AssetRef, Dialogue, Shot
>>> from cutan.expression.registration import expression
>>> shot = Shot(id="s", renderer="cutout", duration=1.0,
... entities=[AssetRef(kind="character", id="c", store="characters", ref="c")],
... actions=[expression("c", "angry", blend=0.0)])
>>> [s.preset for s in expression_spans(shot, "c")]
['angry']
>>> curves = {c.axis: c for c in DefaultExpressionProvider().curves(shot, "c", fps=4)}
>>> curves["brow_angle_l"].samples
(-0.8, -0.8, -0.8, -0.8, -0.8)
Module Attributes
The |
Functions
|
Every expression contributor on |
|
The shot's |
Classes
|
One axis sampled at the frame times |
Sum of the shot's expression spans on the entity, ramped, per frame. |
|
|
The seam: whatever produces per-axis curves for one entity of one shot. |
|
One expression contributor on one entity, in absolute shot time. |
- class cutan.expression.provider.AxisCurve(axis, samples)[source]¶
Bases:
objectOne axis sampled at the frame times
0, 1/fps, …, n/fps(offline, deterministic).
- cutan.expression.provider.DIALOGUE_EMOTION_BLEND_S: float = 0.15¶
The
[emotion]sugar ramps in and out over this; it is a comment on the line, not a cut.
- class cutan.expression.provider.DefaultExpressionProvider[source]¶
Bases:
objectSum of the shot’s expression spans on the entity, ramped, per frame.
- mouth_preset_at(shot, entity_id, t)[source]¶
The preset whose mouth form is in force at
t: the heaviest span attthat prefers a form, orNone(the neutral set).Whole-line by construction when called at a line’s start — the solver asks once per line, never per frame, so at most one mouth swap property is live per instant.
- class cutan.expression.provider.ExpressionProvider(*args, **kwargs)[source]¶
Bases:
ProtocolThe seam: whatever produces per-axis curves for one entity of one shot.
- class cutan.expression.provider.ExpressionSpan(start, end, preset, axes=dict(), intensity=1.0, blend=0.0, source='action')[source]¶
Bases:
objectOne expression contributor on one entity, in absolute shot time.