Add split_index validation, auto-middle mode, and merge bounds checks
- Middle Extend: split_index=0 now auto-splits at B//2 instead of empty first half - Middle Extend/Replace: raise ValueError when split_index >= frame count - Merge blend loops: add bounds checks to prevent index-out-of-bounds Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -145,11 +145,15 @@ Blend methods:
|
|||||||
|
|
||||||
# Blend across full left context zone
|
# Blend across full left context zone
|
||||||
for j in range(left_ctx):
|
for j in range(left_ctx):
|
||||||
|
if trim_start + j >= source_clip.shape[0]:
|
||||||
|
break
|
||||||
alpha = (j + 1) / (left_ctx + 1)
|
alpha = (j + 1) / (left_ctx + 1)
|
||||||
result[trim_start + j] = blend_frame(source_clip[trim_start + j], vace_output[j], alpha)
|
result[trim_start + j] = blend_frame(source_clip[trim_start + j], vace_output[j], alpha)
|
||||||
|
|
||||||
# Blend across full right context zone
|
# Blend across full right context zone
|
||||||
for j in range(right_ctx):
|
for j in range(right_ctx):
|
||||||
|
if trim_end - right_ctx + j >= right_orig.shape[0]:
|
||||||
|
break
|
||||||
alpha = 1.0 - (j + 1) / (right_ctx + 1)
|
alpha = 1.0 - (j + 1) / (right_ctx + 1)
|
||||||
frame_idx = V - right_ctx + j
|
frame_idx = V - right_ctx + j
|
||||||
result[trim_start + frame_idx] = blend_frame(right_orig[trim_end - right_ctx + j], vace_output[frame_idx], alpha)
|
result[trim_start + frame_idx] = blend_frame(right_orig[trim_end - right_ctx + j], vace_output[frame_idx], alpha)
|
||||||
|
|||||||
28
nodes.py
28
nodes.py
@@ -86,7 +86,7 @@ If your source is longer, use VACE Source Prep upstream to trim it first."""
|
|||||||
"default": 0,
|
"default": 0,
|
||||||
"min": -10000,
|
"min": -10000,
|
||||||
"max": 10000,
|
"max": 10000,
|
||||||
"description": "Where to split the source. End: trim from end (e.g. -16). Pre: reference frames from start (e.g. 24). Middle: split frame index. Unused by Edge/Join. Bidirectional: frames before clip (0 = even split). Frame Interpolation: new frames per gap. Replace/Inpaint: start index of replace region. Unused by Video Inpaint and Keyframe.",
|
"description": "Where to split the source. Middle: split frame index (0 = auto-middle). Bidirectional: frames before clip (0 = even split). Frame Interpolation: new frames per gap. Replace/Inpaint: start index of replace region. Unused by End/Pre/Edge/Join/Video Inpaint/Keyframe.",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
"edge_frames": (
|
"edge_frames": (
|
||||||
@@ -152,6 +152,13 @@ If your source is longer, use VACE Source Prep upstream to trim it first."""
|
|||||||
return (control_frames, mask, frames_to_generate)
|
return (control_frames, mask, frames_to_generate)
|
||||||
|
|
||||||
elif mode == "Middle Extend":
|
elif mode == "Middle Extend":
|
||||||
|
if split_index <= 0:
|
||||||
|
split_index = B // 2
|
||||||
|
if split_index >= B:
|
||||||
|
raise ValueError(
|
||||||
|
f"Middle Extend: split_index ({split_index}) is out of range — "
|
||||||
|
f"source_clip only has {B} frames. Use 0 for auto-middle."
|
||||||
|
)
|
||||||
image_a = source_clip[:split_index]
|
image_a = source_clip[:split_index]
|
||||||
image_b = source_clip[split_index:]
|
image_b = source_clip[split_index:]
|
||||||
a_count = image_a.shape[0]
|
a_count = image_a.shape[0]
|
||||||
@@ -211,6 +218,11 @@ If your source is longer, use VACE Source Prep upstream to trim it first."""
|
|||||||
return (control_frames, mask, frames_to_generate)
|
return (control_frames, mask, frames_to_generate)
|
||||||
|
|
||||||
elif mode == "Replace/Inpaint":
|
elif mode == "Replace/Inpaint":
|
||||||
|
if split_index >= B:
|
||||||
|
raise ValueError(
|
||||||
|
f"Replace/Inpaint: split_index ({split_index}) is out of range — "
|
||||||
|
f"source_clip only has {B} frames."
|
||||||
|
)
|
||||||
start = max(0, min(split_index, B))
|
start = max(0, min(split_index, B))
|
||||||
length = max(0, min(edge_frames, B - start))
|
length = max(0, min(edge_frames, B - start))
|
||||||
end = start + length
|
end = start + length
|
||||||
@@ -348,7 +360,7 @@ input_left / input_right (0 = use all available):
|
|||||||
"default": 0,
|
"default": 0,
|
||||||
"min": -10000,
|
"min": -10000,
|
||||||
"max": 10000,
|
"max": 10000,
|
||||||
"description": "Split position in the full source video. Same meaning as mask generator's split_index.",
|
"description": "Split position in the full source video (0 = auto-middle for Middle Extend). Same meaning as mask generator's split_index.",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
"input_left": (
|
"input_left": (
|
||||||
@@ -450,6 +462,13 @@ input_left / input_right (0 = use all available):
|
|||||||
return (output, mode, output.shape[0], edge_frames, trim_mask(0, end), kp_out, pipe)
|
return (output, mode, output.shape[0], edge_frames, trim_mask(0, end), kp_out, pipe)
|
||||||
|
|
||||||
elif mode == "Middle Extend":
|
elif mode == "Middle Extend":
|
||||||
|
if split_index <= 0:
|
||||||
|
split_index = B // 2
|
||||||
|
if split_index >= B:
|
||||||
|
raise ValueError(
|
||||||
|
f"Middle Extend: split_index ({split_index}) is out of range — "
|
||||||
|
f"source_clip only has {B} frames. Use 0 for auto-middle."
|
||||||
|
)
|
||||||
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
|
||||||
right_end = min(B, split_index + input_right) if input_right > 0 else B
|
right_end = min(B, split_index + input_right) if input_right > 0 else B
|
||||||
output = source_clip[left_start:right_end]
|
output = source_clip[left_start:right_end]
|
||||||
@@ -510,6 +529,11 @@ input_left / input_right (0 = use all available):
|
|||||||
return (source_clip, mode, split_index, edge_frames, trim_mask(0, B), kp_out, pipe)
|
return (source_clip, mode, split_index, edge_frames, trim_mask(0, B), kp_out, pipe)
|
||||||
|
|
||||||
elif mode == "Replace/Inpaint":
|
elif mode == "Replace/Inpaint":
|
||||||
|
if split_index >= B:
|
||||||
|
raise ValueError(
|
||||||
|
f"Replace/Inpaint: split_index ({split_index}) is out of range — "
|
||||||
|
f"source_clip only has {B} frames."
|
||||||
|
)
|
||||||
start = max(0, min(split_index, B))
|
start = max(0, min(split_index, B))
|
||||||
end_idx = min(start + edge_frames, B)
|
end_idx = min(start + edge_frames, B)
|
||||||
length = end_idx - start
|
length = end_idx - start
|
||||||
|
|||||||
Reference in New Issue
Block a user