From a340def000025c8e88fafcf558ebace740c298a7 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Wed, 1 Jul 2026 01:03:54 +0200 Subject: [PATCH] Filter atlas clothing restore foreground cues --- krea_pair_formatter.py | 42 ++++++++++++++++++++++++ tools/prompt_smoke.py | 74 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/krea_pair_formatter.py b/krea_pair_formatter.py index 86473f9..11547f9 100644 --- a/krea_pair_formatter.py +++ b/krea_pair_formatter.py @@ -11,6 +11,7 @@ except ImportError: # Allows local smoke tests with top-level imports. MOUTH_EXPRESSION_TERMS = ("mouth", "oral", "tongue", "lips", "gagging", "saliva", "drool") TOP_VIEW_ORAL_VARIANT = "pov_blowjob_top_down_vertical_shaft" +SIDE_PROFILE_ORAL_VARIANT = "pov_blowjob_side_profile_oral" ORAL_CONTACT_VARIANTS = frozenset( ( 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 +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: for key in _krea2_variant_keys(row): variant = krea2_pose_variant_catalog.get_variant(key) @@ -232,6 +273,7 @@ def format_insta_pair_result(request: KreaPairFormatRequest, deps: KreaPairForma ), hard_labels, ) + hard_clothing = _krea2_atlas_clothing_text(hard, hard_clothing) 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_cast_presence = deps.softcore_cast_presence_phrase( diff --git a/tools/prompt_smoke.py b/tools/prompt_smoke.py index 218f6b7..32833b0 100644 --- a/tools/prompt_smoke.py +++ b/tools/prompt_smoke.py @@ -8665,6 +8665,10 @@ def smoke_pov_oral_position_routes() -> None: "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}", ) + _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( 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}", @@ -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("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( row_number=1, start_index=1,