Add workspace lounge Insta OF workflow

This commit is contained in:
2026-06-28 00:41:29 +02:00
parent 78e39734b5
commit b8d8066fdb
5 changed files with 2128 additions and 7 deletions
+6
View File
@@ -168,6 +168,12 @@ A proposed adapter-style v2 layout is available at
chain in one center lane and parks layer-specific option nodes beside the layer chain in one center lane and parks layer-specific option nodes beside the layer
they override. they override.
A no-freeform workspace lounge Insta/OF branch demo is available at
`examples/scene_chain_workspace_lounge_insta_of_workflow.json`. It uses the
`workspace_lounge` location theme with camera orbit control, so the coworking
layout text adapts to camera position while the softcore and hardcore prompts
stay split.
## Loop Nodes ## Loop Nodes
`SxCP For Loop Start` and `SxCP For Loop End` provide a lightweight replacement `SxCP For Loop Start` and `SxCP For Loop End` provide a lightweight replacement
File diff suppressed because it is too large Load Diff
+11
View File
@@ -95,6 +95,17 @@ THEMATIC_LOCATION_PRESETS = {
"glossy mirror-wall composition with floor reflection line at the lower edge", "glossy mirror-wall composition with floor reflection line at the lower edge",
], ],
}, },
"workspace_lounge": {
"locations": [
{"slug": "coworking_lounge_window", "prompt": "coworking lounge with tall windows, warm desks, laptop tables, glass partition seams, repeated desk rows, plants, and soft shared-office depth"},
],
"compositions": [
"camera-aware coworking lounge frame with the subjects near a desk edge and tall-window depth behind them",
"mid-distance workspace lounge composition with laptop tables and glass partition seams readable around the bodies",
"diagonal desk-row frame using repeated work tables, plants, and tall windows for room continuity",
"foreground desk-edge composition with the subject dominant and coworking lounge depth still readable",
],
},
"boudoir_bedroom": { "boudoir_bedroom": {
"locations": [ "locations": [
{"slug": "warm_boudoir_canopy_bed", "prompt": "warm boudoir bedroom with satin sheets, canopy curtains, low lamplight, and bedside phone framing"}, {"slug": "warm_boudoir_canopy_bed", "prompt": "warm boudoir bedroom with satin sheets, canopy curtains, low lamplight, and bedside phone framing"},
+9 -7
View File
@@ -895,11 +895,13 @@ def scene_direction_detail(
background = profile["background"] background = profile["background"]
detail_label = profile.get("detail_label") or "location details" detail_label = profile.get("detail_label") or "location details"
subject, pronoun = scene_subject_terms(subject_kind, pov_labels) subject, pronoun = scene_subject_terms(subject_kind, pov_labels)
is_verb = "are" if subject == "the subjects" else "is"
face_verb = "face" if subject == "the subjects" else "faces"
if pov_labels: if pov_labels:
if "right side" in direction: if "right side" in direction:
return f"{subject} is in right-side profile; {midground} run behind {pronoun} toward {background}, with {detail_label} kept at the frame edges" return f"{subject} {is_verb} in right-side profile; {midground} run behind {pronoun} toward {background}, with {detail_label} kept at the frame edges"
if "left side" in direction: if "left side" in direction:
return f"{subject} is in left-side profile; {midground} run behind {pronoun} toward {background}, with {detail_label} kept at the frame edges" return f"{subject} {is_verb} in left-side profile; {midground} run behind {pronoun} toward {background}, with {detail_label} kept at the frame edges"
if "back-right" in direction or "back-left" in direction: if "back-right" in direction or "back-left" in direction:
return f"{subject} stays close in one continuous diagonal first-person body angle; {midground} lead toward {background} behind {pronoun} at the edges, not in the lower foreground" return f"{subject} stays close in one continuous diagonal first-person body angle; {midground} lead toward {background} behind {pronoun} at the edges, not in the lower foreground"
if direction == "back view": if direction == "back view":
@@ -908,14 +910,14 @@ def scene_direction_detail(
return f"{subject} fills the first-person front-quarter view; {midground} recede diagonally behind {pronoun} toward {background}" return f"{subject} fills the first-person front-quarter view; {midground} recede diagonally behind {pronoun} toward {background}"
return f"{subject} faces the viewer in first-person view; {midground} and {background} stay behind {pronoun}, not between viewer and body" return f"{subject} faces the viewer in first-person view; {midground} and {background} stay behind {pronoun}, not between viewer and body"
if "right side" in direction or "left side" in direction: if "right side" in direction or "left side" in direction:
return f"{subject} is held in side profile along the {foreground}; {midground} run laterally behind {pronoun}, with {background} still readable" return f"{subject} {is_verb} held in side profile along the {foreground}; {midground} run laterally behind {pronoun}, with {background} still readable"
if "back-right" in direction or "back-left" in direction: if "back-right" in direction or "back-left" in direction:
return f"{subject} is viewed from a rear-quarter angle, partly turning back toward camera; the {foreground} stays low in frame while {midground} lead into {background}" return f"{subject} {is_verb} viewed from a rear-quarter angle, partly turning back toward camera; the {foreground} stays low in frame while {midground} lead into {background}"
if direction == "back view": if direction == "back view":
return f"{subject} is seen from behind with the {foreground} at camera side, facing into {midground} and {background}" return f"{subject} {is_verb} seen from behind with the {foreground} at camera side, facing into {midground} and {background}"
if "front-right" in direction or "front-left" in direction: if "front-right" in direction or "front-left" in direction:
return f"{subject} is placed beside the {foreground}; {midground} recede diagonally behind {pronoun} toward {background}" return f"{subject} {is_verb} placed beside the {foreground}; {midground} recede diagonally behind {pronoun} toward {background}"
return f"{subject} faces camera beside the {foreground}; {midground} sit between {pronoun} and {background}" return f"{subject} {face_verb} camera beside the {foreground}; {midground} sit between {pronoun} and {background}"
def coworking_direction_detail( def coworking_direction_detail(
+26
View File
@@ -841,6 +841,18 @@ def smoke_scene_camera_adapter_pov_profile_policy() -> None:
"lower foreground is reserved for POV body or hand cues" in pov, "lower foreground is reserved for POV body or hand cues" in pov,
f"{key} POV scene directive lost lower-foreground body-cue reservation", f"{key} POV scene directive lost lower-foreground body-cue reservation",
) )
plural_directive = scene_camera_adapters.scene_camera_directive(
"",
parsed_camera,
pov_labels=[],
subject_kind="subjects",
profile_key="coworking_lounge",
)
_expect(
"the subjects are placed" in plural_directive,
"scene camera adapter used singular grammar for plural subjects",
)
_expect("the subjects is" not in plural_directive, "scene camera adapter leaked 'the subjects is'")
def smoke_row_camera_policy() -> None: def smoke_row_camera_policy() -> None:
@@ -1724,6 +1736,7 @@ def smoke_location_config_policy() -> None:
_expect("classical_library" in location_config.location_theme_choices(), "Location themes lost classical_library") _expect("classical_library" in location_config.location_theme_choices(), "Location themes lost classical_library")
_expect("creator_bedroom" in location_config.location_theme_choices(), "Location themes lost creator_bedroom") _expect("creator_bedroom" in location_config.location_theme_choices(), "Location themes lost creator_bedroom")
_expect("mirror_room" in location_config.location_theme_choices(), "Location themes lost mirror_room") _expect("mirror_room" in location_config.location_theme_choices(), "Location themes lost mirror_room")
_expect("workspace_lounge" in location_config.location_theme_choices(), "Location themes lost workspace_lounge")
_expect("fetish_studio" in location_config.location_theme_choices(), "Location themes lost fetish_studio") _expect("fetish_studio" in location_config.location_theme_choices(), "Location themes lost fetish_studio")
custom = json.loads( custom = json.loads(
@@ -1822,6 +1835,19 @@ def smoke_location_config_policy() -> None:
_expect(themed_composition_payload.get("theme") == "classical_library", "Themed composition config lost theme metadata") _expect(themed_composition_payload.get("theme") == "classical_library", "Themed composition config lost theme metadata")
parsed_themed = pb._parse_location_config(themed_location_payload) parsed_themed = pb._parse_location_config(themed_location_payload)
_expect(parsed_themed.get("theme") == "classical_library", "Location parser lost theme metadata") _expect(parsed_themed.get("theme") == "classical_library", "Location parser lost theme metadata")
workspace_location, workspace_composition, workspace_summary = pb.build_thematic_location_json(
enabled=True,
combine_mode="replace",
theme="workspace_lounge",
)
workspace_location_payload = json.loads(workspace_location)
workspace_composition_payload = json.loads(workspace_composition)
_expect("workspace_lounge" in workspace_summary, "Workspace theme summary lost theme name")
_expect(
workspace_location_payload.get("scene_entries", [{}])[0].get("slug") == "coworking_lounge_window",
"Workspace theme lost coworking lounge location slug",
)
_expect(workspace_composition_payload.get("composition_entries"), "Workspace theme did not output compositions")
replaced_after_theme = json.loads( replaced_after_theme = json.loads(
location_config.build_location_pool_json( location_config.build_location_pool_json(
enabled=True, enabled=True,