diff --git a/README.md b/README.md index b0cda5c2..cc709a72 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ This takes latent as input and outputs latent as the result. * Concat Conditionings - It takes multiple conditionings as input and concat them into a single conditioning. * Logics (experimental) - These nodes are experimental nodes designed to implement the logic for loops and dynamic switching. - * ImpactCompare, ImpactConditionalBranch, ImpactInt, ImpactValueSender, ImpactValueReceiver, ImpactImageInfo, ImpactMinMax, ImpactNeg, ImpactConditionalStopIteration + * ImpactCompare, ImpactConditionalBranch, ImpactConditionalBranchSelMode, ImpactInt, ImpactValueSender, ImpactValueReceiver, ImpactImageInfo, ImpactMinMax, ImpactNeg, ImpactConditionalStopIteration * ImpactIsNotEmptySEGS - This node returns `true` only if the input SEGS is not empty. * Queue Trigger - When this node is executed, it adds a new queue to assist with repetitive tasks. It will only execute if the signal's status changes. * Queue Trigger (Countdown) - Like the Queue Trigger, it adds a queue, but only adds it if it's greater than 1, and decrements the count by one each time it runs. diff --git a/__init__.py b/__init__.py index 0196735e..34633c8c 100644 --- a/__init__.py +++ b/__init__.py @@ -287,6 +287,7 @@ NODE_CLASS_MAPPINGS = { "ImpactCompare": ImpactCompare, "ImpactConditionalBranch": ImpactConditionalBranch, + "ImpactConditionalBranchSelMode": ImpactConditionalBranchSelMode, "ImpactInt": ImpactInt, "ImpactFloat": ImpactFloat, "ImpactValueSender": ImpactValueSender, diff --git a/js/impact-pack.js b/js/impact-pack.js index 49bca623..5113d66b 100644 --- a/js/impact-pack.js +++ b/js/impact-pack.js @@ -237,11 +237,14 @@ app.registerExtension({ } } - if(nodeData.name == "ImpactConditionalBranch") { - const onConnectionsChange = nodeType.prototype.onConnectionsChange; - nodeType.prototype.onConnectionsChange = function (type, index, connected, link_info) { - if(!link_info || this.inputs[0].type != '*') - return; + if(nodeData.name == "ImpactConditionalBranch" || nodeData.name == "ImpactConditionalBranchSelMode") { + const onConnectionsChange = nodeType.prototype.onConnectionsChange; + nodeType.prototype.onConnectionsChange = function (type, index, connected, link_info) { + if(!link_info || this.inputs[0].type != '*') + return; + + if(index >= 2) + return; // assign type let slot_type = '*'; @@ -370,8 +373,8 @@ app.registerExtension({ } if (nodeData.name === 'ImpactMakeImageList' || nodeData.name === 'ImpactMakeImageBatch' || - nodeData.name === 'CombineRegionalPrompts' || - nodeData.name === 'ImpactCombineConditionings' || nodeData.name === 'ImpactConcatConditionings' || + nodeData.name === 'CombineRegionalPrompts' || + nodeData.name === 'ImpactCombineConditionings' || nodeData.name === 'ImpactConcatConditionings' || nodeData.name === 'ImpactSEGSConcat' || nodeData.name === 'ImpactSwitch' || nodeData.name === 'LatentSwitch' || nodeData.name == 'SEGSSwitch') { var input_name = "input"; diff --git a/modules/impact/config.py b/modules/impact/config.py index 552c1c8c..335fd13d 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -2,7 +2,7 @@ import configparser import os -version_code = [4, 66, 4] +version_code = [4, 67] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 20 diff --git a/modules/impact/impact_server.py b/modules/impact/impact_server.py index 0e84ae05..350fc95b 100644 --- a/modules/impact/impact_server.py +++ b/modules/impact/impact_server.py @@ -338,6 +338,7 @@ async def view_previewbridge_image(request): def onprompt_for_switch(json_data): inversed_switch_info = {} onprompt_switch_info = {} + onprompt_cond_branch_info = {} for k, v in json_data['prompt'].items(): if 'class_type' not in v: @@ -368,6 +369,21 @@ def onprompt_for_switch(json_data): else: onprompt_switch_info[k] = select_input + elif cls == 'ImpactConditionalBranchSelMode': + if 'sel_mode' in v['inputs'] and v['inputs']['sel_mode'] and 'cond' in v['inputs']: + cond_input = v['inputs']['cond'] + if isinstance(cond_input, list) and len(cond_input) == 2: + input_node = json_data['prompt'][cond_input[0]] + if (input_node['class_type'] == 'ImpactValueReceiver' and 'inputs' in input_node + and 'value' in input_node['inputs'] and 'typ' in input_node['inputs']): + if 'BOOLEAN' == input_node['inputs']['typ']: + try: + onprompt_cond_branch_info[k] = input_node['inputs']['value'].lower() == "true" + except: + pass + else: + onprompt_cond_branch_info[k] = cond_input + for k, v in json_data['prompt'].items(): disable_targets = set() @@ -383,6 +399,12 @@ def onprompt_for_switch(json_data): if kk != selected_slot_name and kk.startswith('input'): disable_targets.add(kk) + if k in onprompt_cond_branch_info: + selected_slot_name = "tt_value" if onprompt_cond_branch_info[k] else "ff_value" + for kk, vv in v['inputs'].items(): + if kk in ['tt_value', 'ff_value'] and kk != selected_slot_name: + disable_targets.add(kk) + for kk in disable_targets: del v['inputs'][kk] diff --git a/modules/impact/logics.py b/modules/impact/logics.py index cd8f861c..46a256ff 100644 --- a/modules/impact/logics.py +++ b/modules/impact/logics.py @@ -81,6 +81,33 @@ class ImpactConditionalBranch: return (ff_value,) +class ImpactConditionalBranchSelMode: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "cond": ("BOOLEAN",), + "sel_mode": ("BOOLEAN", {"default": True, "label_on": "select_on_prompt", "label_off": "select_on_execution"}), + }, + "optional": { + "tt_value": (any_typ,), + "ff_value": (any_typ,), + }, + } + + FUNCTION = "doit" + CATEGORY = "ImpactPack/Logic" + + RETURN_TYPES = (any_typ, ) + + def doit(self, cond, sel_mode, tt_value=None, ff_value=None): + print(f'tt={tt_value is None}\nff={ff_value is None}') + if cond: + return (tt_value,) + else: + return (ff_value,) + + class ImpactConditionalStopIteration: @classmethod def INPUT_TYPES(cls): @@ -224,7 +251,7 @@ class ImpactValueReceiver: elif typ == "FLOAT": return (float(value), ) elif typ == "BOOLEAN": - return (bool(value), ) + return (value.lower() == "true", ) else: return (value, )