Extract camera utility nodes

This commit is contained in:
2026-06-26 22:38:21 +02:00
parent 029ece173e
commit e6937d96ac
5 changed files with 319 additions and 206 deletions
+10 -204
View File
@@ -393,7 +393,6 @@ def _install_input_tooltips(node_classes: dict[str, type]) -> None:
try:
from .loop_nodes import (
ANY_TYPE,
LOOP_NODE_CLASS_MAPPINGS,
LOOP_NODE_DISPLAY_NAME_MAPPINGS,
accumulator_delete_entries,
@@ -401,14 +400,15 @@ try:
accumulator_move_entry,
accumulator_save_entries,
)
from .node_camera import (
NODE_CLASS_MAPPINGS as CAMERA_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as CAMERA_NODE_DISPLAY_NAME_MAPPINGS,
)
from .node_seed_resolution import (
NODE_CLASS_MAPPINGS as SEED_RESOLUTION_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as SEED_RESOLUTION_NODE_DISPLAY_NAME_MAPPINGS,
)
from .prompt_builder import (
build_camera_config_json,
build_camera_orbit_config_json,
build_qwen_camera_config_json,
build_cast_config_json,
build_category_config_json,
build_character_slot_json,
@@ -428,17 +428,8 @@ try:
build_insta_of_pair,
build_prompt,
build_prompt_from_configs,
camera_angle_choices,
camera_detail_choices,
camera_distance_choices,
camera_lens_choices,
camera_mode_choices,
camera_orbit_focus_choices,
camera_orbit_framing_choices,
camera_orientation_choices,
camera_phone_choices,
camera_priority_choices,
camera_shot_choices,
cast_preset_choices,
category_preset_choices,
category_choices,
@@ -478,7 +469,6 @@ try:
from .sdxl_formatter import format_sdxl_prompt, sdxl_quality_preset_choices, sdxl_style_preset_choices
except ImportError:
from loop_nodes import (
ANY_TYPE,
LOOP_NODE_CLASS_MAPPINGS,
LOOP_NODE_DISPLAY_NAME_MAPPINGS,
accumulator_delete_entries,
@@ -486,14 +476,15 @@ except ImportError:
accumulator_move_entry,
accumulator_save_entries,
)
from node_camera import (
NODE_CLASS_MAPPINGS as CAMERA_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as CAMERA_NODE_DISPLAY_NAME_MAPPINGS,
)
from node_seed_resolution import (
NODE_CLASS_MAPPINGS as SEED_RESOLUTION_NODE_CLASS_MAPPINGS,
NODE_DISPLAY_NAME_MAPPINGS as SEED_RESOLUTION_NODE_DISPLAY_NAME_MAPPINGS,
)
from prompt_builder import (
build_camera_config_json,
build_camera_orbit_config_json,
build_qwen_camera_config_json,
build_cast_config_json,
build_category_config_json,
build_character_slot_json,
@@ -513,17 +504,8 @@ except ImportError:
build_insta_of_pair,
build_prompt,
build_prompt_from_configs,
camera_angle_choices,
camera_detail_choices,
camera_distance_choices,
camera_lens_choices,
camera_mode_choices,
camera_orbit_focus_choices,
camera_orbit_framing_choices,
camera_orientation_choices,
camera_phone_choices,
camera_priority_choices,
camera_shot_choices,
cast_preset_choices,
category_preset_choices,
category_choices,
@@ -754,178 +736,6 @@ class SxCPPromptBuilder:
)
class SxCPCameraControl:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"camera_mode": (camera_mode_choices(), {"default": "handheld_selfie"}),
"shot_size": (camera_shot_choices(), {"default": "auto"}),
"angle": (camera_angle_choices(), {"default": "auto"}),
"lens": (camera_lens_choices(), {"default": "smartphone_wide"}),
"distance": (camera_distance_choices(), {"default": "arm_length"}),
"orientation": (camera_orientation_choices(), {"default": "vertical_story"}),
"phone_visibility": (camera_phone_choices(), {"default": "phone_visible"}),
"priority": (camera_priority_choices(), {"default": "locked"}),
"camera_detail": (camera_detail_choices(), {"default": "compact"}),
}
}
RETURN_TYPES = (SXCP_CAMERA_CONFIG,)
RETURN_NAMES = ("camera_config",)
FUNCTION = "build"
CATEGORY = "prompt_builder"
def build(
self,
camera_mode,
shot_size,
angle,
lens,
distance,
orientation,
phone_visibility,
priority,
camera_detail,
):
return (
build_camera_config_json(
camera_mode=camera_mode,
shot_size=shot_size,
angle=angle,
lens=lens,
distance=distance,
orientation=orientation,
phone_visibility=phone_visibility,
priority=priority,
camera_detail=camera_detail,
),
)
class SxCPCameraOrbitControl:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"enabled": ("BOOLEAN", {"default": True}),
"camera_mode": (camera_mode_choices(), {"default": "standard"}),
"horizontal_angle": ("INT", {"default": 0, "min": 0, "max": 359, "step": 1}),
"vertical_angle": ("INT", {"default": 0, "min": -90, "max": 90, "step": 1}),
"zoom": ("FLOAT", {"default": 5.0, "min": 0.0, "max": 10.0, "step": 0.1}),
"framing": (camera_orbit_framing_choices(), {"default": "from_zoom"}),
"subject_focus": (camera_orbit_focus_choices(), {"default": "auto"}),
"lens": (camera_lens_choices(), {"default": "auto"}),
"orientation": (camera_orientation_choices(), {"default": "auto"}),
"phone_visibility": (camera_phone_choices(), {"default": "auto"}),
"priority": (camera_priority_choices(), {"default": "locked"}),
"camera_detail": (camera_detail_choices(), {"default": "compact"}),
"include_degrees": ("BOOLEAN", {"default": True}),
}
}
RETURN_TYPES = (SXCP_CAMERA_CONFIG, "STRING", "STRING")
RETURN_NAMES = ("camera_config", "camera_prompt", "camera_info_json")
FUNCTION = "build"
CATEGORY = "prompt_builder"
def build(
self,
enabled,
camera_mode,
horizontal_angle,
vertical_angle,
zoom,
framing,
subject_focus,
lens,
orientation,
phone_visibility,
priority,
camera_detail,
include_degrees,
):
config = build_camera_orbit_config_json(
enabled=enabled,
camera_mode=camera_mode,
horizontal_angle=horizontal_angle,
vertical_angle=vertical_angle,
zoom=zoom,
framing=framing,
subject_focus=subject_focus,
lens=lens,
orientation=orientation,
phone_visibility=phone_visibility,
priority=priority,
camera_detail=camera_detail,
include_degrees=include_degrees,
)
parsed = json.loads(config)
camera_prompt = parsed.get("custom_camera_prompt", "")
return config, camera_prompt, json.dumps(parsed, ensure_ascii=True, sort_keys=True)
class SxCPQwenCameraTranslator:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"qwen_prompt": ("STRING", {"default": ""}),
"prefer_camera_info": ("BOOLEAN", {"default": True}),
"camera_mode": (camera_mode_choices(), {"default": "standard"}),
"subject_focus": (camera_orbit_focus_choices(), {"default": "auto"}),
"lens": (camera_lens_choices(), {"default": "auto"}),
"orientation": (camera_orientation_choices(), {"default": "auto"}),
"phone_visibility": (camera_phone_choices(), {"default": "auto"}),
"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,),
},
}
RETURN_TYPES = (SXCP_CAMERA_CONFIG, "STRING", "STRING")
RETURN_NAMES = ("camera_config", "camera_prompt", "camera_info_json")
FUNCTION = "build"
CATEGORY = "prompt_builder"
def build(
self,
qwen_prompt,
prefer_camera_info,
camera_mode,
subject_focus,
lens,
orientation,
phone_visibility,
priority,
camera_detail,
include_degrees,
suppress_phone_visibility,
camera_info=None,
):
config = build_qwen_camera_config_json(
qwen_prompt=qwen_prompt or "",
camera_info=camera_info,
prefer_camera_info=prefer_camera_info,
camera_mode=camera_mode,
subject_focus=subject_focus,
lens=lens,
orientation=orientation,
phone_visibility=phone_visibility,
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", "")
return config, camera_prompt, json.dumps(parsed, ensure_ascii=True, sort_keys=True)
class SxCPCategoryPreset:
@classmethod
def INPUT_TYPES(cls):
@@ -2671,10 +2481,8 @@ NODE_CLASS_MAPPINGS = {
"SxCPPromptBuilder": SxCPPromptBuilder,
}
NODE_CLASS_MAPPINGS.update(SEED_RESOLUTION_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update(CAMERA_NODE_CLASS_MAPPINGS)
NODE_CLASS_MAPPINGS.update({
"SxCPCameraControl": SxCPCameraControl,
"SxCPCameraOrbitControl": SxCPCameraOrbitControl,
"SxCPQwenCameraTranslator": SxCPQwenCameraTranslator,
"SxCPCategoryPreset": SxCPCategoryPreset,
"SxCPLocationPool": SxCPLocationPool,
"SxCPCompositionPool": SxCPCompositionPool,
@@ -2715,10 +2523,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"SxCPPromptBuilder": "SxCP Prompt Builder",
}
NODE_DISPLAY_NAME_MAPPINGS.update(SEED_RESOLUTION_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(CAMERA_NODE_DISPLAY_NAME_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update({
"SxCPCameraControl": "SxCP Camera Control",
"SxCPCameraOrbitControl": "SxCP Camera Orbit Control",
"SxCPQwenCameraTranslator": "SxCP Qwen Camera Translator",
"SxCPCategoryPreset": "SxCP Category Preset",
"SxCPLocationPool": "SxCP Location Pool",
"SxCPCompositionPool": "SxCP Composition Pool",