Refactor to VACE_PIPE: bundle merge metadata into single pipe connection

Replace 3 separate forceInput wires (mode, trim_start, trim_end) plus
mask and blend_frames with a single VACE_PIPE dict carrying mode, trim
bounds, and context frame counts. SourcePrep outputs reduced from 12 to
7 (segments removed), MergeBack inputs reduced from 9 to 5. Blending
now auto-derives from context counts instead of manual blend_frames.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 23:08:21 +01:00
parent 89fa3405cb
commit 605279d88e
4 changed files with 58 additions and 100 deletions

View File

@@ -38,11 +38,9 @@ Irrelevant widgets are automatically hidden based on the selected mode.
| `mode` | STRING | Selected mode — wire to mask generator's mode (convert widget to input). | | `mode` | STRING | Selected mode — wire to mask generator's mode (convert widget to input). |
| `split_index` | INT | Adjusted for the trimmed clip — wire to mask generator. | | `split_index` | INT | Adjusted for the trimmed clip — wire to mask generator. |
| `edge_frames` | INT | Adjusted/passed through — wire to mask generator. | | `edge_frames` | INT | Adjusted/passed through — wire to mask generator. |
| `segment_1``segment_4` | IMAGE | Frame segments per mode (same meaning as mask generator segments). Unused segments are 1-frame black placeholders. |
| `inpaint_mask` | MASK | Trimmed to match output, or placeholder. | | `inpaint_mask` | MASK | Trimmed to match output, or placeholder. |
| `keyframe_positions` | STRING | Pass-through. | | `keyframe_positions` | STRING | Pass-through. |
| `trim_start` | INT | Start index of the trimmed region in the original clip — wire to VACE Merge Back. | | `vace_pipe` | VACE_PIPE | Pipe carrying mode, trim bounds, and context frame counts — wire to VACE Merge Back. |
| `trim_end` | INT | End index of the trimmed region in the original clip — wire to VACE Merge Back. |
### Per-Mode Trimming ### Per-Mode Trimming
@@ -318,7 +316,7 @@ control_frames: [ k0][ GREY ][ k1][ GREY ][ k2][ GREY ][ k3]
## Node: VACE Merge Back ## Node: VACE Merge Back
Splices VACE sampler output back into the original full-length video. Connect the original (untrimmed) clip, the VACE sampler output, the mask from VACE Mask Generator, and the `mode`/`trim_start`/`trim_end` from VACE Source Prep. Splices VACE sampler output back into the original full-length video. Connect the original (untrimmed) clip, the VACE sampler output, and the `vace_pipe` from VACE Source Prep. The pipe carries mode, trim bounds, and context frame counts for automatic blending.
Irrelevant widgets are automatically hidden based on the selected blend method. Irrelevant widgets are automatically hidden based on the selected blend method.
@@ -328,11 +326,7 @@ Irrelevant widgets are automatically hidden based on the selected blend method.
|---|---|---|---| |---|---|---|---|
| `original_clip` | IMAGE | — | Full original video (before any trimming). | | `original_clip` | IMAGE | — | Full original video (before any trimming). |
| `vace_output` | IMAGE | — | VACE sampler output. | | `vace_output` | IMAGE | — | VACE sampler output. |
| `mask` | IMAGE | — | Mask from VACE Mask Generator — BLACK=context, WHITE=generated. | | `vace_pipe` | VACE_PIPE | — | Pipe from VACE Source Prep carrying mode, trim bounds, and context counts. |
| `mode` | STRING | *(wired)* | Mode from VACE Source Prep (must be wired, not typed). |
| `trim_start` | INT | *(wired)* | Start of trimmed region in original (from VACE Source Prep). |
| `trim_end` | INT | *(wired)* | End of trimmed region in original (from VACE Source Prep). |
| `blend_frames` | INT | `4` | Context frames to blend at each seam (0 = hard cut). |
| `blend_method` | ENUM | `optical_flow` | `none` (hard cut), `alpha` (linear crossfade), or `optical_flow` (motion-compensated). | | `blend_method` | ENUM | `optical_flow` | `none` (hard cut), `alpha` (linear crossfade), or `optical_flow` (motion-compensated). |
| `of_preset` | ENUM | `balanced` | Optical flow quality: `fast`, `balanced`, `quality`, `max`. | | `of_preset` | ENUM | `balanced` | Optical flow quality: `fast`, `balanced`, `quality`, `max`. |
@@ -346,23 +340,23 @@ Irrelevant widgets are automatically hidden based on the selected blend method.
**Pass-through modes** (Edge Extend, Frame Interpolation, Keyframe, Video Inpaint): returns `vace_output` as-is — the VACE output IS the final result for these modes. **Pass-through modes** (Edge Extend, Frame Interpolation, Keyframe, Video Inpaint): returns `vace_output` as-is — the VACE output IS the final result for these modes.
**Splice modes** (End, Pre, Middle, Join, Bidirectional, Replace): reconstructs `original[:trim_start] + vace_output + original[trim_end:]`, then blends at the seams where context frames meet original frames. **Splice modes** (End, Pre, Middle, Join, Bidirectional, Replace): reconstructs `original[:trim_start] + vace_output + original[trim_end:]`, then blends across the full context zones at each seam.
The node detects context zones by counting consecutive black frames at the start and end of the mask. At each seam, `blend_frames` frames are blended with a smooth alpha ramp. Optical flow blending warps both frames along the motion field before blending, reducing ghosting on moving subjects. Context frame counts (`left_ctx`, `right_ctx`) are carried in the `vace_pipe` and determined automatically by VACE Source Prep based on the mode and input_left/input_right settings. Blending uses a smooth alpha ramp across the entire context zone. Optical flow blending warps both frames along the motion field before blending, reducing ghosting on moving subjects.
### Example: Middle Extend ### Example: Middle Extend
``` ```
Original: 274 frames (0273) Original: 274 frames (0273)
Prep: split_index=137, input_left=16, input_right=16 Prep: split_index=137, input_left=16, input_right=16
→ trim_start=121, trim_end=153, trimmed=32 frames vace_pipe: trim_start=121, trim_end=153, left_ctx=16, right_ctx=16
Mask Gen: target_frames=81 Mask Gen: target_frames=81
→ mask = [BLACK×16] [WHITE×49] [BLACK×16] → mask = [BLACK×16] [WHITE×49] [BLACK×16]
VACE out: 81 frames (from sampler) VACE out: 81 frames (from sampler)
Merge: result = original[0:121] + vace[0:81] + original[153:274] Merge: result = original[0:121] + vace[0:81] + original[153:274]
→ 121 + 81 + 121 = 323 frames → 121 + 81 + 121 = 323 frames
Left blend: vace[0..3] ↔ original[121..124] Left blend: vace[0..15] ↔ original[121..136] (full 16-frame context zone)
Right blend: vace[77..80] ↔ original[149..152] Right blend: vace[65..80] ↔ original[137..152] (full 16-frame context zone)
``` ```
### Wiring Diagram ### Wiring Diagram
@@ -370,14 +364,12 @@ Merge: result = original[0:121] + vace[0:81] + original[153:274]
``` ```
[Load Video] [Load Video]
├─ source_clip ──→ [VACESourcePrep] ─┬─ source_clip ──→ [MaskGen] ─→ mask ──┐ ├─ source_clip ──→ [VACESourcePrep] ─┬─ source_clip ──→ [MaskGen] ─→ [Sampler]
│ ├─ mode ───────────────────────────────┤ │ ├─ mode ──────────→ [MaskGen] │
trim_start ─────────────────────────┤ vace_pipe ─────────────────┐ │
└─ trim_end ──────────────────────────┤ │ │
│ │ └─ original_clip ──────────────────────────────────────→ [VACEMergeBack] ←┘
└─ original_clip ───────────────────────────────────────────────────────────→ [VACEMergeBack] vace_output
[Sampler] ─→ vace_output ────────────────┘
``` ```
--- ---

