From dc70f40effeb21681f30af65062bc1b2a40fdd82 Mon Sep 17 00:00:00 2001 From: Vedat Baday <54285744+badayvedat@users.noreply.github.com> Date: Sat, 2 Nov 2024 19:13:37 +0000 Subject: [PATCH 01/19] perf: cache pip installed packages (#803) --- install-manual.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install-manual.py b/install-manual.py index cc2b70c..5d15423 100644 --- a/install-manual.py +++ b/install-manual.py @@ -1,3 +1,4 @@ +import functools import os import re import shutil @@ -70,6 +71,7 @@ def process_wrap(cmd_str, cwd=None, handler=None, env=None): return process.wait() +@functools.cache def get_installed_packages() -> Set[str]: try: result = subprocess.check_output([sys.executable, '-m', 'pip', 'list'], universal_newlines=True) From cd89590a7ddb50bb17b147b87d11e7e6618f06ac Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Thu, 7 Nov 2024 23:33:59 +0900 Subject: [PATCH 02/19] FEAT: `List Bridge` node is added. --- README.md | 1 + __init__.py | 2 ++ modules/impact/config.py | 2 +- modules/impact/logics.py | 23 +++++++++++++++++++++++ pyproject.toml | 2 +- 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 23b1532..fc74297 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,7 @@ This custom node helps to conveniently enhance images through Detector, Detailer * `Negative Cond Placeholder` - Models like FLUX.1 do not use Negative Conditioning. This is a placeholder node for them. You can use FLUX.1 by replacing the Negative Conditioning used in Impact KSampler, KSampler (Inspire), and Detailer with this node. * `Execution Order Controller` - A helper node that can forcibly control the execution order of nodes. * Connect the output of the node that should be executed first to the signal, and make the input of the node that should be executed later pass through this node. + * `List Bridge` - When passing the list output through this node, it collects and organizes the data before forwarding it, which ensures that the previous stage's sub-workflow has been completed. ## MMDet nodes (DEPRECATED) - Don't use these nodes diff --git a/__init__.py b/__init__.py index 862b8b3..922c59b 100644 --- a/__init__.py +++ b/__init__.py @@ -273,6 +273,7 @@ NODE_CLASS_MAPPINGS = { "StringListToString": StringListToString, "WildcardPromptFromString": WildcardPromptFromString, "ImpactExecutionOrderController": ImpactExecutionOrderController, + "ImpactListBridge": ImpactListBridge, "RemoveNoiseMask": RemoveNoiseMask, @@ -393,6 +394,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { "ImpactSwitch": "Switch (Any)", "ImpactInversedSwitch": "Inversed Switch (Any)", "ImpactExecutionOrderController": "Execution Order Controller", + "ImpactListBridge": "List Bridge", "MasksToMaskList": "Mask Batch to Mask List", "MaskListToMaskBatch": "Mask List to Mask Batch", diff --git a/modules/impact/config.py b/modules/impact/config.py index 25807f0..2b14e2b 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 10, 7] +version_code = [7, 11] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 23 diff --git a/modules/impact/logics.py b/modules/impact/logics.py index eeea845..d943342 100644 --- a/modules/impact/logics.py +++ b/modules/impact/logics.py @@ -766,6 +766,29 @@ class ImpactExecutionOrderController: return signal, value +class ImpactListBridge: + @classmethod + def INPUT_TYPES(cls): + return {"required": { + "list_input": (any_typ,), + }} + + FUNCTION = "doit" + + DESCRIPTION = "When passing the list output through this node, it collects and organizes the data before forwarding it, which ensures that the previous stage's sub-workflow has been completed." + + CATEGORY = "ImpactPack/Util" + RETURN_TYPES = (any_typ, ) + RETURN_NAMES = ("list_output", ) + + INPUT_IS_LIST = True + OUTPUT_IS_LIST = (True, ) + + @staticmethod + def doit(list_input): + return (list_input,) + + original_handle_execution = execution.PromptExecutor.handle_execution_error diff --git a/pyproject.toml b/pyproject.toml index 9c821d8..c4fa04c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.10.7" +version = "7.11" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From 314b676cc35e336f13f9a05c8d0c93d21ba2f4bd Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Fri, 8 Nov 2024 21:58:06 +0900 Subject: [PATCH 03/19] FIX: compatibility patch latest ComfyUI update. https://github.com/comfyanonymous/ComfyUI/commit/b49616f9511c57c8d54c4032e305d72352ac4ff5 https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/812 --- modules/impact/config.py | 2 +- modules/impact/core.py | 41 ++++++++++++++++++++++------------------ pyproject.toml | 2 +- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index 2b14e2b..c9a5272 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 11] +version_code = [7, 11, 1] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 23 diff --git a/modules/impact/core.py b/modules/impact/core.py index a1bf30b..c763ae5 100644 --- a/modules/impact/core.py +++ b/modules/impact/core.py @@ -1354,9 +1354,14 @@ def segs_to_masklist(segs): return masks -def vae_decode(vae, samples, use_tile, hook, tile_size=512): +def vae_decode(vae, samples, use_tile, hook, tile_size=512, overlap=64): if use_tile: - pixels = nodes.VAEDecodeTiled().decode(vae, samples, tile_size)[0] + decoder = nodes.VAEDecodeTiled() + if 'overlap' in inspect.signature(decoder.decode).parameters: + pixels = decoder.decode(vae, samples, tile_size, overlap=overlap)[0] + else: + print(f"[Impact Pack] Your ComfyUI is outdated.") + pixels = decoder.decode(vae, samples, tile_size)[0] else: pixels = nodes.VAEDecode().decode(vae, samples)[0] @@ -1378,12 +1383,12 @@ def vae_encode(vae, pixels, use_tile, hook, tile_size=512): return samples -def latent_upscale_on_pixel_space_shape(samples, scale_method, w, h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None): - return latent_upscale_on_pixel_space_shape2(samples, scale_method, w, h, vae, use_tile, tile_size, save_temp_prefix, hook)[0] +def latent_upscale_on_pixel_space_shape(samples, scale_method, w, h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None, overlap=64): + return latent_upscale_on_pixel_space_shape2(samples, scale_method, w, h, vae, use_tile, tile_size, save_temp_prefix, hook, overlap=overlap)[0] -def latent_upscale_on_pixel_space_shape2(samples, scale_method, w, h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None): - pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size) +def latent_upscale_on_pixel_space_shape2(samples, scale_method, w, h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None, overlap=64): + pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size, overlap=overlap) if save_temp_prefix is not None: nodes.PreviewImage().save_images(pixels, filename_prefix=save_temp_prefix) @@ -1397,12 +1402,12 @@ def latent_upscale_on_pixel_space_shape2(samples, scale_method, w, h, vae, use_t return (vae_encode(vae, pixels, use_tile, hook, tile_size=tile_size), old_pixels) -def latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None): - return latent_upscale_on_pixel_space2(samples, scale_method, scale_factor, vae, use_tile, tile_size, save_temp_prefix, hook)[0] +def latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None, overlap=64): + return latent_upscale_on_pixel_space2(samples, scale_method, scale_factor, vae, use_tile, tile_size, save_temp_prefix, hook, overlap=overlap)[0] -def latent_upscale_on_pixel_space2(samples, scale_method, scale_factor, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None): - pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size) +def latent_upscale_on_pixel_space2(samples, scale_method, scale_factor, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None, overlap=64): + pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size, overlap=overlap) if save_temp_prefix is not None: nodes.PreviewImage().save_images(pixels, filename_prefix=save_temp_prefix) @@ -1418,12 +1423,12 @@ def latent_upscale_on_pixel_space2(samples, scale_method, scale_factor, vae, use return (vae_encode(vae, pixels, use_tile, hook, tile_size=tile_size), old_pixels) -def latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, upscale_model, new_w, new_h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None): - return latent_upscale_on_pixel_space_with_model_shape2(samples, scale_method, upscale_model, new_w, new_h, vae, use_tile, tile_size, save_temp_prefix, hook)[0] +def latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, upscale_model, new_w, new_h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None, overlap=64): + return latent_upscale_on_pixel_space_with_model_shape2(samples, scale_method, upscale_model, new_w, new_h, vae, use_tile, tile_size, save_temp_prefix, hook, overlap=overlap)[0] -def latent_upscale_on_pixel_space_with_model_shape2(samples, scale_method, upscale_model, new_w, new_h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None): - pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size) +def latent_upscale_on_pixel_space_with_model_shape2(samples, scale_method, upscale_model, new_w, new_h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None, overlap=64): + pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size, overlap=overlap) if save_temp_prefix is not None: nodes.PreviewImage().save_images(pixels, filename_prefix=save_temp_prefix) @@ -1450,12 +1455,12 @@ def latent_upscale_on_pixel_space_with_model_shape2(samples, scale_method, upsca def latent_upscale_on_pixel_space_with_model(samples, scale_method, upscale_model, scale_factor, vae, use_tile=False, - tile_size=512, save_temp_prefix=None, hook=None): - return latent_upscale_on_pixel_space_with_model2(samples, scale_method, upscale_model, scale_factor, vae, use_tile, tile_size, save_temp_prefix, hook)[0] + tile_size=512, save_temp_prefix=None, hook=None, overlap=64): + return latent_upscale_on_pixel_space_with_model2(samples, scale_method, upscale_model, scale_factor, vae, use_tile, tile_size, save_temp_prefix, hook, overlap=overlap)[0] def latent_upscale_on_pixel_space_with_model2(samples, scale_method, upscale_model, scale_factor, vae, use_tile=False, - tile_size=512, save_temp_prefix=None, hook=None): - pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size) + tile_size=512, save_temp_prefix=None, hook=None, overlap=64): + pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size, overlap=overlap) if save_temp_prefix is not None: nodes.PreviewImage().save_images(pixels, filename_prefix=save_temp_prefix) diff --git a/pyproject.toml b/pyproject.toml index c4fa04c..bb728aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.11" +version = "7.11.1" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From 216f4660e1c6e2ecba6a07fbda3a4d719df682e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=2ED=2ET=C3=A0i?= Date: Fri, 8 Nov 2024 20:01:28 +0700 Subject: [PATCH 04/19] Typecast possible float values in SEG_ELT to int (#811) --- modules/impact/segs_nodes.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/impact/segs_nodes.py b/modules/impact/segs_nodes.py index 9ba4d25..37bb95f 100644 --- a/modules/impact/segs_nodes.py +++ b/modules/impact/segs_nodes.py @@ -896,7 +896,7 @@ class From_SEG_ELT_bbox: CATEGORY = "ImpactPack/Util" def doit(self, bbox): - return bbox + return [int(c) for c in bbox] class From_SEG_ELT_crop_region: @@ -1101,10 +1101,10 @@ class SEG_ELT_BBOX_ScaleBy: x1, y1, x2, y2 = x1-cx1, y1-cy1, x2-cx1, y2-cy1 h, w = mask.shape - x1 = min(w-1, max(0, x1)) - x2 = min(w-1, max(0, x2)) - y1 = min(h-1, max(0, y1)) - y2 = min(h-1, max(0, y2)) + x1 = int(min(w-1, max(0, x1))) + x2 = int(min(w-1, max(0, x2))) + y1 = int(min(h-1, max(0, y1))) + y2 = int(min(h-1, max(0, y2))) mask_cropped = mask.copy() mask_cropped[:, :x1] = 0 # zero fill left side From 6fe85ed6bfab0776777a520f70deaef62f59e650 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Fri, 8 Nov 2024 22:02:22 +0900 Subject: [PATCH 05/19] version marker --- modules/impact/config.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index c9a5272..b6ff6c8 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 11, 1] +version_code = [7, 11, 2] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 23 diff --git a/pyproject.toml b/pyproject.toml index bb728aa..afaaa41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.11.1" +version = "7.11.2" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From 24de5a846bb9b1c1830af0218f76266c375cc904 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Sat, 9 Nov 2024 19:46:33 +0900 Subject: [PATCH 06/19] hotfix: failing of ultralytics due to security policy --- modules/impact/config.py | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index b6ff6c8..553ddba 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,10 +1,10 @@ import configparser import os -version_code = [7, 11, 2] +version_code = [7, 11, 3] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') -dependency_version = 23 +dependency_version = 24 my_path = os.path.dirname(__file__) old_config_path = os.path.join(my_path, "impact-pack.ini") diff --git a/pyproject.toml b/pyproject.toml index afaaa41..50ae96e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.11.2" +version = "7.11.3" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From 48b4254e811b9d1794d5053cc4e282cdc17edb67 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 20 Nov 2024 09:46:42 +0900 Subject: [PATCH 07/19] fix: compatibility patch for updated ComfyUI https://github.com/comfyanonymous/ComfyUI/commit/156a28786be9ba6352061090096462bfb1b485bb https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/821 --- modules/impact/config.py | 2 +- modules/impact/core.py | 7 ++++++- modules/impact/segs_upscaler.py | 7 ++++++- pyproject.toml | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index 553ddba..e064469 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 11, 3] +version_code = [7, 11, 4] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 24 diff --git a/modules/impact/core.py b/modules/impact/core.py index c763ae5..a1cc056 100644 --- a/modules/impact/core.py +++ b/modules/impact/core.py @@ -319,7 +319,12 @@ def enhance_detail(image, model, clip, vae, guide_size, guide_size_for_bbox, max # prepare mask if noise_mask is not None and inpaint_model: - positive, negative, latent_image = nodes.InpaintModelConditioning().encode(positive, negative, upscaled_image, vae, noise_mask) + imc_encode = nodes.InpaintModelConditioning().encode + if 'noise_mask' in inspect.signature(imc_encode).parameters: + positive, negative, latent_image = imc_encode(positive, negative, upscaled_image, vae, mask=noise_mask, noise_mask=True) + else: + print(f"[Impact Pack] ComfyUI is an outdated version.") + positive, negative, latent_image = imc_encode(positive, negative, upscaled_image, vae, noise_mask) else: latent_image = to_latent_image(upscaled_image, vae) if noise_mask is not None: diff --git a/modules/impact/segs_upscaler.py b/modules/impact/segs_upscaler.py index 08bbf95..3696855 100644 --- a/modules/impact/segs_upscaler.py +++ b/modules/impact/segs_upscaler.py @@ -106,7 +106,12 @@ def img2img_segs(image, model, clip, vae, seed, steps, cfg, sampler_name, schedu # prepare mask if noise_mask is not None and inpaint_model: - positive, negative, latent_image = nodes.InpaintModelConditioning().encode(positive, negative, image, vae, noise_mask) + imc_encode = nodes.InpaintModelConditioning().encode + if 'noise_mask' in inspect.signature(imc_encode).parameters: + positive, negative, latent_image = imc_encode(positive, negative, image, vae, mask=noise_mask, noise_mask=True) + else: + print(f"[Impact Pack] ComfyUI is an outdated version.") + positive, negative, latent_image = imc_encode(positive, negative, image, vae, noise_mask) else: latent_image = to_latent_image(image, vae) if noise_mask is not None: diff --git a/pyproject.toml b/pyproject.toml index 50ae96e..a8e464f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.11.3" +version = "7.11.4" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From 37f465d4a971c9377e681e326c81a0f51c851e05 Mon Sep 17 00:00:00 2001 From: FennelFetish Date: Fri, 22 Nov 2024 05:28:50 +0100 Subject: [PATCH 08/19] Fixes call to make_3d_mask in MakeMaskBatch (#823) --- modules/impact/util_nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/impact/util_nodes.py b/modules/impact/util_nodes.py index 734f43d..6b91468 100644 --- a/modules/impact/util_nodes.py +++ b/modules/impact/util_nodes.py @@ -501,7 +501,7 @@ class MakeMaskBatch: def doit(self, **kwargs): mask1 = kwargs['mask1'] del kwargs['mask1'] - masks = [utils.make_3d_mask(value) for value in kwargs.values()] + masks = [make_3d_mask(value) for value in kwargs.values()] if len(masks) == 0: return (mask1,) From f7686845c6e99b3797b3cabb660ab82869945ccf Mon Sep 17 00:00:00 2001 From: Jonathan Nogueira Date: Fri, 22 Nov 2024 04:41:55 +0000 Subject: [PATCH 09/19] Update core.py - save mask when edited (#817) * Update core.py - save mask when edited In order to facilitate the `restore_mask` functionality better, one needs to save the mask to the cache when the mask is edited. * Update core.py - add missing unsqueeze(0) mask cache was missing unsqueeze function, giving the resulting mask the wrong size. --- modules/impact/core.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/impact/core.py b/modules/impact/core.py index a1cc056..2abfd11 100644 --- a/modules/impact/core.py +++ b/modules/impact/core.py @@ -11,6 +11,7 @@ from impact.utils import * from collections import namedtuple import numpy as np from skimage.measure import label +from PIL import ImageOps import nodes import comfy_extras.nodes_upscale_model as model_upscale @@ -69,6 +70,13 @@ def set_previewbridge_image(node_id, file, item): pb_id = f"${node_id}-{pb_id_cnt}" preview_bridge_image_id_map[pb_id] = (file, item) preview_bridge_image_name_map[node_id, file] = (pb_id, item) + if os.path.isfile(file): + i = Image.open(file) + i = ImageOps.exif_transpose(i) + if 'A' in i.getbands(): + mask = np.array(i.getchannel('A')).astype(np.float32) / 255.0 + mask = 1. - torch.from_numpy(mask) + preview_bridge_last_mask_cache[node_id] = mask.unsqueeze(0) pb_id_cnt += 1 return pb_id From e1e408d8c9330dac7beff8688b1895bff5a191e2 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Fri, 22 Nov 2024 21:37:23 +0900 Subject: [PATCH 10/19] improve: add description to wildcard nodes --- modules/impact/config.py | 2 +- modules/impact/impact_pack.py | 24 ++++++++++++++++-------- pyproject.toml | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index e064469..128aa9b 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 11, 4] +version_code = [7, 11, 5] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 24 diff --git a/modules/impact/impact_pack.py b/modules/impact/impact_pack.py index 6dab1ac..b41c698 100644 --- a/modules/impact/impact_pack.py +++ b/modules/impact/impact_pack.py @@ -2150,16 +2150,19 @@ class ImpactWildcardProcessor: @classmethod def INPUT_TYPES(s): return {"required": { - "wildcard_text": ("STRING", {"multiline": True, "dynamicPrompts": False}), - "populated_text": ("STRING", {"multiline": True, "dynamicPrompts": False}), - "mode": ("BOOLEAN", {"default": True, "label_on": "Populate", "label_off": "Fixed"}), - "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), + "wildcard_text": ("STRING", {"multiline": True, "dynamicPrompts": False, "tooltip": "Enter a prompt using wildcard syntax."}), + "populated_text": ("STRING", {"multiline": True, "dynamicPrompts": False, "tooltip": "The actual value passed during the execution of 'ImpactWildcardProcessor' is what is shown here. The behavior varies slightly depending on the mode. Wildcard syntax can also be used in 'populated_text'."}), + "mode": ("BOOLEAN", {"default": True, "label_on": "Populate", "label_off": "Fixed", "tooltip": "Populate: Before running the workflow, it overwrites the existing value of 'populated_text' with the prompt processed from 'wildcard_text'. In this mode, 'populated_text' cannot be edited.\nFixed: Ignores wildcard_text and keeps 'populated_text' as is. You can edit 'populated_text' in this mode."}), + "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff, "tooltip": "Determines the random seed to be used for wildcard processing."}), "Select to add Wildcard": (["Select the Wildcard to add to the text"],), }, } CATEGORY = "ImpactPack/Prompt" + DESCRIPTION = ("The 'ImpactWildcardProcessor' processes text prompts written in wildcard syntax and outputs the processed text prompt.\n\n" + "TIP: Before the workflow is executed, the processing result of 'wildcard_text' is displayed in 'populated_text', and the populated text is saved along with the workflow. If you want to use a seed converted as input, write the prompt directly in 'populated_text' instead of 'wildcard_text', and set the mode to 'Fixed'.") + RETURN_TYPES = ("STRING", ) FUNCTION = "doit" @@ -2178,17 +2181,22 @@ class ImpactWildcardEncode: return {"required": { "model": ("MODEL",), "clip": ("CLIP",), - "wildcard_text": ("STRING", {"multiline": True, "dynamicPrompts": False}), - "populated_text": ("STRING", {"multiline": True, "dynamicPrompts": False}), - "mode": ("BOOLEAN", {"default": True, "label_on": "Populate", "label_off": "Fixed"}), + "wildcard_text": ("STRING", {"multiline": True, "dynamicPrompts": False, "tooltip": "Enter a prompt using wildcard syntax."}), + "populated_text": ("STRING", {"multiline": True, "dynamicPrompts": False, "tooltip": "The actual value passed during the execution of 'ImpactWildcardEncode' is what is shown here. The behavior varies slightly depending on the mode. Wildcard syntax can also be used in 'populated_text'."}), + "mode": ("BOOLEAN", {"default": True, "label_on": "Populate", "label_off": "Fixed", "tooltip": "Populate: Before running the workflow, it overwrites the existing value of 'populated_text' with the prompt processed from 'wildcard_text'. In this mode, 'populated_text' cannot be edited.\n" + "Fixed: Ignores wildcard_text and keeps 'populated_text' as is. You can edit 'populated_text' in this mode."}), "Select to add LoRA": (["Select the LoRA to add to the text"] + folder_paths.get_filename_list("loras"), ), "Select to add Wildcard": (["Select the Wildcard to add to the text"], ), - "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), + "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff, "tooltip": "Determines the random seed to be used for wildcard processing."}), }, } CATEGORY = "ImpactPack/Prompt" + DESCRIPTION = ("The 'ImpactWildcardEncode' node processes text prompts written in wildcard syntax and outputs them as conditioning. It also supports LoRA syntax, with the applied LoRA reflected in the model's output.\n\n" + "TIP1: Before the workflow is executed, the processing result of 'wildcard_text' is displayed in 'populated_text', and the populated text is saved along with the workflow. If you want to use a seed converted as input, write the prompt directly in 'populated_text' instead of 'wildcard_text', and set the mode to 'Fixed'.\n" + "TIP2: If the 'Inspire Pack' is installed, LBW(LoRA Block Weight) syntax can also be applied.") + RETURN_TYPES = ("MODEL", "CLIP", "CONDITIONING", "STRING") RETURN_NAMES = ("model", "clip", "conditioning", "populated_text") FUNCTION = "doit" diff --git a/pyproject.toml b/pyproject.toml index a8e464f..bacda34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.11.4" +version = "7.11.5" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From a2bb6f7c910ccf44a1ae86ff660e82a7133e7be0 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Tue, 26 Nov 2024 01:16:57 +0900 Subject: [PATCH 11/19] feat: `LTXV[default]` scheduler is added --- modules/impact/config.py | 2 +- modules/impact/core.py | 2 +- modules/impact/impact_pack.py | 2 +- modules/impact/impact_sampling.py | 2 ++ pyproject.toml | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index 128aa9b..1de4647 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 11, 5] +version_code = [7, 12] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 24 diff --git a/modules/impact/core.py b/modules/impact/core.py index 2abfd11..f5e4ef6 100644 --- a/modules/impact/core.py +++ b/modules/impact/core.py @@ -48,7 +48,7 @@ preview_bridge_last_mask_cache = {} current_prompt = None -SCHEDULERS = comfy.samplers.KSampler.SCHEDULERS + ['AYS SDXL', 'AYS SD1', 'AYS SVD', 'GITS[coeff=1.2]'] +SCHEDULERS = comfy.samplers.KSampler.SCHEDULERS + ['AYS SDXL', 'AYS SD1', 'AYS SVD', 'GITS[coeff=1.2]', 'LTXV[default]'] def is_execution_model_version_supported(): diff --git a/modules/impact/impact_pack.py b/modules/impact/impact_pack.py index b41c698..8b36a8c 100644 --- a/modules/impact/impact_pack.py +++ b/modules/impact/impact_pack.py @@ -2221,7 +2221,7 @@ class ImpactSchedulerAdapter: def INPUT_TYPES(s): return {"required": { "scheduler": (comfy.samplers.KSampler.SCHEDULERS, {"defaultInput": True, }), - "extra_scheduler": (['None', 'AYS SDXL', 'AYS SD1', 'AYS SVD', 'GITS[coeff=1.2]'],), + "extra_scheduler": (['None', 'AYS SDXL', 'AYS SD1', 'AYS SVD', 'GITS[coeff=1.2]', 'LTXV[default]'],), }} CATEGORY = "ImpactPack/Util" diff --git a/modules/impact/impact_sampling.py b/modules/impact/impact_sampling.py index ea1eb45..2a35894 100644 --- a/modules/impact/impact_sampling.py +++ b/modules/impact/impact_sampling.py @@ -27,6 +27,8 @@ def calculate_sigmas(model, sampler, scheduler, steps): sigmas = nodes.NODE_CLASS_MAPPINGS['AlignYourStepsScheduler']().get_sigmas(scheduler[4:], steps, denoise=1.0)[0] elif scheduler.startswith('GITS[coeff='): sigmas = nodes.NODE_CLASS_MAPPINGS['GITSScheduler']().get_sigmas(float(scheduler[11:-1]), steps, denoise=1.0)[0] + elif scheduler == 'LTXV[default]': + sigmas = nodes.NODE_CLASS_MAPPINGS['LTXVScheduler']().get_sigmas(20, 2.05, 0.95, True, 0.1)[0] else: sigmas = samplers.calculate_sigmas(model.get_model_object("model_sampling"), scheduler, steps) diff --git a/pyproject.toml b/pyproject.toml index bacda34..4be81dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.11.5" +version = "7.12" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From c9b3aecd1af14f39b2dd311f096a24dbea18d5aa Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Tue, 26 Nov 2024 18:33:27 +0900 Subject: [PATCH 12/19] fix: install script exception handling for torchvision.download_url --- install.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/install.py b/install.py index 6fbb9b5..5803d79 100644 --- a/install.py +++ b/install.py @@ -114,19 +114,22 @@ try: onnx_path = os.path.join(model_path, "onnx") if not os.path.exists(os.path.join(os.path.dirname(__file__), '..', 'skip_download_model')): - if not impact.config.get_config()['mmdet_skip']: - bbox_path = os.path.join(model_path, "mmdets", "bbox") - if not os.path.exists(bbox_path): - os.makedirs(bbox_path) + try: + if not impact.config.get_config()['mmdet_skip']: + bbox_path = os.path.join(model_path, "mmdets", "bbox") + if not os.path.exists(bbox_path): + os.makedirs(bbox_path) - if not os.path.exists(os.path.join(bbox_path, "mmdet_anime-face_yolov3.pth")): - download_url("https://huggingface.co/dustysys/ddetailer/resolve/main/mmdet/bbox/mmdet_anime-face_yolov3.pth", bbox_path) + if not os.path.exists(os.path.join(bbox_path, "mmdet_anime-face_yolov3.pth")): + download_url("https://huggingface.co/dustysys/ddetailer/resolve/main/mmdet/bbox/mmdet_anime-face_yolov3.pth", bbox_path) - if not os.path.exists(os.path.join(bbox_path, "mmdet_anime-face_yolov3.py")): - download_url("https://raw.githubusercontent.com/Bing-su/dddetailer/master/config/mmdet_anime-face_yolov3.py", bbox_path) + if not os.path.exists(os.path.join(bbox_path, "mmdet_anime-face_yolov3.py")): + download_url("https://raw.githubusercontent.com/Bing-su/dddetailer/master/config/mmdet_anime-face_yolov3.py", bbox_path) - if not os.path.exists(os.path.join(sam_path, "sam_vit_b_01ec64.pth")): - download_url("https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth", sam_path) + if not os.path.exists(os.path.join(sam_path, "sam_vit_b_01ec64.pth")): + download_url("https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth", sam_path) + except: + print(f"[Impact Pack] Failed to auto-download model files. Please download them manually.") if not os.path.exists(onnx_path): print(f"### ComfyUI-Impact-Pack: onnx model directory created ({onnx_path})") From d4136bc95531606afc77226a2db43a8703945e30 Mon Sep 17 00:00:00 2001 From: filtered <176114999+webfiltered@users.noreply.github.com> Date: Sat, 30 Nov 2024 23:47:22 +1100 Subject: [PATCH 13/19] Prefer widget.callback over stack trace check (#838) * Prefer widget.callback over stack trace check Update to LiteGraph included a rename of a local function. This value was being checked to prevent unwanted value sets. This has been replaced with widget callback(), which for combo boxes is always called when a value is clicked, regardless of any change. * nit * Fix error caused by bug in litegraph Known issue w/widget.callback and setter/getter. --- js/impact-pack.js | 74 ++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/js/impact-pack.js b/js/impact-pack.js index 97ca6ce..4cc1aba 100644 --- a/js/impact-pack.js +++ b/js/impact-pack.js @@ -587,17 +587,17 @@ app.registerExtension({ } if(node.comfyClass == "ImpactSEGSLabelFilter" || node.comfyClass == "SEGSLabelFilterDetailerHookProvider") { + node.widgets[0].callback = (value, canvas, node, pos, e) => { + if(node.widgets[1].value.trim() != "" && !node.widgets[1].value.trim().endsWith(",")) + node.widgets[1].value += ", " + + node.widgets[1].value += value; + if(node.widgets_values) + node.widgets_values[1] = node.widgets[1].value; + } + Object.defineProperty(node.widgets[0], "value", { set: (value) => { - const stackTrace = new Error().stack; - if(stackTrace.includes('inner_value_change')) { - if(node.widgets[1].value.trim() != "" && !node.widgets[1].value.trim().endsWith(",")) - node.widgets[1].value += ", " - - node.widgets[1].value += value; - node.widgets_values[1] = node.widgets[1].value; - } - node._value = value; }, get: () => { @@ -667,18 +667,22 @@ app.registerExtension({ break; } - Object.defineProperty(node.widgets[combo_id+1], "value", { - set: (value) => { - const stackTrace = new Error().stack; - if(stackTrace.includes('inner_value_change')) { - if(value != "Select the Wildcard to add to the text") { - if(node.widgets[tbox_id].value != '') - node.widgets[tbox_id].value += ', ' + const { onWidgetChanged } = node + node.onWidgetChanged = function (widgetName, value, oldValue, widget) { + const result = onWidgetChanged?.apply(this, arguments) - node.widgets[tbox_id].value += value; - } - } - }, + if (value != "Select the Wildcard to add to the text") { + if(node.widgets[tbox_id].value != '') + node.widgets[tbox_id].value += ', ' + + node.widgets[tbox_id].value += value; + } + + return result + } + + Object.defineProperty(node.widgets[combo_id+1], "value", { + set: (value) => {}, get: () => { return "Select the Wildcard to add to the text"; } }); @@ -690,24 +694,22 @@ app.registerExtension({ }); if(has_lora) { + node.widgets[combo_id].callback = (value, canvas, node, pos, e) => { + let lora_name = node._value; + if(lora_name.endsWith('.safetensors')) { + lora_name = lora_name.slice(0, -12); + } + + node.widgets[tbox_id].value += ``; + if(node.widgets_values) { + node.widgets_values[tbox_id] = node.widgets[tbox_id].value; + } + } + Object.defineProperty(node.widgets[combo_id], "value", { set: (value) => { - const stackTrace = new Error().stack; - if(stackTrace.includes('inner_value_change')) { - if(value != "Select the LoRA to add to the text") { - let lora_name = value; - if (lora_name.endsWith('.safetensors')) { - lora_name = lora_name.slice(0, -12); - } - - node.widgets[tbox_id].value += ``; - if(node.widgets_values) { - node.widgets_values[tbox_id] = node.widgets[tbox_id].value; - } - } - } - - node._value = value; + if (value !== "Select the LoRA to add to the text") + node._value = value; }, get: () => { return "Select the LoRA to add to the text"; } From 1ec303761303ce50e2ab715f1f16b7abaf641edb Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Sat, 30 Nov 2024 22:48:00 +0900 Subject: [PATCH 14/19] FIXED: wildcard, lora selector bug from https://github.com/ltdrdata/ComfyUI-Impact-Pack/pull/838/files) FIXED: SAM Detector https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/836 --- js/impact-pack.js | 22 +++++++++------------- js/impact-sam-editor.js | 7 +++++-- modules/impact/config.py | 2 +- pyproject.toml | 2 +- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/js/impact-pack.js b/js/impact-pack.js index 4cc1aba..21dd006 100644 --- a/js/impact-pack.js +++ b/js/impact-pack.js @@ -667,22 +667,18 @@ app.registerExtension({ break; } - const { onWidgetChanged } = node - node.onWidgetChanged = function (widgetName, value, oldValue, widget) { - const result = onWidgetChanged?.apply(this, arguments) + node.widgets[combo_id+1].callback = (value, canvas, node, pos, e) => { + if(node.widgets[tbox_id].value != '') + node.widgets[tbox_id].value += ', ' - if (value != "Select the Wildcard to add to the text") { - if(node.widgets[tbox_id].value != '') - node.widgets[tbox_id].value += ', ' - - node.widgets[tbox_id].value += value; - } - - return result - } + node.widgets[tbox_id].value += node._wildcard_value; + } Object.defineProperty(node.widgets[combo_id+1], "value", { - set: (value) => {}, + set: (value) => { + if (value !== "Select the Wildcard to add to the text") + node._wildcard_value = value; + }, get: () => { return "Select the Wildcard to add to the text"; } }); diff --git a/js/impact-sam-editor.js b/js/impact-sam-editor.js index e7bf6f2..cb34309 100644 --- a/js/impact-sam-editor.js +++ b/js/impact-sam-editor.js @@ -353,13 +353,16 @@ class ImpactSamEditorDialog extends ComfyDialog { imgCtx.drawImage(orig_image, 0, 0, drawWidth, drawHeight); // update mask + let w = (drawWidth * imgCanvas.clientWidth/imgCanvas.width) + "px"; + let h = (drawHeight * imgCanvas.clientHeight/imgCanvas.height) + "px"; + pointsCanvas.width = drawWidth; pointsCanvas.height = drawHeight; pointsCanvas.style.top = imgCanvas.offsetTop + "px"; pointsCanvas.style.left = imgCanvas.offsetLeft + "px"; - maskCanvas.width = drawWidth; - maskCanvas.height = drawHeight; + maskCanvas.style.width = w; + maskCanvas.style.height = h; maskCanvas.style.top = imgCanvas.offsetTop + "px"; maskCanvas.style.left = imgCanvas.offsetLeft + "px"; diff --git a/modules/impact/config.py b/modules/impact/config.py index 1de4647..1d7a695 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 12] +version_code = [7, 13] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 24 diff --git a/pyproject.toml b/pyproject.toml index 4be81dd..0199293 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.12" +version = "7.13" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From 348c3dcb6b3f9e5fe42f184a01df0bb22b7bfc8d Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Sun, 1 Dec 2024 02:02:05 +0900 Subject: [PATCH 15/19] improve: PreviewBridgeLatent - add Latent2RGB-LTXV improve: LatentSender - add multiple latent formats --- modules/impact/bridge_nodes.py | 12 +++++++++- modules/impact/config.py | 2 +- modules/impact/impact_pack.py | 40 +++++++++++++++++++++++++++------- pyproject.toml | 2 +- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/modules/impact/bridge_nodes.py b/modules/impact/bridge_nodes.py index 326618a..26381c0 100644 --- a/modules/impact/bridge_nodes.py +++ b/modules/impact/bridge_nodes.py @@ -186,6 +186,9 @@ def decode_latent(latent, preview_method, vae_opt=None): elif preview_method == "Latent2RGB-FLUX.1": latent_format = latent_formats.Flux() method = LatentPreviewMethod.Latent2RGB + elif preview_method == "Latent2RGB-LTXV": + latent_format = latent_formats.LTXV() + method = LatentPreviewMethod.Latent2RGB else: print(f"[Impact Pack] PreviewBridgeLatent: '{preview_method}' is unsupported preview method.") latent_format = latent_formats.SD15() @@ -211,6 +214,7 @@ class PreviewBridgeLatent: "Latent2RGB-SDXL", "Latent2RGB-SD15", "Latent2RGB-SD3", "Latent2RGB-SD-X4", "Latent2RGB-Playground-2.5", "Latent2RGB-SC-Prior", "Latent2RGB-SC-B", + "Latent2RGB-LTXV", "TAEF1", "TAESDXL", "TAESD15", "TAESD3"],), }, "optional": { @@ -274,7 +278,13 @@ class PreviewBridgeLatent: def doit(self, latent, image, preview_method, vae_opt=None, block=False, unique_id=None, restore_mask='never', prompt=None, extra_pnginfo=None): latent_channels = latent['samples'].shape[1] - preview_method_channels = 16 if 'SD3' in preview_method or 'SC-Prior' in preview_method or 'FLUX.1' in preview_method or 'TAEF1' == preview_method else 4 + + if 'SD3' in preview_method or 'SC-Prior' in preview_method or 'FLUX.1' in preview_method or 'TAEF1' == preview_method: + preview_method_channels = 16 + elif 'LTXV' in preview_method: + preview_method_channels = 128 + else: + preview_method_channels = 4 if vae_opt is None and latent_channels != preview_method_channels: print(f"[PreviewBridgeLatent] The version of latent is not compatible with preview_method.\nSD3, SD1/SD2, SDXL, SC-Prior, SC-B and FLUX.1 are not compatible with each other.") diff --git a/modules/impact/config.py b/modules/impact/config.py index 1d7a695..041b83b 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 13] +version_code = [7, 14] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 24 diff --git a/modules/impact/impact_pack.py b/modules/impact/impact_pack.py index 8b36a8c..7d0071f 100644 --- a/modules/impact/impact_pack.py +++ b/modules/impact/impact_pack.py @@ -2027,7 +2027,12 @@ class LatentSender(nodes.SaveLatent): "samples": ("LATENT", ), "filename_prefix": ("STRING", {"default": "latents/LatentSender"}), "link_id": ("INT", {"default": 0, "min": 0, "max": sys.maxsize, "step": 1}), - "preview_method": (["Latent2RGB-SDXL", "Latent2RGB-SD15", "TAESDXL", "TAESD15"],) + "preview_method": (["Latent2RGB-FLUX.1", + "Latent2RGB-SDXL", "Latent2RGB-SD15", "Latent2RGB-SD3", + "Latent2RGB-SD-X4", "Latent2RGB-Playground-2.5", + "Latent2RGB-SC-Prior", "Latent2RGB-SC-B", + "Latent2RGB-LTXV", + "TAEF1", "TAESDXL", "TAESD15", "TAESD3"],) }, "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"}, } @@ -2069,14 +2074,33 @@ class LatentSender(nodes.SaveLatent): if preview_method == "Latent2RGB-SD15": latent_format = latent_formats.SD15() method = LatentPreviewMethod.Latent2RGB - elif preview_method == "TAESD15": + elif preview_method == "Latent2RGB-SDXL": + latent_format = latent_formats.SDXL() + method = LatentPreviewMethod.Latent2RGB + elif preview_method == "Latent2RGB-SD3": + latent_format = latent_formats.SD3() + method = LatentPreviewMethod.Latent2RGB + elif preview_method == "Latent2RGB-SD-X4": + latent_format = latent_formats.SD_X4() + method = LatentPreviewMethod.Latent2RGB + elif preview_method == "Latent2RGB-Playground-2.5": + latent_format = latent_formats.SDXL_Playground_2_5() + method = LatentPreviewMethod.Latent2RGB + elif preview_method == "Latent2RGB-SC-Prior": + latent_format = latent_formats.SC_Prior() + method = LatentPreviewMethod.Latent2RGB + elif preview_method == "Latent2RGB-SC-B": + latent_format = latent_formats.SC_B() + method = LatentPreviewMethod.Latent2RGB + elif preview_method == "Latent2RGB-FLUX.1": + latent_format = latent_formats.Flux() + method = LatentPreviewMethod.Latent2RGB + elif preview_method == "Latent2RGB-LTXV": + latent_format = latent_formats.LTXV() + method = LatentPreviewMethod.Latent2RGB + else: + print(f"[Impact Pack] LatentSender: '{preview_method}' is unsupported preview method.") latent_format = latent_formats.SD15() - method = LatentPreviewMethod.TAESD - elif preview_method == "TAESDXL": - latent_format = latent_formats.SDXL() - method = LatentPreviewMethod.TAESD - else: # preview_method == "Latent2RGB-SDXL" - latent_format = latent_formats.SDXL() method = LatentPreviewMethod.Latent2RGB previewer = core.get_previewer("cpu", latent_format=latent_format, force=True, method=method) diff --git a/pyproject.toml b/pyproject.toml index 0199293..682cd5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.13" +version = "7.14" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From 20f2cac6f05d0031da99e713d59143bd61c197ef Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Fri, 6 Dec 2024 05:10:09 +0900 Subject: [PATCH 16/19] docs: update README.md (#844) minor fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc74297..30ec162 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ This custom node helps to conveniently enhance images through Detector, Detailer ### ControlNet, IPAdapter * `ControlNetApply (SEGS)` - To apply ControlNet in SEGS, you need to use the Preprocessor Provider node from the Inspire Pack to utilize this node. - * `segs_preprocessor` and `control_image` can be selectively applied. If an `control_image` is given, `segs_preprocessor` will be ignored. + * `segs_preprocessor` and `control_image` can be selectively applied. If a `control_image` is given, `segs_preprocessor` will be ignored. * If set to `control_image`, you can preview the cropped cnet image through `SEGSPreview (CNET Image)`. Images generated by `segs_preprocessor` should be verified through the `cnet_images` output of each Detailer. * The `segs_preprocessor` operates by applying preprocessing on-the-fly based on the cropped image during the detailing process, while `control_image` will be cropped and used as input to `ControlNetApply (SEGS)`. * `ControlNetClear (SEGS)` - Clear applied ControlNet in SEGS From 81045cc845706c159a825739137815cfd50971fa Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 11 Dec 2024 03:25:29 +0900 Subject: [PATCH 17/19] fixed: remove from lazy input if empty slot is selected. https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/846 --- modules/impact/config.py | 2 +- modules/impact/util_nodes.py | 5 ++++- pyproject.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index 041b83b..905254f 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 14] +version_code = [7, 14, 1] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 24 diff --git a/modules/impact/util_nodes.py b/modules/impact/util_nodes.py index 6b91468..2afba50 100644 --- a/modules/impact/util_nodes.py +++ b/modules/impact/util_nodes.py @@ -52,7 +52,10 @@ class GeneralSwitch: print(f"SELECTED: {input_name}") - return [input_name] + if input_name in kwargs: + return [input_name] + else: + return [] @staticmethod def doit(*args, **kwargs): diff --git a/pyproject.toml b/pyproject.toml index 682cd5d..4df769a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.14" +version = "7.14.1" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From 5f630466fb1df14c589f542bc37a4d30518b979a Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 11 Dec 2024 03:36:12 +0900 Subject: [PATCH 18/19] fixed: block if empty slot is selected and select_on_prompt https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/846 --- modules/impact/config.py | 2 +- modules/impact/util_nodes.py | 7 +++++++ pyproject.toml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index 905254f..d20bffb 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 14, 1] +version_code = [7, 14, 2] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 24 diff --git a/modules/impact/util_nodes.py b/modules/impact/util_nodes.py index 2afba50..8f08080 100644 --- a/modules/impact/util_nodes.py +++ b/modules/impact/util_nodes.py @@ -65,6 +65,13 @@ class GeneralSwitch: selected_label = input_name node_id = kwargs['unique_id'] + if input_name not in kwargs: + if core.is_execution_model_version_supported(): + from comfy_execution.graph import ExecutionBlocker + return ExecutionBlocker(None), selected_label, selected_index + else: + print("[Impact Pack] ImpactSwitch: ComfyUI is outdated. Cannot block empty selection.") + if 'extra_pnginfo' in kwargs and kwargs['extra_pnginfo'] is not None: nodelist = kwargs['extra_pnginfo']['workflow']['nodes'] for node in nodelist: diff --git a/pyproject.toml b/pyproject.toml index 4df769a..a8ed568 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.14.1" +version = "7.14.2" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] From ce23d436fc857a8d008abf0a022a89339dba1aee Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 11 Dec 2024 05:25:01 +0900 Subject: [PATCH 19/19] improve: switch - disconnect output connection instead of input connection if select_on_prompt --- modules/impact/config.py | 2 +- modules/impact/impact_server.py | 9 +++++++++ modules/impact/util_nodes.py | 7 ------- pyproject.toml | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index d20bffb..abcb40f 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -1,7 +1,7 @@ import configparser import os -version_code = [7, 14, 2] +version_code = [7, 14, 3] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 24 diff --git a/modules/impact/impact_server.py b/modules/impact/impact_server.py index 4568857..24036b0 100644 --- a/modules/impact/impact_server.py +++ b/modules/impact/impact_server.py @@ -315,6 +315,8 @@ def onprompt_for_switch(json_data): inversed_switch_info = {} onprompt_switch_info = {} onprompt_cond_branch_info = {} + disabled_switch = set() + for k, v in json_data['prompt'].items(): if 'class_type' not in v: @@ -348,6 +350,10 @@ def onprompt_for_switch(json_data): else: onprompt_switch_info[k] = select_input + if k in onprompt_switch_info and f'input{onprompt_switch_info[k]}' not in v['inputs']: + # disconnect output + disabled_switch.add(k) + elif cls == 'ImpactConditionalBranchSelMode': if 'sel_mode' in v['inputs'] and v['inputs']['sel_mode'] and 'cond' in v['inputs']: cond_input = v['inputs']['cond'] @@ -372,6 +378,9 @@ def onprompt_for_switch(json_data): if vv[1] + 1 != inversed_switch_info[vv[0]]: disable_targets.add(kk) + if vv[0] in disabled_switch: + disable_targets.add(kk) + if k in onprompt_switch_info: selected_slot_name = f"input{onprompt_switch_info[k]}" for kk, vv in v['inputs'].items(): diff --git a/modules/impact/util_nodes.py b/modules/impact/util_nodes.py index 8f08080..2afba50 100644 --- a/modules/impact/util_nodes.py +++ b/modules/impact/util_nodes.py @@ -65,13 +65,6 @@ class GeneralSwitch: selected_label = input_name node_id = kwargs['unique_id'] - if input_name not in kwargs: - if core.is_execution_model_version_supported(): - from comfy_execution.graph import ExecutionBlocker - return ExecutionBlocker(None), selected_label, selected_index - else: - print("[Impact Pack] ImpactSwitch: ComfyUI is outdated. Cannot block empty selection.") - if 'extra_pnginfo' in kwargs and kwargs['extra_pnginfo'] is not None: nodelist = kwargs['extra_pnginfo']['workflow']['nodes'] for node in nodelist: diff --git a/pyproject.toml b/pyproject.toml index a8ed568..35d13c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.14.2" +version = "7.14.3" license = { file = "LICENSE.txt" } dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"]