Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04223778ea | ||
|
|
3fc749d6ba | ||
|
|
c2ccf7f879 | ||
|
|
8e99bebdfe | ||
|
|
8814b8901a | ||
|
|
291d3dd13f | ||
|
|
5619e51b01 | ||
|
|
0f38db4180 |
@@ -2,7 +2,8 @@
|
||||
This repository offers various extension nodes for ComfyUI. Nodes here have different characteristics compared to those in the ComfyUI Impact Pack. The Impact Pack has become too large now...
|
||||
|
||||
## Notice:
|
||||
* v1.9.1 To avoid confusion with the `NOISE` type in core, the type name has been changed to `NOISE_IMAGE`.
|
||||
* V1.18: To use the 'OSS' Scheduler, please update to ComfyUI version 0.3.28 or later (April 13th or newer) and Impact Pack version V8.11 or higher.
|
||||
* V1.9.1 To avoid confusion with the `NOISE` type in core, the type name has been changed to `NOISE_IMAGE`.
|
||||
* V0.73 The Variation Seed feature is added to Regional Prompt nodes, and it is only compatible with versions Impact Pack V5.10 and above.
|
||||
* V0.69 incompatible with the outdated **ComfyUI IPAdapter Plus**. (A version dated March 24th or later is required.)
|
||||
* V0.64 add sigma_factor to RegionalPrompt... nodes required Impact Pack V4.76 or later.
|
||||
|
||||
+1
-11
@@ -8,7 +8,7 @@
|
||||
import importlib
|
||||
import logging
|
||||
|
||||
version_code = [1, 17]
|
||||
version_code = [1, 21]
|
||||
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
||||
logging.info(f"### Loading: ComfyUI-Inspire-Pack ({version_str})")
|
||||
|
||||
@@ -39,13 +39,3 @@ for module_name in node_list:
|
||||
|
||||
WEB_DIRECTORY = "./js"
|
||||
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
|
||||
|
||||
try:
|
||||
import cm_global
|
||||
cm_global.register_extension('ComfyUI-Inspire-Pack',
|
||||
{'version': version_code,
|
||||
'name': 'Inspire Pack',
|
||||
'nodes': set(NODE_CLASS_MAPPINGS.keys()),
|
||||
'description': 'This extension provides various nodes to support Lora Block Weight and the Impact Pack. Provides many easily applicable regional features and applications for Variation Seed.', })
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -189,7 +189,7 @@ class RetrieveBackendData:
|
||||
|
||||
if v is None:
|
||||
logging.warning(f"[RetrieveBackendData] '{key}' is unregistered key.")
|
||||
return (None,)
|
||||
return ([None],)
|
||||
|
||||
is_list, data = v[1]
|
||||
|
||||
|
||||
+48
-4
@@ -15,6 +15,48 @@ from .libs.utils import ByPassTypeTuple, empty_pil_tensor, empty_latent
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
import logging
|
||||
import re
|
||||
|
||||
|
||||
def extract_first_number(s):
|
||||
match = re.search(r'\d+', s)
|
||||
return int(match.group()) if match else float('inf')
|
||||
|
||||
|
||||
sort_methods = [
|
||||
"None",
|
||||
"Alphabetical (ASC)",
|
||||
"Alphabetical (DESC)",
|
||||
"Numerical (ASC)",
|
||||
"Numerical (DESC)",
|
||||
"Datetime (ASC)",
|
||||
"Datetime (DESC)"
|
||||
]
|
||||
|
||||
|
||||
def sort_by(items, base_path='.', method=None):
|
||||
def fullpath(x): return os.path.join(base_path, x)
|
||||
|
||||
def get_timestamp(path):
|
||||
try:
|
||||
return os.path.getmtime(path)
|
||||
except FileNotFoundError:
|
||||
return float('-inf')
|
||||
|
||||
if method == "Alphabetical (ASC)":
|
||||
return sorted(items)
|
||||
elif method == "Alphabetical (DESC)":
|
||||
return sorted(items, reverse=True)
|
||||
elif method == "Numerical (ASC)":
|
||||
return sorted(items, key=lambda x: extract_first_number(os.path.splitext(x)[0]))
|
||||
elif method == "Numerical (DESC)":
|
||||
return sorted(items, key=lambda x: extract_first_number(os.path.splitext(x)[0]), reverse=True)
|
||||
elif method == "Datetime (ASC)":
|
||||
return sorted(items, key=lambda x: get_timestamp(fullpath(x)))
|
||||
elif method == "Datetime (DESC)":
|
||||
return sorted(items, key=lambda x: get_timestamp(fullpath(x)), reverse=True)
|
||||
else:
|
||||
return items
|
||||
|
||||
|
||||
class LoadImagesFromDirBatch:
|
||||
@@ -28,6 +70,7 @@ class LoadImagesFromDirBatch:
|
||||
"image_load_cap": ("INT", {"default": 0, "min": 0, "step": 1}),
|
||||
"start_index": ("INT", {"default": 0, "min": -1, "max": 0xffffffffffffffff, "step": 1}),
|
||||
"load_always": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"sort_method": (sort_methods,),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +86,7 @@ class LoadImagesFromDirBatch:
|
||||
else:
|
||||
return hash(frozenset(kwargs))
|
||||
|
||||
def load_images(self, directory: str, image_load_cap: int = 0, start_index: int = 0, load_always=False):
|
||||
def load_images(self, directory: str, image_load_cap: int = 0, start_index: int = 0, load_always=False, sort_method=None):
|
||||
if not os.path.isdir(directory):
|
||||
raise FileNotFoundError(f"Directory '{directory} cannot be found.'")
|
||||
dir_files = os.listdir(directory)
|
||||
@@ -56,7 +99,7 @@ class LoadImagesFromDirBatch:
|
||||
valid_extensions.extend('.jxl')
|
||||
dir_files = [f for f in dir_files if any(f.lower().endswith(ext) for ext in valid_extensions)]
|
||||
|
||||
dir_files = sorted(dir_files)
|
||||
dir_files = sort_by(dir_files, directory, sort_method)
|
||||
dir_files = [os.path.join(directory, x) for x in dir_files]
|
||||
|
||||
# start at start_index
|
||||
@@ -133,6 +176,7 @@ class LoadImagesFromDirList:
|
||||
"image_load_cap": ("INT", {"default": 0, "min": 0, "step": 1}),
|
||||
"start_index": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff, "step": 1}),
|
||||
"load_always": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"sort_method": (sort_methods,),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +195,7 @@ class LoadImagesFromDirList:
|
||||
else:
|
||||
return hash(frozenset(kwargs))
|
||||
|
||||
def load_images(self, directory: str, image_load_cap: int = 0, start_index: int = 0, load_always=False):
|
||||
def load_images(self, directory: str, image_load_cap: int = 0, start_index: int = 0, load_always=False, sort_method=None):
|
||||
if not os.path.isdir(directory):
|
||||
raise FileNotFoundError(f"Directory '{directory}' cannot be found.")
|
||||
dir_files = os.listdir(directory)
|
||||
@@ -164,7 +208,7 @@ class LoadImagesFromDirList:
|
||||
valid_extensions.extend('.jxl')
|
||||
dir_files = [f for f in dir_files if any(f.lower().endswith(ext) for ext in valid_extensions)]
|
||||
|
||||
dir_files = sorted(dir_files)
|
||||
dir_files = sort_by(dir_files, directory, sort_method)
|
||||
dir_files = [os.path.join(directory, x) for x in dir_files]
|
||||
|
||||
# start at start_index
|
||||
|
||||
@@ -5,7 +5,7 @@ import logging
|
||||
from server import PromptServer
|
||||
|
||||
|
||||
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]", 'OSS FLUX', 'OSS Wan', 'OSS Chroma']
|
||||
|
||||
|
||||
def impact_sampling(*args, **kwargs):
|
||||
|
||||
@@ -130,7 +130,7 @@ class LoadPromptsFromDir:
|
||||
|
||||
for prompt in prompt_list:
|
||||
pattern = r"^(?:(?:positive:(?P<positive>.*?)|negative:(?P<negative>.*?)|name:(?P<name>.*?))\n*)+$"
|
||||
matches = re.search(pattern, prompt, re.DOTALL)
|
||||
matches = re.search(pattern, prompt, re.DOTALL | re.IGNORECASE)
|
||||
|
||||
if matches:
|
||||
positive_text = matches.group('positive').strip()
|
||||
@@ -487,6 +487,37 @@ class GlobalSeed:
|
||||
return {}
|
||||
|
||||
|
||||
class SeedLogger:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
||||
"seeds": ("STRING", {"multiline": True, "dynamicPrompts": False, "control_after_generate": False}),
|
||||
"limit": ("INT", {"default": 5, "min": 0, "max": 0xffffffffffffffff}),
|
||||
},
|
||||
"hidden": {"unique_id": "UNIQUE_ID"}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ()
|
||||
FUNCTION = "doit"
|
||||
|
||||
CATEGORY = "InspirePack/Prompt"
|
||||
|
||||
OUTPUT_NODE = True
|
||||
|
||||
def doit(self, seed, seeds: str, limit, unique_id):
|
||||
|
||||
if limit > 0:
|
||||
lines = seeds.split('\n')
|
||||
res = str(seed) + '\n' + '\n'.join(lines[:limit-1])
|
||||
else:
|
||||
res = str(seed) + '\n' + seeds
|
||||
|
||||
PromptServer.instance.send_sync("inspire-node-feedback", {"node_id": unique_id, "widget_name": "seeds", "type": "text", "data": res})
|
||||
return {}
|
||||
|
||||
|
||||
class GlobalSampler:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
@@ -993,6 +1024,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"ZipPrompt //Inspire": ZipPrompt,
|
||||
"PromptExtractor //Inspire": PromptExtractor,
|
||||
"GlobalSeed //Inspire": GlobalSeed,
|
||||
"SeedLogger //Inspire": SeedLogger,
|
||||
"GlobalSampler //Inspire": GlobalSampler,
|
||||
"BindImageListPromptList //Inspire": BindImageListPromptList,
|
||||
"WildcardEncode //Inspire": WildcardEncodeInspire,
|
||||
@@ -1004,7 +1036,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"MakeBasicPipe //Inspire": MakeBasicPipe,
|
||||
"RemoveControlNet //Inspire": RemoveControlNet,
|
||||
"RemoveControlNetFromRegionalPrompts //Inspire": RemoveControlNetFromRegionalPrompts,
|
||||
"CompositeNoise //Inspire": CompositeNoise
|
||||
"CompositeNoise //Inspire": CompositeNoise,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
@@ -1015,6 +1047,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"ZipPrompt //Inspire": "Zip Prompt (Inspire)",
|
||||
"PromptExtractor //Inspire": "Prompt Extractor (Inspire)",
|
||||
"GlobalSeed //Inspire": "Global Seed (Inspire)",
|
||||
"SeedLogger //Inspire": "Seed Logger (Inspire)",
|
||||
"GlobalSampler //Inspire": "Global Sampler (Inspire)",
|
||||
"BindImageListPromptList //Inspire": "Bind [ImageList, PromptList] (Inspire)",
|
||||
"WildcardEncode //Inspire": "Wildcard Encode (Inspire)",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "comfyui-inspire-pack"
|
||||
description = "This extension provides various nodes to support Lora Block Weight, Regional Nodes, Backend Cache, Prompt Utils, List Utils, Noise(Seed) Utils, ... and the Impact Pack."
|
||||
version = "1.17"
|
||||
version = "1.21"
|
||||
license = { file = "LICENSE" }
|
||||
dependencies = ["matplotlib", "cachetools"]
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
matplotlib
|
||||
cachetools
|
||||
numpy<2
|
||||
numpy
|
||||
webcolors
|
||||
opencv-python
|
||||
|
||||
Reference in New Issue
Block a user