Filter atlas clothing restore foreground cues
This commit is contained in:
@@ -11,6 +11,7 @@ except ImportError: # Allows local smoke tests with top-level imports.
|
|||||||
|
|
||||||
MOUTH_EXPRESSION_TERMS = ("mouth", "oral", "tongue", "lips", "gagging", "saliva", "drool")
|
MOUTH_EXPRESSION_TERMS = ("mouth", "oral", "tongue", "lips", "gagging", "saliva", "drool")
|
||||||
TOP_VIEW_ORAL_VARIANT = "pov_blowjob_top_down_vertical_shaft"
|
TOP_VIEW_ORAL_VARIANT = "pov_blowjob_top_down_vertical_shaft"
|
||||||
|
SIDE_PROFILE_ORAL_VARIANT = "pov_blowjob_side_profile_oral"
|
||||||
ORAL_CONTACT_VARIANTS = frozenset(
|
ORAL_CONTACT_VARIANTS = frozenset(
|
||||||
(
|
(
|
||||||
TOP_VIEW_ORAL_VARIANT,
|
TOP_VIEW_ORAL_VARIANT,
|
||||||
@@ -107,6 +108,46 @@ def _restores_krea2_prompt_axis(row: dict[str, Any], axis_name: str) -> bool:
|
|||||||
return axis_name in restored_axes
|
return axis_name in restored_axes
|
||||||
|
|
||||||
|
|
||||||
|
def _side_profile_hidden_lower_clothing_clause(clause: str) -> bool:
|
||||||
|
lower = clause.lower()
|
||||||
|
if "below the hips" in lower or "lower body" in lower:
|
||||||
|
return True
|
||||||
|
return any(
|
||||||
|
term in lower
|
||||||
|
for term in (
|
||||||
|
"panty",
|
||||||
|
"panties",
|
||||||
|
"brief",
|
||||||
|
"briefs",
|
||||||
|
"thong",
|
||||||
|
"shorts",
|
||||||
|
"jeans",
|
||||||
|
"trousers",
|
||||||
|
"pants",
|
||||||
|
"skirt",
|
||||||
|
)
|
||||||
|
) and any(term in lower for term in ("pulled aside", "removed", "lowered", "visible"))
|
||||||
|
|
||||||
|
|
||||||
|
def _krea2_atlas_clothing_text(row: dict[str, Any], text: Any) -> str:
|
||||||
|
clothing = str(text or "").strip()
|
||||||
|
if not clothing or not _has_krea2_atlas_variant(row):
|
||||||
|
return clothing
|
||||||
|
side_profile_oral = _has_krea2_variant(row, SIDE_PROFILE_ORAL_VARIANT)
|
||||||
|
kept: list[str] = []
|
||||||
|
for clause in clothing.split(";"):
|
||||||
|
clause = clause.strip(" .")
|
||||||
|
if not clause:
|
||||||
|
continue
|
||||||
|
lower = clause.lower()
|
||||||
|
if lower.startswith(("pov foreground clothing cue:", "pov foreground body cue:")):
|
||||||
|
continue
|
||||||
|
if side_profile_oral and _side_profile_hidden_lower_clothing_clause(clause):
|
||||||
|
continue
|
||||||
|
kept.append(clause)
|
||||||
|
return "; ".join(kept)
|
||||||
|
|
||||||
|
|
||||||
def _has_krea2_top_down_variant(row: dict[str, Any]) -> bool:
|
def _has_krea2_top_down_variant(row: dict[str, Any]) -> bool:
|
||||||
for key in _krea2_variant_keys(row):
|
for key in _krea2_variant_keys(row):
|
||||||
variant = krea2_pose_variant_catalog.get_variant(key)
|
variant = krea2_pose_variant_catalog.get_variant(key)
|
||||||
@@ -232,6 +273,7 @@ def format_insta_pair_result(request: KreaPairFormatRequest, deps: KreaPairForma
|
|||||||
),
|
),
|
||||||
hard_labels,
|
hard_labels,
|
||||||
)
|
)
|
||||||
|
hard_clothing = _krea2_atlas_clothing_text(hard, hard_clothing)
|
||||||
same_soft_cast = options.get("softcore_cast") == "same_as_hardcore"
|
same_soft_cast = options.get("softcore_cast") == "same_as_hardcore"
|
||||||
soft_output_composition = deps.pov_composition_text(soft.get("composition"), pov_labels if same_soft_cast else [])
|
soft_output_composition = deps.pov_composition_text(soft.get("composition"), pov_labels if same_soft_cast else [])
|
||||||
soft_cast_presence = deps.softcore_cast_presence_phrase(
|
soft_cast_presence = deps.softcore_cast_presence_phrase(
|
||||||
|
|||||||
@@ -8665,6 +8665,10 @@ def smoke_pov_oral_position_routes() -> None:
|
|||||||
"clothing state:" not in clothing_only_top_prompt,
|
"clothing state:" not in clothing_only_top_prompt,
|
||||||
f"Krea2 POV Prompt Restore clothing-only final prompt leaked raw clothing label: {clothing_only_top_prompt}",
|
f"Krea2 POV Prompt Restore clothing-only final prompt leaked raw clothing label: {clothing_only_top_prompt}",
|
||||||
)
|
)
|
||||||
|
_expect(
|
||||||
|
"pov foreground clothing cue" not in clothing_only_top_prompt,
|
||||||
|
f"Krea2 POV Prompt Restore clothing-only final prompt should not add a second POV clothing/body cue: {clothing_only_top_prompt}",
|
||||||
|
)
|
||||||
_expect(
|
_expect(
|
||||||
not any(str(detail).lower() in clothing_only_top_prompt for detail in clothing_only_details),
|
not any(str(detail).lower() in clothing_only_top_prompt for detail in clothing_only_details),
|
||||||
f"Krea2 POV Prompt Restore clothing-only final prompt should not dump raw clothing_detail: {clothing_only_top_prompt}",
|
f"Krea2 POV Prompt Restore clothing-only final prompt should not dump raw clothing_detail: {clothing_only_top_prompt}",
|
||||||
@@ -8816,6 +8820,76 @@ def smoke_pov_oral_position_routes() -> None:
|
|||||||
_expect(term in side_body_prompt, f"Side-profile oral Krea prompt missing {term!r}: {side_body_prompt}")
|
_expect(term in side_body_prompt, f"Side-profile oral Krea prompt missing {term!r}: {side_body_prompt}")
|
||||||
_expect("side-phone" not in side_body_prompt, f"Side-profile oral Krea prompt drifted into non-POV side-phone wording: {side_body_prompt}")
|
_expect("side-phone" not in side_body_prompt, f"Side-profile oral Krea prompt drifted into non-POV side-phone wording: {side_body_prompt}")
|
||||||
|
|
||||||
|
side_body_clothing_config = sxcp_nodes.NODE_CLASS_MAPPINGS["SxCPKrea2POVOralFilter"]().build(
|
||||||
|
"replace",
|
||||||
|
"",
|
||||||
|
include_blowjob_side_profile_oral=True,
|
||||||
|
)[0]
|
||||||
|
side_body_clothing_config = sxcp_nodes.NODE_CLASS_MAPPINGS["SxCPKrea2POVPromptRestore"]().build(
|
||||||
|
True,
|
||||||
|
False,
|
||||||
|
False,
|
||||||
|
False,
|
||||||
|
True,
|
||||||
|
side_body_clothing_config,
|
||||||
|
)[0]
|
||||||
|
side_body_clothing_pair = pb.build_insta_of_pair(
|
||||||
|
row_number=1,
|
||||||
|
start_index=1,
|
||||||
|
seed=3730,
|
||||||
|
ethnicity="any",
|
||||||
|
figure="random",
|
||||||
|
no_plus_women=False,
|
||||||
|
no_black=False,
|
||||||
|
trigger=Trigger,
|
||||||
|
prepend_trigger_to_prompt=True,
|
||||||
|
options_json=_insta_options(
|
||||||
|
softcore_camera_mode="from_camera_config",
|
||||||
|
hardcore_camera_mode="from_camera_config",
|
||||||
|
camera_detail="compact",
|
||||||
|
hardcore_clothing_continuity="partially_removed",
|
||||||
|
),
|
||||||
|
character_cast=_character_cast(pov_man=True),
|
||||||
|
hardcore_position_config=side_body_clothing_config,
|
||||||
|
location_config=_coworking_location_config(),
|
||||||
|
hardcore_camera_config=_orbit_camera(
|
||||||
|
horizontal_angle=45,
|
||||||
|
vertical_angle=0,
|
||||||
|
zoom=7.5,
|
||||||
|
subject_focus="action",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
side_body_problem_clothing = (
|
||||||
|
"Clothing state: Woman A's denim shorts are pulled aside or removed below the hips; "
|
||||||
|
"button-down shirt tied at the waist, a fitted bralette remain visible from the same outfit; "
|
||||||
|
"POV foreground clothing cue: a casual shirt with belt open and pants partly lowered, "
|
||||||
|
"appearing as the viewer's hands, forearms, sleeves, or torso edge."
|
||||||
|
)
|
||||||
|
side_body_clothing_pair["hardcore_clothing_state"] = side_body_problem_clothing
|
||||||
|
side_body_clothing_pair["hardcore_row"]["hardcore_clothing_state"] = side_body_problem_clothing
|
||||||
|
side_body_clothing_krea = krea_formatter.format_krea2_prompt("", metadata_json=_json(side_body_clothing_pair), target="hardcore")
|
||||||
|
side_body_clothing_prompt = _expect_text(
|
||||||
|
"pov_oral_side_profile_body_line_restore_clothing.krea_prompt",
|
||||||
|
side_body_clothing_krea.get("krea_prompt"),
|
||||||
|
80,
|
||||||
|
).lower()
|
||||||
|
_expect(
|
||||||
|
"pov side-profile oral body-line position" in side_body_clothing_prompt,
|
||||||
|
"Side-profile oral clothing restore lost the atlas body-line pose",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
"pov foreground clothing cue" not in side_body_clothing_prompt,
|
||||||
|
f"Side-profile oral clothing restore should not add a second POV foreground clothing cue: {side_body_clothing_prompt}",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
"denim shorts" not in side_body_clothing_prompt and "below the hips" not in side_body_clothing_prompt,
|
||||||
|
f"Side-profile oral clothing restore should not expose hidden lower-body clothing: {side_body_clothing_prompt}",
|
||||||
|
)
|
||||||
|
_expect(
|
||||||
|
"button-down shirt tied at the waist" in side_body_clothing_prompt and "fitted bralette" in side_body_clothing_prompt,
|
||||||
|
f"Side-profile oral clothing restore should preserve visible upper outfit continuity: {side_body_clothing_prompt}",
|
||||||
|
)
|
||||||
|
|
||||||
sitting_pair = pb.build_insta_of_pair(
|
sitting_pair = pb.build_insta_of_pair(
|
||||||
row_number=1,
|
row_number=1,
|
||||||
start_index=1,
|
start_index=1,
|
||||||
|
|||||||
Reference in New Issue
Block a user