modified: mikey_nodes.py

This commit is contained in:
bash-j
2023-07-25 23:00:07 +09:30
parent 6abdc64680
commit ef35a4546f
+88 -96
View File
@@ -1,18 +1,28 @@
import datetime
from fractions import Fraction
import importlib.util
import json
from math import ceil, pow
import os
import re
import sys
import numpy as np
from PIL import Image
from PIL.PngImagePlugin import PngInfo
import torch
import folder_paths
file_path = os.path.join(folder_paths.base_path, 'comfy_extras/nodes_clip_sdxl.py')
module_name = "nodes_clip_sdxl"
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
from nodes_clip_sdxl import CLIPTextEncodeSDXL, CLIPTextEncodeSDXLRefiner
from comfy.model_management import unload_model, soft_empty_cache
import comfy.utils
import folder_paths
def sdxl_size(width: int, height: int) -> (int, int):
# solver
@@ -91,6 +101,28 @@ def read_styles():
styles.append(style)
return styles, pos_style, neg_style
def find_and_replace_wildcards(prompt, offset_seed):
# wildcards use the __file_name__ syntax
wildcard_path = os.path.join(folder_paths.base_path, 'wildcards')
wildcard_regex = r'__.*?__'
match_str = ''
offset = offset_seed
for match in re.findall(wildcard_regex, prompt):
if match_str == match:
offset += 1
else:
offset = offset_seed
is_file = os.path.isfile(os.path.join(wildcard_path, match[2:-2] + '.txt'))
if is_file:
with open(os.path.join(wildcard_path, match[2:-2] + '.txt'), 'r') as file:
wildcard_lines = file.readlines()
line_number = (offset % len(wildcard_lines))
prompt = prompt.replace(match, wildcard_lines[line_number].strip(), 1)
match_str = match
else:
print(f'Wildcard file {match[2:-2]}.txt not found in {wildcard_path}')
return prompt
def read_cluts():
p = os.path.dirname(os.path.realpath(__file__))
halddir = os.path.join(p, 'HaldCLUT')
@@ -288,8 +320,6 @@ class SaveImagesMikey:
return { "ui": { "images": results } }
class PromptWithStyle:
#elrs = EmptyLatentRatioSelector()
@classmethod
def INPUT_TYPES(s):
s.ratio_sizes, s.ratio_dict = read_ratios()
@@ -310,50 +340,8 @@ class PromptWithStyle:
CATEGORY = 'Mikey'
def start(self, positive_prompt, negative_prompt, style, ratio_selected, batch_size, seed):
# wildcards always have a __ prefix and __ suffix
# regex to find all wildcards
# path to wildcard folder with matching wildcard.txt files is the root_project_dir/wildcards
wildcard_path = os.path.join(folder_paths.base_path, 'wildcards')
wildcard_regex = r'__.*?__'
pos_wildcard = ''
pos_seed = seed
for match in re.findall(wildcard_regex, positive_prompt):
# check for matching file in wildcard folder
if pos_wildcard == match:
pos_seed += 1
else:
pos_seed = seed
is_file = os.path.isfile(os.path.join(wildcard_path, match[2:-2] + '.txt'))
if is_file:
with open(os.path.join(wildcard_path, match[2:-2] + '.txt'), 'r') as file:
wildcard_lines = file.readlines()
# offset can be larger than the number of lines in the file, or it could even be a negative number
# starting with line 0, so we need to use modulo to wrap around
line_number = (pos_seed % len(wildcard_lines))
# only replace the first match so that duplicates can be read from the next line
positive_prompt = positive_prompt.replace(match, wildcard_lines[line_number].strip(), 1)
pos_wildcard = match
else:
print(f'Wildcard file {match[2:-2]}.txt not found in {wildcard_path}')
neg_wildcard = ''
neg_seed = seed
for match in re.findall(wildcard_regex, negative_prompt):
# check for matching file in wildcard folder
if neg_wildcard == match:
neg_seed += 1
else:
neg_seed = seed
is_file = os.path.isfile(os.path.join(wildcard_path, match[2:-2] + '.txt'))
if is_file:
with open(os.path.join(wildcard_path, match[2:-2] + '.txt'), 'r') as file:
wildcard_lines = file.readlines()
# offset can be larger than the number of lines in the file, or it could even be a negative number
# starting with line 0, so we need to use modulo to wrap around
line_number = (neg_seed % len(wildcard_lines))
negative_prompt = negative_prompt.replace(match, wildcard_lines[line_number].strip(), 1)
neg_wildcard = match
else:
print(f'Wildcard file {match[2:-2]}.txt not found in {wildcard_path}')
positive_prompt = find_and_replace_wildcards(positive_prompt, seed)
negative_prompt = find_and_replace_wildcards(negative_prompt, seed)
if '{prompt}' in self.pos_style[style]:
positive_prompt = self.pos_style[style].replace('{prompt}', positive_prompt)
if positive_prompt == '' or positive_prompt == 'Positive Prompt' or positive_prompt is None:
@@ -367,8 +355,8 @@ class PromptWithStyle:
width = self.ratio_dict[ratio_selected]["width"]
height = self.ratio_dict[ratio_selected]["height"]
latent = torch.zeros([batch_size, 4, height // 8, width // 8])
refiner_width = width * 8
refiner_height = height * 8
refiner_width = width * 4
refiner_height = height * 4
return ({"samples":latent},
str(pos_prompt),
str(neg_prompt),
@@ -379,6 +367,52 @@ class PromptWithStyle:
refiner_width,
refiner_height,)
class PromptWithStyleV2:
@classmethod
def INPUT_TYPES(s):
s.ratio_sizes, s.ratio_dict = read_ratios()
s.styles, s.pos_style, s.neg_style = read_styles()
return {"required": {"positive_prompt": ("STRING", {"multiline": True, 'default': 'Positive Prompt'}),
"negative_prompt": ("STRING", {"multiline": True, 'default': 'Negative Prompt'}),
"style": (s.styles,),
"ratio_selected": (s.ratio_sizes,),
"batch_size": ("INT", {"default": 1, "min": 1, "max": 64}),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"clip_base": ("CLIP",), "clip_refiner": ("CLIP",),
}
}
RETURN_TYPES = ('LATENT',
'CONDITIONING','CONDITIONING','CONDITIONING','CONDITIONING',
'STRING','STRING')
RETURN_NAMES = ('samples',
'base_pos_cond','base_neg_cond','refiner_pos_cond','refiner_neg_cond',
'positive_prompt','negative_prompt')
FUNCTION = 'start'
CATEGORY = 'Mikey'
def start(self, clip_base, clip_refiner, positive_prompt, negative_prompt, style, ratio_selected, batch_size, seed):
""" get output from PromptWithStyle.start """
(latent,
pos_prompt, neg_prompt,
pos_style, neg_style,
width, height,
refiner_width, refiner_height) = PromptWithStyle.start(self, positive_prompt,
negative_prompt,
style, ratio_selected,
batch_size, seed)
# encode text
sdxl_pos_cond = CLIPTextEncodeSDXL.encode(self, clip_base, width, height, 0, 0, width, height, pos_prompt, pos_style)[0]
sdxl_neg_cond = CLIPTextEncodeSDXL.encode(self, clip_base, width, height, 0, 0, width, height, neg_prompt, neg_style)[0]
refiner_pos_cond = CLIPTextEncodeSDXLRefiner.encode(self, clip_refiner, 6, refiner_width, refiner_height, pos_prompt)[0]
refiner_neg_cond = CLIPTextEncodeSDXLRefiner.encode(self, clip_refiner, 2.5, refiner_width, refiner_height, neg_prompt)[0]
# return
return (latent,
sdxl_pos_cond, sdxl_neg_cond,
refiner_pos_cond, refiner_neg_cond,
pos_prompt, neg_prompt)
class PromptWithSDXL:
@classmethod
def INPUT_TYPES(s):
@@ -400,55 +434,13 @@ class PromptWithSDXL:
CATEGORY = 'Mikey'
def start(self, positive_prompt, negative_prompt, positive_style, negative_style, ratio_selected, batch_size, seed):
# wildcards always have a __ prefix and __ suffix
# regex to find all wildcards
# path to wildcard folder with matching wildcard.txt files is the root_project_dir/wildcards
wildcard_path = os.path.join(folder_paths.base_path, 'wildcards')
wildcard_regex = r'__.*?__'
pos_wildcard = ''
pos_seed = seed
for match in re.findall(wildcard_regex, positive_prompt):
# check for matching file in wildcard folder
if pos_wildcard == match:
pos_seed += 1
else:
pos_seed = seed
is_file = os.path.isfile(os.path.join(wildcard_path, match[2:-2] + '.txt'))
if is_file:
with open(os.path.join(wildcard_path, match[2:-2] + '.txt'), 'r') as file:
wildcard_lines = file.readlines()
# offset can be larger than the number of lines in the file, or it could even be a negative number
# starting with line 0, so we need to use modulo to wrap around
line_number = (pos_seed % len(wildcard_lines))
# only replace the first match so that duplicates can be read from the next line
positive_prompt = positive_prompt.replace(match, wildcard_lines[line_number].strip(), 1)
pos_wildcard = match
else:
print(f'Wildcard file {match[2:-2]}.txt not found in {wildcard_path}')
neg_wildcard = ''
neg_seed = seed
for match in re.findall(wildcard_regex, negative_prompt):
# check for matching file in wildcard folder
if neg_wildcard == match:
neg_seed += 1
else:
neg_seed = seed
is_file = os.path.isfile(os.path.join(wildcard_path, match[2:-2] + '.txt'))
if is_file:
with open(os.path.join(wildcard_path, match[2:-2] + '.txt'), 'r') as file:
wildcard_lines = file.readlines()
# offset can be larger than the number of lines in the file, or it could even be a negative number
# starting with line 0, so we need to use modulo to wrap around
line_number = (neg_seed % len(wildcard_lines))
negative_prompt = negative_prompt.replace(match, wildcard_lines[line_number].strip(), 1)
neg_wildcard = match
else:
print(f'Wildcard file {match[2:-2]}.txt not found in {wildcard_path}')
positive_prompt = find_and_replace_wildcards(positive_prompt, seed)
negative_prompt = find_and_replace_wildcards(negative_prompt, seed)
width = self.ratio_dict[ratio_selected]["width"]
height = self.ratio_dict[ratio_selected]["height"]
latent = torch.zeros([batch_size, 4, height // 8, width // 8])
refiner_width = width * 8
refiner_height = height * 8
refiner_width = width * 4
refiner_height = height * 4
return ({"samples":latent},
str(positive_prompt),
str(negative_prompt),
@@ -459,7 +451,6 @@ class PromptWithSDXL:
refiner_width,
refiner_height,)
class VAEDecode6GB:
""" deprecated. update comfy to fix issue. """
@classmethod
@@ -481,6 +472,7 @@ NODE_CLASS_MAPPINGS = {
'Save Image With Prompt Data': SaveImagesMikey,
'Resize Image for SDXL': ResizeImageSDXL,
'Prompt With Style': PromptWithStyle,
'Prompt With Style V2': PromptWithStyleV2, # 'Prompt With Style V2
'Prompt With SDXL': PromptWithSDXL,
'HaldCLUT': HaldCLUT,
'VAE Decode 6GB SDXL (deprecated)': VAEDecode6GB,