add:easy ipadapterApply and easy ipadapterApplyADV
This commit is contained in:
@@ -33,6 +33,13 @@
|
||||
|
||||
**v1.1.2 (2024/3/25)**
|
||||
|
||||
PS: Please update [ComfyUI_IPAdapter_plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) to v2, and moved v1 models to **ComfyUI\models\ipadapter** (Otherwise, the latest model is automatically downloaded from Huggingface)
|
||||
<br>
|
||||
- Added `easy ipadapterApply`
|
||||
- Added `easy ipadapterApplyADV`
|
||||
|
||||
(4c25580)
|
||||
|
||||
- `easy kSamplerInpainting` add *additional* widget,you can choose 'Differential Diffusion' or 'Only InpaintModelConditioning'
|
||||
- Fixed `easy pipeEdit` error when add lora to prompt
|
||||
- Fixed layerDiffuse xyplot bug
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
- 简化 Stable Cascade [示例参考](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#StableCascade)
|
||||
- 简化 Layer Diffuse [示例参考](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#LayerDiffusion), 首次使用您可能需要运行 `pip install -r requirements.txt` 安装所需依赖
|
||||
- 简化 InstantID [示例参考](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#InstantID), 需先保证自定义节点包中安装了 [ComfyUI_InstantID](https://github.com/cubiq/ComfyUI_InstantID)
|
||||
- 简化 IPAdapter, 需先保证自定义节点包中安装最新版v2的 [ComfyUI_IPAdapter_plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus)
|
||||
- 扩展 XYplot 的可用性
|
||||
- 整合了Fooocus Inpaint功能
|
||||
- 整合了常用的逻辑计算、转换类型、展示所有类型等
|
||||
@@ -36,11 +37,18 @@
|
||||
|
||||
**v1.1.2 (2024/3/25)**
|
||||
|
||||
PS: 请更新至最新版v2的 [ComfyUI_IPAdapter_plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus), 并移动v1版本模型文件至 ComfyUI\models\ipadapter (否则会自动从huggingface下载最新模型)
|
||||
<br>
|
||||
- 增加 `easy ipadapterApply`
|
||||
- 增加 `easy ipadapterApplyADV`
|
||||
|
||||
(4c25580)
|
||||
|
||||
- `easy kSamplerInpainting` 增加 *additional* 属性,可设置成 Differential Diffusion 或 Only InpaintModelConditioning
|
||||
- 修复 `easy pipeEdit` 提示词输入lora时报错
|
||||
- 修复 layerDiffuse xyplot相关bug
|
||||
|
||||
**v1.1.1 (2024/3/21)**
|
||||
**v1.1.1 (5c8af8f)**
|
||||
|
||||
- 修复首次添加含seed的节点且当前模式为control_before_generate时,seed为0的问题
|
||||
- `easy preSamplingAdvanced` 增加 **return_with_leftover_noise**
|
||||
|
||||
@@ -141,4 +141,95 @@ REMBG_MODELS = {
|
||||
"RMBG-1.4": {
|
||||
"model_url": "https://huggingface.co/briaai/RMBG-1.4/resolve/main/model.pth"
|
||||
}
|
||||
}
|
||||
|
||||
#ipadapter
|
||||
IPADAPTER_DIR = os.path.join(folder_paths.models_dir, "ipadapter")
|
||||
IPADAPTER_MODELS = {
|
||||
"LIGHT - SD1.5 only (low strength)": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15_light_v11.bin"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": ""
|
||||
}
|
||||
},
|
||||
"STANDARD (medium strength)": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter_sdxl.safetensors"
|
||||
}
|
||||
},
|
||||
"VIT-G (medium strength)": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15_vit-G.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter_sdxl_vit-h.safetensors"
|
||||
}
|
||||
},
|
||||
"PLUS (high strength)": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-plus_sd15.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter-plus_sdxl_vit-h.safetensors"
|
||||
}
|
||||
},
|
||||
"PLUS FACE (portraits)": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-plus-face_sd15.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/sdxl_models/ip-adapter-plus-face_sdxl_vit-h.safetensors"
|
||||
}
|
||||
},
|
||||
"FULL FACE - SD1.5 only (portraits stronger)": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-full-face_sd15.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": ""
|
||||
}
|
||||
},
|
||||
"FACEID": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid_sd15.bin",
|
||||
"lora_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid_sd15_lora.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid_sdxl.bin",
|
||||
"lora_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid_sdxl_lora.safetensors"
|
||||
}
|
||||
},
|
||||
"FACEID PLUS - SD1.5 only": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-plus_sd15.bin",
|
||||
"lora_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-plus_sd15_lora.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": "",
|
||||
"lora_url": ""
|
||||
}
|
||||
},
|
||||
"FACEID PLUS V2": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-plusv2_sd15.bin",
|
||||
"lora_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-plusv2_sd15_lora.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-plusv2_sdxl.bin",
|
||||
"lora_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-plusv2_sdxl_lora.safetensors"
|
||||
}
|
||||
},
|
||||
"FACEID PORTRAIT (style transfer)": {
|
||||
"sd15": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-portrait-v11_sd15.bin",
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-portrait_sdxl.bin",
|
||||
}
|
||||
}
|
||||
}
|
||||
+368
-21
@@ -6,18 +6,19 @@ from comfy.sd import CLIP, VAE
|
||||
from comfy.model_patcher import ModelPatcher
|
||||
from comfy_extras.chainner_models import model_loading
|
||||
from comfy_extras.nodes_mask import LatentCompositeMasked
|
||||
from comfy.clip_vision import load as load_clip_vision
|
||||
from urllib.request import urlopen
|
||||
from PIL import Image
|
||||
|
||||
from server import PromptServer
|
||||
from nodes import MAX_RESOLUTION, LatentFromBatch, RepeatLatentBatch, NODE_CLASS_MAPPINGS as ALL_NODE_CLASS_MAPPINGS, ConditioningSetMask, ConditioningConcat, CLIPTextEncode, VAEEncodeForInpaint, InpaintModelConditioning
|
||||
from .config import MAX_SEED_NUM, BASE_RESOLUTIONS, RESOURCES_DIR, INPAINT_DIR, FOOOCUS_STYLES_DIR, FOOOCUS_INPAINT_HEAD, FOOOCUS_INPAINT_PATCH
|
||||
from .config import MAX_SEED_NUM, BASE_RESOLUTIONS, RESOURCES_DIR, INPAINT_DIR, FOOOCUS_STYLES_DIR, FOOOCUS_INPAINT_HEAD, FOOOCUS_INPAINT_PATCH, IPADAPTER_DIR, IPADAPTER_MODELS
|
||||
from .log import log_node_info, log_node_error, log_node_warn
|
||||
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, get_sd_version
|
||||
from .libs.utils import find_wildcards_seed, is_linked_styles_selector, easySave, get_local_filepath, add_folder_path_and_extensions
|
||||
from .libs.loader import easyLoader
|
||||
from .libs.sampler import easySampler
|
||||
from .libs.xyplot import easyXYPlot
|
||||
@@ -40,6 +41,7 @@ add_folder_path_and_extensions("onnx", [os.path.join(model_path, "onnx")], {'.on
|
||||
add_folder_path_and_extensions("instantid", [os.path.join(model_path, "instantid")], folder_paths.supported_pt_extensions)
|
||||
add_folder_path_and_extensions("layer_model", [os.path.join(model_path, "layer_model")], folder_paths.supported_pt_extensions)
|
||||
add_folder_path_and_extensions("rembg", [os.path.join(model_path, "rembg")], folder_paths.supported_pt_extensions)
|
||||
add_folder_path_and_extensions("ipadapter", [os.path.join(model_path, "ipadapter")], folder_paths.supported_pt_extensions)
|
||||
|
||||
# ---------------------------------------------------------------提示词 开始----------------------------------------------------------------------#
|
||||
|
||||
@@ -1543,9 +1545,9 @@ class LLLiteLoader:
|
||||
|
||||
return (model_lllite,)
|
||||
|
||||
#---------------------------------------------------------------测试 开始----------------------------------------------------------------------#
|
||||
#---------------------------------------------------------------Inpaint 开始----------------------------------------------------------------------#
|
||||
|
||||
# FooocusInpaint (Testing)
|
||||
# FooocusInpaint
|
||||
from .fooocus import InpaintHead, InpaintWorker
|
||||
inpaint_head_model = None
|
||||
class fooocusInpaintLoader:
|
||||
@@ -1560,7 +1562,7 @@ class fooocusInpaintLoader:
|
||||
|
||||
RETURN_TYPES = ("INPAINT_PATCH",)
|
||||
RETURN_NAMES = ("patch",)
|
||||
CATEGORY = "EasyUse/__for_testing"
|
||||
CATEGORY = "EasyUse/Inpaint"
|
||||
FUNCTION = "apply"
|
||||
|
||||
def apply(self, head, patch):
|
||||
@@ -1577,6 +1579,345 @@ class fooocusInpaintLoader:
|
||||
|
||||
return ((inpaint_head_model, inpaint_lora),)
|
||||
|
||||
#---------------------------------------------------------------适配器 开始----------------------------------------------------------------------#
|
||||
def insightface_loader(provider):
|
||||
try:
|
||||
from insightface.app import FaceAnalysis
|
||||
except ImportError as e:
|
||||
raise Exception(e)
|
||||
|
||||
path = os.path.join(folder_paths.models_dir, "insightface")
|
||||
model = FaceAnalysis(name="buffalo_l", root=path, providers=[provider + 'ExecutionProvider', ])
|
||||
model.prepare(ctx_id=0, det_size=(640, 640))
|
||||
return model
|
||||
|
||||
# Apply Ipadapter
|
||||
class ipadapter:
|
||||
|
||||
def __init__(self):
|
||||
self.normol_presets = [
|
||||
'LIGHT - SD1.5 only (low strength)',
|
||||
'STANDARD (medium strength)',
|
||||
'VIT-G (medium strength)',
|
||||
'PLUS (high strength)',
|
||||
'PLUS FACE (portraits)',
|
||||
'FULL FACE - SD1.5 only (portraits stronger)'
|
||||
]
|
||||
self.faceid_presets = [
|
||||
'FACEID',
|
||||
'FACEID PLUS - SD1.5 only',
|
||||
'FACEID PLUS V2',
|
||||
'FACEID PORTRAIT (style transfer)'
|
||||
]
|
||||
self.presets = self.normol_presets + self.faceid_presets
|
||||
|
||||
|
||||
def error(self):
|
||||
raise Exception(f"[ERROR] To use ipadapterApply, you need to install 'ComfyUI_IPAdapter_plus'")
|
||||
|
||||
def get_clipvision_file(self, preset, node_name):
|
||||
preset = preset.lower()
|
||||
clipvision_list = folder_paths.get_filename_list("clip_vision")
|
||||
|
||||
if preset.startswith("vit-g"):
|
||||
pattern = '(ViT.bigG.14.*39B.b160k|ipadapter.*sdxl|sdxl.*model\.(bin|safetensors))'
|
||||
else:
|
||||
pattern = '(ViT.H.14.*s32B.b79K|ipadapter.*sd15|sd1.?5.*model\.(bin|safetensors))'
|
||||
clipvision_files = [e for e in clipvision_list if re.search(pattern, e, re.IGNORECASE)]
|
||||
|
||||
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}")
|
||||
|
||||
return clipvision_file, clipvision_name
|
||||
|
||||
def get_ipadapter_file(self, preset, is_sdxl, node_name):
|
||||
preset = preset.lower()
|
||||
ipadapter_list = folder_paths.get_filename_list("ipadapter")
|
||||
is_insightface = False
|
||||
lora_pattern = None
|
||||
|
||||
if preset.startswith("light"):
|
||||
if is_sdxl:
|
||||
raise Exception("light model is not supported for SDXL")
|
||||
pattern = 'sd15.light.v11\.(safetensors|bin)$'
|
||||
# if light model v11 is not found, try with the old version
|
||||
if not [e for e in ipadapter_list if re.search(pattern, e, re.IGNORECASE)]:
|
||||
pattern = 'sd15.light\.(safetensors|bin)$'
|
||||
elif preset.startswith("standard"):
|
||||
if is_sdxl:
|
||||
pattern = 'ip.adapter.sdxl.vit.h\.(safetensors|bin)$'
|
||||
else:
|
||||
pattern = 'ip.adapter.sd15\.(safetensors|bin)$'
|
||||
elif preset.startswith("vit-g"):
|
||||
if is_sdxl:
|
||||
pattern = 'ip.adapter.sdxl\.(safetensors|bin)$'
|
||||
else:
|
||||
pattern = 'sd15.vit.g\.(safetensors|bin)$'
|
||||
elif preset.startswith("plus ("):
|
||||
if is_sdxl:
|
||||
pattern = 'plus.sdxl.vit.h\.(safetensors|bin)$'
|
||||
else:
|
||||
pattern = 'ip.adapter.plus.sd15\.(safetensors|bin)$'
|
||||
elif preset.startswith("plus face"):
|
||||
if is_sdxl:
|
||||
pattern = 'plus.face.sdxl.vit.h\.(safetensors|bin)$'
|
||||
else:
|
||||
pattern = 'plus.face.sd15\.(safetensors|bin)$'
|
||||
elif preset.startswith("full"):
|
||||
if is_sdxl:
|
||||
raise Exception("full face model is not supported for SDXL")
|
||||
pattern = 'full.face.sd15\.(safetensors|bin)$'
|
||||
elif preset.startswith("faceid portrait"):
|
||||
if is_sdxl:
|
||||
raise Exception("portrait model is not supported for SDXL")
|
||||
pattern = 'portrait.sd15\.(safetensors|bin)$'
|
||||
is_insightface = True
|
||||
elif preset == "faceid":
|
||||
if is_sdxl:
|
||||
pattern = 'faceid.sdxl\.(safetensors|bin)$'
|
||||
lora_pattern = 'faceid.sdxl.lora\.safetensors$'
|
||||
else:
|
||||
pattern = 'faceid.sd15\.(safetensors|bin)$'
|
||||
lora_pattern = 'faceid.sd15.lora\.safetensors$'
|
||||
is_insightface = True
|
||||
elif preset.startswith("faceid plus -"):
|
||||
if is_sdxl:
|
||||
raise Exception("faceid plus model is not supported for SDXL")
|
||||
pattern = 'faceid.plus.sd15\.(safetensors|bin)$'
|
||||
lora_pattern = 'faceid.plus.sd15.lora\.safetensors$'
|
||||
is_insightface = True
|
||||
elif preset.startswith("faceid plus v2"):
|
||||
if is_sdxl:
|
||||
pattern = 'faceid.plusv2.sdxl\.(safetensors|bin)$'
|
||||
lora_pattern = 'faceid.plusv2.sdxl.lora\.safetensors$'
|
||||
else:
|
||||
pattern = 'faceid.plusv2.sd15\.(safetensors|bin)$'
|
||||
lora_pattern = 'faceid.plusv2.sd15.lora\.safetensors$'
|
||||
is_insightface = True
|
||||
else:
|
||||
raise Exception(f"invalid type '{preset}'")
|
||||
|
||||
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}")
|
||||
|
||||
return ipadapter_file, ipadapter_name, is_insightface, lora_pattern
|
||||
|
||||
def get_lora_file(self, preset, pattern, model_type, model, model_strength, clip_strength, clip=None):
|
||||
lora_list = folder_paths.get_filename_list("loras")
|
||||
lora_files = [e for e in lora_list if re.search(pattern, e, re.IGNORECASE)]
|
||||
lora_name = lora_files[0] if lora_files else None
|
||||
if lora_name:
|
||||
return easyCache.load_lora({"model": model, "clip": clip, "lora_name": lora_name, "model_strength":model_strength, "clip_strength":clip_strength},)
|
||||
else:
|
||||
if "lora_url" in IPADAPTER_MODELS[preset][model_type]:
|
||||
lora_name = get_local_filepath(IPADAPTER_MODELS[preset][model_type]["lora_url"], os.path.join(folder_paths.models_dir, "loras"))
|
||||
return easyCache.load_lora({"model": model, "clip": clip, "lora_name": lora_name, "model_strength":model_strength, "clip_strength":clip_strength},)
|
||||
return (model, clip)
|
||||
|
||||
def ipadapter_model_loader(self, file):
|
||||
model = comfy.utils.load_torch_file(file, safe_load=True)
|
||||
|
||||
if file.lower().endswith(".safetensors"):
|
||||
st_model = {"image_proj": {}, "ip_adapter": {}}
|
||||
for key in model.keys():
|
||||
if key.startswith("image_proj."):
|
||||
st_model["image_proj"][key.replace("image_proj.", "")] = model[key]
|
||||
elif key.startswith("ip_adapter."):
|
||||
st_model["ip_adapter"][key.replace("ip_adapter.", "")] = model[key]
|
||||
model = st_model
|
||||
del st_model
|
||||
|
||||
if not "ip_adapter" in model.keys() or not model["ip_adapter"]:
|
||||
raise Exception("invalid IPAdapter model {}".format(file))
|
||||
|
||||
if 'plusv2' in file.lower():
|
||||
model["faceidplusv2"] = True
|
||||
|
||||
return model
|
||||
|
||||
def load_model(self, model, preset, lora_model_strength, provider="CPU", clip_vision=None, optional_ipadapter=None, cache_mode='none', node_name='easy ipadapterApply'):
|
||||
pipeline = {"clipvision": {'file': None, 'model': None}, "ipadapter": {'file': None, 'model': None},
|
||||
"insightface": {'provider': None, 'model': None}}
|
||||
if optional_ipadapter is not None:
|
||||
pipeline = optional_ipadapter
|
||||
|
||||
# 1. Load the clipvision model
|
||||
if not clip_vision:
|
||||
clipvision_file, clipvision_name = self.get_clipvision_file(preset, node_name)
|
||||
if clipvision_file is None:
|
||||
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]
|
||||
else:
|
||||
clip_vision = load_clip_vision(clipvision_file)
|
||||
update_cache(clipvision_name, (False, clip_vision))
|
||||
pipeline['clipvision']['file'] = clipvision_file
|
||||
pipeline['clipvision']['model'] = clip_vision
|
||||
|
||||
# 2. Load the ipadapter model
|
||||
is_sdxl = isinstance(model.model, comfy.model_base.SDXL)
|
||||
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
|
||||
pipeline['ipadapter']['model'] = ipadapter
|
||||
|
||||
# 3. Load the lora model if needed
|
||||
if lora_pattern is not None:
|
||||
if lora_model_strength > 0:
|
||||
model, _ = self.get_lora_file(preset, lora_pattern, model_type, model, lora_model_strength, 1)
|
||||
|
||||
# 4. Load the insightface model if needed
|
||||
if is_insightface:
|
||||
icache_key = 'insightface-' + provider
|
||||
if provider == pipeline['insightface']['provider']:
|
||||
insightface = pipeline['insightface']['model']
|
||||
elif icache_key in cache:
|
||||
log_node_info("easy ipadapterApply", f"Using InsightFaceModel {icache_key} Cached")
|
||||
insightface = cache[icache_key][1]
|
||||
else:
|
||||
insightface = insightface_loader(provider)
|
||||
update_cache(icache_key, (False, insightface))
|
||||
pipeline['insightface']['provider'] = provider
|
||||
pipeline['insightface']['model'] = insightface
|
||||
|
||||
return (model, pipeline,)
|
||||
|
||||
class ipadapterApply(ipadapter):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
presets = cls().presets
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MODEL",),
|
||||
"image": ("IMAGE",),
|
||||
"preset": (presets,),
|
||||
"lora_strength": ("FLOAT", {"default": 0.6, "min": 0, "max": 1, "step": 0.01}),
|
||||
"provider": (["CPU", "CUDA", "ROCM", "DirectML", "OpenVINO", "CoreML"],),
|
||||
"weight": ("FLOAT", {"default": 1.0, "min": -1, "max": 3, "step": 0.05}),
|
||||
"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"},),
|
||||
"use_tiled": ("BOOLEAN", {"default": False},),
|
||||
},
|
||||
|
||||
"optional": {
|
||||
"attn_mask": ("MASK",),
|
||||
"optional_ipadapter": ("IPADAPTER",),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("MODEL", "IMAGE", "MASK", "IPADAPTER",)
|
||||
RETURN_NAMES = ("model", "tiles", "masks", "ipadapter", )
|
||||
CATEGORY = "EasyUse/Adapter"
|
||||
FUNCTION = "apply"
|
||||
|
||||
def apply(self, model, image, preset, lora_strength, provider, weight, weight_faceidv2, start_at, end_at, cache_mode, use_tiled, attn_mask=None, optional_ipadapter=None):
|
||||
tiles, masks = [None], [None]
|
||||
model, ipadapter = self.load_model(model, preset, lora_strength, provider, clip_vision=None, optional_ipadapter=optional_ipadapter, cache_mode=cache_mode)
|
||||
if use_tiled:
|
||||
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, "linear", start_at, end_at, sharpening=0.0, combine_embeds="concat", image_negative=None, attn_mask=attn_mask, clip_vision=None, embeds_scaling='V only')
|
||||
else:
|
||||
if preset in ['FACEID PLUS V2', 'FACEID PORTRAIT (style transfer)']:
|
||||
if "IPAdapterAdvanced" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
self.error()
|
||||
cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterAdvanced"]
|
||||
model, = cls().apply_ipadapter(model, ipadapter, image, weight, "linear", start_at, end_at, combine_embeds="concat", weight_faceidv2=weight_faceidv2, image_negative=None, clip_vision=None, attn_mask=attn_mask, insightface=None, embeds_scaling='V only')
|
||||
else:
|
||||
if "IPAdapter" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
self.error()
|
||||
cls = ALL_NODE_CLASS_MAPPINGS["IPAdapter"]
|
||||
model, = cls().apply_ipadapter(model, ipadapter, image, weight, start_at, end_at, attn_mask)
|
||||
|
||||
return (model, tiles, masks, ipadapter)
|
||||
|
||||
class ipadapterApplyAdvanced(ipadapter):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
presets = cls().presets
|
||||
WEIGHT_TYPES = ["linear", "ease in", "ease out", 'ease in-out', 'reverse in-out', 'weak input', 'weak output',
|
||||
'weak middle', 'strong middle', 'style transfer (SDXL)']
|
||||
return {
|
||||
"required": {
|
||||
"model": ("MODEL",),
|
||||
"image": ("IMAGE",),
|
||||
"preset": (presets,),
|
||||
"lora_strength": ("FLOAT", {"default": 0.6, "min": 0, "max": 1, "step": 0.01}),
|
||||
"provider": (["CPU", "CUDA", "ROCM", "DirectML", "OpenVINO", "CoreML"],),
|
||||
"weight": ("FLOAT", {"default": 1.0, "min": -1, "max": 3, "step": 0.05}),
|
||||
"weight_faceidv2": ("FLOAT", {"default": 1.0, "min": -1, "max": 5.0, "step": 0.05 }),
|
||||
"weight_type": (WEIGHT_TYPES,),
|
||||
"combine_embeds": (["concat", "add", "subtract", "average", "norm 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", "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}),
|
||||
},
|
||||
|
||||
"optional": {
|
||||
"image_negative": ("IMAGE",),
|
||||
"attn_mask": ("MASK",),
|
||||
"clip_vision": ("CLIP_VISION",),
|
||||
"optional_ipadapter": ("IPADAPTER",),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("MODEL", "IMAGE", "MASK", "IPADAPTER",)
|
||||
RETURN_NAMES = ("model", "tiles", "masks", "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):
|
||||
tiles, masks = [None], [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:
|
||||
self.error()
|
||||
cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterTiledBatch"]
|
||||
else:
|
||||
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)
|
||||
else:
|
||||
if use_batch:
|
||||
if "IPAdapterBatch" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
self.error()
|
||||
cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterBatch"]
|
||||
else:
|
||||
if "IPAdapterAdvanced" not in ALL_NODE_CLASS_MAPPINGS:
|
||||
self.error()
|
||||
cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterAdvanced"]
|
||||
model, = cls().apply_ipadapter(model, ipadapter, image, weight, weight_type, start_at, end_at, combine_embeds=combine_embeds, weight_faceidv2=weight_faceidv2, image_negative=image_negative, clip_vision=clip_vision, attn_mask=attn_mask, insightface=None, embeds_scaling=embeds_scaling)
|
||||
|
||||
return (model, tiles, masks, ipadapter)
|
||||
|
||||
#Apply InstantID
|
||||
class instantID:
|
||||
|
||||
@@ -1670,7 +2011,7 @@ class instantIDApply(instantID):
|
||||
OUTPUT_NODE = True
|
||||
|
||||
FUNCTION = "apply"
|
||||
CATEGORY = "EasyUse/__for_testing"
|
||||
CATEGORY = "EasyUse/Adapter"
|
||||
|
||||
|
||||
def apply(self, pipe, image, instantid_file, insightface, control_net_name, cn_strength, cn_soft_weights, weight, start_at, end_at, noise, image_kps=None, mask=None, control_net=None, prompt=None, extra_pnginfo=None, my_unique_id=None):
|
||||
@@ -1718,7 +2059,7 @@ class instantIDApplyAdvanced(instantID):
|
||||
OUTPUT_NODE = True
|
||||
|
||||
FUNCTION = "apply_advanced"
|
||||
CATEGORY = "EasyUse/__for_testing"
|
||||
CATEGORY = "EasyUse/Adapter"
|
||||
|
||||
def apply_advanced(self, pipe, image, instantid_file, insightface, control_net_name, cn_strength, cn_soft_weights, weight, start_at, end_at, noise, image_kps=None, mask=None, control_net=None, positive=None, negative=None, prompt=None, extra_pnginfo=None, my_unique_id=None):
|
||||
|
||||
@@ -5326,6 +5667,9 @@ class showLoaderSettingsNames:
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
# seed 随机种
|
||||
"easy seed": easySeed,
|
||||
"easy globalSeed": globalSeed,
|
||||
# prompt 提示词
|
||||
"easy positive": positivePrompt,
|
||||
"easy negative": negativePrompt,
|
||||
@@ -5344,12 +5688,16 @@ NODE_CLASS_MAPPINGS = {
|
||||
"easy controlnetLoader": controlnetSimple,
|
||||
"easy controlnetLoaderADV": controlnetAdvanced,
|
||||
"easy LLLiteLoader": LLLiteLoader,
|
||||
# Adapter 适配器
|
||||
"easy ipadapterApply": ipadapterApply,
|
||||
"easy ipadapterApplyADV": ipadapterApplyAdvanced,
|
||||
"easy instantIDApply": instantIDApply,
|
||||
"easy instantIDApplyADV": instantIDApplyAdvanced,
|
||||
# Inpaint 内补
|
||||
"easy fooocusInpaintLoader": fooocusInpaintLoader,
|
||||
# latent 潜空间
|
||||
"easy latentNoisy": latentNoisy,
|
||||
"easy latentCompositeMaskedWithCond": latentCompositeMaskedWithCond,
|
||||
# seed 随机种
|
||||
"easy seed": easySeed,
|
||||
"easy globalSeed": globalSeed,
|
||||
# preSampling 预采样处理
|
||||
"easy preSampling": samplerSettings,
|
||||
"easy preSamplingAdvanced": samplerSettingsAdvanced,
|
||||
@@ -5404,13 +5752,12 @@ NODE_CLASS_MAPPINGS = {
|
||||
"easy showLoaderSettingsNames": showLoaderSettingsNames,
|
||||
# "easy imageRemoveBG": imageREMBG,
|
||||
"dynamicThresholdingFull": dynamicThresholdingFull,
|
||||
# __for_testing 测试
|
||||
"easy fooocusInpaintLoader": fooocusInpaintLoader,
|
||||
"easy instantIDApply": instantIDApply,
|
||||
"easy instantIDApplyADV": instantIDApplyAdvanced,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
# seed 随机种
|
||||
"easy seed": "EasySeed",
|
||||
"easy globalSeed": "EasyGlobalSeed",
|
||||
# prompt 提示词
|
||||
"easy positive": "Positive",
|
||||
"easy negative": "Negative",
|
||||
@@ -5429,12 +5776,16 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy controlnetLoader": "EasyControlnet",
|
||||
"easy controlnetLoaderADV": "EasyControlnet (Advanced)",
|
||||
"easy LLLiteLoader": "EasyLLLite",
|
||||
# Adapter 适配器
|
||||
"easy ipadapterApply": "Easy Apply IPAdapter",
|
||||
"easy ipadapterApplyADV": "Easy Apply IPAdapter (Advanced)",
|
||||
"easy instantIDApply": "Easy Apply InstantID",
|
||||
"easy instantIDApplyADV": "Easy Apply InstantID (Advanced)",
|
||||
# Inpaint 内补
|
||||
"easy fooocusInpaintLoader": "Load Fooocus Inpaint",
|
||||
# latent 潜空间
|
||||
"easy latentNoisy": "LatentNoisy",
|
||||
"easy latentCompositeMaskedWithCond": "LatentCompositeMaskedWithCond",
|
||||
# seed 随机种
|
||||
"easy seed": "EasySeed",
|
||||
"easy globalSeed": "EasyGlobalSeed",
|
||||
# preSampling 预采样处理
|
||||
"easy preSampling": "PreSampling",
|
||||
"easy preSamplingAdvanced": "PreSampling (Advanced)",
|
||||
@@ -5489,8 +5840,4 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy showLoaderSettingsNames": "Show Loader Settings Names",
|
||||
"easy imageRemoveBG": "ImageRemoveBG",
|
||||
"dynamicThresholdingFull": "DynamicThresholdingFull",
|
||||
# __for_testing 测试
|
||||
"easy fooocusInpaintLoader": "Load Fooocus Inpaint",
|
||||
"easy instantIDApply": "Easy Apply InstantID",
|
||||
"easy instantIDApplyADV": "Easy Apply InstantID (Advanced)",
|
||||
}
|
||||
+2
-32
@@ -1,5 +1,4 @@
|
||||
from PIL import Image
|
||||
from enum import Enum
|
||||
import os
|
||||
import hashlib
|
||||
import folder_paths
|
||||
@@ -7,37 +6,7 @@ import torch
|
||||
import numpy as np
|
||||
from nodes import MAX_RESOLUTION
|
||||
from .log import log_node_info
|
||||
|
||||
|
||||
def pil2tensor(image):
|
||||
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
|
||||
|
||||
class ResizeMode(Enum):
|
||||
RESIZE = "Just Resize"
|
||||
INNER_FIT = "Crop and Resize"
|
||||
OUTER_FIT = "Resize and Fill"
|
||||
def int_value(self):
|
||||
if self == ResizeMode.RESIZE:
|
||||
return 0
|
||||
elif self == ResizeMode.INNER_FIT:
|
||||
return 1
|
||||
elif self == ResizeMode.OUTER_FIT:
|
||||
return 2
|
||||
assert False, "NOTREACHED"
|
||||
|
||||
RESIZE_MODES = [ResizeMode.RESIZE.value, ResizeMode.INNER_FIT.value, ResizeMode.OUTER_FIT.value]
|
||||
|
||||
def get_new_bounds(width, height, left, right, top, bottom):
|
||||
"""Returns the new bounds for an image with inset crop data."""
|
||||
left = 0 + left
|
||||
right = width - right
|
||||
top = 0 + top
|
||||
bottom = height - bottom
|
||||
return (left, right, top, bottom)
|
||||
|
||||
# Tensor to PIL
|
||||
def tensor2pil(image):
|
||||
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
|
||||
from .libs.image import pil2tensor, tensor2pil, ResizeMode, get_new_bounds
|
||||
|
||||
# 图像裁切
|
||||
class imageInsetCrop:
|
||||
@@ -324,6 +293,7 @@ class imageScaleDownToSize(imageScaleDownBy):
|
||||
class imagePixelPerfect:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
RESIZE_MODES = [ResizeMode.RESIZE.value, ResizeMode.INNER_FIT.value, ResizeMode.OUTER_FIT.value]
|
||||
return {
|
||||
"required": {
|
||||
"image": ("IMAGE",),
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import torch
|
||||
import numpy as np
|
||||
from enum import Enum
|
||||
from PIL import Image
|
||||
|
||||
# PIL to Tensor
|
||||
def pil2tensor(image):
|
||||
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
|
||||
# Tensor to PIL
|
||||
def tensor2pil(image):
|
||||
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
|
||||
|
||||
# Get new bounds
|
||||
def get_new_bounds(width, height, left, right, top, bottom):
|
||||
"""Returns the new bounds for an image with inset crop data."""
|
||||
left = 0 + left
|
||||
right = width - right
|
||||
top = 0 + top
|
||||
bottom = height - bottom
|
||||
return (left, right, top, bottom)
|
||||
|
||||
|
||||
class ResizeMode(Enum):
|
||||
RESIZE = "Just Resize"
|
||||
INNER_FIT = "Crop and Resize"
|
||||
OUTER_FIT = "Resize and Fill"
|
||||
def int_value(self):
|
||||
if self == ResizeMode.RESIZE:
|
||||
return 0
|
||||
elif self == ResizeMode.INNER_FIT:
|
||||
return 1
|
||||
elif self == ResizeMode.OUTER_FIT:
|
||||
return 2
|
||||
assert False, "NOTREACHED"
|
||||
|
||||
+1
-28
@@ -154,31 +154,4 @@ def easySave(images, filename_prefix, output_type, prompt=None, extra_pnginfo=No
|
||||
return results['ui']['images']
|
||||
else:
|
||||
results = SaveImage().save_images(images, filename_prefix, prompt, extra_pnginfo)
|
||||
return results['ui']['images']
|
||||
|
||||
# Image Utils
|
||||
# from PIL import Image, ImageDraw
|
||||
# import numpy as np
|
||||
# import torch
|
||||
# def is_image_transparent(img):
|
||||
# print(img.shape)
|
||||
# if len(img.shape) > 3 and img.shape[3] == 4:
|
||||
# return True
|
||||
# else:
|
||||
# m = tensor2pil(img)
|
||||
# if m.mode == "RGBA":
|
||||
# return True
|
||||
# else:
|
||||
# return False
|
||||
#
|
||||
# def create_grid(image_size, box_size):
|
||||
# img = Image.new('RGBA', image_size, (255, 255, 255, 255)) # 白色背景
|
||||
# draw = ImageDraw.Draw(img)
|
||||
#
|
||||
# for x in range(0, img.width, box_size):
|
||||
# for y in range(0, img.height, box_size):
|
||||
# if (x // box_size % 2 == 0 and y // box_size % 2 == 0) or (x // box_size % 2 == 1 and y // box_size % 2 == 1):
|
||||
# draw.rectangle([(x, y), (x+box_size, y+box_size)], fill=(204, 204, 204, 255)) # 不透明
|
||||
# else:
|
||||
# continue # 保持透明
|
||||
# return img
|
||||
return results['ui']['images']
|
||||
@@ -4,13 +4,13 @@ import { ComfyWidgets } from "/scripts/widgets.js";
|
||||
|
||||
let origProps = {};
|
||||
|
||||
const seedNodes = ["easy seed", "easy latentNoisy", "easy wildcards", "easy preSampling", "easy preSamplingAdvanced", "easy preSamplingNoiseIn", "easy preSamplingSdTurbo", "easy preSamplingCascade", "easy preSamplingDynamicCFG", "easy preSamplingLayerDiffusion", "easy fullkSampler", "easy fullCascadeKSampler"]
|
||||
const loaderNodes = ["easy fullLoader", "easy a1111Loader", "easy comfyLoader"]
|
||||
const findWidgetByName = (node, name) => node.widgets.find((w) => w.name === name);
|
||||
|
||||
const doesInputWithNameExist = (node, name) => node.inputs ? node.inputs.some((input) => input.name === name) : false;
|
||||
|
||||
function updateNodeHeight(node) {
|
||||
node.setSize([node.size[0], node.computeSize()[1]]);
|
||||
}
|
||||
function updateNodeHeight(node) {node.setSize([node.size[0], node.computeSize()[1]]);}
|
||||
|
||||
function toggleWidget(node, widget, show = false, suffix = "") {
|
||||
if (!widget || doesInputWithNameExist(node, widget.name)) return;
|
||||
@@ -26,7 +26,6 @@ function toggleWidget(node, widget, show = false, suffix = "") {
|
||||
|
||||
const height = show ? Math.max(node.computeSize()[1], origSize[1]) : node.size[1];
|
||||
node.setSize([node.size[0], height]);
|
||||
|
||||
}
|
||||
|
||||
function widgetLogic(node, widget) {
|
||||
@@ -208,6 +207,45 @@ function widgetLogic(node, widget) {
|
||||
toggleWidget(node, findWidgetByName(node, 'new_cond_end'), true)
|
||||
}
|
||||
}
|
||||
|
||||
if (widget.name === 'preset') {
|
||||
const normol_presets = [
|
||||
'LIGHT - SD1.5 only (low strength)',
|
||||
'STANDARD (medium strength)',
|
||||
'VIT-G (medium strength)',
|
||||
'PLUS (high strength)', 'PLUS FACE (portraits)',
|
||||
'FULL FACE - SD1.5 only (portraits stronger)',
|
||||
'FACEID PORTRAIT (style transfer)'
|
||||
]
|
||||
const faceid_presets = [
|
||||
'FACEID',
|
||||
'FACEID PLUS - SD1.5 only',
|
||||
'FACEID PLUS V2',
|
||||
]
|
||||
if(normol_presets.includes(widget.value)){
|
||||
toggleWidget(node, findWidgetByName(node, 'lora_strength'))
|
||||
toggleWidget(node, findWidgetByName(node, 'provider'))
|
||||
toggleWidget(node, findWidgetByName(node, 'weight_faceidv2'))
|
||||
}
|
||||
else if(faceid_presets.includes(widget.value)){
|
||||
if(widget.value == 'FACEID PLUS V2'){
|
||||
toggleWidget(node, findWidgetByName(node, 'weight_faceidv2'), true)
|
||||
}else{
|
||||
toggleWidget(node, findWidgetByName(node, 'weight_faceidv2'))
|
||||
}
|
||||
toggleWidget(node, findWidgetByName(node, 'lora_strength'), true)
|
||||
toggleWidget(node, findWidgetByName(node, 'provider'), true)
|
||||
}
|
||||
updateNodeHeight(node)
|
||||
}
|
||||
|
||||
if (widget.name === 'use_tiled') {
|
||||
if(widget.value)
|
||||
toggleWidget(node, findWidgetByName(node, 'sharpening'), true)
|
||||
else
|
||||
toggleWidget(node, findWidgetByName(node, 'sharpening'))
|
||||
updateNodeHeight(node)
|
||||
}
|
||||
}
|
||||
|
||||
function widgetLogic2(node, widget) {
|
||||
@@ -486,6 +524,8 @@ app.registerExtension({
|
||||
case "easy rangeFloat":
|
||||
case 'easy latentCompositeMaskedWithCond':
|
||||
case 'easy pipeEdit':
|
||||
case 'easy ipadapterApply':
|
||||
case 'easy ipadapterApplyADV':
|
||||
getSetters(node)
|
||||
break
|
||||
case "easy wildcards":
|
||||
@@ -734,7 +774,7 @@ app.registerExtension({
|
||||
};
|
||||
}
|
||||
|
||||
if (["easy fullLoader", "easy a1111Loader", "easy comfyLoader"].includes(nodeData.name)) {
|
||||
if (loaderNodes.includes(nodeData.name)) {
|
||||
function populate(text, type = 'positive') {
|
||||
if (this.widgets) {
|
||||
const pos = this.widgets.findIndex((w) => w.name === type + "_prompt");
|
||||
@@ -781,7 +821,7 @@ app.registerExtension({
|
||||
};
|
||||
}
|
||||
|
||||
if (["easy seed", "easy latentNoisy", "easy wildcards", "easy preSampling", "easy preSamplingAdvanced", "easy preSamplingNoiseIn", "easy preSamplingSdTurbo", "easy preSamplingCascade", "easy preSamplingDynamicCFG", "easy preSamplingLayerDiffusion", "easy fullkSampler", "easy fullCascadeKSampler"].includes(nodeData.name)) {
|
||||
if (seedNodes.includes(nodeData.name)) {
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
||||
nodeType.prototype.onNodeCreated = async function () {
|
||||
onNodeCreated ? onNodeCreated.apply(this, []) : undefined;
|
||||
@@ -922,7 +962,7 @@ const getSetWidgets = ['rescale_after_model', 'rescale',
|
||||
'refiner_lora1_name', 'refiner_lora2_name', 'upscale_method',
|
||||
'image_output', 'add_noise', 'info', 'sampler_name',
|
||||
'ckpt_B_name', 'ckpt_C_name', 'save_model', 'refiner_ckpt_name',
|
||||
'num_loras', 'mode', 'toggle', 'resolution', 'target_parameter', 'input_count', 'replace_count', 'downscale_mode', 'range_mode','text_combine_mode', 'input_mode','lora_count','ckpt_count', 'conditioning_mode']
|
||||
'num_loras', 'mode', 'toggle', 'resolution', 'target_parameter', 'input_count', 'replace_count', 'downscale_mode', 'range_mode','text_combine_mode', 'input_mode','lora_count','ckpt_count', 'conditioning_mode', 'preset', 'use_tiled', 'use_batch']
|
||||
|
||||
function getSetters(node) {
|
||||
if (node.widgets)
|
||||
|
||||
@@ -4,6 +4,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 positive_prompt = ['easy positive', 'easy wildcards']
|
||||
const widgetMapping = {
|
||||
"positive_prompt":{
|
||||
@@ -45,6 +46,17 @@ const widgetMapping = {
|
||||
"cn_strength": ["strength", "cn_strength"],
|
||||
"cn_soft_weights": ["scale_soft_weights","cn_soft_weights"],
|
||||
},
|
||||
"ipadapter":{
|
||||
"preset":"preset",
|
||||
"lora_strength": "lora_strength",
|
||||
"provider": "provider",
|
||||
"weight":"weight",
|
||||
"weight_faceidv2": "weight_faceidv2",
|
||||
"start_at": "start_at",
|
||||
"end_at": "end_at",
|
||||
"cache_mode": "cache_mode",
|
||||
"use_tiled": "use_tiled",
|
||||
}
|
||||
}
|
||||
const inputMapping = {
|
||||
"loaders":{
|
||||
@@ -73,6 +85,12 @@ const inputMapping = {
|
||||
"positive_prompt":{
|
||||
|
||||
},
|
||||
"ipadapter":{
|
||||
"model":"model",
|
||||
"image":"image",
|
||||
"attn_mask":"attn_mask",
|
||||
"optional_ipadapter":"optional_ipadapter"
|
||||
}
|
||||
};
|
||||
|
||||
const outputMapping = {
|
||||
@@ -104,6 +122,12 @@ const outputMapping = {
|
||||
"load_image":{
|
||||
"IMAGE":"IMAGE",
|
||||
"MASK": "MASK"
|
||||
},
|
||||
"ipadapter":{
|
||||
"model":"model",
|
||||
"tiles":"tiles",
|
||||
"masks":"masks",
|
||||
"ipadapter":"ipadapter"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -491,6 +515,10 @@ app.registerExtension({
|
||||
if (controlnet.includes(nodeData.name)) {
|
||||
addMenu("↪️ Swap EasyControlnet", 'controlnet', controlnet, nodeType)
|
||||
}
|
||||
// Swap IPAdapater
|
||||
if (ipadapter.includes(nodeData.name)) {
|
||||
addMenu("↪️ Swap EasyIPAdapater", 'ipadapter', ipadapter, nodeType)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user