Triptych Split
Cut the animated canvas back into three columns, per frame
- frames
- layout
- view_a
- view_b
- view_c
- names
This is Triptych Compose running backwards. Compose glued three orthographic views into one canvas so a video model would animate them together; Split takes the animated clip back apart and hands you three clean per-view batches, in keyframe order, ready for a contact sheet and a rigger.
It's a pure geometry node - no pixels are invented, nothing is resampled unless it has to be - and almost all of its correctness comes from the layout JSON rather than from anything clever in the code.
How it works
Per frame, in order:
- Read the layout. It carries the canvas size, the background colour, and each panel's x/y/w/h. The panels are never re-derived from the image; the geometry is read back. That's the whole reason a layout that travelled as a sidecar JSON exists - if the clip came back resized or letterboxed, the boxes would be wrong, and no amount of pixel inspection would tell you where the right columns were.
- If the layout carries a
transform(i.e. Triptych Register ran), resample the frame by that scale, paste it at the recovered offset onto a canvas of the layout's size, then crop. This is the correct path. - If there's no transform and the frame size differs from the layout, it resizes with LANCZOS to the layout size. That is a plain stretch, and it's only correct when the model preserved the aspect ratio exactly.
- Crop each panel box out of the frame, appending to that view's list.
You get back three IMAGE batches with one panel per keyframe, plus the view order as a string.
Inputs and outputs
frames - the batch from Sample Keyframes (16 of them, usually). layout - and this is where people go wrong: it must be the layout that came out of Triptych Register, not the one straight from Compose. Same type, same shape, different numbers.
view_a, view_b, view_c - three IMAGE batches, one per orthographic view, each N frames long, in the same keyframe order as the input. Wire all three into Keyframe Sheet, Save Keyframe Manifest and Identity QA. There is no "animate" output and nothing here goes back to a video model; the sheet is the terminal artefact.
names - the panel order joined with commas, e.g. front,side,back. It's a string you could just type into the next three nodes, and wiring it instead is worth the two extra noodles: the labels can then never disagree with which crop went where.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/meryboth/from-mesh-to-motion
# restart ComfyUI
Or ComfyUI Manager → from-mesh-to-motion, or comfy node install from-mesh-to-motion. Pillow and numpy, nothing downloaded, no GPU. Nothing in this pack touches a model; the only heavy node in the reference graph is the MiniMax partner node, which runs on Comfy's side and bills per call.
Where people get burned
Skipping Register. Without a transform, Split stretches any frame whose size doesn't match the layout. If the provider returned a rescaled canvas that's a silent 2% shear; if it letterboxed, the outer panels are half background. There's no warning at this step, which is why Register prints one.
Swapping the layout. Compose's layout and Register's layout are both FMM_LAYOUT, so ComfyUI will happily accept the wrong one. The failure looks like a slightly-off crop rather than a hard error, and it gets worse the further you are into the clip.
Panel order coming from the wrong place. The order is Compose's names widget, so if you typed side,front,back there, your "front" column is the side view and every downstream label is a lie. It won't look broken. Front and back views of a chunky character are easy to confuse at thumbnail size - which is exactly why the contact sheet prints the names.
Batches of different lengths. Save Keyframe Manifest and Keyframe Sheet both use the shortest of the three batches. If one view somehow ends up short, you get a quiet truncation rather than an error.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| frames | IMAGE | — | |
| layout | FMM_LAYOUT | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| view_a | IMAGE | — |
| view_b | IMAGE | — |
| view_c | IMAGE | — |
| names | STRING | — |