View File

@@ -12,27 +12,6 @@ OPTICAL_FLOW_PRESETS = {
PASS_THROUGH_MODES = {"Edge Extend", "Frame Interpolation", "Keyframe", "Video Inpaint"} PASS_THROUGH_MODES = {"Edge Extend", "Frame Interpolation", "Keyframe", "Video Inpaint"}
def _count_leading_black(mask):
"""Count consecutive black (context) frames at the start of mask."""
count = 0
for i in range(mask.shape[0]):
if mask[i].max().item() < 0.01:
count += 1
else:
break
return count
def _count_trailing_black(mask):
"""Count consecutive black (context) frames at the end of mask."""
count = 0
for i in range(mask.shape[0] - 1, -1, -1):
if mask[i].max().item() < 0.01:
count += 1
else:
break
return count
def _alpha_blend(frame_a, frame_b, alpha): def _alpha_blend(frame_a, frame_b, alpha):
"""Simple linear crossfade between two frames (H,W,3 tensors).""" """Simple linear crossfade between two frames (H,W,3 tensors)."""
@@ -102,16 +81,15 @@ class VACEMergeBack:
) )
DESCRIPTION = """VACE Merge Back — splices VACE sampler output back into the original full-length video. DESCRIPTION = """VACE Merge Back — splices VACE sampler output back into the original full-length video.
Connect the original (untrimmed) clip, the VACE sampler output, the mask from VACE Mask Generator, Connect the original (untrimmed) clip, the VACE sampler output, and the vace_pipe from VACE Source Prep.
and the mode/trim_start/trim_end from VACE Source Prep. The node detects context zones from the mask The pipe carries mode, trim bounds, and context frame counts for automatic blending.
and blends at the seams where context meets generated frames.
Pass-through modes (Edge Extend, Frame Interpolation, Keyframe, Video Inpaint): Pass-through modes (Edge Extend, Frame Interpolation, Keyframe, Video Inpaint):
Returns vace_output as-is — the VACE output IS the final result. Returns vace_output as-is — the VACE output IS the final result.
Splice modes (End, Pre, Middle, Join, Bidirectional, Replace): Splice modes (End, Pre, Middle, Join, Bidirectional, Replace):
Reconstructs original[:trim_start] + vace_output + original[trim_end:] Reconstructs original[:trim_start] + vace_output + original[trim_end:]
with optional blending at the seams. with automatic blending across the full context zones.
Blend methods: Blend methods:
none — Hard cut at seams (fastest) none — Hard cut at seams (fastest)
@@ -124,17 +102,19 @@ Blend methods:
"required": { "required": {
"original_clip": ("IMAGE", {"description": "Full original video (before any trimming)."}), "original_clip": ("IMAGE", {"description": "Full original video (before any trimming)."}),
"vace_output": ("IMAGE", {"description": "VACE sampler output."}), "vace_output": ("IMAGE", {"description": "VACE sampler output."}),
"mask": ("IMAGE", {"description": "Mask from VACE Mask Generator — BLACK=context, WHITE=generated."}), "vace_pipe": ("VACE_PIPE", {"description": "Pipe from VACE Source Prep carrying mode, trim bounds, and context counts."}),
"mode": ("STRING", {"forceInput": True, "description": "Mode from VACE Source Prep."}),
"trim_start": ("INT", {"forceInput": True, "default": 0, "description": "Start of trimmed region in original."}),
"trim_end": ("INT", {"forceInput": True, "default": 0, "description": "End of trimmed region in original."}),
"blend_frames": ("INT", {"default": 4, "min": 0, "max": 100, "description": "Context frames to blend at each seam (0 = hard cut)."}),
"blend_method": (["optical_flow", "alpha", "none"], {"default": "optical_flow", "description": "Blending method at seams."}), "blend_method": (["optical_flow", "alpha", "none"], {"default": "optical_flow", "description": "Blending method at seams."}),
"of_preset": (["fast", "balanced", "quality", "max"], {"default": "balanced", "description": "Optical flow quality preset."}), "of_preset": (["fast", "balanced", "quality", "max"], {"default": "balanced", "description": "Optical flow quality preset."}),
}, },
} }
def merge(self, original_clip, vace_output, mask, mode, trim_start, trim_end, blend_frames, blend_method, of_preset): def merge(self, original_clip, vace_output, vace_pipe, blend_method, of_preset):
mode = vace_pipe["mode"]
trim_start = vace_pipe["trim_start"]
trim_end = vace_pipe["trim_end"]
left_ctx = vace_pipe["left_ctx"]
right_ctx = vace_pipe["right_ctx"]
# Pass-through modes: VACE output IS the final result # Pass-through modes: VACE output IS the final result
if mode in PASS_THROUGH_MODES: if mode in PASS_THROUGH_MODES:
return (vace_output,) return (vace_output,)
@@ -145,34 +125,24 @@ Blend methods:
tail = original_clip[trim_end:] tail = original_clip[trim_end:]
result = torch.cat([head, vace_output, tail], dim=0) result = torch.cat([head, vace_output, tail], dim=0)
if blend_method == "none" or blend_frames <= 0: if blend_method == "none" or (left_ctx == 0 and right_ctx == 0):
return (result,) return (result,)
# Detect context zones from mask
left_ctx_len = _count_leading_black(mask)
right_ctx_len = _count_trailing_black(mask)
def blend_frame(orig, vace, alpha): def blend_frame(orig, vace, alpha):
if blend_method == "optical_flow": if blend_method == "optical_flow":
return _optical_flow_blend(orig, vace, alpha, of_preset) return _optical_flow_blend(orig, vace, alpha, of_preset)
return _alpha_blend(orig, vace, alpha) return _alpha_blend(orig, vace, alpha)
# Blend at LEFT seam (context → generated transition) # Blend across full left context zone
bf_left = min(blend_frames, left_ctx_len) for j in range(left_ctx):
for j in range(bf_left): alpha = (j + 1) / (left_ctx + 1)
alpha = (j + 1) / (bf_left + 1) result[trim_start + j] = blend_frame(original_clip[trim_start + j], vace_output[j], alpha)
orig_frame = original_clip[trim_start + j]
vace_frame = vace_output[j]
result[trim_start + j] = blend_frame(orig_frame, vace_frame, alpha)
# Blend at RIGHT seam (generated → context transition) # Blend across full right context zone
bf_right = min(blend_frames, right_ctx_len) for j in range(right_ctx):
for j in range(bf_right): alpha = 1.0 - (j + 1) / (right_ctx + 1)
alpha = 1.0 - (j + 1) / (bf_right + 1) frame_idx = V - right_ctx + j
frame_idx = V - bf_right + j result[trim_start + frame_idx] = blend_frame(original_clip[trim_end - right_ctx + j], vace_output[frame_idx], alpha)
orig_frame = original_clip[trim_end - bf_right + j]
vace_frame = vace_output[frame_idx]
result[trim_start + frame_idx] = blend_frame(orig_frame, vace_frame, alpha)
return (result,) return (result,)

