45 lines
3.5 KiB
Python
45 lines
3.5 KiB
Python
"""PromptForge Action node: a pose or act plus place, camera, light and outfit for still-image prompts."""
|
|
from . import image_actions
|
|
|
|
|
|
class PROMPTFORGE_ImageAction:
|
|
CATEGORY = "🔮 PromptForge/Prompts"
|
|
RETURN_TYPES = ("PROMPTFORGE_ACTION", "STRING")
|
|
RETURN_NAMES = ("ACTION", "BRIEF")
|
|
FUNCTION = "build"
|
|
DESCRIPTION = ("A pose, place and camera as a binding brief for the prompt writer, for any image model. "
|
|
"Works from an input image or from words, for one person or two.")
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"category": (list(image_actions.CATEGORIES), {"default": image_actions.CATEGORIES[0]}),
|
|
"action": ([f"{group} · {label}" for label, (_, group, _) in image_actions.ACTIONS.items()],
|
|
{"default": f"{next(iter(image_actions.ACTIONS.values()))[1]} · {next(iter(image_actions.ACTIONS))}"}),
|
|
"source": (list(image_actions.SUBJECT_SOURCES), {"default": "input image",
|
|
"tooltip": "input image: keep the person from the connected image. text description: the writer invents the person from the text below."}),
|
|
"place": (list(image_actions.PLACES), {"default": "auto"}),
|
|
"camera": (list(image_actions.CAMERAS), {"default": "auto"}),
|
|
"lighting": (list(image_actions.LIGHTING), {"default": "auto"}),
|
|
"outfit": (list(image_actions.OUTFITS), {"default": "as in the image"}),
|
|
"style": (list(image_actions.STYLES), {"default": "auto"}),
|
|
},
|
|
"optional": {
|
|
"subject_1": ("STRING", {"default": "", "multiline": True, "placeholder": "Who the first person is. Empty keeps the person from the input image.", "tooltip": "Identity text for the first person. With an image source this adds to the image; without one it is all the writer knows."}),
|
|
"subject_2": ("STRING", {"default": "", "multiline": True, "placeholder": "Who the second person is. Empty = the other person in the image, or an invented man.", "tooltip": "Identity text for the second person in a couple act."}),
|
|
"notes": ("STRING", {"default": "", "multiline": True, "placeholder": "Anything else: mood, props, weather, exact framing.", "tooltip": "Extra binding detail for this shot."}),
|
|
"overrides": ("STRING", {"default": "", "multiline": True, "placeholder": "Hard overrides, for example: red dress, no glasses.", "tooltip": "Passed last and wins over the rest of the brief."}),
|
|
"instructions": ("STRING", {"default": "", "multiline": True, "placeholder": "Extra instructions for this shot: mood, prop, exact framing. Replaces the enhancer prompt while the action is on.", "tooltip": "Custom instructions appended to the action brief."}),
|
|
},
|
|
}
|
|
|
|
def build(self, category, action, source, place, camera, lighting, outfit, style,
|
|
subject_1="", subject_2="", notes="", overrides="", instructions=""):
|
|
action = action.split(" · ", 1)[-1]
|
|
data = {"action": action, "source": source, "place": place, "camera": camera, "lighting": lighting,
|
|
"outfit": outfit, "style": style, "subject_1": subject_1,
|
|
"subject_2": subject_2, "notes": notes, "overrides": overrides, "instructions": instructions}
|
|
text = image_actions.brief(action, (subject_1, subject_2), camera, place, lighting, outfit, style, notes, overrides, source, instructions)
|
|
return (data, text)
|