From 50ded3c5fae4d590f0c23b27863d445ed4685388 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Wed, 1 Jul 2026 16:59:54 +0200 Subject: [PATCH] Map scene clothing seeds to clothing axis --- node_scene.py | 7 ++- tools/prompt_smoke.py | 121 ++++++++++++++++++++++++++++-------------- 2 files changed, 87 insertions(+), 41 deletions(-) diff --git a/node_scene.py b/node_scene.py index ad7234d..98a4e7d 100644 --- a/node_scene.py +++ b/node_scene.py @@ -215,7 +215,7 @@ BRANCH_TARGET_CHOICES = ["both", "softcore", "hardcore"] SCENE_LAYER_SEED_AXES = { "cast": ("category",), "character": ("person",), - "wardrobe": ("content",), + "wardrobe": ("clothing",), "location": ("scene",), "set_dressing": ("scene",), "blocking": ("pose",), @@ -224,7 +224,7 @@ SCENE_LAYER_SEED_AXES = { "camera": ("composition",), "composition": ("composition",), "lighting": ("composition",), - "softcore_branch": ("content", "pose", "role"), + "softcore_branch": ("clothing", "pose", "role"), "hardcore_branch": ("pose", "role"), } SCENE_REROLL_GROUPS = { @@ -232,6 +232,7 @@ SCENE_REROLL_GROUPS = { "category": ("category",), "subcategory": ("subcategory",), "content": ("content",), + "clothing": ("clothing",), "person": ("person",), "scene": ("scene",), "pose": ("pose", "role"), @@ -239,6 +240,8 @@ SCENE_REROLL_GROUPS = { "expression": ("expression",), "composition": ("composition",), "content_pose": ("content", "pose", "role"), + "content_clothing": ("content", "clothing"), + "clothing_pose": ("clothing", "pose", "role"), "scene_pose": ("scene", "pose", "role"), } SCENE_OPTION_TEXT_KEYS = { diff --git a/tools/prompt_smoke.py b/tools/prompt_smoke.py index df0159d..dae836e 100644 --- a/tools/prompt_smoke.py +++ b/tools/prompt_smoke.py @@ -16467,7 +16467,7 @@ def smoke_node_scene_chain_registration() -> None: -1, ) seed_fixture_scene = scene - wardrobe_seed_options = nodes["SxCPSceneLayerSeedOptions"]().build("wardrobe", "fixed", 9981, "content", "same_for_all_rows", "replace_layer")[0] + wardrobe_seed_options = nodes["SxCPSceneLayerSeedOptions"]().build("wardrobe", "fixed", 9981, "clothing", "same_for_all_rows", "replace_layer")[0] wardrobe_options = nodes["SxCPSceneWardrobeOptions"]().build( "replace", "woman", @@ -16496,7 +16496,9 @@ def smoke_node_scene_chain_registration() -> None: woman_slot = next(slot for slot in slots if slot.get("subject_type") == "woman") _expect(woman_slot.get("softcore_outfit") == "simple black dress", "Scene Wardrobe did not update softcore outfit") _expect(woman_slot.get("hardcore_clothing") == "fully nude", "Scene Wardrobe did not update hardcore clothing") - _expect(json.loads(scene).get("seed_trace", {}).get("wardrobe", {}).get("seed") == 9981, "Scene Wardrobe seed options did not write seed trace") + wardrobe_trace = json.loads(scene).get("seed_trace", {}).get("wardrobe", {}) + _expect(wardrobe_trace.get("seed") == 9981, "Scene Wardrobe seed options did not write seed trace") + _expect(wardrobe_trace.get("axes") == ["clothing"], "Scene Wardrobe seed options should write clothing trace axes") location_options = nodes["SxCPSceneLocationLayoutOptions"]().build( "replace", @@ -16615,32 +16617,14 @@ def smoke_node_scene_chain_registration() -> None: hard_trace_axes.get("pose", {}).get("seed") == 7799, "Scene Pair Output generation trace did not use hardcore branch pose seed", ) - soft_content_seed_options = nodes["SxCPSceneLayerSeedOptions"]().build( + soft_clothing_seed_options = nodes["SxCPSceneLayerSeedOptions"]().build( "softcore_branch", "fixed", 6679, - "content", + "clothing", "same_for_all_rows", "replace_layer", )[0] - seeded_soft_scene, seeded_hard_scene, _summary, _metadata = nodes["SxCPSceneBranchPair"]().build( - seed_fixture_scene, - "same_creator_same_room", - "hybrid", - branch_options=branch_options, - ) - seeded_soft_scene = nodes["SxCPSoftcoreBranchOptions"]().build( - seeded_soft_scene, - "same_as_hardcore", - "lingerie_tease", - True, - 0.45, - "from_camera_config", - "compact", - "", - branch_options=branch_options, - seed_options=soft_content_seed_options, - )[0] default_hardcore_continuity = ( nodes["SxCPHardcoreBranchOptions"].INPUT_TYPES() .get("required", {}) @@ -16651,28 +16635,76 @@ def smoke_node_scene_chain_registration() -> None: default_hardcore_continuity == "partially_removed", "Hardcore Branch Options default should inherit softcore outfit continuity", ) - seeded_hard_scene = nodes["SxCPHardcoreBranchOptions"]().build( - seeded_hard_scene, - "couple", - 1, - 1, - "hardcore", - True, - 0.85, - default_hardcore_continuity, - "from_camera_config", - "compact", - "balanced", - "", - branch_options=branch_options, - )[0] - seeded_pair = json.loads(nodes["SxCPScenePairOutput"]().build(seeded_soft_scene, seeded_hard_scene)[7]) + + def _soft_clothing_pair(clothing_seed: int, seed_options: str | None = None) -> dict[str, Any]: + soft_seed_options = seed_options or nodes["SxCPSceneLayerSeedOptions"]().build( + "softcore_branch", + "fixed", + clothing_seed, + "clothing", + "same_for_all_rows", + "replace_layer", + )[0] + seeded_soft_scene, seeded_hard_scene, _summary, _metadata = nodes["SxCPSceneBranchPair"]().build( + seed_fixture_scene, + "same_creator_same_room", + "hybrid", + branch_options=branch_options, + ) + seeded_soft_scene = nodes["SxCPSoftcoreBranchOptions"]().build( + seeded_soft_scene, + "same_as_hardcore", + "lingerie_tease", + True, + 0.45, + "from_camera_config", + "compact", + "", + branch_options=branch_options, + seed_options=soft_seed_options, + )[0] + seeded_hard_scene = nodes["SxCPHardcoreBranchOptions"]().build( + seeded_hard_scene, + "couple", + 1, + 1, + "hardcore", + True, + 0.85, + default_hardcore_continuity, + "from_camera_config", + "compact", + "balanced", + "", + branch_options=branch_options, + )[0] + return json.loads(nodes["SxCPScenePairOutput"]().build(seeded_soft_scene, seeded_hard_scene)[7]) + + seeded_pair = _soft_clothing_pair(6679, soft_clothing_seed_options) seeded_soft_item = str(seeded_pair.get("softcore_row", {}).get("item") or "").lower() seeded_hard_clothing = str(seeded_pair.get("hardcore_clothing_state") or "").lower() seeded_hard_prompt = str(seeded_pair.get("hardcore_prompt") or "").lower() + seeded_soft_seed_config = ( + seeded_pair.get("softcore_row", {}).get("seed_config") + if isinstance(seeded_pair.get("softcore_row"), dict) + else {} + ) + seeded_trace = seeded_pair.get("scene_chain", {}).get("softcore", {}).get("seed_trace", {}).get("softcore.softcore_branch", {}) + _expect( + seeded_soft_seed_config.get("clothing_seed") == 6679, + "Scene softcore branch clothing seed did not reach softcore row clothing_seed", + ) + _expect( + seeded_soft_seed_config.get("content_seed") != 6679, + "Scene softcore branch clothing seed should not write softcore row content_seed", + ) + _expect( + seeded_trace.get("axes") == ["clothing"], + "Scene softcore branch clothing seed should write clothing trace axes", + ) _expect( "black lace lingerie" in seeded_soft_item, - "Scene softcore branch content seed fixture no longer selects the expected outfit", + "Scene softcore branch clothing seed fixture no longer selects the expected outfit", ) _expect( "black lace lingerie" in seeded_hard_clothing, @@ -16682,6 +16714,13 @@ def smoke_node_scene_chain_registration() -> None: "black lace lingerie" in seeded_hard_prompt, "Hardcore prompt text did not include the softcore-branch seeded woman outfit", ) + soft_clothing_pairs = [_soft_clothing_pair(seed) for seed in (6677, 6678, 6679, 6680)] + soft_clothing_items = {pair.get("softcore_row", {}).get("item") for pair in soft_clothing_pairs} + soft_clothing_poses = {pair.get("softcore_row", {}).get("pose") for pair in soft_clothing_pairs} + inherited_hard_clothing = {pair.get("hardcore_clothing_state") for pair in soft_clothing_pairs} + _expect(len(soft_clothing_items) > 1, "Softcore branch clothing reroll did not change softcore outfit") + _expect(len(inherited_hard_clothing) > 1, "Softcore branch clothing reroll did not change inherited hard clothing state") + _expect(len(soft_clothing_poses) == 1, "Softcore branch clothing reroll should keep softcore pose stable") content_pose_seed_options = nodes["SxCPSceneLayerSeedOptions"]().build( "hardcore_branch", "fixed", @@ -16743,6 +16782,10 @@ def smoke_node_scene_chain_registration() -> None: content_hard_seed_config.get("content_seed") == 8899, "Hardcore branch content_pose reroll did not reach hardcore content seed", ) + _expect( + content_hard_seed_config.get("clothing_seed") != 8899, + "Hardcore branch content_pose reroll should not write clothing_seed", + ) _expect( content_hard_seed_config.get("pose_seed") == 8899 and content_hard_seed_config.get("role_seed") == 8899, "Hardcore branch content_pose reroll did not reach hardcore pose and role seeds",