cutan.expression.registration¶
The face side of the cut-out genre, as declarations: expression and [emotion].
What the cut-out genre (cutan.genre) registers from here:
the ``expression`` action kind —
ExpressionAction(hold a facial expression, an#98): zero-width in asequencewhen it runs to the shot end, and itsscene.mdspelling;the ``[emotion]`` dialogue sugar —
maya [happy]: Hi!fillsan.ir.schema.Dialogue.emotion, which the expression provider turnsinto an expression over the line, in memory only.
Plain declarations: importing this module registers nothing.
>>> EXPRESSION.name, EMOTION.opener, EMOTION.parse(" Happy ")
('expression', '[', {'emotion': 'happy'})
Module Attributes
Default ramp in/out of an expression, seconds (0 = cut). |
|
a preset name ( |
|
The Dialogue field an |
Functions
|
Hold a facial expression on an entity (an#98). |
|
An expression's span: its |
|
The |
|
|
|
|
|
The |
Classes
|
Hold a facial expression on an entity (an#98, epic #9 Wave 6). |
- cutan.expression.registration.DFLT_EXPRESSION_BLEND_S: float = 0.15¶
Default ramp in/out of an expression, seconds (0 = cut). The dialogue
[emotion]sugar uses its own inan.expression.provider.
- cutan.expression.registration.EMOTION_INTENSITY_FIELD: str = 'emotion_intensity'¶
The Dialogue field an
[emotion level]sets beside the emotion (an#253).
- cutan.expression.registration.EMOTION_NAME_RE = re.compile('[\\w-]+')¶
a preset name (
happy,wry-smile).- Type:
What an emotion name may be
- class cutan.expression.registration.ExpressionAction(*, name=None, kind='expression', target, preset=None, axes=<factory>, intensity=1.0, duration=None, blend=0.15, **extra_data)[source]¶
Bases:
ExtensionActionHold a facial expression on an entity (an#98, epic #9 Wave 6).
presetnames one ofan.expression.presets.PRESETS;axesare per-axis overrides layered on it (axis units, seean.expression.axes);None+ no axes is a cheap “return to rest”.duration=Noneruns to the shot end (the looping-play rule) and is zero-width in a sequence, like a loopingplay.blendramps the intensity in and out; two overlapping expressions cross-fade because the face solver sums offsets. The dialoguespeaker [emotion]: …bracket is sugar for one of these over the line, desugared in memory only.A leaf action, flattened like
play: the compiler resolves it in the face solver (one channel per(node, property)), never per action.The ramp is a min over the two ends, so a span shorter than
2·blendnever reaches full intensity (a 0.2 s expression at the default 0.15 s blend peaks at 0.67) and aduration=0expression shows only where a frame lands on it withblend=0— cut the blend for a flash.
- cutan.expression.registration.expression(target, preset=None, *, axes=None, intensity=1.0, duration=None, blend=0.15)[source]¶
Hold a facial expression on an entity (an#98).
duration=Noneruns to the shot end and counts as zero in asequence, as a loopingplaydoes:>>> [f.start for f in flatten(sequence(expression("a", "happy"), delay(1.0), expression("a", "sad")))] [0.0, 1.0] >>> flatten(expression("a", "angry", duration=2.0))[0].end 2.0- Return type:
- cutan.expression.registration.expression_duration(action, extent)[source]¶
An expression’s span: its
duration, else zero (it runs to the shot end).>>> expression_duration(ExpressionAction(target="a", duration=2.0), None) 2.0 >>> expression_duration(ExpressionAction(target="a"), None) 0.0- Return type:
- cutan.expression.registration.format_emotion(line)[source]¶
The
[…]content forline(angry 0.4with an intensity), orNonewhen it carries no emotion.
- cutan.expression.registration.parse_emotion(content)[source]¶
[happy]’s content to the line’s emotion, lower-cased, and[angry 0.4]’s to the emotion and its intensity (0..1, an#253); refuse anything else.>>> parse_emotion("Happy"), parse_emotion(" angry 0.4 ") ({'emotion': 'happy'}, {'emotion': 'angry', 'emotion_intensity': 0.4})
- cutan.expression.registration.read_expression_md(item, *, index)[source]¶
{kind: expression, target, [preset], [axes], [intensity], [duration], [blend]}.Landed with its writer and round trip in one commit (an#98): the writer skips unknown leaves, so a parser-only entry would vanish from scene.md on the next sync and then from the JSON on the next md edit.
- Return type: