add:easy ipadapterStyleComposition
This commit is contained in:
+2
-1
@@ -31,8 +31,9 @@
|
||||
|
||||
## Changelog
|
||||
|
||||
**v1.1.4**
|
||||
**v1.1.4 2024/4/10)**
|
||||
|
||||
- Added `easy ipadapterStyleComposition`
|
||||
- Added the right-click menu to view checkpoints and lora information in all Loaders
|
||||
- Fixed `easy preSamplingNoiseIn`、`easy latentNoisy`、`east Unsampler` compatible with ComfyUI Revision>=2098 [0542088e] or later
|
||||
|
||||
|
||||
@@ -35,8 +35,9 @@
|
||||
|
||||
## 更新日志
|
||||
|
||||
**v1.1.4 (2024/4/7)**
|
||||
**v1.1.4 2024/4/10)**
|
||||
|
||||
- 增加 `easy ipadapterStyleComposition`
|
||||
- 增加 在Loaders上右键菜单可查看 checkpoints、lora 信息
|
||||
- 修复 `easy preSamplingNoiseIn`、`easy latentNoisy`、`east Unsampler` 以兼容ComfyUI Revision>=2098 [0542088e] 以上版本
|
||||
|
||||
|
||||
+113
-40
@@ -22,13 +22,13 @@ from .wildcards import process_with_loras, get_wildcard_list, process
|
||||
from .adv_encode import advanced_encode
|
||||
from .layer_diffuse.func import LayerDiffuse, LayerMethod
|
||||
|
||||
from .libs.utils import find_wildcards_seed, is_linked_styles_selector, easySave, get_local_filepath, add_folder_path_and_extensions
|
||||
from .libs.utils import find_wildcards_seed, is_linked_styles_selector, easySave, get_local_filepath, add_folder_path_and_extensions, AlwaysEqualProxy
|
||||
from .libs.loader import easyLoader
|
||||
from .libs.sampler import easySampler
|
||||
from .libs.xyplot import easyXYPlot
|
||||
from .libs.controlnet import easyControlnet
|
||||
from .libs.conditioning import prompt_to_cond, set_cond
|
||||
from .libs.cache import cache, update_cache
|
||||
from .libs import cache as backend_cache
|
||||
from .libs.easing import EasingBase
|
||||
|
||||
sampler = easySampler()
|
||||
@@ -280,20 +280,23 @@ class promptLine:
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {"prompt": ("STRING", {"multiline": True, "default": "text"}),
|
||||
"start_index": ("INT", {"default": 0, "min": 0, "max": 9999}),
|
||||
"max_rows": ("INT", {"default": 1000, "min": 1, "max": 9999}),
|
||||
}
|
||||
}
|
||||
return {"required": {
|
||||
"prompt": ("STRING", {"multiline": True, "default": "text"}),
|
||||
"start_index": ("INT", {"default": 0, "min": 0, "max": 9999}),
|
||||
"max_rows": ("INT", {"default": 1000, "min": 1, "max": 9999}),
|
||||
},
|
||||
"hidden":{
|
||||
"workflow_prompt": "PROMPT", "my_unique_id": "UNIQUE_ID"
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("STRING",)
|
||||
OUTPUT_IS_LIST = (True,)
|
||||
RETURN_TYPES = ("STRING", AlwaysEqualProxy('*'))
|
||||
RETURN_NAMES = ("STRING", "COMBO")
|
||||
OUTPUT_IS_LIST = (True, True)
|
||||
FUNCTION = "generate_strings"
|
||||
CATEGORY = "EasyUse/Prompt"
|
||||
|
||||
def generate_strings(self, prompt, start_index, max_rows):
|
||||
|
||||
def generate_strings(self, prompt, start_index, max_rows, workflow_prompt=None, my_unique_id=None):
|
||||
lines = prompt.split('\n')
|
||||
|
||||
start_index = max(0, min(start_index, len(lines) - 1))
|
||||
@@ -302,7 +305,8 @@ class promptLine:
|
||||
|
||||
rows = lines[start_index:end_index]
|
||||
|
||||
return (rows,)
|
||||
|
||||
return (rows, rows)
|
||||
|
||||
class promptConcat:
|
||||
@classmethod
|
||||
@@ -2041,8 +2045,7 @@ class ipadapter:
|
||||
'FACEID PLUS V2',
|
||||
'FACEID PORTRAIT (style transfer)'
|
||||
]
|
||||
self.weight_types = ["linear", "ease in", "ease out", 'ease in-out', 'reverse in-out', 'weak input', 'weak output',
|
||||
'weak middle', 'strong middle', 'style transfer (SDXL)']
|
||||
self.weight_types = ["linear", "ease in", "ease out", 'ease in-out', 'reverse in-out', 'weak input', 'weak output', 'weak middle', 'strong middle', 'style transfer', 'composition']
|
||||
self.presets = self.normal_presets + self.faceid_presets
|
||||
|
||||
|
||||
@@ -2061,8 +2064,8 @@ class ipadapter:
|
||||
|
||||
clipvision_name = clipvision_files[0] if len(clipvision_files)>0 else None
|
||||
clipvision_file = folder_paths.get_full_path("clip_vision", clipvision_name) if clipvision_name else None
|
||||
if clipvision_name is not None:
|
||||
log_node_info(node_name, f"Using {clipvision_name}")
|
||||
# if clipvision_name is not None:
|
||||
# log_node_info(node_name, f"Using {clipvision_name}")
|
||||
|
||||
return clipvision_file, clipvision_name
|
||||
|
||||
@@ -2145,8 +2148,8 @@ class ipadapter:
|
||||
ipadapter_files = [e for e in ipadapter_list if re.search(pattern, e, re.IGNORECASE)]
|
||||
ipadapter_name = ipadapter_files[0] if len(ipadapter_files)>0 else None
|
||||
ipadapter_file = folder_paths.get_full_path("ipadapter", ipadapter_name) if ipadapter_name else None
|
||||
if ipadapter_name is not None:
|
||||
log_node_info(node_name, f"Using {ipadapter_name}")
|
||||
# if ipadapter_name is not None:
|
||||
# log_node_info(node_name, f"Using {ipadapter_name}")
|
||||
|
||||
return ipadapter_file, ipadapter_name, is_insightface, lora_pattern
|
||||
|
||||
@@ -2196,12 +2199,14 @@ class ipadapter:
|
||||
raise Exception("ClipVision model not found.")
|
||||
if clipvision_file == pipeline['clipvision']['file']:
|
||||
clip_vision = pipeline['clipvision']['model']
|
||||
elif cache_mode in ["all", "clip_vision only"] and clipvision_name in cache:
|
||||
log_node_info("easy ipadapterApply", f"Using ClipModel {clipvision_name} Cached")
|
||||
clip_vision = cache[clipvision_name][1]
|
||||
elif cache_mode in ["all", "clip_vision only"] and clipvision_name in backend_cache.cache:
|
||||
log_node_info("easy ipadapterApply", f"Using ClipVisonModel {clipvision_name} Cached")
|
||||
_, clip_vision = backend_cache.cache[clipvision_name][1]
|
||||
else:
|
||||
clip_vision = load_clip_vision(clipvision_file)
|
||||
update_cache(clipvision_name, (False, clip_vision))
|
||||
log_node_info("easy ipadapterApply", f"Using ClipVisonModel {clipvision_name}")
|
||||
if cache_mode in ["all", "clip_vision only"]:
|
||||
backend_cache.update_cache(clipvision_name, 'clip_vision', (False, clip_vision))
|
||||
pipeline['clipvision']['file'] = clipvision_file
|
||||
pipeline['clipvision']['model'] = clip_vision
|
||||
|
||||
@@ -2210,9 +2215,21 @@ class ipadapter:
|
||||
ipadapter_file, ipadapter_name, is_insightface, lora_pattern = self.get_ipadapter_file(preset, is_sdxl, node_name)
|
||||
model_type = 'sdxl' if is_sdxl else 'sd15'
|
||||
if ipadapter_file is None:
|
||||
ipadapter_file = get_local_filepath(IPADAPTER_MODELS[preset][model_type]["model_url"], IPADAPTER_DIR)
|
||||
ipadapter = self.ipadapter_model_loader(ipadapter_file)
|
||||
pipeline['ipadapter']['file'] = ipadapter_file
|
||||
model_url = IPADAPTER_MODELS[preset][model_type]["model_url"]
|
||||
ipadapter_file = get_local_filepath(model_url, IPADAPTER_DIR)
|
||||
ipadapter_name = os.path.basename(model_url)
|
||||
if ipadapter_file == pipeline['ipadapter']['file']:
|
||||
ipadapter = pipeline['ipadapter']['model']
|
||||
elif cache_mode in ["all", "ipadapter only"] and ipadapter_name in backend_cache.cache:
|
||||
log_node_info("easy ipadapterApply", f"Using IpAdapterModel {ipadapter_name} Cached")
|
||||
_, ipadapter = backend_cache.cache[ipadapter_name][1]
|
||||
else:
|
||||
ipadapter = self.ipadapter_model_loader(ipadapter_file)
|
||||
pipeline['ipadapter']['file'] = ipadapter_file
|
||||
log_node_info("easy ipadapterApply", f"Using IpAdapterModel {ipadapter_name}")
|
||||
if cache_mode in ["all", "ipadapter only"]:
|
||||
backend_cache.update_cache(ipadapter_name, 'ipadapter', (False, ipadapter))
|
||||
|
||||
pipeline['ipadapter']['model'] = ipadapter
|
||||
|
||||
# 3. Load the lora model if needed
|
||||
@@ -2225,12 +2242,13 @@ class ipadapter:
|
||||
icache_key = 'insightface-' + provider
|
||||
if provider == pipeline['insightface']['provider']:
|
||||
insightface = pipeline['insightface']['model']
|
||||
elif icache_key in cache:
|
||||
elif cache_mode in ["all", "insightface only"] and icache_key in backend_cache.cache:
|
||||
log_node_info("easy ipadapterApply", f"Using InsightFaceModel {icache_key} Cached")
|
||||
insightface = cache[icache_key][1]
|
||||
_, insightface = backend_cache.cache[icache_key][1]
|
||||
else:
|
||||
insightface = insightface_loader(provider)
|
||||
update_cache(icache_key, (False, insightface))
|
||||
if cache_mode in ["all", "insightface only"]:
|
||||
backend_cache.update_cache(icache_key, 'insightface',(False, insightface))
|
||||
pipeline['insightface']['provider'] = provider
|
||||
pipeline['insightface']['model'] = insightface
|
||||
|
||||
@@ -2255,7 +2273,7 @@ class ipadapterApply(ipadapter):
|
||||
"weight_faceidv2": ("FLOAT", { "default": 1.0, "min": -1, "max": 5.0, "step": 0.05 }),
|
||||
"start_at": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"end_at": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"cache_mode": (["insightface only", "clip_vision only", "all", "none"], {"default": "insightface only"},),
|
||||
"cache_mode": (["insightface only", "clip_vision only", "ipadapter only", "all", "none"], {"default": "insightface only"},),
|
||||
"use_tiled": ("BOOLEAN", {"default": False},),
|
||||
},
|
||||
|
||||
@@ -2316,7 +2334,7 @@ class ipadapterApplyAdvanced(ipadapter):
|
||||
"start_at": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"end_at": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"embeds_scaling": (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],),
|
||||
"cache_mode": (["insightface only", "clip_vision only", "all", "none"], {"default": "insightface only"},),
|
||||
"cache_mode": (["insightface only", "clip_vision only","ipadapter only", "all", "none"], {"default": "insightface only"},),
|
||||
"use_tiled": ("BOOLEAN", {"default": False},),
|
||||
"use_batch": ("BOOLEAN", {"default": False},),
|
||||
"sharpening": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.05}),
|
||||
@@ -2335,9 +2353,10 @@ class ipadapterApplyAdvanced(ipadapter):
|
||||
CATEGORY = "EasyUse/Adapter"
|
||||
FUNCTION = "apply"
|
||||
|
||||
def apply(self, model, image, preset, lora_strength, provider, weight, weight_faceidv2, weight_type, combine_embeds, start_at, end_at, embeds_scaling, cache_mode, use_tiled, use_batch, sharpening, image_negative=None, clip_vision=None, attn_mask=None, optional_ipadapter=None):
|
||||
def apply(self, model, image, preset, lora_strength, provider, weight, weight_faceidv2, weight_type, combine_embeds, start_at, end_at, embeds_scaling, cache_mode, use_tiled, use_batch, sharpening, weight_style=1.0, weight_composition=1.0, image_style=None, image_composition=None, expand_style=False, image_negative=None, clip_vision=None, attn_mask=None, optional_ipadapter=None):
|
||||
tiles, masks = image, [None]
|
||||
model, ipadapter = self.load_model(model, preset, lora_strength, provider, clip_vision=clip_vision, optional_ipadapter=optional_ipadapter, cache_mode=cache_mode)
|
||||
|
||||
if use_tiled:
|
||||
if use_batch:
|
||||
if "IPAdapterTiledBatch" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
@@ -2347,7 +2366,7 @@ class ipadapterApplyAdvanced(ipadapter):
|
||||
if "IPAdapterTiled" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
self.error()
|
||||
cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterTiled"]
|
||||
model, tiles, masks = cls().apply_tiled(model, ipadapter, image, weight, weight_type, start_at, end_at, sharpening=sharpening, combine_embeds=combine_embeds, image_negative=image_negative, attn_mask=attn_mask, clip_vision=clip_vision, embeds_scaling=embeds_scaling)
|
||||
model, tiles, masks = cls().apply_tiled(model, ipadapter, weight, weight_type, start_at, end_at, sharpening=sharpening, combine_embeds=combine_embeds, image_negative=image_negative, attn_mask=attn_mask, clip_vision=clip_vision, embeds_scaling=embeds_scaling)
|
||||
else:
|
||||
if use_batch:
|
||||
if "IPAdapterBatch" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
@@ -2357,9 +2376,61 @@ class ipadapterApplyAdvanced(ipadapter):
|
||||
if "IPAdapterAdvanced" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
self.error()
|
||||
cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterAdvanced"]
|
||||
model, = cls().apply_ipadapter(model, ipadapter, weight=weight, weight_type=weight_type, start_at=start_at, end_at=end_at, combine_embeds=combine_embeds, weight_faceidv2=weight_faceidv2, image=image, image_negative=image_negative, clip_vision=clip_vision, attn_mask=attn_mask, insightface=None, embeds_scaling=embeds_scaling)
|
||||
model, = cls().apply_ipadapter(model, ipadapter, weight=weight, weight_type=weight_type, start_at=start_at, end_at=end_at, combine_embeds=combine_embeds, weight_faceidv2=weight_faceidv2, image=image, image_negative=image_negative, weight_style=1.0, weight_composition=1.0, image_style=image_style, image_composition=image_composition, expand_style=expand_style, clip_vision=clip_vision, attn_mask=attn_mask, insightface=None, embeds_scaling=embeds_scaling)
|
||||
|
||||
return (model, tiles, masks, ipadapter)
|
||||
|
||||
class ipadapterStyleComposition(ipadapter):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
ipa_cls = cls()
|
||||
normal_presets = ipa_cls.normal_presets
|
||||
weight_types = ipa_cls.weight_types
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MODEL",),
|
||||
"image_style": ("IMAGE",),
|
||||
"preset": (normal_presets,),
|
||||
"weight_style": ("FLOAT", {"default": 1.0, "min": -1, "max": 5, "step": 0.05}),
|
||||
"weight_composition": ("FLOAT", {"default": 1.0, "min": -1, "max": 5, "step": 0.05}),
|
||||
"expand_style": ("BOOLEAN", {"default": False}),
|
||||
"combine_embeds": (["concat", "add", "subtract", "average", "norm average"], {"default": "average"}),
|
||||
"start_at": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"end_at": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"embeds_scaling": (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],),
|
||||
"cache_mode": (["insightface only", "clip_vision only", "ipadapter only", "all", "none"],
|
||||
{"default": "insightface only"},),
|
||||
},
|
||||
"optional": {
|
||||
"image_composition": ("IMAGE",),
|
||||
"image_negative": ("IMAGE",),
|
||||
"attn_mask": ("MASK",),
|
||||
"clip_vision": ("CLIP_VISION",),
|
||||
"optional_ipadapter": ("IPADAPTER",),
|
||||
}
|
||||
}
|
||||
|
||||
CATEGORY = "EasyUse/Adapter"
|
||||
|
||||
RETURN_TYPES = ("MODEL", "IPADAPTER",)
|
||||
RETURN_NAMES = ("model", "ipadapter",)
|
||||
CATEGORY = "EasyUse/Adapter"
|
||||
FUNCTION = "apply"
|
||||
|
||||
def apply(self, model, preset, weight_style, weight_composition, expand_style, combine_embeds, start_at, end_at, embeds_scaling, cache_mode, image_style=None , image_composition=None, image_negative=None, clip_vision=None, attn_mask=None, optional_ipadapter=None):
|
||||
model, ipadapter = self.load_model(model, preset, 0, 'CPU', clip_vision=None, optional_ipadapter=optional_ipadapter, cache_mode=cache_mode)
|
||||
|
||||
if "IPAdapterAdvanced" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
self.error()
|
||||
cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterAdvanced"]
|
||||
|
||||
model, = cls().apply_ipadapter(model, ipadapter, start_at=start_at, end_at=end_at, weight_style=weight_style, weight_composition=weight_composition, weight_type='linear', combine_embeds=combine_embeds, weight_faceidv2=weight_composition, image_style=image_style, image_composition=image_composition, image_negative=image_negative, expand_style=expand_style, clip_vision=clip_vision, attn_mask=attn_mask, insightface=None, embeds_scaling=embeds_scaling)
|
||||
return (model, ipadapter)
|
||||
|
||||
class ipadapterApplyEncoder(ipadapter):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -2501,23 +2572,23 @@ class instantID:
|
||||
model = pipe['model']
|
||||
# Load InstantID
|
||||
cache_key = 'instantID'
|
||||
if cache_key in cache:
|
||||
if cache_key in backend_cache.cache:
|
||||
log_node_info("easy instantIDApply","Using InstantIDModel Cached")
|
||||
instantid_model = cache[cache_key][1]
|
||||
_, instantid_model = backend_cache.cache[cache_key][1]
|
||||
if "InstantIDModelLoader" in ALL_NODE_CLASS_MAPPINGS:
|
||||
load_instant_cls = ALL_NODE_CLASS_MAPPINGS["InstantIDModelLoader"]
|
||||
instantid_model, = load_instant_cls().load_model(instantid_file)
|
||||
update_cache(cache_key, (False, instantid_model))
|
||||
backend_cache.update_cache(cache_key, 'instantid', (False, instantid_model))
|
||||
else:
|
||||
self.error()
|
||||
icache_key = 'insightface-' + insightface
|
||||
if icache_key in cache:
|
||||
if icache_key in backend_cache.cache:
|
||||
log_node_info("easy instantIDApply", f"Using InsightFaceModel {insightface} Cached")
|
||||
insightface_model = cache[icache_key][1]
|
||||
_, insightface_model = backend_cache.cache[icache_key][1]
|
||||
elif "InstantIDFaceAnalysis" in ALL_NODE_CLASS_MAPPINGS:
|
||||
load_insightface_cls = ALL_NODE_CLASS_MAPPINGS["InstantIDFaceAnalysis"]
|
||||
insightface_model, = load_insightface_cls().load_insight_face(insightface)
|
||||
update_cache(icache_key, (False, insightface_model))
|
||||
backend_cache.update_cache(icache_key, 'insightface', (False, insightface_model))
|
||||
else:
|
||||
self.error()
|
||||
|
||||
@@ -6417,6 +6488,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"easy ipadapterApplyADV": ipadapterApplyAdvanced,
|
||||
"easy ipadapterApplyEncoder": ipadapterApplyEncoder,
|
||||
"easy ipadapterApplyEmbeds": ipadapterApplyEmbeds,
|
||||
"easy ipadapterStyleComposition": ipadapterStyleComposition,
|
||||
"easy instantIDApply": instantIDApply,
|
||||
"easy instantIDApplyADV": instantIDApplyAdvanced,
|
||||
# Inpaint 内补
|
||||
@@ -6511,6 +6583,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
# Adapter 适配器
|
||||
"easy ipadapterApply": "Easy Apply IPAdapter",
|
||||
"easy ipadapterApplyADV": "Easy Apply IPAdapter (Advanced)",
|
||||
"easy ipadapterStyleComposition": "Easy Apply IPAdapter (StyleComposition)",
|
||||
"easy ipadapterApplyEncoder": "Easy Apply IPAdapter (Encoder)",
|
||||
"easy ipadapterApplyEmbeds": "Easy Apply IPAdapter (Embeds)",
|
||||
"easy instantIDApply": "Easy Apply InstantID",
|
||||
|
||||
+79
-5
@@ -1,12 +1,86 @@
|
||||
cache = {}
|
||||
import itertools
|
||||
from typing import Optional
|
||||
|
||||
class TaggedCache:
|
||||
def __init__(self, tag_settings: Optional[dict]=None):
|
||||
self._tag_settings = tag_settings or {} # tag cache size
|
||||
self._data = {}
|
||||
|
||||
def __getitem__(self, key):
|
||||
for tag_data in self._data.values():
|
||||
if key in tag_data:
|
||||
return tag_data[key]
|
||||
raise KeyError(f'Key `{key}` does not exist')
|
||||
|
||||
def __setitem__(self, key, value: tuple):
|
||||
# value: (tag: str, (islist: bool, data: *))
|
||||
|
||||
# if key already exists, pop old value
|
||||
for tag_data in self._data.values():
|
||||
if key in tag_data:
|
||||
tag_data.pop(key, None)
|
||||
break
|
||||
|
||||
tag = value[0]
|
||||
if tag not in self._data:
|
||||
|
||||
try:
|
||||
from cachetools import LRUCache
|
||||
|
||||
default_size = 20
|
||||
if 'ckpt' in tag:
|
||||
default_size = 5
|
||||
elif tag in ['latent', 'image']:
|
||||
default_size = 100
|
||||
|
||||
self._data[tag] = LRUCache(maxsize=self._tag_settings.get(tag, default_size))
|
||||
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
# TODO: implement a simple lru dict
|
||||
self._data[tag] = {}
|
||||
self._data[tag][key] = value
|
||||
|
||||
def __delitem__(self, key):
|
||||
for tag_data in self._data.values():
|
||||
if key in tag_data:
|
||||
del tag_data[key]
|
||||
return
|
||||
raise KeyError(f'Key `{key}` does not exist')
|
||||
|
||||
def __contains__(self, key):
|
||||
return any(key in tag_data for tag_data in self._data.values())
|
||||
|
||||
def items(self):
|
||||
yield from itertools.chain(*map(lambda x :x.items(), self._data.values()))
|
||||
|
||||
def get(self, key, default=None):
|
||||
"""D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None."""
|
||||
for tag_data in self._data.values():
|
||||
if key in tag_data:
|
||||
return tag_data[key]
|
||||
return default
|
||||
|
||||
def clear(self):
|
||||
# clear all cache
|
||||
self._data = {}
|
||||
|
||||
cache_settings = {}
|
||||
cache = TaggedCache(cache_settings)
|
||||
cache_count = {}
|
||||
|
||||
|
||||
def update_cache(k, v):
|
||||
cache[k] = v
|
||||
def update_cache(k, tag, v):
|
||||
cache[k] = (tag, v)
|
||||
cnt = cache_count.get(k)
|
||||
if cnt is None:
|
||||
cnt = 0
|
||||
cache_count[k] = cnt
|
||||
else:
|
||||
cache_count[k] += 1
|
||||
cache_count[k] += 1
|
||||
def remove_cache(key):
|
||||
global cache
|
||||
if key == '*':
|
||||
cache = TaggedCache(cache_settings)
|
||||
elif key in cache:
|
||||
del cache[key]
|
||||
else:
|
||||
print(f"invalid {key}")
|
||||
@@ -1,3 +1,10 @@
|
||||
class AlwaysEqualProxy(str):
|
||||
def __eq__(self, _):
|
||||
return True
|
||||
|
||||
def __ne__(self, _):
|
||||
return False
|
||||
|
||||
comfy_ui_revision = None
|
||||
def get_comfyui_revision():
|
||||
try:
|
||||
|
||||
+46
-7
@@ -1,6 +1,7 @@
|
||||
from typing import Iterator, List, Tuple, Dict, Any, Union, Optional
|
||||
from _decimal import Context, getcontext
|
||||
from decimal import Decimal
|
||||
from .libs.utils import AlwaysEqualProxy
|
||||
import torch
|
||||
import numpy as np
|
||||
import json
|
||||
@@ -287,12 +288,6 @@ COMPARE_FUNCTIONS = {
|
||||
"a <= b": lambda a, b: a <= b,
|
||||
"a >= b": lambda a, b: a >= b,
|
||||
}
|
||||
class AlwaysEqualProxy(str):
|
||||
def __eq__(self, _):
|
||||
return True
|
||||
|
||||
def __ne__(self, _):
|
||||
return False
|
||||
|
||||
# 比较
|
||||
class Compare:
|
||||
@@ -517,6 +512,46 @@ class cleanGPUUsed:
|
||||
|
||||
return ()
|
||||
|
||||
from .libs.cache import remove_cache
|
||||
class cleanCacheKey:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {
|
||||
"anything": (AlwaysEqualProxy("*"), {}),
|
||||
"cache_key": ("STRING", {"default": "*"}),
|
||||
}, "optional": {},
|
||||
"hidden": {"unique_id": "UNIQUE_ID", "extra_pnginfo": "EXTRA_PNGINFO",}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ()
|
||||
RETURN_NAMES = ()
|
||||
OUTPUT_NODE = True
|
||||
FUNCTION = "empty_cache"
|
||||
CATEGORY = "EasyUse/Logic"
|
||||
|
||||
def empty_cache(self, anything, cache_name, unique_id=None, extra_pnginfo=None):
|
||||
remove_cache(cache_name)
|
||||
return ()
|
||||
|
||||
class cleanCacheAll:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {
|
||||
"anything": (AlwaysEqualProxy("*"), {}),
|
||||
}, "optional": {},
|
||||
"hidden": {"unique_id": "UNIQUE_ID", "extra_pnginfo": "EXTRA_PNGINFO",}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ()
|
||||
RETURN_NAMES = ()
|
||||
OUTPUT_NODE = True
|
||||
FUNCTION = "empty_cache"
|
||||
CATEGORY = "EasyUse/Logic"
|
||||
|
||||
def empty_cache(self, anything, unique_id=None, extra_pnginfo=None):
|
||||
remove_cache('*')
|
||||
return ()
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"easy string": String,
|
||||
"easy int": Int,
|
||||
@@ -532,7 +567,9 @@ NODE_CLASS_MAPPINGS = {
|
||||
"easy convertAnything": ConvertAnything,
|
||||
"easy showAnything": showAnything,
|
||||
"easy showTensorShape": showTensorShape,
|
||||
"easy cleanGpuUsed": cleanGPUUsed
|
||||
"easy cleanCacheKey": cleanCacheKey,
|
||||
"easy cleanCacheAll": cleanCacheAll,
|
||||
"easy cleanGpuUsed": cleanGPUUsed,
|
||||
}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy string": "String",
|
||||
@@ -549,5 +586,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy convertAnything": "Convert Any",
|
||||
"easy showAnything": "Show Any",
|
||||
"easy showTensorShape": "Show Tensor Shape",
|
||||
"easy cleanCacheKey": "Clean Cache Key",
|
||||
"easy cleanCacheAll": "Clean Cache All",
|
||||
"easy cleanGpuUsed": "Clean GPU Used"
|
||||
}
|
||||
@@ -24,6 +24,7 @@ const zhCN = {
|
||||
"Saving Preview...": "正在保存预览图...",
|
||||
"Saving Succeed":"保存成功",
|
||||
"Saving Failed":"保存失败",
|
||||
"No COMBO link": "沒有找到COMBO连接",
|
||||
// GroupMap
|
||||
"Groups Map (EasyUse)": "管理组 (EasyUse)",
|
||||
"Always": "启用中",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { app } from "/scripts/app.js";
|
||||
import { api } from "/scripts/api.js";
|
||||
import { ComfyWidgets } from "/scripts/widgets.js";
|
||||
import { toast} from "../common/toast.js";
|
||||
import { $t } from '../common/i18n.js';
|
||||
|
||||
let origProps = {};
|
||||
|
||||
@@ -1028,6 +1030,36 @@ app.registerExtension({
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeData.name == 'easy promptLine') {
|
||||
const onAdded = nodeType.prototype.onAdded;
|
||||
nodeType.prototype.onAdded = async function () {
|
||||
onAdded ? onAdded.apply(this, []) : undefined;
|
||||
let prompt_widget = this.widgets.find(w => w.name == "prompt")
|
||||
const button = this.addWidget("button", "get values from COMBO link", '', () => {
|
||||
const output_link = this.outputs[1]?.links?.length>0 ? this.outputs[1]['links'][0] : null
|
||||
const all_nodes = app.graph._nodes
|
||||
const node = all_nodes.find(cate=> cate.inputs?.find(input=> input.link == output_link))
|
||||
if(!output_link || !node){
|
||||
toast.error($t('No COMBO link'), 3000)
|
||||
return
|
||||
}
|
||||
else{
|
||||
const input = node.inputs.find(input=> input.link == output_link)
|
||||
const widget_name = input.widget.name
|
||||
const widgets = node.widgets
|
||||
const widget = widgets.find(cate=> cate.name == widget_name)
|
||||
let values = widget?.options.values || null
|
||||
if(values){
|
||||
values = values.join('\n')
|
||||
prompt_widget.value = values
|
||||
}
|
||||
}
|
||||
}, {
|
||||
serialize: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ const loaders = ['easy fullLoader', 'easy a1111Loader', 'easy comfyLoader']
|
||||
const preSampling = ['easy preSampling', 'easy preSamplingAdvanced', 'easy preSamplingDynamicCFG', 'easy preSamplingNoiseIn', 'easy preSamplingLayerDiffusion', 'easy fullkSampler']
|
||||
const kSampler = ['easy kSampler', 'easy kSamplerTiled', 'easy kSamplerInpainting', 'easy kSamplerDownscaleUnet', 'easy kSamplerLayerDiffusion']
|
||||
const controlnet = ['easy controlnetLoader', 'easy controlnetLoaderADV', 'easy instantIDApply', 'easy instantIDApplyADV']
|
||||
const ipadapter = ['easy ipadapterApply', 'easy ipadapterApplyADV']
|
||||
const ipadapter = ['easy ipadapterApply', 'easy ipadapterApplyADV', 'easy ipadapterStyleComposition']
|
||||
const positive_prompt = ['easy positive', 'easy wildcards']
|
||||
const widgetMapping = {
|
||||
"positive_prompt":{
|
||||
@@ -90,6 +90,7 @@ const inputMapping = {
|
||||
"ipadapter":{
|
||||
"model":"model",
|
||||
"image":"image",
|
||||
"image_style": "image",
|
||||
"attn_mask":"attn_mask",
|
||||
"optional_ipadapter":"optional_ipadapter"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ const preSamplingNodes = ["easy preSampling", "easy preSamplingAdvanced", "easy
|
||||
const kSampler = ["easy kSampler", "easy kSamplerTiled","easy kSamplerInpainting", "easy kSamplerDownscaleUnet", "easy kSamplerSDTurbo"]
|
||||
const controlNetNodes = ["easy controlnetLoader", "easy controlnetLoaderADV"]
|
||||
const instantIDNodes = ["easy instantIDApply", "easy instantIDApplyADV"]
|
||||
const ipadapterNodes = ["easy ipadapterApply", "easy ipadapterApplyADV"]
|
||||
const ipadapterNodes = ["easy ipadapterApply", "easy ipadapterApplyADV" , "easy ipadapterStyleComposition"]
|
||||
const pipeNodes = ['easy pipeIn','easy pipeOut', 'easy pipeEdit']
|
||||
const xyNodes = ['easy XYPlot', 'easy XYPlotAdvanced']
|
||||
const extraNodes = ['easy setNode']
|
||||
|
||||
Reference in New Issue
Block a user