This commit is contained in:
lilly
2023-03-20 17:26:23 +09:00
parent 479025c947
commit 0ac73701c6
12 changed files with 566 additions and 1 deletions
+2
View File
@@ -0,0 +1,2 @@
*.pyc
+22
View File
@@ -0,0 +1,22 @@
import os, glob, sys
import random
import re
from .wildcards import *
#import wildcards
print("wildcards_ComfyUI")
#print(os.getcwd())
class CLIPTextEncodeWildcards:
@classmethod
def INPUT_TYPES(s):
return {"required": {"text": ("STRING", {"multiline": True}), "clip": ("CLIP", )}}
RETURN_TYPES = ("CONDITIONING",)
FUNCTION = "encode"
CATEGORY = "conditioning"
def encode(self, clip, text):
r=run(text)
print(f"encode : {r}")
return ([[clip.encode(r), {}]], )
+49
View File
@@ -0,0 +1,49 @@
import os
import comfy.sd
from nodes import *
import random
import folder_paths
cnt=0
ckpt_name=""
ckpt_path=""
class CheckpointLoaderRandom:
models_dir = os.path.join(os.getcwd(),"ComfyUI", "models")
ckpt_dir = os.path.join(models_dir, "checkpoints")
cnt=0
ckpt_name=""
ckpt_path=""
def __init__(self):
print(f"CheckpointLoaderRandom __init__")
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"max": ("INT", {"default": 10, "min": 0, "max": 0xffffffffffffffff}),
#"ckpt_name": (filter_files_extensions(recursive_search(s.ckpt_dir), supported_ckpt_extensions), ),
}
}
RETURN_TYPES = ("MODEL", "CLIP", "VAE")
FUNCTION = "load_checkpoint"
CATEGORY = "loaders"
def load_checkpoint(self, seed, max, output_vae=True, output_clip=True):
global cnt, ckpt_name, ckpt_path
print(f"cnt : { cnt}")
if ckpt_name=="" or cnt>=max :
cnt=0
ckpt_names= folder_paths.get_filename_list("checkpoints")
#print(f"ckpt_names : { ckpt_names}")
ckpt_name=random.choice(ckpt_names)
print(f"ckpt_name : { ckpt_name}")
ckpt_path = folder_paths.get_full_path("checkpoints", ckpt_name)
out = comfy.sd.load_checkpoint_guess_config(ckpt_path, output_vae=True, output_clip=True, embedding_directory=folder_paths.get_folder_paths("embeddings"))
cnt+=1
return out
+43
View File
@@ -0,0 +1,43 @@
import os
import comfy.sd
from nodes import *
import folder_paths
import random
from .check_name import *
print(os.getcwd())
class CheckpointLoaderSimpleText:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"ckpt_name": (
"STRING", {
"multiline": False,
"default": random.choice(folder_paths.get_filename_list("checkpoints"))
}
),
}
}
RETURN_TYPES = ("MODEL", "CLIP", "VAE")
FUNCTION = "load_checkpoint"
CATEGORY = "loaders"
def load_checkpoint(self, ckpt_name, output_vae=True, output_clip=True):
ckpt_path =check_name_ckpt(name_split_choice(ckpt_name))
if ckpt_path is None:
print(f"{ckpt_name} is none")
return
try:
out = comfy.sd.load_checkpoint_guess_config(ckpt_path, output_vae=True, output_clip=True, embedding_directory=folder_paths.get_folder_paths("embeddings"))
return out
except Exception as e:
print("CheckpointLoaderSimpleText Exception : "+ e)
return
#NODE_CLASS_MAPPINGS = {
# "CheckpointLoaderSimpleText": CheckpointLoaderSimpleText,
#}
+52
View File
@@ -0,0 +1,52 @@
import os
import comfy.sd
from nodes import *
import folder_paths
class LoraLoaderText:
@classmethod
def INPUT_TYPES(s):
return {"required": { "model": ("MODEL",),
"clip": ("CLIP", ),
"lora_name": ("STRING", {
"multiline": False, #True if you want the field to look like the one on the ClipTextEncode node
"default": (folder_paths.get_filename_list("loras"), )
}),
#"lora_name": (folder_paths.get_filename_list("loras"), ),
"strength_model": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"strength_clip": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
}}
RETURN_TYPES = ("MODEL", "CLIP")
FUNCTION = "load_lora"
CATEGORY = "loaders"
def load_lora(self, model, clip, lora_name, strength_model, strength_clip):
if lora_name is None or lora_name =="":
print("LoraLoaderText No")
return (strength_model, strength_clip)
if lora_name.endswith('.safetensors') or lora_name.endswith('.ckpt') :
lora_path = folder_paths.get_full_path("loras", lora_name)
else:
lora_path = folder_paths.get_full_path("loras", lora_name+'.safetensors')
print("LoraLoaderText lora_path : "+ lora_path)
if lora_path is None:
lora_path = folder_paths.get_full_path("loras", lora_name+'.ckpt')
print("LoraLoaderText lora_path : "+ lora_path)
if lora_path is None:
print("LoraLoaderText No : "+ lora_name)
return (strength_model, strength_clip)
try:
model_lora, clip_lora = comfy.sd.load_lora_for_models(model, clip, lora_path, strength_model, strength_clip)
return (model_lora, clip_lora)
except Exception as e:
print("LoraLoaderText Exception : "+ e)
return (strength_model, strength_clip)
#NODE_CLASS_MAPPINGS = {
# "LoraLoaderText": LoraLoaderText,
#}
+60
View File
@@ -0,0 +1,60 @@
import os
import comfy.sd
from nodes import *
import folder_paths
import random
from .check_name import *
class LoraLoaderTextRandom:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": ("MODEL",),
"clip": ("CLIP", ),
"lora_name": ("STRING", {
"multiline": False, #True if you want the field to look like the one on the ClipTextEncode node
"default": (folder_paths.get_filename_list("loras"), )
}),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
#"lora_name": (folder_paths.get_filename_list("loras"), ),
"strength_model_min": ("FLOAT", {"default": 0.50, "min": 0.0, "max": 10.0, "step": 0.01}),
"strength_model_max": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"strength_clip_min": ("FLOAT", {"default": 0.50, "min": 0.0, "max": 10.0, "step": 0.01}),
"strength_clip_max": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
}
}
RETURN_TYPES = ("MODEL", "CLIP")
FUNCTION = "load_lora"
CATEGORY = "loaders"
def load_lora(self,
model,
clip,
lora_name,
seed,
strength_model_min,
strength_model_max,
strength_clip_min,
strength_clip_max
):
strength_model=random.uniform(min(strength_model_min,strength_model_max),max(strength_model_min,strength_model_max))
strength_clip=random.uniform(min(strength_clip_min,strength_clip_max),max(strength_clip_min,strength_clip_max))
lora_path =check_name_pt("loras",name_split_choice(lora_name))
if lora_path is None:
print(f"{lora_name} is none")
return (strength_model, strength_clip)
print(f"LoraLoaderTextRandom : {lora_path} ")
try:
model_lora, clip_lora = comfy.sd.load_lora_for_models(model, clip, lora_path, strength_model, strength_clip)
return (model_lora, clip_lora)
except Exception as e:
print("LoraLoaderTextRandom Exception : "+ e)
return (strength_model, strength_clip)
#NODE_CLASS_MAPPINGS = {
# "LoraLoaderTextRandom": LoraLoaderTextRandom,
#}
+1 -1
View File
@@ -1,2 +1,2 @@
# ComfyUI_node_Lilly
# ComfyUI-node-Lilly
+104
View File
@@ -0,0 +1,104 @@
import os
import nodes
import comfy.samplers
import random
from nodes import common_ksampler
#wd = os.getcwd()
#print("working directory is ", wd)
#
#filePath = __file__
#print("This script file path is ", filePath)
#
#absFilePath = os.path.abspath(__file__)
#print("This script absolute path is ", absFilePath)
#
#path, filename = os.path.split(absFilePath)
#print("Script file path is {}, filename is {}".format(path, filename))
class Random_Sampler:
def __init__(self):
print(f"Random_Sampler __init__")
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": ("MODEL",),
"positive": ("CONDITIONING", ),
"negative": ("CONDITIONING", ),
"LATENT": ("LATENT", ),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
#"Random": (["enable", "disable"],),
"steps_min": ("INT", {"default": 20, "min": 1,"max": 10000, "step": 1 }),
"steps_max": ("INT", {"default": 30, "min": 1,"max": 10000, "step": 1 }),
"cfg_min": ("FLOAT", {"default": 5.0, "min": 0.0, "max": 100.0, "step": 0.5}),
"cfg_max": ("FLOAT", {"default": 9.0, "min": 0.0, "max": 100.0, "step": 0.5}),
"denoise_min": ("FLOAT", {"default": 0.50, "min": 0.01, "max": 1.0, "step": 0.01}),
"denoise_max": ("FLOAT", {"default": 1.00, "min": 0.01, "max": 1.0, "step": 0.01}),
},
}
RETURN_TYPES = ("LATENT",)
FUNCTION = "test"
OUTPUT_NODE = False
CATEGORY = "sampling"
def test(self,
model,
positive,
negative,
LATENT,
sampler_name,
scheduler,
seed,
#Random,
steps_min,
steps_max,
cfg_min,
cfg_max,
denoise_min,
denoise_max,
):
print(f"""
model : {model} ;
positive : {positive} ;
negative : {negative} ;
LATENT: {LATENT} ;
sampler_name : {sampler_name} ;
scheduler: {scheduler} ;
{seed} ;
{steps_min} ;
{steps_max} ;
{cfg_min} ;
{cfg_max} ;
{denoise_min} ;
{denoise_max} ;
""")
#if Random == "enable":
# print(f"Random enable")
# return common_ksampler(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise=denoise)
return common_ksampler(
model,
seed,
random.randint( min(steps_min,steps_max), max(steps_min,steps_max) ),
random.randint( int(cfg_min*2) , int(cfg_max*2) ) / 2 ,
sampler_name,
scheduler,
positive,
negative,
LATENT,
denoise=random.uniform(min(denoise_min,denoise_max),max(denoise_min,denoise_max))
)
#return (LATENT,)
#NODE_CLASS_MAPPINGS = {
# "Random_Sampler": Random_Sampler
#}
+75
View File
@@ -0,0 +1,75 @@
import os
import comfy.sd
from nodes import *
import folder_paths
# VAEDecode
# VAELoader
# VAELoaderDecode
#wd = os.getcwd()
#print("working directory is ", wd)
#
#filePath = __file__
#print("This script file path is ", filePath)
#
#absFilePath = os.path.abspath(__file__)
#print("This script absolute path is ", absFilePath)
#
#realFilePath = os.path.realpath(__file__)
#print("This script real path is ", realFilePath)
#
#path, filename = os.path.split(absFilePath)
#print("Script file path is {}, filename is {}".format(path, filename))
class VAELoaderDecode:
def __init__(self, device="cpu"):
self.device = device
#@classmethod
#def INPUT_TYPES(s):
# return {"required": { "samples": ("LATENT", ), "vae": ("VAE", )}}
#
#@classmethod
#def INPUT_TYPES(s):
# return {"required": { "vae_name": (filter_files_extensions(recursive_search(s.vae_dir), supported_pt_extensions), )}}
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"samples": ("LATENT", ),
"vae_name": (folder_paths.get_filename_list("vae"), )
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "test"
CATEGORY = "latent"
#TODO: scale factor?
#def load_vae(self, vae_name):
# vae_path = os.path.join(self.vae_dir, vae_name)
# vae = comfy.sd.VAE(ckpt_path=vae_path)
# return (vae,)
#
#def decode(self, vae, samples):
# return (vae.decode(samples["samples"]), )
def test(self, vae_name, samples):
t=folder_paths.get_filename_list("vae")
print(f"VAELoaderDecode : {t}")
vae_path = folder_paths.get_full_path("vae", vae_name)
print(f"VAELoaderDecode : {vae_path}")
vae = comfy.sd.VAE(ckpt_path=vae_path)
return (vae.decode(samples["samples"]), )
#NODE_CLASS_MAPPINGS = {
# "VAELoaderDecode": VAELoaderDecode,
#}
+24
View File
@@ -0,0 +1,24 @@
print("ComfyUI_node_Lilly.__init__")
import importlib
#from custom_nodes.ComfyUI_node_Lilly import eval(f"{name}")
NODE_CLASS_MAPPINGS = {
}
def add(name):
print(f"Load : {name}")
try:
pkg = importlib.import_module(f"custom_nodes.ComfyUI_node_Lilly.{name}")
NODE_CLASS_MAPPINGS[name]=eval(f"pkg.{name}")
print(f"ok : {name}")
except Exception as e:
print(f"Exception : {e}")
add("CheckpointLoaderRandom")
add("CheckpointLoaderSimpleText")
add("CLIPTextEncodeWildcards")
add("LoraLoaderText")
add("LoraLoaderTextRandom")
add("Random_Sampler")
add("VAELoaderDecode")
+25
View File
@@ -0,0 +1,25 @@
import os
from folder_paths import supported_ckpt_extensions,supported_pt_extensions
import folder_paths
import random
def check_name(kind,name,supported_extensions):
for ext in supported_extensions:
if name.lower().endswith(ext):
path = folder_paths.get_full_path(kind, name)
if path is not None:
return path
for ext in supported_extensions:
path = folder_paths.get_full_path(kind, name+ext)
if path is not None:
return path
def check_name_ckpt(name):
return check_name("checkpoints",name,supported_ckpt_extensions)
def check_name_pt(kind,name):
return check_name(kind,name,supported_pt_extensions)
def name_split_choice(name):
return random.choice(name.split('|'))
+109
View File
@@ -0,0 +1,109 @@
import os, glob, sys
import random
import re
#import wildcards
print("wildcards")
#print(os.getcwd())
# ============================================================
# 가져올 파일 목록
card_path=os.path.dirname(__file__)+"\\wildcards\\**\\*.txt"
print(f"wildcards card_path {card_path}")
# 정규식
resub = re.compile(r"(\{)([^\{\}]*)(\})")
recard = re.compile(r"(__)(.*?)(__)")
# 카드 목록
cards = {}
# | 로 입력된것중 하나 가져오기
def sub(match):
m=match.group(2).split("|")
#print(f"sub : {m}")
return random.choice(m)
# | 로 입력된것중 하나 가져오기 반복
def sub_loop(text):
bak=text
for i in range(1, 50):
tmp=resub.sub(sub, bak)
if bak==tmp :
return tmp
bak=tmp
return bak
# 카드 중에서 가져오기
def card(match):
#print(f"card i : {match.group(2)}")
if match.group(2) in cards :
r=random.choice(cards[match.group(2)])
else :
r= match.group(2)
#print(f"card r : {r}")
return r
# 카드 중에서 가져오기 반복. | 의 것도 처리
def card_loop(text):
bak=text
for i in range(1, 50):
tmp=recard.sub(card, bak)
#print(f"card l : {bak}")
if bak==tmp :
tmp=sub_loop(tmp)
if bak==tmp :
#print(f"card le : {bak}")
return tmp
bak=tmp
#print(f"card le : {bak}")
return bak
# 카드 파일 읽기
def card_load():
global cards , card_path
cards = {}
#print(f"path : {path}")
files=glob.glob(card_path, recursive=True)
#print(f"files : {files}")
for file in files:
basename = os.path.basename(file)
file_name = os.path.splitext(basename)[0]
if not file_name in cards:
cards[file_name]=[]
#print(f"file_name : {file_name}")
f = open(file, 'r', encoding='UTF8')
lines = f.readlines()
for line in lines:
line=line.strip()
# 주석 빈줄 제외
if line.startswith("#") or len(line)==0:
continue
cards[file_name]+=[line]
#print(f"line : {line}")
print(f"cards : {len(cards)}")
#print(f"cards : {cards.keys()}")
# 실행기
def run(text):
card_load()
#print(f"text : {text}")
result=card_loop(text)
#print(f"result : {result}")
return result
# ============================================================
# 테스트용
test="__my__"
#m = p.sub(sub, test)
#print(m)
run(test)