Avoid clothing cues for nude mode
This commit is contained in:
+18
-4
@@ -375,6 +375,15 @@ def _natural_clothing_state(text: Any) -> str:
|
|||||||
if not text:
|
if not text:
|
||||||
return ""
|
return ""
|
||||||
text = re.sub(r"^Clothing state:\s*", "", text, flags=re.IGNORECASE)
|
text = re.sub(r"^Clothing state:\s*", "", text, flags=re.IGNORECASE)
|
||||||
|
body_exposure = re.match(r"^Body exposure:\s*(.*?)\.?$", text, flags=re.IGNORECASE)
|
||||||
|
if body_exposure:
|
||||||
|
return _clean(body_exposure.group(1)).rstrip(".")
|
||||||
|
if re.search(r"\bfully nude\b|\bbody is fully exposed\b|\bno clothing covering\b", text, flags=re.IGNORECASE):
|
||||||
|
owner = "the woman"
|
||||||
|
owner_match = re.match(r"^\s*((?:Woman|Man) [A-Z])\b", text)
|
||||||
|
if owner_match:
|
||||||
|
owner = _natural_label_text(owner_match.group(1), ["Woman A", "Man A"]) or owner
|
||||||
|
return f"{owner.capitalize()}'s body is fully exposed, bare skin unobstructed"
|
||||||
match = re.match(
|
match = re.match(
|
||||||
r"^(.*?)\b(?:softcore|teaser) outfit is (.*?)(?: for the (?:hardcore|sex) scene)?;\s*(?:softcore visual reference|teaser outfit detail):\s*(.*?)\.?$",
|
r"^(.*?)\b(?:softcore|teaser) outfit is (.*?)(?: for the (?:hardcore|sex) scene)?;\s*(?:softcore visual reference|teaser outfit detail):\s*(.*?)\.?$",
|
||||||
text,
|
text,
|
||||||
@@ -384,10 +393,10 @@ def _natural_clothing_state(text: Any) -> str:
|
|||||||
owner = _natural_label_text(match.group(1).strip(" 's"), ["Woman A", "Man A"]).strip() or "the woman"
|
owner = _natural_label_text(match.group(1).strip(" 's"), ["Woman A", "Man A"]).strip() or "the woman"
|
||||||
state = _clean(match.group(2)).lower()
|
state = _clean(match.group(2)).lower()
|
||||||
outfit = _clean(match.group(3)).rstrip(".")
|
outfit = _clean(match.group(3)).rstrip(".")
|
||||||
if "fully nude" in state:
|
if "fully nude" in state or "fully exposed" in state or "no clothing covering" in state:
|
||||||
return f"{owner.capitalize()} is fully nude, with the removed {outfit} visible nearby"
|
return f"{owner.capitalize()}'s body is fully exposed, bare skin unobstructed"
|
||||||
if "nude-adjacent" in state:
|
if "nude-adjacent" in state:
|
||||||
return f"{owner.capitalize()} is partly nude, with the {outfit} slipping off and no abstract clothing-reference wording"
|
return f"{owner.capitalize()}'s body is partly exposed"
|
||||||
if "partially removed" in state or "pushed aside" in state:
|
if "partially removed" in state or "pushed aside" in state:
|
||||||
return f"{owner.capitalize()}'s {outfit} is pushed aside and partly removed, exposing the sexual contact clearly"
|
return f"{owner.capitalize()}'s {outfit} is pushed aside and partly removed, exposing the sexual contact clearly"
|
||||||
if "keeps" in state:
|
if "keeps" in state:
|
||||||
@@ -1589,6 +1598,11 @@ def _insta_pair_to_krea(row: dict[str, Any], detail_level: str, style_mode: str)
|
|||||||
hard_expression_source,
|
hard_expression_source,
|
||||||
hard_labels,
|
hard_labels,
|
||||||
)
|
)
|
||||||
|
soft_item = _clean(soft.get("item"))
|
||||||
|
soft_item_label = _clean(soft.get("softcore_item_prompt_label"))
|
||||||
|
soft_item_phrase = ""
|
||||||
|
if soft_item:
|
||||||
|
soft_item_phrase = f"body exposure: {soft_item}" if soft_item_label == "Body exposure" else f"wearing {soft_item}"
|
||||||
|
|
||||||
soft_parts = [
|
soft_parts = [
|
||||||
soft_cast_prose,
|
soft_cast_prose,
|
||||||
@@ -1596,7 +1610,7 @@ def _insta_pair_to_krea(row: dict[str, Any], detail_level: str, style_mode: str)
|
|||||||
partner_outfit_text,
|
partner_outfit_text,
|
||||||
partner_pose,
|
partner_pose,
|
||||||
_pov_camera_phrase(pov_labels, softcore=True) if same_soft_cast else "",
|
_pov_camera_phrase(pov_labels, softcore=True) if same_soft_cast else "",
|
||||||
f"wearing {soft.get('item')}" if soft.get("item") else "",
|
soft_item_phrase,
|
||||||
f"{soft.get('pose')}" if soft.get("pose") else "",
|
f"{soft.get('pose')}" if soft.get("pose") else "",
|
||||||
_expression_phrase(soft_expression),
|
_expression_phrase(soft_expression),
|
||||||
f"in {soft.get('scene_text')}" if soft.get("scene_text") else "",
|
f"in {soft.get('scene_text')}" if soft.get("scene_text") else "",
|
||||||
|
|||||||
+62
-18
@@ -2306,6 +2306,32 @@ def _pov_composition_prompt(composition: Any, pov_labels: list[str]) -> str:
|
|||||||
return _clean_prompt_punctuation(text)
|
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:
|
def _slot_softcore_outfit(slot: dict[str, Any] | None) -> str:
|
||||||
return _slot_value(slot.get("softcore_outfit")) if slot else ""
|
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:
|
if not clothing:
|
||||||
return ""
|
return ""
|
||||||
lower = clothing.lower()
|
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 ")):
|
if lower.startswith(("is ", "wears ", "wearing ", "keeps ", "has ", "with ")):
|
||||||
return f"{label} {clothing}"
|
return f"{label} {clothing}"
|
||||||
if lower.startswith(("fully nude", "nude", "partly nude")):
|
|
||||||
return f"{label} is {clothing}"
|
|
||||||
return f"{label}'s clothing: {clothing}"
|
return f"{label}'s clothing: {clothing}"
|
||||||
|
|
||||||
|
|
||||||
@@ -3863,8 +3891,8 @@ INSTA_OF_HARDCORE_CLOTHING_CONTINUITY = {
|
|||||||
"none": "",
|
"none": "",
|
||||||
"same_outfit": "Woman A keeps her teaser outfit on, with sexual contact still clearly visible",
|
"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",
|
"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",
|
"implied_nude": "Woman A's body is partly exposed, with fabric slipping off or covering only part of the body",
|
||||||
"explicit_nude": "Woman A is fully nude, with the removed teaser outfit visible nearby",
|
"explicit_nude": "Woman A's body is fully exposed, bare skin unobstructed",
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTA_OF_NEGATIVE = (
|
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",
|
"strappy lingerie set with covered cups and high-waisted bottoms, styled as a stronger solo teaser",
|
||||||
],
|
],
|
||||||
"explicit_nude": [
|
"explicit_nude": [
|
||||||
"fully nude creator styling with jewelry, heels, and direct adult selfie confidence",
|
"body fully exposed with jewelry accents and direct adult selfie confidence",
|
||||||
"fully nude mirror-selfie styling with jewelry only and bold creator-shot framing",
|
"mirror-selfie body exposure with jewelry accents and bold creator-shot framing",
|
||||||
"nude-on-sheets creator pose with lingerie discarded nearby and direct eye contact",
|
"body fully exposed on soft sheets with direct eye contact",
|
||||||
"fully nude vanity-mirror pose with heels, necklace, and premium adult teaser styling",
|
"vanity-mirror body exposure with necklace detail and premium creator-shot styling",
|
||||||
"nude shower-afterglow creator pose with wet hair, skin highlights, and phone-shot framing",
|
"shower-afterglow body exposure with wet hair, skin highlights, and phone-shot framing",
|
||||||
"fully nude bedroom creator pose with one hand holding the phone and lingerie visible nearby",
|
"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",
|
"arching subtly in a solo adult tease while the styling keeps explicit anatomy obscured",
|
||||||
],
|
],
|
||||||
"explicit_nude": [
|
"explicit_nude": [
|
||||||
"taking a bold nude mirror selfie with direct eye contact and the body clearly framed",
|
"taking a bold 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",
|
"posing on the bed with body fully exposed and jewelry accents as styling",
|
||||||
"standing at the vanity fully nude in a premium creator-shot pose",
|
"standing at the vanity with body fully exposed in a premium creator-shot pose",
|
||||||
"reclining fully nude on soft sheets with the phone held close",
|
"reclining on soft sheets with body fully exposed and the phone held close",
|
||||||
"turning slightly in a nude mirror pose with the body framed head-to-thigh",
|
"turning slightly in a mirror pose with the body framed head-to-thigh",
|
||||||
"kneeling fully nude in a controlled adult teaser pose with direct phone-camera awareness",
|
"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)
|
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:
|
def _insta_of_softcore_pose(rng: random.Random, level: str) -> str:
|
||||||
pool = INSTA_OF_SOFTCORE_POSES.get(level, INSTA_OF_SOFTCORE_POSES["lingerie_tease"])
|
pool = INSTA_OF_SOFTCORE_POSES.get(level, INSTA_OF_SOFTCORE_POSES["lingerie_tease"])
|
||||||
return g.choose(rng, pool)
|
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:
|
if mode == "none" or not outfit:
|
||||||
return ""
|
return ""
|
||||||
base = INSTA_OF_HARDCORE_CLOTHING_CONTINUITY[mode]
|
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}."
|
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)
|
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["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["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["custom_item"] = "insta_of_softcore_outfit"
|
||||||
soft_row["softcore_outfit_policy"] = "character_slot:Woman A" if primary_softcore_outfit else "insta_of_safe_softcore"
|
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"] = (
|
soft_row["pov_character_labels"] = (
|
||||||
pov_character_labels
|
pov_character_labels
|
||||||
if options["softcore_cast"] == "same_as_hardcore"
|
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_parts = [part for part in (fallback_hard_clothing_state, *character_hardcore_clothing_entries) if part]
|
||||||
hard_clothing_state = " ".join(hard_clothing_parts)
|
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_density = options["hardcore_detail_density"]
|
||||||
hard_detail_directive = {
|
hard_detail_directive = {
|
||||||
"compact": "Use one compact position-first sexual action sentence; avoid repeated aftermath wording. ",
|
"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"Softcore setup: {soft_level}. Cast: {soft_cast}. "
|
||||||
f"{soft_cast_presence}"
|
f"{soft_cast_presence}"
|
||||||
f"{soft_cast_styling_sentence}"
|
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"{_labeled_expression_sentence('Facial expression', soft_row.get('expression'))}"
|
||||||
f"Composition: {soft_row['composition']}. "
|
f"Composition: {soft_row['composition']}. "
|
||||||
f"{soft_camera_sentence}"
|
f"{soft_camera_sentence}"
|
||||||
|
|||||||
Reference in New Issue
Block a user