View File

@@ -330,25 +330,19 @@ If your source is longer, use VACE Source Prep upstream to trim it first."""
class VACESourcePrep: class VACESourcePrep:
CATEGORY = "VACE Tools" CATEGORY = "VACE Tools"
FUNCTION = "prepare" FUNCTION = "prepare"
RETURN_TYPES = ("IMAGE", "STRING", "INT", "INT", "IMAGE", "IMAGE", "IMAGE", "IMAGE", "MASK", "STRING", "INT", "INT") RETURN_TYPES = ("IMAGE", "STRING", "INT", "INT", "MASK", "STRING", "VACE_PIPE")
RETURN_NAMES = ( RETURN_NAMES = (
"source_clip", "mode", "split_index", "edge_frames", "source_clip", "mode", "split_index", "edge_frames",
"segment_1", "segment_2", "segment_3", "segment_4", "inpaint_mask", "keyframe_positions", "vace_pipe",
"inpaint_mask", "keyframe_positions", "trim_start", "trim_end",
) )
OUTPUT_TOOLTIPS = ( OUTPUT_TOOLTIPS = (
"Trimmed source frames — wire to VACE Mask Generator's source_clip.", "Trimmed source frames — wire to VACE Mask Generator's source_clip.",
"Selected mode — wire to VACE Mask Generator's mode (convert widget to input).", "Selected mode — wire to VACE Mask Generator's mode (convert widget to input).",
"Adjusted split_index for the trimmed clip — wire to VACE Mask Generator.", "Adjusted split_index for the trimmed clip — wire to VACE Mask Generator.",
"Adjusted edge_frames — wire to VACE Mask Generator.", "Adjusted edge_frames — wire to VACE Mask Generator.",
"Segment 1: End/Pre/Bidirectional/Frame Interpolation/Video Inpaint/Keyframe: full output clip. Middle: part A. Edge: start edge. Join: part 1. Replace/Inpaint: before region.",
"Segment 2: Middle: part B. Edge: discarded middle. Join: part 2. Replace/Inpaint: replace region. Others: placeholder.",
"Segment 3: Edge: end edge. Join: part 3. Replace/Inpaint: after region. Others: placeholder.",
"Segment 4: Join: part 4. Others: placeholder.",
"Inpaint mask trimmed to match output — wire to VACE Mask Generator.", "Inpaint mask trimmed to match output — wire to VACE Mask Generator.",
"Keyframe positions pass-through — wire to VACE Mask Generator.", "Keyframe positions pass-through — wire to VACE Mask Generator.",
"Start index of the trimmed region in the original clip — wire to VACE Merge Back.", "Pipe carrying mode, trim bounds, and context counts — wire to VACE Merge Back.",
"End index of the trimmed region in the original clip — wire to VACE Merge Back.",
) )
DESCRIPTION = """VACE Source Prep — trims long source clips for VACE Mask Generator. DESCRIPTION = """VACE Source Prep — trims long source clips for VACE Mask Generator.
@@ -454,12 +448,6 @@ input_left / input_right (0 = use all available):
B, H, W, C = source_clip.shape B, H, W, C = source_clip.shape
dev = source_clip.device dev = source_clip.device
def ph():
return _placeholder(H, W, dev)
def safe(t):
return _ensure_nonempty(t, H, W, dev)
def mask_ph(): def mask_ph():
return torch.zeros((1, H, W), dtype=torch.float32, device=dev) return torch.zeros((1, H, W), dtype=torch.float32, device=dev)
@@ -485,7 +473,8 @@ input_left / input_right (0 = use all available):
else: else:
output = source_clip output = source_clip
start = 0 start = 0
return (output, mode, 0, edge_frames, safe(output), ph(), ph(), ph(), trim_mask(start, B), kp_out, start, B) pipe = {"mode": mode, "trim_start": start, "trim_end": B, "left_ctx": output.shape[0], "right_ctx": 0}
return (output, mode, 0, edge_frames, trim_mask(start, B), kp_out, pipe)
elif mode == "Pre Extend": elif mode == "Pre Extend":
if input_right > 0: if input_right > 0:
@@ -494,7 +483,8 @@ input_left / input_right (0 = use all available):
else: else:
output = source_clip output = source_clip
end = B end = B
return (output, mode, output.shape[0], edge_frames, safe(output), ph(), ph(), ph(), trim_mask(0, end), kp_out, 0, end) pipe = {"mode": mode, "trim_start": 0, "trim_end": end, "left_ctx": 0, "right_ctx": output.shape[0]}
return (output, mode, output.shape[0], edge_frames, trim_mask(0, end), kp_out, pipe)
elif mode == "Middle Extend": elif mode == "Middle Extend":
left_start = max(0, split_index - input_left) if input_left > 0 else 0 left_start = max(0, split_index - input_left) if input_left > 0 else 0
@@ -503,7 +493,8 @@ input_left / input_right (0 = use all available):
out_split = split_index - left_start out_split = split_index - left_start
part_a = source_clip[left_start:split_index] part_a = source_clip[left_start:split_index]
part_b = source_clip[split_index:right_end] part_b = source_clip[split_index:right_end]
return (output, mode, out_split, edge_frames, safe(part_a), safe(part_b), ph(), ph(), trim_mask(left_start, right_end), kp_out, left_start, right_end) pipe = {"mode": mode, "trim_start": left_start, "trim_end": right_end, "left_ctx": out_split, "right_ctx": part_b.shape[0]}
return (output, mode, out_split, edge_frames, trim_mask(left_start, right_end), kp_out, pipe)
elif mode == "Edge Extend": elif mode == "Edge Extend":
eff_left = min(input_left if input_left > 0 else edge_frames, B) eff_left = min(input_left if input_left > 0 else edge_frames, B)
@@ -513,7 +504,8 @@ input_left / input_right (0 = use all available):
end_seg = source_clip[-sym:] if sym > 0 else source_clip[:0] end_seg = source_clip[-sym:] if sym > 0 else source_clip[:0]
mid_seg = source_clip[sym:B - sym] if 2 * sym < B else source_clip[:0] mid_seg = source_clip[sym:B - sym] if 2 * sym < B else source_clip[:0]
output = torch.cat([start_seg, end_seg], dim=0) output = torch.cat([start_seg, end_seg], dim=0)
return (output, mode, 0, sym, safe(start_seg), safe(mid_seg), safe(end_seg), ph(), mask_ph(), kp_out, 0, B) pipe = {"mode": mode, "trim_start": 0, "trim_end": B, "left_ctx": 0, "right_ctx": 0}
return (output, mode, 0, sym, mask_ph(), kp_out, pipe)
elif mode == "Join Extend": elif mode == "Join Extend":
half = B // 2 half = B // 2
@@ -529,7 +521,8 @@ input_left / input_right (0 = use all available):
part_3 = second_half[:sym] part_3 = second_half[:sym]
part_4 = second_half[sym:] part_4 = second_half[sym:]
output = torch.cat([part_2, part_3], dim=0) output = torch.cat([part_2, part_3], dim=0)
return (output, mode, 0, sym, safe(part_1), safe(part_2), safe(part_3), safe(part_4), mask_ph(), kp_out, half - sym, half + sym) pipe = {"mode": mode, "trim_start": half - sym, "trim_end": half + sym, "left_ctx": sym, "right_ctx": sym}
return (output, mode, 0, sym, mask_ph(), kp_out, pipe)
elif mode == "Bidirectional Extend": elif mode == "Bidirectional Extend":
if input_left > 0: if input_left > 0:
@@ -538,10 +531,12 @@ input_left / input_right (0 = use all available):
else: else:
output = source_clip output = source_clip
start = 0 start = 0
return (output, mode, split_index, edge_frames, safe(output), ph(), ph(), ph(), trim_mask(start, B), kp_out, start, B) pipe = {"mode": mode, "trim_start": start, "trim_end": B, "left_ctx": 0, "right_ctx": 0}
return (output, mode, split_index, edge_frames, trim_mask(start, B), kp_out, pipe)
elif mode == "Frame Interpolation": elif mode == "Frame Interpolation":
return (source_clip, mode, split_index, edge_frames, safe(source_clip), ph(), ph(), ph(), trim_mask(0, B), kp_out, 0, B) pipe = {"mode": mode, "trim_start": 0, "trim_end": B, "left_ctx": 0, "right_ctx": 0}
return (source_clip, mode, split_index, edge_frames, trim_mask(0, B), kp_out, pipe)
elif mode == "Replace/Inpaint": elif mode == "Replace/Inpaint":
start = max(0, min(split_index, B)) start = max(0, min(split_index, B))
@@ -555,14 +550,17 @@ input_left / input_right (0 = use all available):
output = torch.cat([before, replace_region, after], dim=0) output = torch.cat([before, replace_region, after], dim=0)
out_split = before.shape[0] out_split = before.shape[0]
out_edge = length out_edge = length
return (output, mode, out_split, out_edge, safe(before), safe(replace_region), safe(after), ph(), trim_mask(ctx_start, ctx_end), kp_out, ctx_start, ctx_end) pipe = {"mode": mode, "trim_start": ctx_start, "trim_end": ctx_end, "left_ctx": before.shape[0], "right_ctx": after.shape[0]}
return (output, mode, out_split, out_edge, trim_mask(ctx_start, ctx_end), kp_out, pipe)
elif mode == "Video Inpaint": elif mode == "Video Inpaint":
out_mask = inpaint_mask.to(dev) if inpaint_mask is not None else mask_ph() out_mask = inpaint_mask.to(dev) if inpaint_mask is not None else mask_ph()
return (source_clip, mode, split_index, edge_frames, safe(source_clip), ph(), ph(), ph(), out_mask, kp_out, 0, B) pipe = {"mode": mode, "trim_start": 0, "trim_end": B, "left_ctx": 0, "right_ctx": 0}
return (source_clip, mode, split_index, edge_frames, out_mask, kp_out, pipe)
elif mode == "Keyframe": elif mode == "Keyframe":
return (source_clip, mode, split_index, edge_frames, safe(source_clip), ph(), ph(), ph(), mask_ph(), kp_out, 0, B) pipe = {"mode": mode, "trim_start": 0, "trim_end": B, "left_ctx": 0, "right_ctx": 0}
return (source_clip, mode, split_index, edge_frames, mask_ph(), kp_out, pipe)
raise ValueError(f"Unknown mode: {mode}") raise ValueError(f"Unknown mode: {mode}")

View File

@@ -92,9 +92,7 @@ app.registerExtension({
} }
function updateVisibility(method) { function updateVisibility(method) {
const showBlend = method !== "none";
const showOf = method === "optical_flow"; const showOf = method === "optical_flow";
toggleWidget(node.widgets.find(w => w.name === "blend_frames"), showBlend);
toggleWidget(node.widgets.find(w => w.name === "of_preset"), showOf); toggleWidget(node.widgets.find(w => w.name === "of_preset"), showOf);
node.setSize(node.computeSize()); node.setSize(node.computeSize());
app.graph.setDirtyCanvas(true); app.graph.setDirtyCanvas(true);