TF Shape Edit
Move a region's boundary without changing what it is
- levels
- regions
- boundary_tokens
- receiving_tokens
- levels
- info
TF Feature Edit changes what a region is. TF Shape Edit changes how big it is - it takes boundary tokens from one region and hands them to a neighboring region, so one semantic part grows and the other shrinks while the content of neither actually changes. Think "the hat region absorbs a row of the background's tokens" rather than "replace the hat with a scarf." It's the geometry counterpart to the feature edit, and the two together cover most of what you'd want to do to a generated image that you can already look inside.
The mechanism is clean and worth internalizing. The tokens you flag in boundary_tokens are reassigned: they take on the receiving region's mean feature vector, so they stop being part of their old region and become part of the new one. Because the receiving region's mean comes from the whole region - not from whatever tokens you happened to point at - a shape edit moves the boundary without inventing new feature content or subtly changing what the absorbing region looks like. You paint the tokens to hand over into boundary_tokens, and you put one token inside the absorbing region into receiving_tokens (any token will do; the node reads which region it's in). regions is required - a TF Region Map for this level - because the whole operation is defined in terms of its clusters, and level must match the map's level or you get the drift error. strength (default 1.0) interpolates the boundary tokens toward the receiving feature rather than jumping them fully.
The node checks its own assumptions, and the errors are educational rather than cryptic. Boundary and receiving tokens both inside the same region raise "a shape edit needs two different regions" - correct, you're trying to grow a region into itself. A region map whose shape doesn't match the token grid, or built on a different level, is refused up front. Those checks exist because the paper's regions are level-specific properties, and getting them wrong produces silent nonsense in an edit - which this pack would rather you not discover after a minute of re-sampling.
Outputs are levels and info, and like its sibling the feature edit, the result is edited but not propagated: TF Shape Edit writes the reassigned canvas at l* and flags it dirty. You still need TF Resume From Level to re-sample every finer level above it, and the region map you used is only valid for the trajectory it was built on - regenerate the base trajectory and you rebuild the map. Both edits also share the same honest limitation when it comes to evaluation: to tell whether a shape change actually changed the outcome rather than just re-rolled the seed, compare arms with TF Sweep Edit (wire the region map in and it sweeps a shape edit over seed or strength).
The one thing worth getting a feel for by hand: level choice. Shape edits at coarse levels move big structural blocks (and cascade far when resumed); at fine levels they're small boundary nudges. Default level 2 is a decent middle - the subparts rung where a region is big enough to be a recognizable part and small enough to nudge precisely.
Install
Pack-standard: Manager → search Trajectory Forcing, or git clone https://github.com/korayulusan/ComfyUI-TrajectoryForcing into custom_nodes/. JAX inside ComfyUI, own Python 3.11 environment on CUDA 12, empty requirements.txt so Manager can't rewrite torch, install.py that adds the JAX stack or declines with a printed reason - declining is normal, and README's env/setup.sh is the fallback. Check health with:
cd ComfyUI/custom_nodes/ComfyUI-TrajectoryForcing
python -m tf_nodes.doctor
Preview the boundary you're about to hand over on TF Level Canvas (regions drawn on, selection highlighted) before queueing - a shape edit is only as good as the tokens you flagged.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| levels | TF_LEVELS | — | |
| level | INT | 20–3 | Hierarchy level, 0 = coarsest (object/background) to 3 = finest. |
| regions | TF_REGIONS | Region map for this level, from TF Region Map. | |
| boundary_tokens | TF_TOKENS | Tokens being reassigned. These are the ones that change. | |
| receiving_tokens | TF_TOKENS | Any token inside the region absorbing them; the whole region it names supplies the mean feature. | |
| strength | FLOAT | 1.000–1 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| levels | TF_LEVELS | — |
| info | STRING | — |