From 29efb954fb7d70cca9a9f6288c7aecab7b6b03d7 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Sat, 27 Jun 2026 23:09:44 +0200 Subject: [PATCH] Add scene chain Insta OF demo workflow --- README.md | 3 + ...ene_chain_insta_of_branching_workflow.json | 543 ++++++++++++++++++ node_scene.py | 31 +- tools/prompt_smoke.py | 1 + 4 files changed, 573 insertions(+), 5 deletions(-) create mode 100644 examples/scene_chain_insta_of_branching_workflow.json diff --git a/README.md b/README.md index d4afa86..6090256 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,9 @@ as one long chain: manually into either generation lane, but they are not part of the default main path. +A dedicated v2 scene-chain Insta/OF branching demo is available at +`examples/scene_chain_insta_of_branching_workflow.json`. + ## Loop Nodes `SxCP For Loop Start` and `SxCP For Loop End` provide a lightweight replacement diff --git a/examples/scene_chain_insta_of_branching_workflow.json b/examples/scene_chain_insta_of_branching_workflow.json new file mode 100644 index 0000000..d4c95e7 --- /dev/null +++ b/examples/scene_chain_insta_of_branching_workflow.json @@ -0,0 +1,543 @@ +{ + "last_node_id": 25, + "last_link_id": 24, + "nodes": [ + { + "id": 1, + "type": "SxCPGlobalSeed", + "pos": [-1900, -760], + "size": [300, 90], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + {"name": "seed", "type": "INT", "links": null, "slot_index": 0}, + {"name": "seed_config", "type": "STRING", "links": [1], "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2} + ], + "properties": {"Node name for S&R": "SxCPGlobalSeed"}, + "widgets_values": [20260801] + }, + { + "id": 2, + "type": "SxCPSceneStart", + "pos": [-1540, -840], + "size": [360, 250], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + {"name": "seed_config", "type": "STRING", "link": 1} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [2], "slot_index": 0}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 2} + ], + "properties": {"Node name for S&R": "SxCPSceneStart"}, + "widgets_values": [1, 41, 20260801, "raw", "provocative_erotic", "random", "balanced", "sxcppnl7", true] + }, + { + "id": 3, + "type": "SxCPSceneCast", + "pos": [-1540, -520], + "size": [360, 150], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 2} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [3], "slot_index": 0}, + {"name": "cast_config", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 3} + ], + "properties": {"Node name for S&R": "SxCPSceneCast"}, + "widgets_values": ["mixed_couple", 1, 1, "woman_a", "none"] + }, + { + "id": 4, + "type": "SxCPSceneCharacter", + "pos": [-1120, -860], + "size": [390, 360], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 3} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [4], "slot_index": 0}, + {"name": "character_cast", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "character_slot", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 3}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 4} + ], + "properties": {"Node name for S&R": "SxCPSceneCharacter"}, + "widgets_values": [true, "woman", "A", -1, "25-year-old adult", "random", "random", "random", "medium", true, 0.45, "visible", -1.0, -1.0] + }, + { + "id": 5, + "type": "SxCPSceneCharacter", + "pos": [-1120, -430], + "size": [390, 360], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 4} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [5], "slot_index": 0}, + {"name": "character_cast", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "character_slot", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 3}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 4} + ], + "properties": {"Node name for S&R": "SxCPSceneCharacter"}, + "widgets_values": [true, "man", "A", -1, "40-year-old adult", "random", "random", "average", "compact", true, 0.35, "visible", -1.0, -1.0] + }, + { + "id": 6, + "type": "SxCPSceneWardrobe", + "pos": [-670, -860], + "size": [390, 250], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 5} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [6], "slot_index": 0}, + {"name": "character_cast", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 3} + ], + "properties": {"Node name for S&R": "SxCPSceneWardrobe"}, + "widgets_values": [true, "woman", "A", "minimal", "black lace lingerie set with stockings and garter details", "fully nude", "base outfit continuity for the creator"] + }, + { + "id": 7, + "type": "SxCPSceneWardrobe", + "pos": [-670, -500], + "size": [390, 250], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 6} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [7], "slot_index": 0}, + {"name": "character_cast", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 3} + ], + "properties": {"Node name for S&R": "SxCPSceneWardrobe"}, + "widgets_values": [true, "man", "A", "full", "half-open black shirt with dark trousers", "shirt open, lower body mostly off-camera when explicit action is framed", "partner outfit continuity"] + }, + { + "id": 8, + "type": "SxCPSceneLocation", + "pos": [-220, -860], + "size": [410, 210], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 7} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [8], "slot_index": 0}, + {"name": "location_config", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 3} + ], + "properties": {"Node name for S&R": "SxCPSceneLocation"}, + "widgets_values": [true, "replace", "custom_only", "private creator bedroom with bed, mirror, phone tripod, warm lamps, and visible content setup", "same room shared by both branches"] + }, + { + "id": 9, + "type": "SxCPSceneSetDressing", + "pos": [-220, -570], + "size": [410, 250], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 8} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [9], "slot_index": 0}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 2} + ], + "properties": {"Node name for S&R": "SxCPSceneSetDressing"}, + "widgets_values": [true, "bed edge, mirror frame, phone tripod", "warm lamps, curtains, rumpled bedding", "phone stand, folded clothes nearby", "creator-room set remains readable without forcing camera phrasing"] + }, + { + "id": 10, + "type": "SxCPSceneBlocking", + "pos": [250, -860], + "size": [410, 250], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 9} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [10], "slot_index": 0}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 2} + ], + "properties": {"Node name for S&R": "SxCPSceneBlocking"}, + "widgets_values": [true, "custom", "woman near the bed and mirror setup", "man close enough for the hardcore branch but not forced into the softcore pose", "shared blocking base for a soft tease or explicit branch"] + }, + { + "id": 11, + "type": "SxCPSceneCamera", + "pos": [250, -500], + "size": [410, 330], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 10} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [11], "slot_index": 0}, + {"name": "camera_config", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 3} + ], + "properties": {"Node name for S&R": "SxCPSceneCamera"}, + "widgets_values": [true, "standard", "three_quarter", "eye_level", "auto", "auto", "vertical_story", "auto", "strong", "compact", ""] + }, + { + "id": 12, + "type": "SxCPSceneComposition", + "pos": [720, -860], + "size": [410, 210], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 11} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [12], "slot_index": 0}, + {"name": "composition_config", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 3} + ], + "properties": {"Node name for S&R": "SxCPSceneComposition"}, + "widgets_values": [true, "replace", "no_outfit_check", "vertical creator-frame with body and room setup readable", ""] + }, + { + "id": 13, + "type": "SxCPSceneLighting", + "pos": [720, -570], + "size": [410, 210], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 12} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [13], "slot_index": 0}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 2} + ], + "properties": {"Node name for S&R": "SxCPSceneLighting"}, + "widgets_values": [true, "practical_lamps", "soft", "medium", "warm", ""] + }, + { + "id": 14, + "type": "SxCPSceneBranchPair", + "pos": [1190, -720], + "size": [340, 120], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 13} + ], + "outputs": [ + {"name": "softcore_scene", "type": "STRING", "links": [14], "slot_index": 0}, + {"name": "hardcore_scene", "type": "STRING", "links": [15], "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 3} + ], + "properties": {"Node name for S&R": "SxCPSceneBranchPair"}, + "widgets_values": ["same_creator_same_room", "hybrid"] + }, + { + "id": 15, + "type": "SxCPSoftcoreBranchOptions", + "pos": [1580, -860], + "size": [390, 260], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 14} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [17], "slot_index": 0}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 2} + ], + "properties": {"Node name for S&R": "SxCPSoftcoreBranchOptions"}, + "widgets_values": ["same_as_hardcore", "lingerie_tease", true, 0.45, "from_camera_config", "compact", ""] + }, + { + "id": 16, + "type": "SxCPHardcoreActionFilter", + "pos": [1190, -470], + "size": [360, 300], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [], + "outputs": [ + {"name": "hardcore_position_config", "type": "STRING", "links": [16], "slot_index": 0}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 1} + ], + "properties": {"Node name for S&R": "SxCPHardcoreActionFilter"}, + "widgets_values": ["penetration_only", false, false, true, false, false, false, false, false, false, false] + }, + { + "id": 17, + "type": "SxCPHardcoreBranchOptions", + "pos": [1580, -480], + "size": [390, 360], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + {"name": "scene", "type": "STRING", "link": 15}, + {"name": "hardcore_position_config", "type": "STRING", "link": 16} + ], + "outputs": [ + {"name": "scene", "type": "STRING", "links": [18], "slot_index": 0}, + {"name": "hardcore_position_config", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "summary", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "metadata_json", "type": "STRING", "links": null, "slot_index": 3} + ], + "properties": {"Node name for S&R": "SxCPHardcoreBranchOptions"}, + "widgets_values": ["couple", 1, 1, "hardcore", true, 0.85, "explicit_nude", "from_camera_config", "compact", "balanced", ""] + }, + { + "id": 18, + "type": "SxCPScenePairOutput", + "pos": [2050, -720], + "size": [430, 290], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + {"name": "softcore_scene", "type": "STRING", "link": 17}, + {"name": "hardcore_scene", "type": "STRING", "link": 18} + ], + "outputs": [ + {"name": "softcore_prompt", "type": "STRING", "links": [21], "slot_index": 0}, + {"name": "hardcore_prompt", "type": "STRING", "links": [22], "slot_index": 1}, + {"name": "softcore_negative_prompt", "type": "STRING", "links": null, "slot_index": 2}, + {"name": "hardcore_negative_prompt", "type": "STRING", "links": null, "slot_index": 3}, + {"name": "softcore_caption", "type": "STRING", "links": null, "slot_index": 4}, + {"name": "hardcore_caption", "type": "STRING", "links": null, "slot_index": 5}, + {"name": "shared_descriptor", "type": "STRING", "links": null, "slot_index": 6}, + {"name": "metadata_json", "type": "STRING", "links": [19, 20], "slot_index": 7}, + {"name": "scene_metadata_json", "type": "STRING", "links": null, "slot_index": 8} + ], + "properties": {"Node name for S&R": "SxCPScenePairOutput"}, + "widgets_values": [] + }, + { + "id": 19, + "type": "SxCPKrea2Formatter", + "pos": [2550, -820], + "size": [390, 270], + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [ + {"name": "metadata_json", "type": "STRING", "link": 19} + ], + "outputs": [ + {"name": "krea_prompt", "type": "STRING", "links": null, "slot_index": 0}, + {"name": "negative_prompt", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "krea_softcore_prompt", "type": "STRING", "links": [23], "slot_index": 2}, + {"name": "krea_hardcore_prompt", "type": "STRING", "links": [24], "slot_index": 3}, + {"name": "softcore_negative_prompt", "type": "STRING", "links": null, "slot_index": 4}, + {"name": "hardcore_negative_prompt", "type": "STRING", "links": null, "slot_index": 5}, + {"name": "method", "type": "STRING", "links": null, "slot_index": 6}, + {"name": "route_trace_json", "type": "STRING", "links": null, "slot_index": 7} + ], + "properties": {"Node name for S&R": "SxCPKrea2Formatter"}, + "widgets_values": ["", "metadata_json", "auto", "balanced", "preserve", false, "", ""] + }, + { + "id": 20, + "type": "SxCPCaptionNaturalizer", + "pos": [2550, -450], + "size": [390, 240], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + {"name": "metadata_json", "type": "STRING", "link": 20} + ], + "outputs": [ + {"name": "natural_caption", "type": "STRING", "links": null, "slot_index": 0}, + {"name": "method", "type": "STRING", "links": null, "slot_index": 1}, + {"name": "route_trace_json", "type": "STRING", "links": null, "slot_index": 2} + ], + "properties": {"Node name for S&R": "SxCPCaptionNaturalizer"}, + "widgets_values": ["", "metadata_json", "training_dense", "balanced", "drop_style_tail", "sxcppnl7", true, "auto"] + }, + { + "id": 21, + "type": "SxCPPreviewAnyAsText", + "pos": [3050, -920], + "size": [420, 180], + "flags": {}, + "order": 20, + "mode": 0, + "inputs": [ + {"name": "value", "type": "*", "link": 21} + ], + "outputs": [ + {"name": "text", "type": "STRING", "links": null, "slot_index": 0} + ], + "properties": {"Node name for S&R": "SxCPPreviewAnyAsText"}, + "widgets_values": ["Raw softcore prompt preview", "auto", 30000] + }, + { + "id": 22, + "type": "SxCPPreviewAnyAsText", + "pos": [3050, -710], + "size": [420, 180], + "flags": {}, + "order": 21, + "mode": 0, + "inputs": [ + {"name": "value", "type": "*", "link": 22} + ], + "outputs": [ + {"name": "text", "type": "STRING", "links": null, "slot_index": 0} + ], + "properties": {"Node name for S&R": "SxCPPreviewAnyAsText"}, + "widgets_values": ["Raw hardcore prompt preview", "auto", 30000] + }, + { + "id": 23, + "type": "SxCPPreviewAnyAsText", + "pos": [3050, -500], + "size": [420, 180], + "flags": {}, + "order": 22, + "mode": 0, + "inputs": [ + {"name": "value", "type": "*", "link": 23} + ], + "outputs": [ + {"name": "text", "type": "STRING", "links": null, "slot_index": 0} + ], + "properties": {"Node name for S&R": "SxCPPreviewAnyAsText"}, + "widgets_values": ["Krea softcore prompt preview", "auto", 30000] + }, + { + "id": 24, + "type": "SxCPPreviewAnyAsText", + "pos": [3050, -290], + "size": [420, 180], + "flags": {}, + "order": 23, + "mode": 0, + "inputs": [ + {"name": "value", "type": "*", "link": 24} + ], + "outputs": [ + {"name": "text", "type": "STRING", "links": null, "slot_index": 0} + ], + "properties": {"Node name for S&R": "SxCPPreviewAnyAsText"}, + "widgets_values": ["Krea hardcore prompt preview", "auto", 30000] + }, + { + "id": 25, + "type": "Note", + "pos": [-1900, -560], + "size": [520, 210], + "flags": {}, + "order": 24, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": {}, + "widgets_values": [ + "Scene-chain Insta/OF demo: build one shared scene, split it with Scene Branch Pair, then refine softcore and hardcore separately before Scene Pair Output. Change pose through Hardcore Action Filter or the seed_config pose/role axes." + ] + } + ], + "links": [ + [1, 1, 1, 2, 0, "STRING"], + [2, 2, 0, 3, 0, "STRING"], + [3, 3, 0, 4, 0, "STRING"], + [4, 4, 0, 5, 0, "STRING"], + [5, 5, 0, 6, 0, "STRING"], + [6, 6, 0, 7, 0, "STRING"], + [7, 7, 0, 8, 0, "STRING"], + [8, 8, 0, 9, 0, "STRING"], + [9, 9, 0, 10, 0, "STRING"], + [10, 10, 0, 11, 0, "STRING"], + [11, 11, 0, 12, 0, "STRING"], + [12, 12, 0, 13, 0, "STRING"], + [13, 13, 0, 14, 0, "STRING"], + [14, 14, 0, 15, 0, "STRING"], + [15, 14, 1, 17, 0, "STRING"], + [16, 16, 0, 17, 1, "STRING"], + [17, 15, 0, 18, 0, "STRING"], + [18, 17, 0, 18, 1, "STRING"], + [19, 18, 7, 19, 0, "STRING"], + [20, 18, 7, 20, 0, "STRING"], + [21, 18, 0, 21, 0, "STRING"], + [22, 18, 1, 22, 0, "STRING"], + [23, 19, 2, 23, 0, "STRING"], + [24, 19, 3, 24, 0, "STRING"] + ], + "groups": [ + { + "title": "Shared scene setup", + "bounding": [-1940, -920, 3100, 820], + "color": "#3f789e", + "font_size": 24 + }, + { + "title": "Softcore/hardcore branch split", + "bounding": [1160, -910, 860, 820], + "color": "#5f4d8f", + "font_size": 24 + }, + { + "title": "Pair output, formatters, previews", + "bounding": [2020, -960, 1490, 880], + "color": "#4d7f45", + "font_size": 24 + } + ], + "config": {}, + "extra": { + "ds": { + "scale": 0.62, + "offset": [1320, 670] + } + }, + "version": 0.4 +} diff --git a/node_scene.py b/node_scene.py index 7a1afe8..88110da 100644 --- a/node_scene.py +++ b/node_scene.py @@ -214,7 +214,9 @@ def _cast_slots(character_cast: Any) -> list[dict[str, Any]]: return [] -def _slot_matches(slot: dict[str, Any], subject_label: str) -> bool: +def _slot_matches(slot: dict[str, Any], subject_type: str, subject_label: str) -> bool: + if subject_type != "all" and str(slot.get("subject_type") or "").strip().lower() != subject_type: + return False if subject_label == "all": return True return str(slot.get("label") or "").strip().upper() == subject_label.upper() @@ -222,6 +224,7 @@ def _slot_matches(slot: dict[str, Any], subject_label: str) -> bool: def _update_character_cast_wardrobe( character_cast: str | dict[str, Any] | list[Any] | None, + subject_type: str, subject_label: str, softcore_outfit: str, hardcore_clothing: str, @@ -231,7 +234,7 @@ def _update_character_cast_wardrobe( return character_cast if isinstance(character_cast, str) else "" changed = False for slot in slots: - if not _slot_matches(slot, subject_label): + if not _slot_matches(slot, subject_type, subject_label): continue if softcore_outfit: slot["softcore_outfit"] = softcore_outfit @@ -555,6 +558,7 @@ class SxCPSceneWardrobe: "required": { "scene": (SXCP_SCENE,), "enabled": ("BOOLEAN", {"default": True}), + "subject_type": (["all", "woman", "man"], {"default": "woman"}), "subject_label": (SUBJECT_LABEL_CHOICES, {"default": "all"}), "clothing_override": (["profile_default", "random", "full", "minimal"], {"default": "profile_default"}), "softcore_outfit": ("STRING", {"default": "", "multiline": True}), @@ -568,24 +572,41 @@ class SxCPSceneWardrobe: FUNCTION = "build" CATEGORY = "prompt_builder/v2_scene" - def build(self, scene, enabled, subject_label, clothing_override, softcore_outfit, hardcore_clothing, wardrobe_prompt): + def build( + self, + scene, + enabled, + subject_type, + subject_label, + clothing_override, + softcore_outfit, + hardcore_clothing, + wardrobe_prompt, + ): parsed = _parse_scene(scene) current_cast = _base_config(parsed, "character_cast") if enabled: - updated_cast = _update_character_cast_wardrobe(current_cast, subject_label, softcore_outfit, hardcore_clothing) + updated_cast = _update_character_cast_wardrobe( + current_cast, + subject_type, + subject_label, + softcore_outfit, + hardcore_clothing, + ) if updated_cast: _set_config(parsed, "character_cast", updated_cast) else: updated_cast = current_cast layer = { "enabled": bool(enabled), + "subject_type": subject_type, "subject_label": subject_label, "clothing_override": clothing_override, "softcore_outfit": softcore_outfit or "", "hardcore_clothing": hardcore_clothing or "", "prompt": wardrobe_prompt or "", } - summary = "disabled" if not enabled else f"{subject_label}; {clothing_override}" + summary = "disabled" if not enabled else f"{subject_type} {subject_label}; {clothing_override}" _set_layer(parsed, "wardrobe", layer, summary) return _dump(parsed), updated_cast or "", summary, _dump(parsed) diff --git a/tools/prompt_smoke.py b/tools/prompt_smoke.py index 7677a73..0c6dbb8 100644 --- a/tools/prompt_smoke.py +++ b/tools/prompt_smoke.py @@ -8875,6 +8875,7 @@ def smoke_node_scene_chain_registration() -> None: scene, character_cast, _wardrobe_summary, _wardrobe_metadata = nodes["SxCPSceneWardrobe"]().build( scene, True, + "woman", "A", "full", "simple black dress",