Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84fbb3fa2e | ||
|
|
b2c7e06e79 | ||
|
|
a500aff476 |
@@ -1,7 +1,7 @@
|
||||
import configparser
|
||||
import os
|
||||
|
||||
version_code = [7, 2, 1]
|
||||
version_code = [7, 3, 1]
|
||||
version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
||||
|
||||
dependency_version = 22
|
||||
|
||||
@@ -238,11 +238,16 @@ class DetailerForEach:
|
||||
else:
|
||||
wmode, wildcard_chooser = None, None
|
||||
|
||||
if wmode in ['ASC', 'DSC']:
|
||||
if wmode in ['ASC', 'DSC', 'ASC-SIZE', 'DSC-SIZE']:
|
||||
if wmode == 'ASC':
|
||||
ordered_segs = sorted(segs[1], key=lambda x: (x.bbox[0], x.bbox[1]))
|
||||
else:
|
||||
elif wmode == 'DSC':
|
||||
ordered_segs = sorted(segs[1], key=lambda x: (x.bbox[0], x.bbox[1]), reverse=True)
|
||||
elif wmode == 'ASC-SIZE':
|
||||
ordered_segs = sorted(segs[1], key=lambda x: (x.bbox[2]-x.bbox[0]) * (x.bbox[3]-x.bbox[1]))
|
||||
|
||||
else: # wmode == 'DSC-SIZE'
|
||||
ordered_segs = sorted(segs[1], key=lambda x: (x.bbox[2]-x.bbox[0]) * (x.bbox[3]-x.bbox[1]), reverse=True)
|
||||
else:
|
||||
ordered_segs = segs[1]
|
||||
|
||||
@@ -291,6 +296,12 @@ class DetailerForEach:
|
||||
# Negative Conditioning is placeholder such as FLUX.1
|
||||
cropped_negative = negative
|
||||
|
||||
if wildcard_item and wildcard_item.strip() == '[SKIP]':
|
||||
continue
|
||||
|
||||
if wildcard_item and wildcard_item.strip() == '[STOP]':
|
||||
break
|
||||
|
||||
enhanced_image, cnet_pils = core.enhance_detail(cropped_image, model, clip, vae, guide_size, guide_size_for_bbox, max_size,
|
||||
seg.bbox, seg_seed, steps, cfg, sampler_name, scheduler,
|
||||
cropped_positive, cropped_negative, denoise, cropped_mask, force_inpaint,
|
||||
|
||||
+78
-60
@@ -10,7 +10,6 @@ import re
|
||||
import nodes
|
||||
import traceback
|
||||
|
||||
|
||||
class ImpactCompare:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -631,85 +630,104 @@ class ImpactControlBridge:
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {
|
||||
"value": (any_typ,),
|
||||
"mode": ("BOOLEAN", {"default": True, "label_on": "Active", "label_off": "Mute/Bypass"}),
|
||||
"behavior": ("BOOLEAN", {"default": True, "label_on": "Mute", "label_off": "Bypass"}),
|
||||
"mode": ("BOOLEAN", {"default": True, "label_on": "Active", "label_off": "Stop/Mute/Bypass"}),
|
||||
"behavior": (["Stop", "Mute", "Bypass"], ),
|
||||
},
|
||||
"hidden": {"unique_id": "UNIQUE_ID", "prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"}
|
||||
}
|
||||
|
||||
FUNCTION = "doit"
|
||||
|
||||
CATEGORY = "ImpactPack/Logic/_for_test"
|
||||
CATEGORY = "ImpactPack/Logic"
|
||||
RETURN_TYPES = (any_typ,)
|
||||
RETURN_NAMES = ("value",)
|
||||
OUTPUT_NODE = True
|
||||
|
||||
DESCRIPTION = ("When behavior is Stop and mode is active, the input value is passed directly to the output.\n"
|
||||
"When behavior is Mute/Bypass and mode is active, the node connected to the output is changed to active state.\n"
|
||||
"When behavior is Stop and mode is Stop/Mute/Bypass, the workflow execution of the current node is halted.\n"
|
||||
"When behavior is Mute/Bypass and mode is Stop/Mute/Bypass, the node connected to the output is changed to Mute/Bypass state.")
|
||||
|
||||
@classmethod
|
||||
def IS_CHANGED(self, value, mode, behavior=True, unique_id=None, prompt=None, extra_pnginfo=None):
|
||||
# NOTE: extra_pnginfo is not populated for IS_CHANGED.
|
||||
# so extra_pnginfo is useless in here
|
||||
try:
|
||||
workflow = core.current_prompt['extra_data']['extra_pnginfo']['workflow']
|
||||
except:
|
||||
print(f"[Impact Pack] core.current_prompt['extra_data']['extra_pnginfo']['workflow']")
|
||||
return 0
|
||||
def IS_CHANGED(self, value, mode, behavior="Stop", unique_id=None, prompt=None, extra_pnginfo=None):
|
||||
if behavior == "Stop":
|
||||
return value, mode, behavior
|
||||
else:
|
||||
# NOTE: extra_pnginfo is not populated for IS_CHANGED.
|
||||
# so extra_pnginfo is useless in here
|
||||
try:
|
||||
workflow = core.current_prompt['extra_data']['extra_pnginfo']['workflow']
|
||||
except:
|
||||
print(f"[Impact Pack] core.current_prompt['extra_data']['extra_pnginfo']['workflow']")
|
||||
return 0
|
||||
|
||||
nodes, links = workflow_to_map(workflow)
|
||||
next_nodes = []
|
||||
nodes, links = workflow_to_map(workflow)
|
||||
next_nodes = []
|
||||
|
||||
for link in nodes[unique_id]['outputs'][0]['links']:
|
||||
node_id = str(links[link][2])
|
||||
impact.utils.collect_non_reroute_nodes(nodes, links, next_nodes, node_id)
|
||||
for link in nodes[unique_id]['outputs'][0]['links']:
|
||||
node_id = str(links[link][2])
|
||||
impact.utils.collect_non_reroute_nodes(nodes, links, next_nodes, node_id)
|
||||
|
||||
return next_nodes
|
||||
|
||||
def doit(self, value, mode, behavior=True, unique_id=None, prompt=None, extra_pnginfo=None):
|
||||
def doit(self, value, mode, behavior="Stop", unique_id=None, prompt=None, extra_pnginfo=None):
|
||||
global error_skip_flag
|
||||
|
||||
workflow_nodes, links = workflow_to_map(extra_pnginfo['workflow'])
|
||||
|
||||
active_nodes = []
|
||||
mute_nodes = []
|
||||
bypass_nodes = []
|
||||
|
||||
for link in workflow_nodes[unique_id]['outputs'][0]['links']:
|
||||
node_id = str(links[link][2])
|
||||
|
||||
next_nodes = []
|
||||
impact.utils.collect_non_reroute_nodes(workflow_nodes, links, next_nodes, node_id)
|
||||
|
||||
for next_node_id in next_nodes:
|
||||
node_mode = workflow_nodes[next_node_id]['mode']
|
||||
|
||||
if node_mode == 0:
|
||||
active_nodes.append(next_node_id)
|
||||
elif node_mode == 2:
|
||||
mute_nodes.append(next_node_id)
|
||||
elif node_mode == 4:
|
||||
bypass_nodes.append(next_node_id)
|
||||
|
||||
if mode:
|
||||
# active
|
||||
should_be_active_nodes = mute_nodes + bypass_nodes
|
||||
if len(should_be_active_nodes) > 0:
|
||||
PromptServer.instance.send_sync("impact-bridge-continue", {"node_id": unique_id, 'actives': list(should_be_active_nodes)})
|
||||
nodes.interrupt_processing()
|
||||
|
||||
elif behavior:
|
||||
# mute
|
||||
should_be_mute_nodes = active_nodes + bypass_nodes
|
||||
if len(should_be_mute_nodes) > 0:
|
||||
PromptServer.instance.send_sync("impact-bridge-continue", {"node_id": unique_id, 'mutes': list(should_be_mute_nodes)})
|
||||
nodes.interrupt_processing()
|
||||
|
||||
if core.is_execution_model_version_supported:
|
||||
from comfy_execution.graph import ExecutionBlocker
|
||||
else:
|
||||
# bypass
|
||||
should_be_bypass_nodes = active_nodes + mute_nodes
|
||||
if len(should_be_bypass_nodes) > 0:
|
||||
PromptServer.instance.send_sync("impact-bridge-continue", {"node_id": unique_id, 'bypasses': list(should_be_bypass_nodes)})
|
||||
nodes.interrupt_processing()
|
||||
print("[Impact Pack] ImpactControlBridge: ComfyUI is outdated. The 'Stop' behavior cannot function properly.")
|
||||
|
||||
return (value, )
|
||||
if behavior == "Stop":
|
||||
if mode:
|
||||
return (value, )
|
||||
else:
|
||||
return (ExecutionBlocker(None), )
|
||||
else:
|
||||
workflow_nodes, links = workflow_to_map(extra_pnginfo['workflow'])
|
||||
|
||||
active_nodes = []
|
||||
mute_nodes = []
|
||||
bypass_nodes = []
|
||||
|
||||
for link in workflow_nodes[unique_id]['outputs'][0]['links']:
|
||||
node_id = str(links[link][2])
|
||||
|
||||
next_nodes = []
|
||||
impact.utils.collect_non_reroute_nodes(workflow_nodes, links, next_nodes, node_id)
|
||||
|
||||
for next_node_id in next_nodes:
|
||||
node_mode = workflow_nodes[next_node_id]['mode']
|
||||
|
||||
if node_mode == 0:
|
||||
active_nodes.append(next_node_id)
|
||||
elif node_mode == 2:
|
||||
mute_nodes.append(next_node_id)
|
||||
elif node_mode == 4:
|
||||
bypass_nodes.append(next_node_id)
|
||||
|
||||
if mode:
|
||||
# active
|
||||
should_be_active_nodes = mute_nodes + bypass_nodes
|
||||
if len(should_be_active_nodes) > 0:
|
||||
PromptServer.instance.send_sync("impact-bridge-continue", {"node_id": unique_id, 'actives': list(should_be_active_nodes)})
|
||||
nodes.interrupt_processing()
|
||||
|
||||
elif behavior == "Mute" or behavior == True:
|
||||
# mute
|
||||
should_be_mute_nodes = active_nodes + bypass_nodes
|
||||
if len(should_be_mute_nodes) > 0:
|
||||
PromptServer.instance.send_sync("impact-bridge-continue", {"node_id": unique_id, 'mutes': list(should_be_mute_nodes)})
|
||||
nodes.interrupt_processing()
|
||||
|
||||
else:
|
||||
# bypass
|
||||
should_be_bypass_nodes = active_nodes + mute_nodes
|
||||
if len(should_be_bypass_nodes) > 0:
|
||||
PromptServer.instance.send_sync("impact-bridge-continue", {"node_id": unique_id, 'bypasses': list(should_be_bypass_nodes)})
|
||||
nodes.interrupt_processing()
|
||||
|
||||
return (value, )
|
||||
|
||||
|
||||
class ImpactExecutionOrderController:
|
||||
|
||||
@@ -5,7 +5,7 @@ from impact.utils import *
|
||||
from nodes import MAX_RESOLUTION
|
||||
import nodes
|
||||
from impact.impact_sampling import KSamplerWrapper, KSamplerAdvancedWrapper, separated_sample, impact_sample
|
||||
|
||||
import comfy
|
||||
|
||||
class TiledKSamplerProvider:
|
||||
@classmethod
|
||||
@@ -332,6 +332,10 @@ class RegionalSampler:
|
||||
@staticmethod
|
||||
def doit(seed, seed_2nd, seed_2nd_mode, steps, base_only_steps, denoise, samples, base_sampler, regional_prompts, overlap_factor, restore_latent,
|
||||
additional_mode, additional_sampler, additional_sigma_ratio, unique_id=None):
|
||||
|
||||
samples = samples.copy()
|
||||
samples['samples'] = comfy.sample.fix_empty_latent_channels(base_sampler.params[0], samples['samples'])
|
||||
|
||||
if restore_latent:
|
||||
latent_compositor = nodes.NODE_CLASS_MAPPINGS['LatentCompositeMasked']()
|
||||
else:
|
||||
@@ -476,6 +480,9 @@ class RegionalSamplerAdvanced:
|
||||
def doit(add_noise, noise_seed, steps, start_at_step, end_at_step, overlap_factor, restore_latent, return_with_leftover_noise, latent_image, base_sampler, regional_prompts,
|
||||
additional_mode, additional_sampler, additional_sigma_ratio, unique_id):
|
||||
|
||||
new_latent_image = latent_image.copy()
|
||||
new_latent_image['samples'] = comfy.sample.fix_empty_latent_channels(base_sampler.params[0], new_latent_image['samples'])
|
||||
|
||||
if restore_latent:
|
||||
latent_compositor = nodes.NODE_CLASS_MAPPINGS['LatentCompositeMasked']()
|
||||
else:
|
||||
@@ -491,7 +498,6 @@ class RegionalSamplerAdvanced:
|
||||
end_at_step = min(steps, end_at_step)
|
||||
total = (end_at_step - start_at_step) * region_len
|
||||
|
||||
new_latent_image = latent_image.copy()
|
||||
base_latent_image = None
|
||||
region_masks = {}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from impact.utils import any_typ, ByPassTypeTuple, make_3d_mask
|
||||
import comfy_extras.nodes_mask
|
||||
from comfy_execution.graph import ExecutionBlocker
|
||||
from nodes import MAX_RESOLUTION
|
||||
import torch
|
||||
import comfy
|
||||
@@ -166,6 +165,8 @@ class GeneralInversedSwitch:
|
||||
def doit(self, select, prompt, unique_id, input, **kwargs):
|
||||
if core.is_execution_model_version_supported:
|
||||
from comfy_execution.graph import ExecutionBlocker
|
||||
else:
|
||||
print("[Impact Pack] InversedSwitch: ComfyUI is outdated. The 'select_on_execution' mode cannot function properly.")
|
||||
|
||||
res = []
|
||||
|
||||
|
||||
+15
-12
@@ -425,7 +425,7 @@ def process_with_loras(wildcard_opt, model, clip, clip_encoder=None, seed=None,
|
||||
|
||||
def starts_with_regex(pattern, text):
|
||||
regex = re.compile(pattern)
|
||||
return bool(regex.match(text))
|
||||
return regex.match(text)
|
||||
|
||||
|
||||
def split_to_dict(text):
|
||||
@@ -507,18 +507,21 @@ def process_wildcard_for_segs(wildcard):
|
||||
|
||||
return 'LAB', WildcardChooserDict(items)
|
||||
|
||||
elif starts_with_regex(r"\[(ASC|DSC|RND)\]", wildcard):
|
||||
mode = wildcard[1:4]
|
||||
items = split_string_with_sep(wildcard[5:])
|
||||
|
||||
if mode == 'RND':
|
||||
random.shuffle(items)
|
||||
return mode, WildcardChooser(items, True)
|
||||
else:
|
||||
return mode, WildcardChooser(items, False)
|
||||
|
||||
else:
|
||||
return None, WildcardChooser([(None, wildcard)], False)
|
||||
match = starts_with_regex(r"\[(ASC-SIZE|DSC-SIZE|ASC|DSC|RND)\]", wildcard)
|
||||
|
||||
if match:
|
||||
mode = match[1]
|
||||
items = split_string_with_sep(wildcard[len(match[0]):])
|
||||
|
||||
if mode == 'RND':
|
||||
random.shuffle(items)
|
||||
return mode, WildcardChooser(items, True)
|
||||
else:
|
||||
return mode, WildcardChooser(items, False)
|
||||
|
||||
else:
|
||||
return None, WildcardChooser([(None, wildcard)], False)
|
||||
|
||||
|
||||
def wildcard_load():
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "comfyui-impact-pack"
|
||||
description = "This extension offers various detector nodes and detailer nodes that allow you to configure a workflow that automatically enhances facial details. And provide iterative upscaler."
|
||||
version = "7.2.1"
|
||||
version = "7.3.1"
|
||||
license = { file = "LICENSE.txt" }
|
||||
dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user