💖Upgrade to v1.1.8

This commit is contained in:
yolain
2024-05-25 11:47:51 +08:00
parent 7cbc2a2a2b
commit d95772147f
19 changed files with 178 additions and 68 deletions
+2 -1
View File
@@ -11,4 +11,5 @@ docs/**
.vscode/
.idea/
mmb-preset.custom.txt
config.yaml
config.yaml
node.tar.gz
+5
View File
@@ -33,6 +33,11 @@
-
## Changelog
**v1.1.8**
- Added `easy applyBrushNet` - [Workflow Example](https://github.com/yolain/ComfyUI-Yolain-Workflows/blob/main/workflows/2_advanced/2-4inpainting/2-4brushnet_1.1.8.json)
- Added `easy applyPowerPaint` - [Workflow Example](https://github.com/yolain/ComfyUI-Yolain-Workflows/blob/main/workflows/2_advanced/2-4inpainting/2-4powerpaint_outpaint_1.1.8.json)
**v1.1.7**
- Added `easy prompt` - Subject and light presets, maybe adjusted later
+5
View File
@@ -39,6 +39,11 @@
## 更新日志
**v1.1.8**
- 增加 `easy applyBrushNet` - [示例参考](https://github.com/yolain/ComfyUI-Yolain-Workflows/blob/main/workflows/2_advanced/2-4inpainting/2-4brushnet_1.1.8.json)
- 增加 `easy applyPowerPaint` - [示例参考](https://github.com/yolain/ComfyUI-Yolain-Workflows/blob/main/workflows/2_advanced/2-4inpainting/2-4powerpaint_outpaint_1.1.8.json)
**v1.1.7**
- 修复 一些模型(如controlnet模型等)未成功写入缓存,导致修改前置节点束参数(如提示词)需要二次载入模型的问题
+2 -2
View File
@@ -1,4 +1,4 @@
__version__ = "1.1.7"
__version__ = "1.1.8"
import os
import glob
@@ -26,7 +26,7 @@ cwd_path = os.path.dirname(os.path.realpath(__file__))
comfy_path = folder_paths.base_path
#Wildcards读取
from .py.wildcards import read_wildcard_dict
from .py.libs.wildcards import read_wildcard_dict
wildcards_path = os.path.join(os.path.dirname(__file__), "wildcards")
if os.path.exists(wildcards_path):
read_wildcard_dict(wildcards_path)
+5
View File
@@ -76,6 +76,11 @@ BRUSHNET_MODELS = {
}
}
}
POWERPAINT_CLIP = {
"base_fp16":{
"model_url":"https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/text_encoder/model.fp16.safetensors"
}
}
# layerDiffuse
LAYER_DIFFUSION_DIR = os.path.join(folder_paths.models_dir, "layer_model")
+145 -12
View File
@@ -18,20 +18,20 @@ 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, BRUSHNET_MODELS, IPADAPTER_DIR, IPADAPTER_MODELS, DYNAMICRAFTER_DIR, DYNAMICRAFTER_MODELS, IC_LIGHT_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 .config import MAX_SEED_NUM, BASE_RESOLUTIONS, RESOURCES_DIR, INPAINT_DIR, FOOOCUS_STYLES_DIR, FOOOCUS_INPAINT_HEAD, FOOOCUS_INPAINT_PATCH, BRUSHNET_MODELS, POWERPAINT_CLIP, IPADAPTER_DIR, IPADAPTER_MODELS, DYNAMICRAFTER_DIR, DYNAMICRAFTER_MODELS, IC_LIGHT_MODELS
from .layer_diffuse.func import LayerDiffuse, LayerMethod
from .libs.log import log_node_info, log_node_error, log_node_warn
from .libs.adv_encode import advanced_encode
from .libs.wildcards import process_with_loras, get_wildcard_list, process
from .libs.utils import find_wildcards_seed, is_linked_styles_selector, easySave, get_local_filepath, AlwaysEqualProxy, get_sd_version
from .libs.loader import easyLoader
from .libs.sampler import easySampler, alignYourStepsScheduler
from .libs.xyplot import easyXYPlot
from .libs.controlnet import easyControlnet
from .libs.conditioning import prompt_to_cond, set_cond
from .libs import cache as backend_cache
from .libs.easing import EasingBase
from .libs import cache as backend_cache
sampler = easySampler()
easyCache = easyLoader()
@@ -2076,7 +2076,7 @@ class controlnetAdvanced:
return (new_pipe, positive, negative)
# LLLiteLoader
from .lllite import load_control_net_lllite_patch
from .libs.lllite import load_control_net_lllite_patch
class LLLiteLoader:
def __init__(self):
pass
@@ -2117,7 +2117,7 @@ class LLLiteLoader:
#---------------------------------------------------------------Inpaint 开始----------------------------------------------------------------------#
# FooocusInpaint
from .fooocus import InpaintHead, InpaintWorker
from .libs.fooocus import InpaintHead, InpaintWorker
inpaint_head_model = None
class applyFooocusInpaint:
@@ -2157,6 +2157,137 @@ class applyFooocusInpaint:
m, = worker.patch(cloned, latent, patch)
return (m,)
# brushnet
class applyBrushNet:
def __init__(self):
self.inpaint_path = os.path.join(folder_paths.models_dir, 'inpaint')
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"pipe": ("PIPE_LINE",),
"image": ("IMAGE",),
"mask": ("MASK",),
"brushnet": (folder_paths.get_filename_list('inpaint'),),
"dtype": (['float16', 'bfloat16', 'float32', 'float64'], ),
"scale": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0}),
"start_at": ("INT", {"default": 0, "min": 0, "max": 10000}),
"end_at": ("INT", {"default": 10000, "min": 0, "max": 10000}),
},
}
RETURN_TYPES = ("PIPE_LINE",)
RETURN_NAMES = ("pipe",)
CATEGORY = "EasyUse/Inpaint"
FUNCTION = "apply"
def apply(self, pipe, image, mask, brushnet, dtype, scale, start_at, end_at):
model = pipe['model']
vae = pipe['vae']
positive = pipe['positive']
negative = pipe['negative']
if brushnet in backend_cache.cache:
log_node_info("easy brushnetApply", f"Using {brushnet} Cached")
_, brushnet_model = backend_cache.cache[brushnet][1]
else:
if "BrushNetLoader" not in ALL_NODE_CLASS_MAPPINGS:
raise Exception("BrushNetLoader not found,please install ComfyUI-BrushNet")
cls = ALL_NODE_CLASS_MAPPINGS['BrushNetLoader']
brushnet_model, = cls.brushnet_loading(self, brushnet, dtype)
backend_cache.update_cache(brushnet, 'brushnet', (False, brushnet_model))
cls = ALL_NODE_CLASS_MAPPINGS['BrushNet']
m, positive, negative, latent = cls().model_update(model=model, vae=vae, image=image, mask=mask,
brushnet=brushnet_model, positive=positive,
negative=negative, scale=scale, start_at=start_at,
end_at=end_at)
new_pipe = {
**pipe,
"model": m,
"positive": positive,
"negative": negative,
"samples": latent,
}
del pipe
return (new_pipe,)
#powerpaint
class applyPowerPaint:
def __init__(self):
self.inpaint_path = os.path.join(folder_paths.models_dir, 'inpaint')
self.clip_path = os.path.join(folder_paths.models_dir, 'clip')
def get_file_list(filenames, ext='.bin'):
return [file for file in filenames if file.lower().endswith(ext)]
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"pipe": ("PIPE_LINE",),
"image": ("IMAGE",),
"mask": ("MASK",),
"powerpaint_model": (s.get_file_list(folder_paths.get_filename_list('inpaint'),'.safetensors'),),
"powerpaint_clip": (s.get_file_list(folder_paths.get_filename_list('inpaint')),),
"dtype": (['float16', 'bfloat16', 'float32', 'float64'],),
"fitting": ("FLOAT", {"default": 1.0, "min": 0.3, "max": 1.0}),
"function": (['text guided', 'shape guided', 'object removal', 'context aware', 'image outpainting'],),
"scale": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0}),
"start_at": ("INT", {"default": 0, "min": 0, "max": 10000}),
"end_at": ("INT", {"default": 10000, "min": 0, "max": 10000}),
},
}
RETURN_TYPES = ("PIPE_LINE",)
RETURN_NAMES = ("pipe",)
CATEGORY = "EasyUse/Inpaint"
FUNCTION = "apply"
def apply(self, pipe, image, mask, powerpaint_model, powerpaint_clip, dtype, fitting, function, scale, start_at, end_at):
model = pipe['model']
vae = pipe['vae']
positive = pipe['positive']
negative = pipe['negative']
# load powerpaint clip
if powerpaint_clip in backend_cache.cache:
log_node_info("easy powerpaintApply", f"Using {powerpaint_clip} Cached")
_, ppclip = backend_cache.cache[powerpaint_clip][1]
else:
if "PowerPaintCLIPLoader" not in ALL_NODE_CLASS_MAPPINGS:
raise Exception("PowerPaintCLIPLoader not found,please install ComfyUI-Brushnet")
cls = ALL_NODE_CLASS_MAPPINGS['PowerPaintCLIPLoader']
model_url = POWERPAINT_CLIP['base_fp16']['model_url']
base_clip = get_local_filepath(model_url, os.path.join(folder_paths.models_dir, 'clip'))
base = os.path.basename(base_clip)
ppclip, = cls.ppclip_loading(self, base, powerpaint_clip)
backend_cache.update_cache(powerpaint_clip, 'ppclip', (False,ppclip))
# load powerpaint model
if powerpaint_model in backend_cache.cache:
log_node_info("easy powerpaintApply", f"Using {powerpaint_model} Cached")
_, powerpaint = backend_cache.cache[powerpaint_model][1]
else:
if "BrushNetLoader" not in ALL_NODE_CLASS_MAPPINGS:
raise Exception("BrushNetLoader not found,please install ComfyUI-Brushnet")
cls = ALL_NODE_CLASS_MAPPINGS['BrushNetLoader']
powerpaint, = cls.brushnet_loading(self, powerpaint_model, dtype)
backend_cache.update_cache(powerpaint_model, 'powerpaint', (False, powerpaint))
cls = ALL_NODE_CLASS_MAPPINGS['PowerPaint']
m, positive, negative, latent = cls().model_update(model=model, vae=vae, image=image, mask=mask, powerpaint=powerpaint,
clip=ppclip, positive=positive,
negative=negative, fitting=fitting, function=function,
scale=scale, start_at=start_at, end_at=end_at)
new_pipe = {
**pipe,
"model": m,
"positive": positive,
"negative": negative,
"samples": latent,
}
del pipe
return (new_pipe,)
#---------------------------------------------------------------适配器 开始----------------------------------------------------------------------#
@@ -3645,7 +3776,7 @@ class samplerCustomSettings:
return {"ui": {"value": [seed]}, "result": (new_pipe,)}
# 预采样设置(SDTurbo)
from .gradual_latent_hires_fix import sample_dpmpp_2s_ancestral, sample_dpmpp_2m_sde, sample_lcm, sample_euler_ancestral
from .libs.gradual_latent_hires_fix import sample_dpmpp_2s_ancestral, sample_dpmpp_2m_sde, sample_lcm, sample_euler_ancestral
class sdTurboSettings:
def __init__(self):
pass
@@ -4014,7 +4145,7 @@ class layerDiffusionSettingsADDTL:
return (new_pipe,)
# 预采样设置(动态CFG)
from .dynthres_core import DynThresh
from .libs.dynthres_core import DynThresh
class dynamicCFGSettings:
def __init__(self):
pass
@@ -7253,8 +7384,9 @@ NODE_CLASS_MAPPINGS = {
"easy styleAlignedBatchAlign": styleAlignedBatchAlign,
"easy icLightApply": icLightApply,
# Inpaint 内补
# "easy fooocusInpaintLoader": fooocusInpaintLoader,
"easy applyFooocusInpaint": applyFooocusInpaint,
"easy applyBrushNet": applyBrushNet,
"easy applyPowerPaint": applyPowerPaint,
# latent 潜空间
"easy latentNoisy": latentNoisy,
"easy latentCompositeMaskedWithCond": latentCompositeMaskedWithCond,
@@ -7362,8 +7494,9 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"easy styleAlignedBatchAlign": "Easy Apply StyleAlign",
"easy icLightApply": "Easy Apply ICLight",
# Inpaint 内补
# "easy fooocusInpaintLoader": "Load Fooocus Inpaint(Removed)",
"easy applyFooocusInpaint": "Apply Fooocus Inpaint",
"easy applyFooocusInpaint": "Easy Apply Fooocus Inpaint",
"easy applyBrushNet": "Easy Apply BrushNet",
"easy applyPowerPaint": "Easy Apply PowerPaint",
# latent 潜空间
"easy latentNoisy": "LatentNoisy",
"easy latentCompositeMaskedWithCond": "LatentCompositeMaskedWithCond",
+3 -3
View File
@@ -8,10 +8,10 @@ import comfy.model_management
from comfy_extras.nodes_compositing import JoinImageWithAlpha
from server import PromptServer
from nodes import MAX_RESOLUTION
from torchvision.transforms import Resize, CenterCrop, InterpolationMode
from torchvision.transforms import Resize, CenterCrop
from torchvision.transforms.functional import to_pil_image
from .log import log_node_info
from .libs.image import pil2tensor, tensor2pil, ResizeMode, get_new_bounds, RGB2RGBA, image2mask, mask2image, blendImage
from .libs.log import log_node_info
from .libs.image import pil2tensor, tensor2pil, ResizeMode, get_new_bounds, RGB2RGBA, image2mask
from .libs.colorfix import adain_color_fix, wavelet_color_fix
from .libs.chooser import ChooserMessage, ChooserCancelled
from .config import REMBG_DIR, REMBG_MODELS, HUMANPARSING_MODELS, MEDIAPIPE_MODELS, MEDIAPIPE_DIR
+1 -3
View File
@@ -4,9 +4,7 @@ import itertools
from comfy import model_management
from comfy.sdxl_clip import SDXLClipModel, SDXLRefinerClipModel, SDXLClipG
from nodes import NODE_CLASS_MAPPINGS, ConditioningConcat, CLIPTextEncode
from .libs.utils import compare_revision
from nodes import NODE_CLASS_MAPPINGS, ConditioningConcat
def _grouper(n, iterable):
it = iter(iterable)
+3 -3
View File
@@ -1,7 +1,7 @@
from .utils import find_wildcards_seed, find_nearest_steps, is_linked_styles_selector
from ..log import log_node_warn
from ..adv_encode import advanced_encode
from ..wildcards import process_with_loras
from .log import log_node_warn
from .wildcards import process_with_loras
from .adv_encode import advanced_encode
from nodes import ConditioningConcat, ConditioningCombine, ConditioningAverage, ConditioningSetTimestepRange
View File
+2 -2
View File
@@ -5,7 +5,7 @@ import comfy.controlnet
import folder_paths
from nodes import NODE_CLASS_MAPPINGS
from collections import defaultdict
from ..log import log_node_info, log_node_error
from .log import log_node_info, log_node_error
stable_diffusion_loaders = ["easy fullLoader", "easy a1111Loader", "easy comfyLoader", "easy zero123Loader", "easy svdLoader"]
stable_cascade_loaders = ["easy cascadeLoader"]
@@ -268,7 +268,7 @@ class easyLoader:
self.add_to_cache("controlnet", unique_id, control_net)
self.eviction_based_on_memory()
return control_net
def load_clip(self, clip_name, type='stable_diffusion'):
def load_clip(self, clip_name, type='stable_diffusion', load_clip=None):
if type == 'stable_diffusion':
clip_type = comfy.sd.CLIPType.STABLE_DIFFUSION
else:
View File
+1 -1
View File
@@ -6,7 +6,7 @@ import pathlib
from aiohttp import web
from server import PromptServer
from .image import tensor2pil, pil2tensor, image2base64, pil2byte
from ..log import log_node_error
from .log import log_node_error
root_path = pathlib.Path(__file__).parent.parent.parent
+4 -3
View File
@@ -2,11 +2,12 @@ import os, torch
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
from .utils import easySave
from ..config import RESOURCES_DIR
from ..log import log_node_warn
from ..adv_encode import advanced_encode
from .adv_encode import advanced_encode
from .controlnet import easyControlnet
from .log import log_node_warn
from ..layer_diffuse.func import LayerDiffuse
from ..config import RESOURCES_DIR
class easyXYPlot():
def __init__(self, xyPlotData, save_prefix, image_output, prompt, extra_pnginfo, my_unique_id, sampler, easyCache):
-38
View File
@@ -2,9 +2,6 @@ import random
import server
from enum import Enum
seed_nodes = ["easy wildcards","easy preSampling","easy preSamplingAdvanced","easy preSamplingSdTurbo","easy preSamplingDynamicCFG","easy preSamplingLayerDiffusion","easy preSamplingCascade","easy fullCascadeKSampler","easy fullkSampler","easy seed","easy latentNoisy", "easy preSamplingNoiseIn"]
class SGmode(Enum):
FIX = 1
INCR = 2
@@ -123,41 +120,6 @@ def prompt_seed_update(json_data):
# control after generated
if mode is not None and not mode:
control_seed(node[1], action, seed_is_global)
# else:
# prompts = json_data['prompt'].items()
# for k, v in prompts:
# if 'class_type' not in v:
# continue
# cls = v['class_type']
# if cls in seed_nodes:
# extra_data = next((x for x in workflow["nodes"] if str(x["id"]) == k), None)
# if extra_data is not None:
# inputs = extra_data.get('inputs')
# widgets_value = extra_data.get('widgets_values')
# widgets_length = len(widgets_value)
# if "disable" in widgets_value:
# break
# if inputs is not None and inputs != []:
# seed_num_input = next((x for x in inputs if x['name'] == 'seed_num' and x['type'] == 'INT'), None)
# if seed_num_input is not None:
# action = 'fixed'
# else:
# action = widgets_value[widgets_length - 1]
# else:
# control_index = widgets_length - 2 if cls == 'easy seed' else widgets_length - 1
# action = widgets_value[control_index]
#
# # print(action)
# node = k, v
# value = control_seed(node[1], action, False)
#
# if k not in seed_widget_map:
# continue
#
# if 'seed_num' in v['inputs']:
# if isinstance(v['inputs']['seed_num'], int):
# v['inputs']['seed_num'] = value
return value is not None