diff --git a/README.md b/README.md index 539eb4a..359aecc 100644 --- a/README.md +++ b/README.md @@ -92,17 +92,18 @@ pattern, but add a dedicated collector output for building a result sequence. Basic loop wiring: 1. Connect `For Loop Start.flow` to `For Loop End.flow`. -2. Use `For Loop Start.index` inside the loop for seed/index changes. +2. Use `For Loop Start.index` inside the loop for row/seed/index changes. 3. Connect the per-iteration output you want to keep, such as an image, latent, prompt, or metadata string, to `For Loop End.collect_value`. 4. Optionally connect `For Loop Start.collected` to `For Loop End.collected`. If omitted, the end node uses the start collector internally. 5. After the loop finishes, use `For Loop End.collected` as the combined output. -`For Loop Start.skip` skips the first N iterations while keeping the index -stable. For example, `total=10` and `skip=1` runs indexes `1..9`; `skip=5` runs -indexes `5..9`. This is useful when you want to resume a loop without changing -index-derived seeds or row numbers. +`For Loop Start.index` is 1-based so it can be wired directly into prompt-builder +`row_number` inputs. `For Loop Start.skip` skips the first N iterations while +keeping the remaining row numbers stable. For example, `total=10` and `skip=1` +runs indexes `2..10`; `skip=5` runs indexes `6..10`. This is useful when you +want to resume a loop without changing index-derived seeds or row numbers. `collection_mode` controls how values are stored: diff --git a/loop_nodes.py b/loop_nodes.py index 357b6eb..a47b020 100644 --- a/loop_nodes.py +++ b/loop_nodes.py @@ -279,8 +279,10 @@ class SxCPForLoopStart: def start(self, total, skip=0, initial_index=None, initial_collected=None, **kwargs): _require_graph_builder() + total = max(1, int(total)) skip = max(0, int(skip)) - index = skip if initial_index is None else max(int(initial_index), skip) + first_index = skip + 1 + index = first_index if initial_index is None else max(int(initial_index), first_index) collected = initial_collected initial_values = { "initial_value0": index, @@ -289,7 +291,7 @@ class SxCPForLoopStart: for carry_index in range(1, MAX_CARRY_VALUES + 1): initial_values[f"initial_value{carry_index + 1}"] = kwargs.get(f"initial_value{carry_index}") graph = GraphBuilder() - graph.node("SxCPWhileLoopStart", condition=index < int(total), **initial_values) + graph.node("SxCPWhileLoopStart", condition=index <= total, **initial_values) return { "result": tuple(["stub", index, collected] + [kwargs.get(f"initial_value{index}") for index in range(1, MAX_CARRY_VALUES + 1)]), "expand": graph.finalize(), @@ -357,7 +359,7 @@ class SxCPForLoopEnd: raise ValueError("SxCP For Loop End must receive flow from SxCP For Loop Start.") total = start_node["inputs"]["total"] next_index = graph.node("SxCPLoopIntAdd", a=[loop_start, 1], b=1) - condition = graph.node("SxCPLoopLessThan", a=next_index.out(0), b=total) + condition = graph.node("SxCPLoopLessThanOrEqual", a=next_index.out(0), b=total) collection = kwargs.get("collected") or [loop_start, 2] collect_value = kwargs.get("collect_value") next_collection = graph.node( @@ -418,6 +420,24 @@ class SxCPLoopLessThan: return (int(a) < int(b),) +class SxCPLoopLessThanOrEqual: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "a": ("INT", {"default": 0}), + "b": ("INT", {"default": 0}), + } + } + + RETURN_TYPES = ("BOOLEAN",) + FUNCTION = "compare" + CATEGORY = "prompt_builder/loop/internal" + + def compare(self, a, b): + return (int(a) <= int(b),) + + LOOP_NODE_CLASS_MAPPINGS = { "SxCPWhileLoopStart": SxCPWhileLoopStart, "SxCPWhileLoopEnd": SxCPWhileLoopEnd, @@ -426,6 +446,7 @@ LOOP_NODE_CLASS_MAPPINGS = { "SxCPLoopAppend": SxCPLoopAppend, "SxCPLoopIntAdd": SxCPLoopIntAdd, "SxCPLoopLessThan": SxCPLoopLessThan, + "SxCPLoopLessThanOrEqual": SxCPLoopLessThanOrEqual, } LOOP_NODE_DISPLAY_NAME_MAPPINGS = { @@ -436,4 +457,5 @@ LOOP_NODE_DISPLAY_NAME_MAPPINGS = { "SxCPLoopAppend": "SxCP Loop Append", "SxCPLoopIntAdd": "SxCP Loop Int Add", "SxCPLoopLessThan": "SxCP Loop Less Than", + "SxCPLoopLessThanOrEqual": "SxCP Loop Less Than Or Equal", }