From 04ff829a9baf7a5ef4691fba0e773a6abbf1e22a Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Wed, 24 Jun 2026 20:01:12 +0200 Subject: [PATCH] Add separate pair camera configs --- README.md | 9 ++++++++- __init__.py | 9 +++++++++ prompt_builder.py | 12 +++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b43dbc8..7950dce 100644 --- a/README.md +++ b/README.md @@ -265,7 +265,8 @@ add `SxCP Qwen Camera Translator` after it: The translator accepts the Qwen labels such as `front-right quarter view`, `eye-level shot`, and `medium shot`, then emits the same `camera_config` format -as the native camera nodes. +as the native camera nodes. `suppress_phone_visibility` is enabled by default so +generic Qwen camera views do not add `phone hidden` or other phone wording. `SxCP Caption Naturalizer` rewrites tag-like captions or labeled prompts into more natural language. Connect the prompt builder's `metadata_json` output to @@ -374,6 +375,9 @@ hardcore defaults to `from_camera_config`, which emits no camera sentence unless a camera config is connected or you select an explicit hardcore camera mode. For stronger camera control, connect `SxCP Camera Control` or `SxCP Camera Orbit Control` to the pair node's optional `camera_config` input. +For different softcore and hardcore camera views, connect separate camera +configs to `softcore_camera_config` and `hardcore_camera_config`; those override +the shared `camera_config` for their side. Options: @@ -414,6 +418,9 @@ Options: separate base camera mode for the hardcore output. `from_camera_config` is neutral with no connected camera config, and uses `SxCP Camera Control` or `SxCP Camera Orbit Control` when one is connected. +- Pair camera inputs: use shared `camera_config` for one camera on both sides, + or use `softcore_camera_config` and `hardcore_camera_config` for two separate + Qwen/Orbit camera controls. - `camera_detail`: `from_camera_config`, `off`, `compact`, or `full` for the pair prompt camera text. Use `from_camera_config` with `SxCP Qwen Camera Translator` so the translator's own detail setting is preserved. diff --git a/__init__.py b/__init__.py index 82ef5f7..1f5f860 100644 --- a/__init__.py +++ b/__init__.py @@ -460,6 +460,7 @@ class SxCPQwenCameraTranslator: "priority": (camera_priority_choices(), {"default": "locked"}), "camera_detail": (camera_detail_choices(), {"default": "compact"}), "include_degrees": ("BOOLEAN", {"default": False}), + "suppress_phone_visibility": ("BOOLEAN", {"default": True}), }, "optional": { "camera_info": (ANY_TYPE,), @@ -483,6 +484,7 @@ class SxCPQwenCameraTranslator: priority, camera_detail, include_degrees, + suppress_phone_visibility, camera_info=None, ): config = build_qwen_camera_config_json( @@ -497,6 +499,7 @@ class SxCPQwenCameraTranslator: priority=priority, camera_detail=camera_detail, include_degrees=include_degrees, + suppress_phone_visibility=suppress_phone_visibility, ) parsed = json.loads(config) camera_prompt = parsed.get("custom_camera_prompt", "") @@ -1286,6 +1289,8 @@ class SxCPInstaOFPromptPair: "options_json": ("STRING", {"default": "", "multiline": True}), "filter_config": ("STRING", {"default": "", "multiline": True}), "camera_config": ("STRING", {"default": "", "multiline": True}), + "softcore_camera_config": ("STRING", {"default": "", "multiline": True}), + "hardcore_camera_config": ("STRING", {"default": "", "multiline": True}), "character_profile": ("STRING", {"default": "", "multiline": True}), "character_cast": ("STRING", {"default": "", "multiline": True}), "extra_positive": ("STRING", {"default": "", "multiline": True}), @@ -1320,6 +1325,8 @@ class SxCPInstaOFPromptPair: options_json="", filter_config="", camera_config="", + softcore_camera_config="", + hardcore_camera_config="", character_profile="", character_cast="", extra_positive="", @@ -1341,6 +1348,8 @@ class SxCPInstaOFPromptPair: options_json=options_json or "", filter_config=filter_config or "", camera_config=camera_config or "", + softcore_camera_config=softcore_camera_config or "", + hardcore_camera_config=hardcore_camera_config or "", character_profile=character_profile or "", character_cast=character_cast or "", extra_positive=extra_positive or "", diff --git a/prompt_builder.py b/prompt_builder.py index 2b6d341..1caf841 100644 --- a/prompt_builder.py +++ b/prompt_builder.py @@ -1760,6 +1760,7 @@ def build_qwen_camera_config_json( priority: str = "locked", camera_detail: str = "compact", include_degrees: bool = False, + suppress_phone_visibility: bool = True, ) -> str: info_values = _qwen_camera_info_values(camera_info) if prefer_camera_info and info_values is not None: @@ -1779,7 +1780,7 @@ def build_qwen_camera_config_json( subject_focus=subject_focus, lens=lens, orientation=orientation, - phone_visibility=phone_visibility, + phone_visibility="auto" if not _is_false(suppress_phone_visibility) else phone_visibility, priority=priority, camera_detail=camera_detail, include_degrees=include_degrees, @@ -4669,6 +4670,8 @@ def build_insta_of_pair( options_json: str | dict[str, Any] | None = None, filter_config: str | dict[str, Any] | None = None, camera_config: str | dict[str, Any] | None = None, + softcore_camera_config: str | dict[str, Any] | None = None, + hardcore_camera_config: str | dict[str, Any] | None = None, character_profile: str | dict[str, Any] | None = "", character_cast: str | dict[str, Any] | list[Any] | None = "", extra_positive: str = "", @@ -4844,10 +4847,13 @@ def build_insta_of_pair( soft_level = INSTA_OF_SOFT_LEVELS[options["softcore_level"]] hard_level = INSTA_OF_HARDCORE_LEVELS[options["hardcore_level"]] hard_camera_mode = options["hardcore_camera_mode"] + soft_camera_source = softcore_camera_config or camera_config + hard_camera_source = hardcore_camera_config or camera_config if hard_camera_mode == "same_as_softcore": hard_camera_mode = options["softcore_camera_mode"] - soft_camera_config = _camera_config_with_mode(camera_config, options["softcore_camera_mode"]) - hard_camera_config = _camera_config_with_mode(camera_config, hard_camera_mode) + hard_camera_source = soft_camera_source + soft_camera_config = _camera_config_with_mode(soft_camera_source, options["softcore_camera_mode"]) + hard_camera_config = _camera_config_with_mode(hard_camera_source, hard_camera_mode) soft_camera_config = _insta_camera_config_with_detail(soft_camera_config, options["camera_detail"]) hard_camera_config = _insta_camera_config_with_detail(hard_camera_config, options["camera_detail"]) soft_camera_directive, soft_camera_config = _camera_directive(soft_camera_config)