Compose¶
Compose 把你 author 的一切 — pose layer 及其 key、control、knob、driver、constraint、visibility group、look-at — 变成 Harmony 场景里一个真正的 Master Controller 节点,以及这个节点需要的文件。
这是 ORC 里唯一会写入你场景的功能。
MC 的名字¶
在 MC Name 里输入一个名字。不需要自己加后缀:
| 你按下 | ORC 做的事 |
|---|---|
| Enter,或点到别处 | 如果还没有后缀就追加 -MC。Head → Head-MC。 |
| 再按一次 Enter | 点击 Compose。 |
这个检查不区分大小写,所以你输入的 head-mc 会原样保留。
除此之外没有别的校验 — 不剥离字符,不做唯一性检查。最终的节点名由 Harmony 决定,所以一个冲突的名字可能会带着改动回来,ORC 会报告它实际拿到的名字。
Compose 为什么会被禁用¶
tooltip 永远就是原因,而且永远是你能处理的东西:
| Tooltip | 解决办法 |
|---|---|
| Enter a name for the Master Controller first. | 输入一个名字。 |
| The "Eyebrows" pose layer has no keys yet. Stamp a snap with F6 or delete the empty layer. | 给它打 key,或者删掉它。 |
| 3 layers are keyed but have no targets (…). Add what each one should move to its target list. | 给它们指定 target。什么都不驱动的 widget 是不能上线的。 |
| Nothing to compose yet. Add poses, drivers, constraints, or look-ats — or set both Front and Back MC to bake a merged runtime. | rig 里什么都没有。 |
当名字已填好、没有半成品 layer,并且以下至少满足一项时,Compose 才会启用:
- 任意地方至少有一个 pose key,
- Front 和 Back MC 都已设置(你在合并它们),
- 零个 pose layer,但至少有一个 driver、constraint 或已启用的 look-at — 一个只有自动化的 rig 也能正常 compose。
那些从不需要 key 的 layer — control 的 face、knob、导入的 grid — 都是例外。
会阻止它的两种情况¶
Blocker — 直接拒绝¶
| 冲突 | 为什么行不通 |
|---|---|
| Knob 冲突 | 两个或以上的 extra knob 写同一个节点和 channel。runtime 只为每个节点和 attribute 捕获一份原始 base,所以这些写入无法叠加 — 最后一个会悄悄胜出。 |
| Drawing 冲突 | 一个 READ 节点被两个或以上的同级(sibling) layer 替换。drawing 的切换是离散的,不能混合,而且没有任何东西给同级排优先级。 |
你会看到一行红字点名冲突,Compose 也不会开始。出问题的 Outliner 行也会变红。
在层级(hierarchy)下方共享的 drawing 切换是没问题的 — 更深的 layer 胜出是有意为之的。
Warning — 确认后继续¶
如果只是有些可疑,按钮会变成 CONFIRM?,持续五秒,旁边列出清单。让它倒数结束,它就会变回 Compose。
No pose data loadedNo Front or Back face: import an MC or author one— 只有两者都没有时才出现。只有 Front 是正常的。Driver 'Blink' (Eyelids) has no keyed valuesConstraint 'Arm Follow' has no target nodesConstraint 'Arm Follow' has no channels selected
Compose Settings¶
| 设置 | 决定的内容 |
|---|---|
Save states / script to |
.tbState 文件、runtime 脚本和 ORC 数据文件写入的位置。默认是你场景的 scripts 文件夹。 |
Connect MC to composite |
新 MC 连接到哪个 Composite。ORC 会预选一个最佳猜测,但场景里的完整 composite 列表始终可选。 |
这个猜测是怎么来的
这个选择是从 rig 本身推导出来的,而不是列表顺序。
首先 ORC 找到 rig 的 main group:target 列表里的每个节点都为它所有的祖先 group 投票,占多数的最深 group 获胜。深度正是防止 deformation group 抢票的关键 — 它永远只包含自己那一小撮成员,所以多数票总会落在它外面的角色 group 上。
在那个 group 内部,按顺序第一个匹配的胜出:
- 已经有 MC 连接的 composite — MC 连接数最多的优先。如果它在 main group 内部,直接胜出。
- 名字符合 master-controller 命名习惯的 composite —
master-controller、masters、controllers、ctrl、-MC…… - 该 group 的 main composite — 也就是喂给它 Multi-Port-Out 的那个。
- group 里根本没有 composite → 那就是 group 节点自身在外部喂给的那个。
什么都不匹配 → 场景里的第一个 composite。不管选中什么,这都只是一个预选 — 下拉框始终列出场景里的每一个 composite。
两次 Compose 之间保持同一个输出文件夹
增量缓存就存在那里。复用文件夹正是让 re-compose 变快的原因。
如果没有选中任何 composite,MC 会创建在 Top 下,不连接任何东西。否则它会创建在那个 composite 的父 group 里,并放在 Node View 中紧邻其上方的位置,方便你找到它。
会发生什么¶
四个阶段,全部实时报告:
| 阶段 | 产出 |
|---|---|
Slicing state files… |
.tbState pose 堆栈,每个 layer/side/page 一份,外加清单。详细行会准确点名当前位置:"Layer 'Eyebrows-L' — Pose 3 of 25 · Knob 2 of 13"。 |
Constraint pre-wiring… |
记录每个 constraint 原来的列,以便它的开关能恢复它们。 |
Generating MC script… |
MC 将要执行的 runtime 脚本。 |
Assembling MC node in Harmony… |
节点本身、它的 attribute、UI 脚本和数据,以及 ORC 自己的数据块。 |
下方的 Recent activity 日志会保留带时间戳的记录,包括任何 warning。
一次 Ctrl+Z 就能撤销一次 Compose
整个组装过程都在一个名为 ORC Compose 的单一 Harmony undo 步骤内运行。
slicing 阶段确实会写列 — 这是它读取你的 pose 的方式 — 但那些写入是临时的、会被丢弃的,而且不管 Compose 成功、失败还是被取消,你的 pose 之后都会被恢复。
取消¶
Cancel 是两次点击确认:第一次点击让它武装四秒(CONFIRM? (4s)),第二次点击才真正取消。窗口的 ✕ 行为相同 — 正在运行的 Compose 不会直接关闭。Enter 永远不会触发 Cancel,所以一次无意识的按键不会中断一个半成品的 MC。
取消是协作式的:它会在下一个安全边界停下,而不是在调用中途,所以你会看到 "Will stop after the current Harmony call returns…"。
取消会留下什么:
- 在 slicing 期间取消:已经写入的
.tbState文件会保留,缓存也会保存,让这些工作计入下一次运行。不会创建 MC 节点。 - 在组装已经开始后取消:节点已经存在。整个 compose 没有事务性可言,
ORC Compose这一步的 Ctrl+Z 就是回退的办法。 - 不管哪种情况,你的 pose 都会被恢复。
结束的方式¶
| 结果 | 意味着什么 |
|---|---|
| Compose complete — Top/robin-head-MC | 12 state stack(s), 2 constraint(s) | 完成了。Node View 会平移到新节点并选中它。 |
| Compose finished with 3 warning(s) — see the log | MC 已经存在并能工作,但某个非致命的步骤出了问题。去读日志。 |
| Compose failed — no state files produced | 没有任何东西可切片。 |
| Compose failed — script generation error | |
| Compose failed — MC assembly error: … |
落到磁盘上的文件¶
在你选择的输出文件夹里:
| 文件 | 是什么 |
|---|---|
<Stack>.tbState,或 <Stack>/0.tbState、1.tbState…… |
pose 堆栈。带 knob 的 layer 会得到一个文件夹,每个 knob 位置一个文件 — 这是 Toon Boom 自己的原生布局。 |
<folder>_compose_state.json |
runtime 清单。 |
<name>_orc.js |
生成的 runtime 脚本。 |
orc_pose_data.json |
你整个 rig 的配置 — re-edit 和独立版 Widget Editor 的数据源。 |
orc_session_state.json |
authoring UI 的状态,重新打开时用来恢复你的工作区。 |
.orc_cache/snaps.json |
增量 compose 缓存。不属于 rig 的一部分,删掉也安全。 |
堆栈名字派生自你的 layer 名字 — Eyebrows 和 Eyebrow 都会变成 Eyebrow,side 会追加 L/R,back 堆栈追加 Back,page 追加它的编号。
落到节点上的东西¶
除了 runtime 脚本及其数据外,ORC 还会向 MC 节点写入三块自己的数据:你的 pose 数据、会话状态和清单。它们只有在足够小的时候才会内嵌;更大的会留在磁盘上,因为把几兆的文本内嵌进 Harmony attribute,读取时会让它的脚本引擎崩溃。
一个小小的指针 attribute 记录着输出文件夹的场景相对路径,re-edit 和 unroll 正是靠它找到其余文件的。
把输出文件夹和场景放在一起
MC 在运行时会从磁盘读取状态文件。移动场景却不带上它们,rig 就没有 pose 可以加载了。路径是以场景相对方式存储的,所以把两者一起移动是安全的。
重新 Compose¶
对同一个 rig 再次 Compose 是正常且预期的行为 — 这就是你迭代的方式。
因为 ORC 存储的是帧引用而不是烘焙好的 pose,你可以回到第 861 帧,修好那道眉毛,再重新 compose:改动会被采纳。不需要重新打 key。
增量缓存意味着 re-compose 只会重新切片真正变化的部分,这也是保持同一个输出文件夹很重要的原因。
相关¶
- Keying & Auto-Capture — Compose 读取的内容
- Re-editing a Composed MC — 重新进入
- Unroll — 反方向操作
- Troubleshooting

