Add themed location and composition controls

This commit is contained in:
2026-06-25 22:37:49 +02:00
parent 38ab587e8e
commit 9434070877
3 changed files with 522 additions and 4 deletions
+100
View File
@@ -19,6 +19,7 @@ SXCP_FILTER_CONFIG = "SXCP_FILTER_CONFIG"
SXCP_SEED_CONFIG = "SXCP_SEED_CONFIG"
SXCP_CAMERA_CONFIG = "SXCP_CAMERA_CONFIG"
SXCP_LOCATION_CONFIG = "SXCP_LOCATION_CONFIG"
SXCP_COMPOSITION_CONFIG = "SXCP_COMPOSITION_CONFIG"
SXCP_CATEGORY_CONFIG = "SXCP_CATEGORY_CONFIG"
SXCP_CAST_CONFIG = "SXCP_CAST_CONFIG"
SXCP_GENERATION_PROFILE = "SXCP_GENERATION_PROFILE"
@@ -60,6 +61,7 @@ COMMON_INPUT_TOOLTIPS = {
"seed_config": "Per-axis seed config. Connect Global Seed, Seed Locker, or Seed Control here.",
"camera_config": "Camera config used by the prompt formatter when camera mode is from_camera_config.",
"location_config": "Location config from SxCP Location Pool. It can replace or add to the category scene pool.",
"composition_config": "Composition config from SxCP Composition Pool or Location Theme. It can replace or add framing options.",
"softcore_camera_config": "Camera config used only for the softcore Insta/OF prompt. Falls back to camera_config if empty.",
"hardcore_camera_config": "Camera config used only for the hardcore Insta/OF prompt. Falls back to camera_config if empty.",
"character_profile": "Saved or loaded single-character profile. Character slots override this for configured casts.",
@@ -67,6 +69,8 @@ COMMON_INPUT_TOOLTIPS = {
"character_slot": "Single slot payload for saving/loading profiles or debugging one character.",
"hardcore_position_config": "Hardcore action/position config. Chain Position Pool into Action Filter, then into the generator.",
"custom_locations": "One custom location per line. Use plain text, or slug: location text.",
"custom_compositions": "One custom composition/framing phrase per line.",
"theme": "Matched location and composition theme, useful when the place needs compatible framing.",
"metadata_json": "Structured metadata from an SxCP generator. Prefer this over raw prompt text for formatters and profile save.",
"source_text": "Raw prompt, caption, or metadata JSON depending on input_hint.",
"source_text_input": "Optional linked raw prompt/caption input. When connected, it overrides the source_text widget.",
@@ -409,6 +413,7 @@ try:
build_character_manual_config_json,
build_character_profile_json,
build_characteristics_config_json,
build_composition_pool_json,
build_ethnicity_list_json,
build_filter_config_json,
build_generation_profile_json,
@@ -417,6 +422,7 @@ try:
build_hardcore_position_pool_json,
build_insta_of_options_json,
build_location_pool_json,
build_thematic_location_json,
build_insta_of_pair,
build_prompt,
build_prompt_from_configs,
@@ -454,6 +460,7 @@ try:
character_softcore_outfit_source_choices,
character_softcore_outfit_values,
character_woman_body_choices,
composition_pool_preset_choices,
ethnicity_choices,
generation_profile_choices,
hardcore_position_family_choices,
@@ -461,6 +468,7 @@ try:
hardcore_position_key_choices,
hardcore_detail_density_choices,
load_character_profile_json,
location_theme_choices,
location_pool_preset_choices,
save_character_profile_payload,
seed_mode_choices,
@@ -489,6 +497,7 @@ except ImportError:
build_character_manual_config_json,
build_character_profile_json,
build_characteristics_config_json,
build_composition_pool_json,
build_ethnicity_list_json,
build_filter_config_json,
build_generation_profile_json,
@@ -497,6 +506,7 @@ except ImportError:
build_hardcore_position_pool_json,
build_insta_of_options_json,
build_location_pool_json,
build_thematic_location_json,
build_insta_of_pair,
build_prompt,
build_prompt_from_configs,
@@ -534,6 +544,7 @@ except ImportError:
character_softcore_outfit_source_choices,
character_softcore_outfit_values,
character_woman_body_choices,
composition_pool_preset_choices,
ethnicity_choices,
generation_profile_choices,
hardcore_position_family_choices,
@@ -541,6 +552,7 @@ except ImportError:
hardcore_position_key_choices,
hardcore_detail_density_choices,
load_character_profile_json,
location_theme_choices,
location_pool_preset_choices,
save_character_profile_payload,
seed_mode_choices,
@@ -654,6 +666,7 @@ class SxCPPromptBuilder:
"seed_config": (SXCP_SEED_CONFIG,),
"camera_config": (SXCP_CAMERA_CONFIG,),
"location_config": (SXCP_LOCATION_CONFIG,),
"composition_config": (SXCP_COMPOSITION_CONFIG,),
"character_profile": (SXCP_CHARACTER_PROFILE,),
"character_cast": (SXCP_CHARACTER_CAST,),
"hardcore_position_config": (SXCP_HARDCORE_POSITION_CONFIG,),
@@ -690,6 +703,7 @@ class SxCPPromptBuilder:
seed_config="",
camera_config="",
location_config="",
composition_config="",
character_profile="",
character_cast="",
hardcore_position_config="",
@@ -725,6 +739,7 @@ class SxCPPromptBuilder:
seed_config=seed_config or "",
camera_config=camera_config or "",
location_config=location_config or "",
composition_config=composition_config or "",
character_profile=character_profile or "",
character_cast=character_cast or "",
hardcore_position_config=hardcore_position_config or "",
@@ -1204,6 +1219,81 @@ class SxCPLocationPool:
return config, parsed.get("summary", "")
class SxCPCompositionPool:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"enabled": ("BOOLEAN", {"default": True}),
"combine_mode": (["replace", "add"], {"default": "replace"}),
"preset": (composition_pool_preset_choices(), {"default": "no_outfit_check"}),
"custom_compositions": ("STRING", {"default": "", "multiline": True}),
},
"optional": {
"composition_config": (SXCP_COMPOSITION_CONFIG,),
},
}
RETURN_TYPES = (SXCP_COMPOSITION_CONFIG, "STRING")
RETURN_NAMES = ("composition_config", "summary")
FUNCTION = "build"
CATEGORY = "prompt_builder"
def build(self, enabled, combine_mode, preset, custom_compositions, composition_config=""):
config = build_composition_pool_json(
enabled=enabled,
combine_mode=combine_mode,
preset=preset,
custom_compositions=custom_compositions or "",
composition_config=composition_config or "",
)
parsed = json.loads(config)
return config, parsed.get("summary", "")
class SxCPLocationTheme:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"enabled": ("BOOLEAN", {"default": True}),
"combine_mode": (["replace", "add"], {"default": "replace"}),
"theme": (location_theme_choices(), {"default": "semi_public_affair"}),
"custom_locations": ("STRING", {"default": "", "multiline": True}),
"custom_compositions": ("STRING", {"default": "", "multiline": True}),
},
"optional": {
"location_config": (SXCP_LOCATION_CONFIG,),
"composition_config": (SXCP_COMPOSITION_CONFIG,),
},
}
RETURN_TYPES = (SXCP_LOCATION_CONFIG, SXCP_COMPOSITION_CONFIG, "STRING")
RETURN_NAMES = ("location_config", "composition_config", "summary")
FUNCTION = "build"
CATEGORY = "prompt_builder"
def build(
self,
enabled,
combine_mode,
theme,
custom_locations,
custom_compositions,
location_config="",
composition_config="",
):
return build_thematic_location_json(
enabled=enabled,
combine_mode=combine_mode,
theme=theme,
custom_locations=custom_locations or "",
custom_compositions=custom_compositions or "",
location_config=location_config or "",
composition_config=composition_config or "",
)
class SxCPCastControl:
@classmethod
def INPUT_TYPES(cls):
@@ -1956,6 +2046,7 @@ class SxCPPromptBuilderFromConfigs:
"seed_config": (SXCP_SEED_CONFIG,),
"camera_config": (SXCP_CAMERA_CONFIG,),
"location_config": (SXCP_LOCATION_CONFIG,),
"composition_config": (SXCP_COMPOSITION_CONFIG,),
"character_profile": (SXCP_CHARACTER_PROFILE,),
"character_cast": (SXCP_CHARACTER_CAST,),
"hardcore_position_config": (SXCP_HARDCORE_POSITION_CONFIG,),
@@ -1982,6 +2073,7 @@ class SxCPPromptBuilderFromConfigs:
seed_config="",
camera_config="",
location_config="",
composition_config="",
character_profile="",
character_cast="",
hardcore_position_config="",
@@ -1999,6 +2091,7 @@ class SxCPPromptBuilderFromConfigs:
seed_config=seed_config or "",
camera_config=camera_config or "",
location_config=location_config or "",
composition_config=composition_config or "",
character_profile=character_profile or "",
character_cast=character_cast or "",
hardcore_position_config=hardcore_position_config or "",
@@ -2720,6 +2813,7 @@ class SxCPInstaOFPromptPair:
"softcore_camera_config": (SXCP_CAMERA_CONFIG,),
"hardcore_camera_config": (SXCP_CAMERA_CONFIG,),
"location_config": (SXCP_LOCATION_CONFIG,),
"composition_config": (SXCP_COMPOSITION_CONFIG,),
"character_profile": (SXCP_CHARACTER_PROFILE,),
"character_cast": (SXCP_CHARACTER_CAST,),
"hardcore_position_config": (SXCP_HARDCORE_POSITION_CONFIG,),
@@ -2759,6 +2853,7 @@ class SxCPInstaOFPromptPair:
softcore_camera_config="",
hardcore_camera_config="",
location_config="",
composition_config="",
character_profile="",
character_cast="",
hardcore_position_config="",
@@ -2784,6 +2879,7 @@ class SxCPInstaOFPromptPair:
softcore_camera_config=softcore_camera_config or "",
hardcore_camera_config=hardcore_camera_config or "",
location_config=location_config or "",
composition_config=composition_config or "",
character_profile=character_profile or "",
character_cast=character_cast or "",
hardcore_position_config=hardcore_position_config or "",
@@ -2813,6 +2909,8 @@ NODE_CLASS_MAPPINGS = {
"SxCPQwenCameraTranslator": SxCPQwenCameraTranslator,
"SxCPCategoryPreset": SxCPCategoryPreset,
"SxCPLocationPool": SxCPLocationPool,
"SxCPCompositionPool": SxCPCompositionPool,
"SxCPLocationTheme": SxCPLocationTheme,
"SxCPCastControl": SxCPCastControl,
"SxCPCastBias": SxCPCastBias,
"SxCPGenerationProfile": SxCPGenerationProfile,
@@ -2856,6 +2954,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"SxCPQwenCameraTranslator": "SxCP Qwen Camera Translator",
"SxCPCategoryPreset": "SxCP Category Preset",
"SxCPLocationPool": "SxCP Location Pool",
"SxCPCompositionPool": "SxCP Composition Pool",
"SxCPLocationTheme": "SxCP Location Theme",
"SxCPCastControl": "SxCP Cast Control",
"SxCPCastBias": "SxCP Cast Bias",
"SxCPGenerationProfile": "SxCP Generation Profile",