Add anchor style preset node
This commit is contained in:
+288
-21
@@ -26,6 +26,196 @@ _H3_PLAN_IMAGE_BINDINGS = OrderedDict()
|
||||
_H3_PLAN_IMAGE_BINDINGS_CAP = 128
|
||||
_H3_PLAN_IMAGE_SLOTS = 9
|
||||
_FOLDER_IMAGE_EXTS = (".png", ".jpg", ".jpeg", ".webp", ".bmp", ".gif", ".tiff", ".tif")
|
||||
_ANCHOR_STYLE_PRESETS = OrderedDict(
|
||||
[
|
||||
(
|
||||
"cinematic action movie",
|
||||
"Big-screen action cinema with assertive visual storytelling: dynamic camera placement, strong "
|
||||
"forward momentum, crisp geography, muscular lighting contrast, practical atmosphere, and a sense "
|
||||
"of physical consequence. Favor heroic framing, controlled handheld energy or motivated tracking "
|
||||
"moves, dramatic silhouettes, tasteful lens flares, impact-driven pacing, and polished studio "
|
||||
"spectacle without drifting into comic-book unreality unless the shot explicitly asks for it.",
|
||||
),
|
||||
(
|
||||
"comedy",
|
||||
"Play the scene for comedic readability and timing: clear staging, expressive performances, slightly "
|
||||
"heightened reactions, clean eyelines, and visual beats that leave room for the joke to land. Use "
|
||||
"bright approachable lighting, grounded but playful production design, readable framing, and a tone "
|
||||
"that feels observant, awkward, or absurd without becoming broad parody unless the action supports it.",
|
||||
),
|
||||
(
|
||||
"found footage",
|
||||
"Captured as raw found-footage material by someone physically present in the scene: imperfect handheld "
|
||||
"movement, reactive reframing, clipped composition, sudden zooms or focus hunts, practical exposure "
|
||||
"changes, and the feeling that the camera operator is discovering events in real time. Keep the image "
|
||||
"messy but legible, accidental rather than cinematic, with authentic panic, hesitation, and ambient noise.",
|
||||
),
|
||||
(
|
||||
"90s sitcom",
|
||||
"Classic 1990s multi-camera sitcom language: bright even stage lighting, cozy production design, clean "
|
||||
"master coverage, medium-wide proscenium framing, fast readable blocking, and performances calibrated "
|
||||
"for studio audience laughs. The world should feel warm, slightly idealized, and television-friendly, "
|
||||
"with practical interiors, punchy pauses, and visual simplicity that prioritizes character business.",
|
||||
),
|
||||
(
|
||||
"mobile/cell phone captured",
|
||||
"Looks like it was shot casually on a phone by an ordinary person: vertical-video instincts even when "
|
||||
"the frame is horizontal, imperfect stabilization, auto-exposure breathing, clipped highlights, shallow "
|
||||
"device-grade dynamic range, and opportunistic framing. Keep it intimate, immediate, and plausibly "
|
||||
"amateur, with sudden pans, uncertain focus, and informal proximity that feel genuinely captured.",
|
||||
),
|
||||
(
|
||||
"news broadcast",
|
||||
"Television news coverage with clear institutional polish: composed framing, practical key lighting, "
|
||||
"sober color balance, authoritative pacing, and a documentarian sense of informational clarity. Favor "
|
||||
"reporter or live-hit visual grammar, observational cutaway logic, steady camera operation, concise "
|
||||
"emphasis, and a tone that feels current, factual, and broadcast-safe rather than entertainment-first.",
|
||||
),
|
||||
(
|
||||
"prestige tv drama",
|
||||
"Prestige television drama with premium streaming polish: restrained confidence, textured naturalism, "
|
||||
"nuanced performances, motivated camera movement, and carefully shaped practical lighting. The mood "
|
||||
"should feel mature and expensive, with layered production design, cinematic color separation, and "
|
||||
"emotionally observant framing that trusts silence and subtext.",
|
||||
),
|
||||
(
|
||||
"psychological thriller",
|
||||
"Unsettling psychological-thriller grammar: controlled tension, negative space, ambiguous visual "
|
||||
"information, subtle distortion of normality, and lighting that suggests emotional danger more than "
|
||||
"physical spectacle. Favor lingering compositions, invasive close-ups, reflective surfaces, uneasy "
|
||||
"stillness, and a slow escalation of dread.",
|
||||
),
|
||||
(
|
||||
"horror",
|
||||
"Lean into horror atmosphere and threat: moody low-key lighting, oppressive space, directional contrast, "
|
||||
"tactile production texture, and suspenseful framing that weaponizes what is barely seen. The scene "
|
||||
"should feel unsafe and anticipatory, with sound-implied menace, uneasy empty areas in frame, and a "
|
||||
"commitment to dread over cheap chaos.",
|
||||
),
|
||||
(
|
||||
"science fiction epic",
|
||||
"Expansive science-fiction worldbuilding with polished futuristic scale: elegant production design, "
|
||||
"disciplined visual effects logic, atmospheric depth, and camera language that makes technology feel "
|
||||
"integrated and believable. Balance awe with clarity, using sleek surfaces, volumetric light, controlled "
|
||||
"color motifs, and a sense of society beyond the immediate shot.",
|
||||
),
|
||||
(
|
||||
"space opera",
|
||||
"Large-scale space opera with mythic emotion and visual grandeur: bold silhouettes, operatic lighting, "
|
||||
"sweeping camera movement, heroic compositions, and a heightened sense of destiny. Keep the worlds rich "
|
||||
"and theatrical, with dramatic color, iconic staging, and spectacle that feels earnest and adventurous.",
|
||||
),
|
||||
(
|
||||
"western",
|
||||
"Cinematic western visual language: expansive landscapes, strong horizon lines, weathered textures, harsh "
|
||||
"natural light, deliberate blocking, and a sense of moral tension embedded in open space. Favor patient "
|
||||
"compositions, boots-on-dust realism, iconic stand-off geometry, and tactile period detail without "
|
||||
"romanticizing away the grit.",
|
||||
),
|
||||
(
|
||||
"neo-noir",
|
||||
"Neo-noir mood with urban tension and seductive darkness: hard contrast, reflective surfaces, sodium "
|
||||
"vapor or neon accents, morally complicated framing, and a sense that every location hides compromise. "
|
||||
"Use rain, smoke, glass, and deep shadow strategically, with stylish but controlled camera work.",
|
||||
),
|
||||
(
|
||||
"period drama",
|
||||
"Refined period-drama treatment with historical texture, tailored production design, graceful camera "
|
||||
"movement, and careful social observation. Light the world with soft elegance and believable practical "
|
||||
"motivation, prioritizing fabric, architecture, etiquette, and emotional restraint over flashy stylization.",
|
||||
),
|
||||
(
|
||||
"documentary vérité",
|
||||
"Observational documentary vérité: minimally intrusive camera behavior, natural available light, patient "
|
||||
"real-time watchfulness, and an emphasis on lived-in truth over visual perfection. The frame can breathe, "
|
||||
"drift, and adjust as events unfold, but it should always feel honestly present rather than staged.",
|
||||
),
|
||||
(
|
||||
"music video",
|
||||
"Stylized music-video direction with strong visual authorship: rhythmic movement, bold color design, "
|
||||
"heightened pose, graphic composition, and a willingness to prioritize vibe and image over literal realism. "
|
||||
"Keep it polished and intent-driven, with kinetic transitions, fashion-forward staging, and synchronized intensity.",
|
||||
),
|
||||
(
|
||||
"luxury commercial",
|
||||
"Premium commercial polish aimed at aspiration and desirability: immaculate composition, glossy surfaces, "
|
||||
"refined lighting control, slow confident camera movement, and tactile focus on premium materials. Everything "
|
||||
"should feel precise, expensive, and seductively curated, with no accidental mess unless it serves the concept.",
|
||||
),
|
||||
(
|
||||
"true crime reenactment",
|
||||
"True-crime reenactment style with documentary dramatization: moody but legible lighting, restrained suspense, "
|
||||
"partial visual withholding, and a tone that suggests reconstruction rather than action filmmaking. Use practical "
|
||||
"locations, careful anonymity or selective detail, and sober tension that feels broadcast-doc adjacent.",
|
||||
),
|
||||
(
|
||||
"surveillance / cctv",
|
||||
"Fixed surveillance-camera capture with institutional detachment: elevated or corner-mounted viewpoint, wide "
|
||||
"coverage, unflattering perspective, limited dynamic range, compressed detail, and an impersonal observational "
|
||||
"tone. Avoid cinematic composition; the power comes from banality, distance, and timestamp-era bluntness.",
|
||||
),
|
||||
(
|
||||
"bodycam",
|
||||
"Police or security bodycam perspective: chest-mounted, wide-angle, unstable, close to breath and motion, "
|
||||
"with abrupt tilts, partial occlusion, clipped framing, and urgent first-person proximity. The footage should "
|
||||
"feel evidentiary and high-stress, more reactive than composed, while remaining coherent enough to follow action.",
|
||||
),
|
||||
(
|
||||
"vlog / creator video",
|
||||
"Online creator or vlog visual style: personable direct address, flattering but casual framing, expressive "
|
||||
"presentation, and a self-aware sense of on-camera performance. Lighting should feel creator-friendly and "
|
||||
"approachable, with clean image quality, lifestyle polish, and a balance between authenticity and charisma.",
|
||||
),
|
||||
(
|
||||
"anime cinematic",
|
||||
"High-end anime feature or prestige series look translated into shot design: expressive composition, dynamic "
|
||||
"perspective, graphic silhouette readability, emotionally heightened staging, and clean intentional shape "
|
||||
"language. Push atmosphere, color motifs, and dramatic key moments while keeping spatial storytelling clear.",
|
||||
),
|
||||
(
|
||||
"indie mumblecore",
|
||||
"Low-budget indie mumblecore naturalism: intimate handheld or locked-off simplicity, imperfect but observant "
|
||||
"framing, natural light or modest practicals, and performances that feel conversational rather than plot-driven. "
|
||||
"Let awkward pauses, environmental plainness, and human messiness carry the tone instead of visual over-design.",
|
||||
),
|
||||
(
|
||||
"elevated fantasy",
|
||||
"Sophisticated fantasy realism with mythic texture and grounded physical detail: rich environments, atmospheric "
|
||||
"scale, carefully motivated magical elements, and a serious emotional register. The world should feel old, "
|
||||
"inhabited, and culturally specific, with visual wonder rooted in tactile materials rather than generic glow.",
|
||||
),
|
||||
(
|
||||
"procedural cop show",
|
||||
"Mainstream procedural television style: efficient visual clarity, stable coverage, lightly stylized realism, "
|
||||
"and quick storytelling that privileges evidence, reactions, and spatial logic. Use functional but polished "
|
||||
"lighting, confident blocking, and a tone that feels network-accessible, competent, and case-driven.",
|
||||
),
|
||||
(
|
||||
"romantic drama",
|
||||
"Emotion-first romantic drama treatment: tender close observation, flattering naturalistic light, soft but not "
|
||||
"mushy contrast, and framing that prioritizes vulnerability, chemistry, and meaningful silence. The scene should "
|
||||
"feel intimate, earnest, and visually attentive to touch, glance, and emotional hesitation.",
|
||||
),
|
||||
(
|
||||
"grindhouse exploitation",
|
||||
"Aggressive grindhouse/exploitation texture: rough-edged energy, dirty contrast, oversaturated or faded color "
|
||||
"bias, abrasive zooms, tactile film wear vibes, and sensational staging that feels dangerous, pulpy, and "
|
||||
"disreputable. Keep the image gleefully imperfect and confrontational rather than polished.",
|
||||
),
|
||||
(
|
||||
"video essay b-roll",
|
||||
"Thoughtful video-essay b-roll style: visually articulate, idea-supporting imagery with tasteful motion, strong "
|
||||
"graphic clarity, and composition that feels editorially useful. The tone should be polished but not flashy, "
|
||||
"descriptive rather than dramatic, with images that communicate theme, context, and texture efficiently.",
|
||||
),
|
||||
(
|
||||
"reality tv",
|
||||
"Unscripted reality-TV coverage: reactive zooms, multiple-camera energy implied in the framing, practical "
|
||||
"interiors, performance-aware spontaneity, and a tone that amplifies interpersonal drama. Keep it bright, "
|
||||
"legible, and emotionally available, with visual beats that feel captured in the moment rather than authored.",
|
||||
),
|
||||
]
|
||||
)
|
||||
_LOAD_IMAGES_FOLDER_DEFAULT_STATE = {
|
||||
"version": 1,
|
||||
"folder": "",
|
||||
@@ -38,6 +228,14 @@ _LOAD_IMAGES_FOLDER_DEFAULT_STATE = {
|
||||
}
|
||||
|
||||
|
||||
def _anchor_style_options():
|
||||
return list(_ANCHOR_STYLE_PRESETS.keys())
|
||||
|
||||
|
||||
def _anchor_style_description(style_name):
|
||||
return _ANCHOR_STYLE_PRESETS.get(str(style_name or "").strip().lower(), "")
|
||||
|
||||
|
||||
def _clean_input_token_value(value):
|
||||
cleaned = ""
|
||||
if value is not None:
|
||||
@@ -822,7 +1020,7 @@ class DumasSaveImageNode:
|
||||
"pattern": (
|
||||
"STRING",
|
||||
{
|
||||
"default": "image_%date:yyyy-MM-dd%_%counter%",
|
||||
"default": "renders/%date:yyyy-MM-dd%/image_%counter%",
|
||||
"multiline": False,
|
||||
"tooltip": (
|
||||
"Filename pattern with optional subfolders. Tokens: "
|
||||
@@ -831,13 +1029,37 @@ class DumasSaveImageNode:
|
||||
),
|
||||
},
|
||||
),
|
||||
"format": (["png", "jpg"], {"default": "png"}),
|
||||
"format": (
|
||||
["png", "jpg"],
|
||||
{
|
||||
"default": "png",
|
||||
"tooltip": "Output image format. PNG is the safe default for lossless saves and workflow metadata."
|
||||
},
|
||||
),
|
||||
"quality": (
|
||||
"INT",
|
||||
{"default": 100, "min": 1, "max": 100, "step": 1},
|
||||
{
|
||||
"default": 95,
|
||||
"min": 1,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"tooltip": "JPEG quality when format=jpg. Ignored for PNG. 95 is a realistic high-quality default."
|
||||
},
|
||||
),
|
||||
"embed_workflow": (
|
||||
"BOOLEAN",
|
||||
{
|
||||
"default": True,
|
||||
"tooltip": "Embed prompt/workflow metadata into PNG saves when possible."
|
||||
},
|
||||
),
|
||||
"save_on_run": (
|
||||
"BOOLEAN",
|
||||
{
|
||||
"default": True,
|
||||
"tooltip": "Save files when the node executes. Turn off to keep wiring in place without writing files."
|
||||
},
|
||||
),
|
||||
"embed_workflow": ("BOOLEAN", {"default": True}),
|
||||
"save_on_run": ("BOOLEAN", {"default": True}),
|
||||
},
|
||||
"optional": {
|
||||
"name": (
|
||||
@@ -1271,7 +1493,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Stable internal identifier for the character.",
|
||||
"tooltip": "Stable internal identifier for the character, for example 'francine-main'.",
|
||||
},
|
||||
),
|
||||
"name": (
|
||||
@@ -1279,7 +1501,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Human-readable character name.",
|
||||
"tooltip": "Human-readable character name, for example 'Francine'.",
|
||||
},
|
||||
),
|
||||
"alias": (
|
||||
@@ -1287,7 +1509,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Comma- or newline-separated aliases for name matching.",
|
||||
"tooltip": "Comma- or newline-separated aliases for name matching, for example 'Fran, Frankie'.",
|
||||
},
|
||||
),
|
||||
"gender": (
|
||||
@@ -1295,7 +1517,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Optional gender field for non-visual character facts.",
|
||||
"tooltip": "Optional gender field for non-visual character facts, for example 'woman'.",
|
||||
},
|
||||
),
|
||||
"age": (
|
||||
@@ -1303,7 +1525,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Optional numeric age. Invalid values are omitted.",
|
||||
"tooltip": "Optional numeric age. Invalid values are omitted, for example '29'.",
|
||||
},
|
||||
),
|
||||
"nationality": (
|
||||
@@ -1311,7 +1533,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Optional nationality, origin, or cultural background.",
|
||||
"tooltip": "Optional nationality, origin, or cultural background, for example 'French'.",
|
||||
},
|
||||
),
|
||||
"occupation": (
|
||||
@@ -1319,7 +1541,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Optional job, role, or function that is not visually obvious.",
|
||||
"tooltip": "Optional job, role, or function that is not visually obvious, for example 'pilot'.",
|
||||
},
|
||||
),
|
||||
"height_feet": (
|
||||
@@ -1341,7 +1563,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Optional accent or speaking-style fact.",
|
||||
"tooltip": "Optional accent or speaking-style fact, for example 'soft Parisian accent'.",
|
||||
},
|
||||
),
|
||||
"description": (
|
||||
@@ -1349,7 +1571,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"tooltip": "Persistent physical identity description for the character.",
|
||||
"tooltip": "Persistent physical identity description for the character, for example 'short silver hair, scar over the left eyebrow, slim build'.",
|
||||
},
|
||||
),
|
||||
"general": (
|
||||
@@ -1357,7 +1579,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"tooltip": "Optional freeform notes or extra context.",
|
||||
"tooltip": "Optional freeform notes or extra context, for example 'grounded movement, confident but understated presence'.",
|
||||
},
|
||||
),
|
||||
"wardrobe": (
|
||||
@@ -1365,7 +1587,7 @@ class DumasCharacterReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"tooltip": "Persistent clothing, styling, accessories, or look notes.",
|
||||
"tooltip": "Persistent clothing, styling, accessories, or look notes, for example 'white blouse, black trousers, gold hoop earrings'.",
|
||||
},
|
||||
),
|
||||
}
|
||||
@@ -1439,7 +1661,7 @@ class DumasLocationReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Stable internal identifier for the location.",
|
||||
"tooltip": "Stable internal identifier for the location, for example 'corner-coffee-shop'.",
|
||||
},
|
||||
),
|
||||
"name": (
|
||||
@@ -1447,7 +1669,7 @@ class DumasLocationReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Human-readable location name.",
|
||||
"tooltip": "Human-readable location name, for example 'Corner Coffee Shop'.",
|
||||
},
|
||||
),
|
||||
"alias": (
|
||||
@@ -1455,7 +1677,7 @@ class DumasLocationReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": False,
|
||||
"tooltip": "Comma- or newline-separated alternate location names.",
|
||||
"tooltip": "Comma- or newline-separated alternate location names, for example 'cafe, front seating area'.",
|
||||
},
|
||||
),
|
||||
"description": (
|
||||
@@ -1463,7 +1685,7 @@ class DumasLocationReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"tooltip": "Persistent environment, layout, and atmosphere description.",
|
||||
"tooltip": "Persistent environment, layout, and atmosphere description, for example 'warm coffee shop interior with amber practical lighting, pale wood tables, and front windows'.",
|
||||
},
|
||||
),
|
||||
"general": (
|
||||
@@ -1471,7 +1693,7 @@ class DumasLocationReferenceNode:
|
||||
{
|
||||
"default": "",
|
||||
"multiline": True,
|
||||
"tooltip": "Optional freeform location notes.",
|
||||
"tooltip": "Optional freeform location notes, for example 'keep it grounded and realistic; use the front seating area as the play space'.",
|
||||
},
|
||||
),
|
||||
}
|
||||
@@ -1493,6 +1715,49 @@ class DumasLocationReferenceNode:
|
||||
)
|
||||
|
||||
|
||||
class DumasAnchorStyleNode:
|
||||
DESCRIPTION = (
|
||||
"Choose an anchor-style preset, auto-fill its full description, and pass "
|
||||
"the editable description downstream as one STRING value."
|
||||
)
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("anchor",)
|
||||
FUNCTION = "build_anchor"
|
||||
CATEGORY = "Dumas/MiniMax"
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
default_style = "cinematic action movie"
|
||||
return {
|
||||
"required": {
|
||||
"anchor_style": (
|
||||
_anchor_style_options(),
|
||||
{
|
||||
"default": default_style,
|
||||
"tooltip": "Preset title used to seed the editable anchor description.",
|
||||
},
|
||||
),
|
||||
"style_description": (
|
||||
"STRING",
|
||||
{
|
||||
"default": _anchor_style_description(default_style),
|
||||
"multiline": True,
|
||||
"tooltip": (
|
||||
"Editable anchor style description. The dropdown can populate this field, but "
|
||||
"whatever text is here is what the node outputs to the anchor socket."
|
||||
),
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
def build_anchor(self, anchor_style, style_description):
|
||||
text = str(style_description or "").strip()
|
||||
if not text:
|
||||
text = _anchor_style_description(anchor_style)
|
||||
return (text,)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"DumasImageCompare": DumasImageCompareNode,
|
||||
"DumasSaveImage": DumasSaveImageNode,
|
||||
@@ -1501,6 +1766,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"DumasH3PlanExtractSceneImages": DumasH3PlanExtractSceneImagesNode,
|
||||
"DumasCharacterReference": DumasCharacterReferenceNode,
|
||||
"DumasLocationReference": DumasLocationReferenceNode,
|
||||
"DumasAnchorStyle": DumasAnchorStyleNode,
|
||||
"DumasCharacterHelper": DumasCharacterReferenceNode,
|
||||
"DumasH3CharacterHelper": DumasCharacterReferenceNode,
|
||||
}
|
||||
@@ -1513,6 +1779,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"DumasH3PlanExtractSceneImages": "Dumas H3 Plan Extract Scene Images",
|
||||
"DumasCharacterReference": "Dumas Character Reference",
|
||||
"DumasLocationReference": "Dumas Location Reference",
|
||||
"DumasAnchorStyle": "Dumas Anchor Style",
|
||||
"DumasCharacterHelper": "Dumas Character Reference",
|
||||
"DumasH3CharacterHelper": "Dumas Character Reference",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user