Clarify vaginal penetration geometry
This commit is contained in:
@@ -856,6 +856,40 @@ def _is_oral_text(*parts: Any) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def _is_vaginal_penetration_text(*parts: Any) -> bool:
|
||||
text = " ".join(_clean(part).lower() for part in parts if _clean(part))
|
||||
if not text or _is_outercourse_text(text) or _is_oral_text(text):
|
||||
return False
|
||||
if any(term in text for term in ("anal", "double penetration", "double-penetration", "toy-assisted", "strap-on")):
|
||||
return False
|
||||
return any(
|
||||
term in text
|
||||
for term in (
|
||||
"vaginal penetration",
|
||||
"deep vaginal sex",
|
||||
"explicit penetrative sex",
|
||||
"penetrative sex",
|
||||
"penis entering pussy",
|
||||
"penis thrusts into her pussy",
|
||||
"penis thrusts into the woman",
|
||||
"pussy stretched around a penis",
|
||||
"hardcore vaginal thrusting",
|
||||
"full-body penetrative sex",
|
||||
"close-contact vaginal sex",
|
||||
"missionary position",
|
||||
"cowgirl position",
|
||||
"reverse cowgirl position",
|
||||
"doggy style position",
|
||||
"standing sex position",
|
||||
"spooning sex position",
|
||||
"edge-of-bed position",
|
||||
"kneeling straddle position",
|
||||
"lotus sex position",
|
||||
"bent-over position",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _is_toy_assisted_double_text(*parts: Any) -> bool:
|
||||
text = " ".join(_clean(part).lower() for part in parts if _clean(part))
|
||||
if "toy" not in text:
|
||||
@@ -1521,6 +1555,74 @@ def _dedupe_oral_detail(detail: str, role_graph: str, hard_item: str = "", axis_
|
||||
return _join_detail_clauses(clauses)
|
||||
|
||||
|
||||
def _dedupe_penetration_detail(detail: str, role_graph: str, hard_item: str = "", axis_values: Any = None) -> str:
|
||||
detail = _clean(detail)
|
||||
if not detail:
|
||||
return ""
|
||||
role_lower = _clean(role_graph).lower()
|
||||
detail = re.sub(
|
||||
r"\b(?:front-facing|side-profile|rear-view|overhead|mirror-reflected|low-angle|close-up|wide full-body)\s+view of\s+"
|
||||
r"(?:vaginal penetration with visible genital contact|deep vaginal sex|explicit penetrative sex|penetrative sex|"
|
||||
r"penis entering pussy|pussy stretched around a penis|hardcore vaginal thrusting|full-body penetrative sex|"
|
||||
r"close-contact vaginal sex)\b,?\s*",
|
||||
"",
|
||||
detail,
|
||||
flags=re.IGNORECASE,
|
||||
)
|
||||
act_terms = (
|
||||
"vaginal penetration with visible genital contact",
|
||||
"deep vaginal sex",
|
||||
"explicit penetrative sex",
|
||||
"penetrative sex",
|
||||
"penis entering pussy",
|
||||
"pussy stretched around a penis",
|
||||
"hardcore vaginal thrusting",
|
||||
"full-body penetrative sex",
|
||||
"close-contact vaginal sex",
|
||||
"missionary position",
|
||||
"cowgirl position",
|
||||
"reverse cowgirl position",
|
||||
"doggy style position",
|
||||
"standing sex position",
|
||||
"spooning sex position",
|
||||
"edge-of-bed position",
|
||||
"kneeling straddle position",
|
||||
"lotus sex position",
|
||||
"bent-over position",
|
||||
)
|
||||
clauses: list[str] = []
|
||||
for clause in _detail_clauses(detail):
|
||||
lower = clause.lower()
|
||||
if any(term in lower for term in act_terms):
|
||||
continue
|
||||
if lower in (
|
||||
"tongues visible while kissing",
|
||||
"deep kissing",
|
||||
"mouth close to the ear",
|
||||
"neck kissing",
|
||||
"explicit genital contact visible",
|
||||
"genitals clearly visible",
|
||||
"anatomically clear penetration",
|
||||
"pussy and penis visible",
|
||||
"wetness visible between the thighs",
|
||||
):
|
||||
continue
|
||||
if lower in ("legs spread wide", "thighs open toward the viewer") and any(
|
||||
term in role_lower for term in ("legs spread wide", "thighs open", "open thighs")
|
||||
):
|
||||
continue
|
||||
if lower == "one body pinned under another" and "lies under" in role_lower:
|
||||
continue
|
||||
if lower in ("hips locked tightly together", "hips aligned") and "hips" in role_lower:
|
||||
continue
|
||||
if lower in ("hands gripping hips", "hands spreading the thighs") and any(
|
||||
term in role_lower for term in ("hips", "thighs", "legs")
|
||||
):
|
||||
continue
|
||||
clauses.append(clause)
|
||||
return _join_detail_clauses(clauses)
|
||||
|
||||
|
||||
def _detail_clauses(detail: str) -> list[str]:
|
||||
return [part.strip(" ,;") for part in re.split(r",\s*(?:and\s+)?", _clean(detail)) if part.strip(" ,;")]
|
||||
|
||||
@@ -1846,6 +1948,7 @@ def _hardcore_action_sentence(
|
||||
anchor = _hardcore_pose_anchor(role_graph, hard_item, composition, axis_values)
|
||||
is_outercourse = _is_outercourse_text(role_graph, hard_item, composition, _axis_values_text(axis_values))
|
||||
is_oral = _is_oral_text(role_graph, hard_item, composition, _axis_values_text(axis_values))
|
||||
is_penetrative = _is_vaginal_penetration_text(role_graph, hard_item, composition, _axis_values_text(axis_values))
|
||||
if _is_toy_assisted_double_text(role_graph, hard_item, composition, _axis_values_text(axis_values)):
|
||||
role_graph = re.sub(
|
||||
r"\s+while a toy adds (?:the|a) second penetration point\b",
|
||||
@@ -1864,6 +1967,10 @@ def _hardcore_action_sentence(
|
||||
anchor = ""
|
||||
detail = _dedupe_oral_detail(detail, role_graph, hard_item, axis_values)
|
||||
detail = _limit_detail_for_density(detail, detail_density, False)
|
||||
elif is_penetrative and role_graph:
|
||||
anchor = ""
|
||||
detail = _dedupe_penetration_detail(detail, role_graph, hard_item, axis_values)
|
||||
detail = _limit_detail_for_density(detail, detail_density, False)
|
||||
else:
|
||||
detail = _dedupe_hardcore_detail(detail, anchor) if anchor else detail
|
||||
if _is_toy_assisted_double_text(role_graph, hard_item, composition, _axis_values_text(axis_values)):
|
||||
|
||||
Reference in New Issue
Block a user