mirror of
https://git.datalinker.icu/comfyanonymous/ComfyUI
synced 2026-08-21 19:23:29 +08:00
643 lines
25 KiB
Python
643 lines
25 KiB
Python
import json
|
||
import os
|
||
from urllib.request import urlopen
|
||
|
||
import folder_paths
|
||
|
||
from .. import easyCache
|
||
from ..config import FOOOCUS_STYLES_DIR, MAX_SEED_NUM, PROMPT_TEMPLATE, RESOURCES_DIR
|
||
from ..libs.log import log_node_info
|
||
from ..libs.utils import AlwaysEqualProxy
|
||
from ..libs.wildcards import WildcardProcessor, get_wildcard_list, process
|
||
|
||
|
||
# 正面提示词
|
||
class positivePrompt:
|
||
|
||
def __init__(self):
|
||
pass
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
return {"required": {
|
||
"positive": ("STRING", {"default": "", "multiline": True, "placeholder": "Positive"}),}
|
||
}
|
||
|
||
RETURN_TYPES = ("STRING",)
|
||
RETURN_NAMES = ("positive",)
|
||
FUNCTION = "main"
|
||
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
@staticmethod
|
||
def main(positive):
|
||
return positive,
|
||
|
||
# 通配符提示词
|
||
class wildcardsPrompt:
|
||
|
||
def __init__(self):
|
||
pass
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
wildcard_list = get_wildcard_list()
|
||
return {"required": {
|
||
"text": ("STRING", {"default": "", "multiline": True, "dynamicPrompts": False, "placeholder": "(Support wildcard)"}),
|
||
"Select to add LoRA": (["Select the LoRA to add to the text"] + folder_paths.get_filename_list("loras"),),
|
||
"Select to add Wildcard": (["Select the Wildcard to add to the text"] + wildcard_list,),
|
||
"seed": ("INT", {"default": 0, "min": 0, "max": MAX_SEED_NUM}),
|
||
"multiline_mode": ("BOOLEAN", {"default": False}),
|
||
},
|
||
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID"},
|
||
}
|
||
|
||
RETURN_TYPES = ("STRING", "STRING")
|
||
RETURN_NAMES = ("text", "populated_text")
|
||
OUTPUT_IS_LIST = (True, True)
|
||
FUNCTION = "main"
|
||
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
def main(self, *args, **kwargs):
|
||
prompt = kwargs["prompt"] if "prompt" in kwargs else None
|
||
seed = kwargs["seed"]
|
||
|
||
# Clean loaded_objects
|
||
if prompt:
|
||
easyCache.update_loaded_objects(prompt)
|
||
|
||
text = kwargs['text']
|
||
if "multiline_mode" in kwargs and kwargs["multiline_mode"]:
|
||
populated_text = []
|
||
_text = []
|
||
text = text.split("\n")
|
||
for t in text:
|
||
_text.append(t)
|
||
populated_text.append(process(t, seed))
|
||
text = _text
|
||
else:
|
||
populated_text = [process(text, seed)]
|
||
text = [text]
|
||
return {"ui": {"value": [seed]}, "result": (text, populated_text)}
|
||
|
||
# 通配符提示词矩阵,会按顺序返回包含通配符的提示词所生成的所有可能
|
||
class wildcardsPromptMatrix:
|
||
|
||
def __init__(self):
|
||
pass
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
wildcard_list = get_wildcard_list()
|
||
return {"required": {
|
||
"text": ("STRING", {"default": "", "multiline": True, "dynamicPrompts": False, "placeholder": "(Support Lora Block Weight and wildcard)"}),
|
||
"Select to add LoRA": (["Select the LoRA to add to the text"] + folder_paths.get_filename_list("loras"),),
|
||
"Select to add Wildcard": (["Select the Wildcard to add to the text"] + wildcard_list,),
|
||
"offset": ("INT", {"default": 0, "min": 0, "step": 1, "control_after_generate": True}),
|
||
},
|
||
"optional":{
|
||
"output_limit": ("INT", {"default": 1, "min": -1, "step": 1, "tooltip": "Output All Probilities"})
|
||
},
|
||
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID"},
|
||
}
|
||
|
||
RETURN_TYPES = ("STRING", "INT", "INT")
|
||
RETURN_NAMES = ("populated_text", "total", "factors")
|
||
OUTPUT_IS_LIST = (True, False, True)
|
||
FUNCTION = "main"
|
||
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
def main(self, *args, **kwargs):
|
||
prompt = kwargs["prompt"] if "prompt" in kwargs else None
|
||
offset = kwargs["offset"]
|
||
output_limit = kwargs.get("output_limit", 1)
|
||
# Clean loaded_objects
|
||
if prompt:
|
||
easyCache.update_loaded_objects(prompt)
|
||
|
||
text = kwargs['text']
|
||
p = WildcardProcessor(text)
|
||
total = p.total()
|
||
limit = total if output_limit > total or output_limit == -1 else output_limit
|
||
offset = 0 if output_limit == -1 else offset
|
||
populated_text = p.getmany(limit, offset) if output_limit != 1 else [p.getn(offset)]
|
||
return {"ui": {"value": [offset]}, "result": (populated_text, p.total(), list(p.placeholder_choices.values()))}
|
||
|
||
# 负面提示词
|
||
class negativePrompt:
|
||
|
||
def __init__(self):
|
||
pass
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
return {"required": {
|
||
"negative": ("STRING", {"default": "", "multiline": True, "placeholder": "Negative"}),}
|
||
}
|
||
|
||
RETURN_TYPES = ("STRING",)
|
||
RETURN_NAMES = ("negative",)
|
||
FUNCTION = "main"
|
||
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
@staticmethod
|
||
def main(negative):
|
||
return negative,
|
||
|
||
# 风格提示词选择器
|
||
class stylesPromptSelector:
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
styles = ["fooocus_styles"]
|
||
styles_dir = FOOOCUS_STYLES_DIR
|
||
for file_name in os.listdir(styles_dir):
|
||
file = os.path.join(styles_dir, file_name)
|
||
if os.path.isfile(file) and file_name.endswith(".json"):
|
||
if file_name != "fooocus_styles.json":
|
||
styles.append(file_name.split(".")[0])
|
||
|
||
return {
|
||
"required": {
|
||
"styles": (styles, {"default": "fooocus_styles"}),
|
||
},
|
||
"optional": {
|
||
"positive": ("STRING", {"forceInput": True}),
|
||
"negative": ("STRING", {"forceInput": True}),
|
||
"select_styles": ("EASY_PROMPT_STYLES", {}),
|
||
},
|
||
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID"},
|
||
}
|
||
|
||
RETURN_TYPES = ("STRING", "STRING",)
|
||
RETURN_NAMES = ("positive", "negative",)
|
||
|
||
CATEGORY = 'EasyUse/Prompt'
|
||
FUNCTION = 'run'
|
||
|
||
def run(self, styles, positive='', negative='', select_styles=None, prompt=None, extra_pnginfo=None, my_unique_id=None):
|
||
values = []
|
||
all_styles = {}
|
||
positive_prompt, negative_prompt = '', negative
|
||
fooocus_custom_dir = os.path.join(FOOOCUS_STYLES_DIR, 'fooocus_styles.json')
|
||
if styles == "fooocus_styles" and not os.path.exists(fooocus_custom_dir):
|
||
file = os.path.join(RESOURCES_DIR, styles + '.json')
|
||
else:
|
||
file = os.path.join(FOOOCUS_STYLES_DIR, styles + '.json')
|
||
f = open(file, 'r', encoding='utf-8')
|
||
data = json.load(f)
|
||
f.close()
|
||
for d in data:
|
||
all_styles[d['name']] = d
|
||
# if my_unique_id in prompt:
|
||
# if prompt[my_unique_id]["inputs"]['select_styles']:
|
||
# values = prompt[my_unique_id]["inputs"]['select_styles'].split(',')
|
||
|
||
if isinstance(select_styles, str):
|
||
values = select_styles.split(',')
|
||
else:
|
||
values = select_styles if select_styles else []
|
||
|
||
has_prompt = False
|
||
if len(values) == 0:
|
||
return (positive, negative)
|
||
|
||
for index, val in enumerate(values):
|
||
if 'prompt' in all_styles[val]:
|
||
if "{prompt}" in all_styles[val]['prompt'] and has_prompt == False:
|
||
positive_prompt = all_styles[val]['prompt'].replace('{prompt}', positive)
|
||
has_prompt = True
|
||
elif "{prompt}" in all_styles[val]['prompt']:
|
||
positive_prompt += ', ' + all_styles[val]['prompt'].replace(', {prompt}', '').replace('{prompt}', '')
|
||
else:
|
||
positive_prompt = all_styles[val]['prompt'] if positive_prompt == '' else positive_prompt + ', ' + all_styles[val]['prompt']
|
||
if 'negative_prompt' in all_styles[val]:
|
||
negative_prompt += ', ' + all_styles[val]['negative_prompt'] if negative_prompt else all_styles[val]['negative_prompt']
|
||
|
||
if has_prompt == False and positive:
|
||
positive_prompt = positive + positive_prompt + ', '
|
||
|
||
return (positive_prompt, negative_prompt)
|
||
|
||
#prompt
|
||
class prompt:
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
return {"required": {
|
||
"text": ("STRING", {"default": "", "multiline": True, "placeholder": "Prompt"}),
|
||
"prefix": (["Select the prefix add to the text"] + PROMPT_TEMPLATE["prefix"], {"default": "Select the prefix add to the text"}),
|
||
"subject": (["👤Select the subject add to the text"] + PROMPT_TEMPLATE["subject"], {"default": "👤Select the subject add to the text"}),
|
||
"action": (["🎬Select the action add to the text"] + PROMPT_TEMPLATE["action"], {"default": "🎬Select the action add to the text"}),
|
||
"clothes": (["👚Select the clothes add to the text"] + PROMPT_TEMPLATE["clothes"], {"default": "👚Select the clothes add to the text"}),
|
||
"environment": (["☀️Select the illumination environment add to the text"] + PROMPT_TEMPLATE["environment"], {"default": "☀️Select the illumination environment add to the text"}),
|
||
"background": (["🎞️Select the background add to the text"] + PROMPT_TEMPLATE["background"], {"default": "🎞️Select the background add to the text"}),
|
||
"nsfw": (["🔞Select the nsfw add to the text"] + PROMPT_TEMPLATE["nsfw"], {"default": "🔞️Select the nsfw add to the text"}),
|
||
},"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID"},}
|
||
|
||
RETURN_TYPES = ("STRING",)
|
||
RETURN_NAMES = ("prompt",)
|
||
FUNCTION = "doit"
|
||
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
def doit(self, *args, **kwargs):
|
||
text = kwargs['text']
|
||
return (text,)
|
||
|
||
#promptList
|
||
class promptList:
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {"required": {
|
||
"prompt_1": ("STRING", {"multiline": True, "default": ""}),
|
||
"prompt_2": ("STRING", {"multiline": True, "default": ""}),
|
||
"prompt_3": ("STRING", {"multiline": True, "default": ""}),
|
||
"prompt_4": ("STRING", {"multiline": True, "default": ""}),
|
||
"prompt_5": ("STRING", {"multiline": True, "default": ""}),
|
||
},
|
||
"optional": {
|
||
"optional_prompt_list": ("LIST",)
|
||
}
|
||
}
|
||
|
||
RETURN_TYPES = ("LIST", "STRING")
|
||
RETURN_NAMES = ("prompt_list", "prompt_strings")
|
||
OUTPUT_IS_LIST = (False, True)
|
||
FUNCTION = "run"
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
def run(self, **kwargs):
|
||
prompts = []
|
||
|
||
if "optional_prompt_list" in kwargs:
|
||
for l in kwargs["optional_prompt_list"]:
|
||
prompts.append(l)
|
||
|
||
# Iterate over the received inputs in sorted order.
|
||
for k in sorted(kwargs.keys()):
|
||
v = kwargs[k]
|
||
|
||
# Only process string input ports.
|
||
if isinstance(v, str) and v != '':
|
||
prompts.append(v)
|
||
|
||
return (prompts, prompts)
|
||
|
||
#promptLine
|
||
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}),
|
||
},
|
||
"hidden":{
|
||
"workflow_prompt": "PROMPT", "my_unique_id": "UNIQUE_ID"
|
||
}
|
||
}
|
||
|
||
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, workflow_prompt=None, my_unique_id=None):
|
||
lines = prompt.split('\n')
|
||
# lines = [zh_to_en([v])[0] if has_chinese(v) else v for v in lines if v]
|
||
|
||
start_index = max(0, min(start_index, len(lines) - 1))
|
||
|
||
end_index = min(start_index + max_rows, len(lines))
|
||
|
||
rows = lines[start_index:end_index]
|
||
|
||
return (rows, rows)
|
||
|
||
import comfy.utils
|
||
from server import PromptServer
|
||
from ..libs.messages import MessageCancelled, Message
|
||
any_type = AlwaysEqualProxy("*")
|
||
class promptAwait:
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {
|
||
"required": {
|
||
"now": (any_type,),
|
||
"prompt": ("STRING", {"multiline": True, "default": "", "placeholder":"Enter a prompt or use voice to enter to text"}),
|
||
"toolbar":("EASY_PROMPT_AWAIT_BAR",),
|
||
},
|
||
"optional":{
|
||
"prev": (any_type,),
|
||
},
|
||
"hidden": {"workflow_prompt": "PROMPT", "my_unique_id": "UNIQUE_ID", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||
}
|
||
|
||
RETURN_TYPES = (any_type, "STRING", "BOOLEAN", "INT")
|
||
RETURN_NAMES = ("output", "prompt", "continue", "seed")
|
||
FUNCTION = "await_select"
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
def await_select(self, now, prompt, toolbar, prev=None, workflow_prompt=None, my_unique_id=None, extra_pnginfo=None, **kwargs):
|
||
id = my_unique_id
|
||
id = id.split('.')[len(id.split('.')) - 1] if "." in id else id
|
||
if ":" in id:
|
||
id = id.split(":")[0]
|
||
pbar = comfy.utils.ProgressBar(100)
|
||
pbar.update_absolute(30)
|
||
PromptServer.instance.send_sync('easyuse_prompt_await', {"id": id})
|
||
try:
|
||
res = Message.waitForMessage(id, asList=False)
|
||
if res is None or res == "-1":
|
||
result = (now, prompt, False, 0)
|
||
else:
|
||
input = now if res['select'] == 'now' or prev is None else prev
|
||
result = (input, res['prompt'], False if res['result'] == -1 else True, res['seed'] if res['unlock'] else res['last_seed'])
|
||
pbar.update_absolute(100)
|
||
return result
|
||
except MessageCancelled:
|
||
pbar.update_absolute(100)
|
||
raise comfy.model_management.InterruptProcessingException()
|
||
|
||
class promptConcat:
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {"required": {},
|
||
"optional": {
|
||
"prompt1": ("STRING", {"multiline": False, "default": "", "forceInput": True}),
|
||
"prompt2": ("STRING", {"multiline": False, "default": "", "forceInput": True}),
|
||
"separator": ("STRING", {"multiline": False, "default": ""}),
|
||
},
|
||
}
|
||
RETURN_TYPES = ("STRING", )
|
||
RETURN_NAMES = ("prompt", )
|
||
FUNCTION = "concat_text"
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
def concat_text(self, prompt1="", prompt2="", separator=""):
|
||
|
||
return (prompt1 + separator + prompt2,)
|
||
|
||
class promptReplace:
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {
|
||
"required": {
|
||
"prompt": ("STRING", {"multiline": True, "default": "", "forceInput": True}),
|
||
},
|
||
"optional": {
|
||
"find1": ("STRING", {"multiline": False, "default": ""}),
|
||
"replace1": ("STRING", {"multiline": False, "default": ""}),
|
||
"find2": ("STRING", {"multiline": False, "default": ""}),
|
||
"replace2": ("STRING", {"multiline": False, "default": ""}),
|
||
"find3": ("STRING", {"multiline": False, "default": ""}),
|
||
"replace3": ("STRING", {"multiline": False, "default": ""}),
|
||
},
|
||
}
|
||
|
||
RETURN_TYPES = ("STRING",)
|
||
RETURN_NAMES = ("prompt",)
|
||
FUNCTION = "replace_text"
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
def replace_text(self, prompt, find1="", replace1="", find2="", replace2="", find3="", replace3=""):
|
||
|
||
prompt = prompt.replace(find1, replace1)
|
||
prompt = prompt.replace(find2, replace2)
|
||
prompt = prompt.replace(find3, replace3)
|
||
|
||
return (prompt,)
|
||
|
||
|
||
# 肖像大师
|
||
# Created by AI Wiz Art (Stefano Flore)
|
||
# Version: 2.2
|
||
# https://stefanoflore.it
|
||
# https://ai-wiz.art
|
||
class portraitMaster:
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
max_float_value = 1.95
|
||
prompt_path = os.path.join(RESOURCES_DIR, 'portrait_prompt.json')
|
||
if not os.path.exists(prompt_path):
|
||
response = urlopen('https://raw.githubusercontent.com/yolain/ComfyUI-Easy-Use/main/resources/portrait_prompt.json')
|
||
temp_prompt = json.loads(response.read())
|
||
prompt_serialized = json.dumps(temp_prompt, indent=4)
|
||
with open(prompt_path, "w") as f:
|
||
f.write(prompt_serialized)
|
||
del response, temp_prompt
|
||
# Load local
|
||
with open(prompt_path, 'r') as f:
|
||
list = json.load(f)
|
||
keys = [
|
||
['shot', 'COMBO', {"key": "shot_list"}], ['shot_weight', 'FLOAT'],
|
||
['gender', 'COMBO', {"default": "Woman", "key": "gender_list"}], ['age', 'INT', {"default": 30, "min": 18, "max": 90, "step": 1, "display": "slider"}],
|
||
['nationality_1', 'COMBO', {"default": "Chinese", "key": "nationality_list"}], ['nationality_2', 'COMBO', {"key": "nationality_list"}], ['nationality_mix', 'FLOAT'],
|
||
['body_type', 'COMBO', {"key": "body_type_list"}], ['body_type_weight', 'FLOAT'], ['model_pose', 'COMBO', {"key": "model_pose_list"}], ['eyes_color', 'COMBO', {"key": "eyes_color_list"}],
|
||
['facial_expression', 'COMBO', {"key": "face_expression_list"}], ['facial_expression_weight', 'FLOAT'], ['face_shape', 'COMBO', {"key": "face_shape_list"}], ['face_shape_weight', 'FLOAT'], ['facial_asymmetry', 'FLOAT'],
|
||
['hair_style', 'COMBO', {"key": "hair_style_list"}], ['hair_color', 'COMBO', {"key": "hair_color_list"}], ['disheveled', 'FLOAT'], ['beard', 'COMBO', {"key": "beard_list"}],
|
||
['skin_details', 'FLOAT'], ['skin_pores', 'FLOAT'], ['dimples', 'FLOAT'], ['freckles', 'FLOAT'],
|
||
['moles', 'FLOAT'], ['skin_imperfections', 'FLOAT'], ['skin_acne', 'FLOAT'], ['tanned_skin', 'FLOAT'],
|
||
['eyes_details', 'FLOAT'], ['iris_details', 'FLOAT'], ['circular_iris', 'FLOAT'], ['circular_pupil', 'FLOAT'],
|
||
['light_type', 'COMBO', {"key": "light_type_list"}], ['light_direction', 'COMBO', {"key": "light_direction_list"}], ['light_weight', 'FLOAT']
|
||
]
|
||
widgets = {}
|
||
for i, obj in enumerate(keys):
|
||
if obj[1] == 'COMBO':
|
||
key = obj[2]['key'] if obj[2] and 'key' in obj[2] else obj[0]
|
||
_list = list[key].copy()
|
||
_list.insert(0, '-')
|
||
widgets[obj[0]] = (_list, {**obj[2]})
|
||
elif obj[1] == 'FLOAT':
|
||
widgets[obj[0]] = ("FLOAT", {"default": 0, "step": 0.05, "min": 0, "max": max_float_value, "display": "slider",})
|
||
elif obj[1] == 'INT':
|
||
widgets[obj[0]] = (obj[1], obj[2])
|
||
del list
|
||
return {
|
||
"required": {
|
||
**widgets,
|
||
"photorealism_improvement": (["enable", "disable"],),
|
||
"prompt_start": ("STRING", {"multiline": True, "default": "raw photo, (realistic:1.5)"}),
|
||
"prompt_additional": ("STRING", {"multiline": True, "default": ""}),
|
||
"prompt_end": ("STRING", {"multiline": True, "default": ""}),
|
||
"negative_prompt": ("STRING", {"multiline": True, "default": ""}),
|
||
}
|
||
}
|
||
|
||
RETURN_TYPES = ("STRING", "STRING",)
|
||
RETURN_NAMES = ("positive", "negative",)
|
||
|
||
FUNCTION = "pm"
|
||
|
||
CATEGORY = "EasyUse/Prompt"
|
||
|
||
def pm(self, shot="-", shot_weight=1, gender="-", body_type="-", body_type_weight=0, eyes_color="-",
|
||
facial_expression="-", facial_expression_weight=0, face_shape="-", face_shape_weight=0,
|
||
nationality_1="-", nationality_2="-", nationality_mix=0.5, age=30, hair_style="-", hair_color="-",
|
||
disheveled=0, dimples=0, freckles=0, skin_pores=0, skin_details=0, moles=0, skin_imperfections=0,
|
||
wrinkles=0, tanned_skin=0, eyes_details=1, iris_details=1, circular_iris=1, circular_pupil=1,
|
||
facial_asymmetry=0, prompt_additional="", prompt_start="", prompt_end="", light_type="-",
|
||
light_direction="-", light_weight=0, negative_prompt="", photorealism_improvement="disable", beard="-",
|
||
model_pose="-", skin_acne=0):
|
||
|
||
prompt = []
|
||
|
||
if gender == "-":
|
||
gender = ""
|
||
else:
|
||
if age <= 25 and gender == 'Woman':
|
||
gender = 'girl'
|
||
if age <= 25 and gender == 'Man':
|
||
gender = 'boy'
|
||
gender = " " + gender + " "
|
||
|
||
if nationality_1 != '-' and nationality_2 != '-':
|
||
nationality = f"[{nationality_1}:{nationality_2}:{round(nationality_mix, 2)}]"
|
||
elif nationality_1 != '-':
|
||
nationality = nationality_1 + " "
|
||
elif nationality_2 != '-':
|
||
nationality = nationality_2 + " "
|
||
else:
|
||
nationality = ""
|
||
|
||
if prompt_start != "":
|
||
prompt.append(f"{prompt_start}")
|
||
|
||
if shot != "-" and shot_weight > 0:
|
||
prompt.append(f"({shot}:{round(shot_weight, 2)})")
|
||
|
||
prompt.append(f"({nationality}{gender}{round(age)}-years-old:1.5)")
|
||
|
||
if body_type != "-" and body_type_weight > 0:
|
||
prompt.append(f"({body_type}, {body_type} body:{round(body_type_weight, 2)})")
|
||
|
||
if model_pose != "-":
|
||
prompt.append(f"({model_pose}:1.5)")
|
||
|
||
if eyes_color != "-":
|
||
prompt.append(f"({eyes_color} eyes:1.25)")
|
||
|
||
if facial_expression != "-" and facial_expression_weight > 0:
|
||
prompt.append(
|
||
f"({facial_expression}, {facial_expression} expression:{round(facial_expression_weight, 2)})")
|
||
|
||
if face_shape != "-" and face_shape_weight > 0:
|
||
prompt.append(f"({face_shape} shape face:{round(face_shape_weight, 2)})")
|
||
|
||
if hair_style != "-":
|
||
prompt.append(f"({hair_style} hairstyle:1.25)")
|
||
|
||
if hair_color != "-":
|
||
prompt.append(f"({hair_color} hair:1.25)")
|
||
|
||
if beard != "-":
|
||
prompt.append(f"({beard}:1.15)")
|
||
|
||
if disheveled != "-" and disheveled > 0:
|
||
prompt.append(f"(disheveled:{round(disheveled, 2)})")
|
||
|
||
if prompt_additional != "":
|
||
prompt.append(f"{prompt_additional}")
|
||
|
||
if skin_details > 0:
|
||
prompt.append(f"(skin details, skin texture:{round(skin_details, 2)})")
|
||
|
||
if skin_pores > 0:
|
||
prompt.append(f"(skin pores:{round(skin_pores, 2)})")
|
||
|
||
if skin_imperfections > 0:
|
||
prompt.append(f"(skin imperfections:{round(skin_imperfections, 2)})")
|
||
|
||
if skin_acne > 0:
|
||
prompt.append(f"(acne, skin with acne:{round(skin_acne, 2)})")
|
||
|
||
if wrinkles > 0:
|
||
prompt.append(f"(skin imperfections:{round(wrinkles, 2)})")
|
||
|
||
if tanned_skin > 0:
|
||
prompt.append(f"(tanned skin:{round(tanned_skin, 2)})")
|
||
|
||
if dimples > 0:
|
||
prompt.append(f"(dimples:{round(dimples, 2)})")
|
||
|
||
if freckles > 0:
|
||
prompt.append(f"(freckles:{round(freckles, 2)})")
|
||
|
||
if moles > 0:
|
||
prompt.append(f"(skin pores:{round(moles, 2)})")
|
||
|
||
if eyes_details > 0:
|
||
prompt.append(f"(eyes details:{round(eyes_details, 2)})")
|
||
|
||
if iris_details > 0:
|
||
prompt.append(f"(iris details:{round(iris_details, 2)})")
|
||
|
||
if circular_iris > 0:
|
||
prompt.append(f"(circular iris:{round(circular_iris, 2)})")
|
||
|
||
if circular_pupil > 0:
|
||
prompt.append(f"(circular pupil:{round(circular_pupil, 2)})")
|
||
|
||
if facial_asymmetry > 0:
|
||
prompt.append(f"(facial asymmetry, face asymmetry:{round(facial_asymmetry, 2)})")
|
||
|
||
if light_type != '-' and light_weight > 0:
|
||
if light_direction != '-':
|
||
prompt.append(f"({light_type} {light_direction}:{round(light_weight, 2)})")
|
||
else:
|
||
prompt.append(f"({light_type}:{round(light_weight, 2)})")
|
||
|
||
if prompt_end != "":
|
||
prompt.append(f"{prompt_end}")
|
||
|
||
prompt = ", ".join(prompt)
|
||
prompt = prompt.lower()
|
||
|
||
if photorealism_improvement == "enable":
|
||
prompt = prompt + ", (professional photo, balanced photo, balanced exposure:1.2), (film grain:1.15)"
|
||
|
||
if photorealism_improvement == "enable":
|
||
negative_prompt = negative_prompt + ", (shinny skin, reflections on the skin, skin reflections:1.25)"
|
||
|
||
log_node_info("Portrait Master as generate the prompt:", prompt)
|
||
|
||
return (prompt, negative_prompt,)
|
||
|
||
|
||
NODE_CLASS_MAPPINGS = {
|
||
"easy positive": positivePrompt,
|
||
"easy negative": negativePrompt,
|
||
"easy wildcards": wildcardsPrompt,
|
||
"easy wildcardsMatrix": wildcardsPromptMatrix,
|
||
"easy prompt": prompt,
|
||
"easy promptList": promptList,
|
||
"easy promptLine": promptLine,
|
||
"easy promptAwait": promptAwait,
|
||
"easy promptConcat": promptConcat,
|
||
"easy promptReplace": promptReplace,
|
||
"easy stylesSelector": stylesPromptSelector,
|
||
"easy portraitMaster": portraitMaster,
|
||
}
|
||
|
||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||
"easy positive": "Positive",
|
||
"easy negative": "Negative",
|
||
"easy wildcards": "Wildcards",
|
||
"easy wildcardsMatrix": "Wildcards Matrix",
|
||
"easy prompt": "Prompt",
|
||
"easy promptList": "PromptList",
|
||
"easy promptLine": "PromptLine",
|
||
"easy promptAwait": "PromptAwait",
|
||
"easy promptConcat": "PromptConcat",
|
||
"easy promptReplace": "PromptReplace",
|
||
"easy stylesSelector": "Styles Selector",
|
||
"easy portraitMaster": "Portrait Master",
|
||
} |