Avoid clothing cues for nude mode
This commit is contained in:
+62
-18
@@ -2306,6 +2306,32 @@ def _pov_composition_prompt(composition: Any, pov_labels: list[str]) -> str:
|
||||
return _clean_prompt_punctuation(text)
|
||||
|
||||
|
||||
def _body_exposure_scene_text(scene: Any) -> str:
|
||||
text = str(scene or "").strip()
|
||||
if not text:
|
||||
return ""
|
||||
replacements = (
|
||||
(r",?\s*\bscattered (?:clothes|clothing)\b", ""),
|
||||
(r",?\s*\bfloor clothes\b", ""),
|
||||
(r"\bclothes scattered\b", "soft floor shadows"),
|
||||
(r",?\s*\bscattered lingerie\b", ""),
|
||||
(r",?\s*\blingerie visible nearby\b", ""),
|
||||
(r"\boutfit racks\b", "mirror shelves"),
|
||||
(r"\bcostume racks\b", "mirror shelves"),
|
||||
(r"\bhanging outfits\b", "hanging fabric"),
|
||||
(r"\bclothing hooks\b", "wall hooks"),
|
||||
(r"\boutfit-check\b", "creator-shot"),
|
||||
(r"\boutfit framing\b", "body framing"),
|
||||
(r"\bfull outfits\b", "full bodies"),
|
||||
(r"\bcoordinated outfits\b", "coordinated posing"),
|
||||
)
|
||||
for pattern, replacement in replacements:
|
||||
text = re.sub(pattern, replacement, text, flags=re.IGNORECASE)
|
||||
text = re.sub(r"\bwith,\s*", "with ", text, flags=re.IGNORECASE)
|
||||
text = re.sub(r",\s*,", ",", text)
|
||||
return _clean_prompt_punctuation(text)
|
||||
|
||||
|
||||
def _slot_softcore_outfit(slot: dict[str, Any] | None) -> str:
|
||||
return _slot_value(slot.get("softcore_outfit")) if slot else ""
|
||||
|
||||
@@ -2329,10 +2355,12 @@ def _hardcore_clothing_sentence(label: str, clothing: str) -> str:
|
||||
if not clothing:
|
||||
return ""
|
||||
lower = clothing.lower()
|
||||
if lower.startswith(("fully nude", "nude")):
|
||||
return f"{label}'s body is fully exposed, bare skin unobstructed"
|
||||
if lower.startswith("partly nude"):
|
||||
return f"{label}'s body is partly exposed"
|
||||
if lower.startswith(("is ", "wears ", "wearing ", "keeps ", "has ", "with ")):
|
||||
return f"{label} {clothing}"
|
||||
if lower.startswith(("fully nude", "nude", "partly nude")):
|
||||
return f"{label} is {clothing}"
|
||||
return f"{label}'s clothing: {clothing}"
|
||||
|
||||
|
||||
@@ -3863,8 +3891,8 @@ INSTA_OF_HARDCORE_CLOTHING_CONTINUITY = {
|
||||
"none": "",
|
||||
"same_outfit": "Woman A keeps her teaser outfit on, with sexual contact still clearly visible",
|
||||
"partially_removed": "Woman A's teaser outfit is pushed aside and partly removed, exposing the sexual contact clearly",
|
||||
"implied_nude": "Woman A is partly nude, with the teaser outfit slipping off or covering only part of the body",
|
||||
"explicit_nude": "Woman A is fully nude, with the removed teaser outfit visible nearby",
|
||||
"implied_nude": "Woman A's body is partly exposed, with fabric slipping off or covering only part of the body",
|
||||
"explicit_nude": "Woman A's body is fully exposed, bare skin unobstructed",
|
||||
}
|
||||
|
||||
INSTA_OF_NEGATIVE = (
|
||||
@@ -3924,12 +3952,12 @@ INSTA_OF_SOFTCORE_OUTFITS = {
|
||||
"strappy lingerie set with covered cups and high-waisted bottoms, styled as a stronger solo teaser",
|
||||
],
|
||||
"explicit_nude": [
|
||||
"fully nude creator styling with jewelry, heels, and direct adult selfie confidence",
|
||||
"fully nude mirror-selfie styling with jewelry only and bold creator-shot framing",
|
||||
"nude-on-sheets creator pose with lingerie discarded nearby and direct eye contact",
|
||||
"fully nude vanity-mirror pose with heels, necklace, and premium adult teaser styling",
|
||||
"nude shower-afterglow creator pose with wet hair, skin highlights, and phone-shot framing",
|
||||
"fully nude bedroom creator pose with one hand holding the phone and lingerie visible nearby",
|
||||
"body fully exposed with jewelry accents and direct adult selfie confidence",
|
||||
"mirror-selfie body exposure with jewelry accents and bold creator-shot framing",
|
||||
"body fully exposed on soft sheets with direct eye contact",
|
||||
"vanity-mirror body exposure with necklace detail and premium creator-shot styling",
|
||||
"shower-afterglow body exposure with wet hair, skin highlights, and phone-shot framing",
|
||||
"bedroom body exposure with one hand holding the phone and direct camera awareness",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -3967,12 +3995,12 @@ INSTA_OF_SOFTCORE_POSES = {
|
||||
"arching subtly in a solo adult tease while the styling keeps explicit anatomy obscured",
|
||||
],
|
||||
"explicit_nude": [
|
||||
"taking a bold nude mirror selfie with direct eye contact and the body clearly framed",
|
||||
"posing fully nude on the bed with jewelry and heels as the only styling",
|
||||
"standing at the vanity fully nude in a premium creator-shot pose",
|
||||
"reclining fully nude on soft sheets with the phone held close",
|
||||
"turning slightly in a nude mirror pose with the body framed head-to-thigh",
|
||||
"kneeling fully nude in a controlled adult teaser pose with direct phone-camera awareness",
|
||||
"taking a bold mirror selfie with direct eye contact and the body clearly framed",
|
||||
"posing on the bed with body fully exposed and jewelry accents as styling",
|
||||
"standing at the vanity with body fully exposed in a premium creator-shot pose",
|
||||
"reclining on soft sheets with body fully exposed and the phone held close",
|
||||
"turning slightly in a mirror pose with the body framed head-to-thigh",
|
||||
"kneeling in a controlled adult teaser pose with body fully exposed and direct phone-camera awareness",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -4226,6 +4254,10 @@ def _insta_of_softcore_outfit(rng: random.Random, level: str) -> str:
|
||||
return g.choose(rng, pool)
|
||||
|
||||
|
||||
def _insta_of_softcore_item_prompt_label(level: str) -> str:
|
||||
return "Body exposure" if level == "explicit_nude" else "Outfit"
|
||||
|
||||
|
||||
def _insta_of_softcore_pose(rng: random.Random, level: str) -> str:
|
||||
pool = INSTA_OF_SOFTCORE_POSES.get(level, INSTA_OF_SOFTCORE_POSES["lingerie_tease"])
|
||||
return g.choose(rng, pool)
|
||||
@@ -4237,6 +4269,10 @@ def _insta_of_hardcore_clothing_state(mode: str, softcore_outfit: str) -> str:
|
||||
if mode == "none" or not outfit:
|
||||
return ""
|
||||
base = INSTA_OF_HARDCORE_CLOTHING_CONTINUITY[mode]
|
||||
if mode == "explicit_nude":
|
||||
return f"Body exposure: {base}."
|
||||
if mode == "implied_nude":
|
||||
return f"Body exposure: {base}."
|
||||
return f"Clothing state: {base}; teaser outfit detail: {outfit}."
|
||||
|
||||
|
||||
@@ -4382,9 +4418,13 @@ def build_insta_of_pair(
|
||||
primary_softcore_outfit = _slot_softcore_outfit(primary_slot)
|
||||
soft_row["item"] = primary_softcore_outfit or _insta_of_softcore_outfit(soft_content_rng, softcore_level_key)
|
||||
soft_row["pose"] = _insta_of_softcore_pose(soft_content_rng, softcore_level_key)
|
||||
soft_row["item_label"] = "Insta/OF softcore outfit"
|
||||
soft_row["item_label"] = "Insta/OF softcore body exposure" if softcore_level_key == "explicit_nude" else "Insta/OF softcore outfit"
|
||||
soft_row["softcore_item_prompt_label"] = _insta_of_softcore_item_prompt_label(softcore_level_key)
|
||||
soft_row["custom_item"] = "insta_of_softcore_outfit"
|
||||
soft_row["softcore_outfit_policy"] = "character_slot:Woman A" if primary_softcore_outfit else "insta_of_safe_softcore"
|
||||
if softcore_level_key == "explicit_nude":
|
||||
soft_row["source_scene_text"] = soft_row.get("source_scene_text") or soft_row.get("scene_text", "")
|
||||
soft_row["scene_text"] = _body_exposure_scene_text(soft_row.get("scene_text", ""))
|
||||
soft_row["pov_character_labels"] = (
|
||||
pov_character_labels
|
||||
if options["softcore_cast"] == "same_as_hardcore"
|
||||
@@ -4512,6 +4552,10 @@ def build_insta_of_pair(
|
||||
)
|
||||
hard_clothing_parts = [part for part in (fallback_hard_clothing_state, *character_hardcore_clothing_entries) if part]
|
||||
hard_clothing_state = " ".join(hard_clothing_parts)
|
||||
if "body is fully exposed" in hard_clothing_state.lower() or "bare skin unobstructed" in hard_clothing_state.lower():
|
||||
hard_scene = _body_exposure_scene_text(hard_scene)
|
||||
hard_row["source_scene_text"] = hard_row.get("source_scene_text") or hard_row.get("scene_text", "")
|
||||
hard_row["scene_text"] = _body_exposure_scene_text(hard_row.get("scene_text", ""))
|
||||
hard_detail_density = options["hardcore_detail_density"]
|
||||
hard_detail_directive = {
|
||||
"compact": "Use one compact position-first sexual action sentence; avoid repeated aftermath wording. ",
|
||||
@@ -4531,7 +4575,7 @@ def build_insta_of_pair(
|
||||
f"Softcore setup: {soft_level}. Cast: {soft_cast}. "
|
||||
f"{soft_cast_presence}"
|
||||
f"{soft_cast_styling_sentence}"
|
||||
f"Outfit: {soft_row['item']}. Pose: {soft_row['pose']}. Setting: {soft_row['scene_text']}. "
|
||||
f"{soft_row['softcore_item_prompt_label']}: {soft_row['item']}. Pose: {soft_row['pose']}. Setting: {soft_row['scene_text']}. "
|
||||
f"{_labeled_expression_sentence('Facial expression', soft_row.get('expression'))}"
|
||||
f"Composition: {soft_row['composition']}. "
|
||||
f"{soft_camera_sentence}"
|
||||
|
||||
Reference in New Issue
Block a user