Spaces:
Running on Zero
Running on Zero
Reject incompatible overhead silhouettes
Browse files
app.py
CHANGED
|
@@ -1947,8 +1947,8 @@ def neural_foreground_cutout(image: Image.Image) -> Image.Image:
|
|
| 1947 |
return cutout
|
| 1948 |
|
| 1949 |
|
| 1950 |
-
def
|
| 1951 |
-
"""
|
| 1952 |
# Classify only from the user's visual description. Custom IDs such as
|
| 1953 |
# ``player`` or ``enemy`` are integration hooks, not reliable anatomy.
|
| 1954 |
description = f"{spec.description} {spec.prompt}".lower()
|
|
@@ -1985,16 +1985,28 @@ def top_down_subject_contract(spec: AssetSpec) -> str:
|
|
| 1985 |
)
|
| 1986 |
|
| 1987 |
if contains_any_term(description, radial_terms):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1988 |
return (
|
| 1989 |
"Top of body dominates; splayed limbs radiate in image plane; "
|
| 1990 |
"no upright torso or side elevation."
|
| 1991 |
)
|
| 1992 |
-
if
|
| 1993 |
return (
|
| 1994 |
"Roof and chassis top dominate; wheel footprints flank both sides; "
|
| 1995 |
"no grille or side elevation."
|
| 1996 |
)
|
| 1997 |
-
if
|
| 1998 |
return (
|
| 1999 |
"Full body overhead: head crown, shoulders and back visible; "
|
| 2000 |
"face and chest invisible; limbs foreshortened."
|
|
@@ -2120,7 +2132,7 @@ def primary_diffusion_png(spec: AssetSpec, index: int, run_id: int) -> tuple[byt
|
|
| 2120 |
continue
|
| 2121 |
if has_front_view_like_top_down_silhouette(content, spec):
|
| 2122 |
last_failure_detail = (
|
| 2123 |
-
"the last output
|
| 2124 |
)
|
| 2125 |
continue
|
| 2126 |
if has_undersized_foreground_subject(content):
|
|
@@ -2467,13 +2479,13 @@ def has_implausibly_thin_foreground_subject(content: bytes, spec: AssetSpec) ->
|
|
| 2467 |
|
| 2468 |
|
| 2469 |
def has_front_view_like_top_down_silhouette(content: bytes, spec: AssetSpec) -> bool:
|
| 2470 |
-
"""
|
| 2471 |
|
| 2472 |
-
Alpha geometry cannot prove camera perspective
|
| 2473 |
-
|
| 2474 |
-
|
| 2475 |
-
|
| 2476 |
-
|
| 2477 |
"""
|
| 2478 |
if spec.camera != "top_down" or spec.composition not in {"single_subject", "icon", "animation_frame"}:
|
| 2479 |
return False
|
|
@@ -2491,31 +2503,19 @@ def has_front_view_like_top_down_silhouette(content: bytes, spec: AssetSpec) ->
|
|
| 2491 |
if height_ratio < 0.72:
|
| 2492 |
return False
|
| 2493 |
|
| 2494 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2495 |
return True
|
| 2496 |
|
| 2497 |
description = f"{spec.description} {spec.prompt}"
|
| 2498 |
-
|
| 2499 |
description,
|
| 2500 |
-
(
|
| 2501 |
-
"broad",
|
| 2502 |
-
"radial",
|
| 2503 |
-
"wide-bodied",
|
| 2504 |
-
"wide bodied",
|
| 2505 |
-
"six-legged",
|
| 2506 |
-
"six legged",
|
| 2507 |
-
"four-legged",
|
| 2508 |
-
"four legged",
|
| 2509 |
-
"multi-legged",
|
| 2510 |
-
"multi legged",
|
| 2511 |
-
"quadruped",
|
| 2512 |
-
"spider-like",
|
| 2513 |
-
"spider like",
|
| 2514 |
-
"crab-like",
|
| 2515 |
-
"crab like",
|
| 2516 |
-
),
|
| 2517 |
)
|
| 2518 |
-
if
|
| 2519 |
return True
|
| 2520 |
|
| 2521 |
narrow_subject_requested = contains_any_term(
|
|
@@ -2840,7 +2840,7 @@ def validate_asset_png(content: bytes, spec: AssetSpec) -> list[str]:
|
|
| 2840 |
elif spec.expected_subjects == 1 and has_implausibly_thin_foreground_subject(content, spec):
|
| 2841 |
warnings.append("sprite foreground silhouette is implausibly thin")
|
| 2842 |
elif spec.expected_subjects == 1 and has_front_view_like_top_down_silhouette(content, spec):
|
| 2843 |
-
warnings.append("top-down sprite silhouette
|
| 2844 |
elif spec.expected_subjects == 1 and has_undersized_foreground_subject(content):
|
| 2845 |
warnings.append("foreground subject occupies too little of the output canvas")
|
| 2846 |
if spec.composition == "seamless" and image.width > 1 and image.height > 1:
|
|
|
|
| 1947 |
return cutout
|
| 1948 |
|
| 1949 |
|
| 1950 |
+
def infer_top_down_subject_geometry(spec: AssetSpec) -> str:
|
| 1951 |
+
"""Infer an overhead footprint from user-authored visual terms, never the asset ID."""
|
| 1952 |
# Classify only from the user's visual description. Custom IDs such as
|
| 1953 |
# ``player`` or ``enemy`` are integration hooks, not reliable anatomy.
|
| 1954 |
description = f"{spec.description} {spec.prompt}".lower()
|
|
|
|
| 1985 |
)
|
| 1986 |
|
| 1987 |
if contains_any_term(description, radial_terms):
|
| 1988 |
+
return "radial"
|
| 1989 |
+
if contains_any_term(description, vehicle_terms):
|
| 1990 |
+
return "vehicle"
|
| 1991 |
+
if spec.silhouette == "humanoid" or contains_any_term(description, humanoid_terms):
|
| 1992 |
+
return "humanoid"
|
| 1993 |
+
return "generic"
|
| 1994 |
+
|
| 1995 |
+
|
| 1996 |
+
def top_down_subject_contract(spec: AssetSpec) -> str:
|
| 1997 |
+
"""Describe visible overhead anatomy without drawing or reshaping model artwork."""
|
| 1998 |
+
geometry = infer_top_down_subject_geometry(spec)
|
| 1999 |
+
if geometry == "radial":
|
| 2000 |
return (
|
| 2001 |
"Top of body dominates; splayed limbs radiate in image plane; "
|
| 2002 |
"no upright torso or side elevation."
|
| 2003 |
)
|
| 2004 |
+
if geometry == "vehicle":
|
| 2005 |
return (
|
| 2006 |
"Roof and chassis top dominate; wheel footprints flank both sides; "
|
| 2007 |
"no grille or side elevation."
|
| 2008 |
)
|
| 2009 |
+
if geometry == "humanoid":
|
| 2010 |
return (
|
| 2011 |
"Full body overhead: head crown, shoulders and back visible; "
|
| 2012 |
"face and chest invisible; limbs foreshortened."
|
|
|
|
| 2132 |
continue
|
| 2133 |
if has_front_view_like_top_down_silhouette(content, spec):
|
| 2134 |
last_failure_detail = (
|
| 2135 |
+
"the last output silhouette conflicted with the requested overhead body footprint"
|
| 2136 |
)
|
| 2137 |
continue
|
| 2138 |
if has_undersized_foreground_subject(content):
|
|
|
|
| 2479 |
|
| 2480 |
|
| 2481 |
def has_front_view_like_top_down_silhouette(content: bytes, spec: AssetSpec) -> bool:
|
| 2482 |
+
"""Reject silhouettes that contradict a requested overhead body footprint.
|
| 2483 |
|
| 2484 |
+
Alpha geometry cannot prove camera perspective. It can, however, fail closed
|
| 2485 |
+
when a normalized, canvas-filling silhouette contradicts explicit user terms:
|
| 2486 |
+
compact humanoids cannot remain upright portraits; radial bodies must not be
|
| 2487 |
+
taller than wide; and explicitly wide vehicles must present a wide footprint.
|
| 2488 |
+
Narrow props remain exempt.
|
| 2489 |
"""
|
| 2490 |
if spec.camera != "top_down" or spec.composition not in {"single_subject", "icon", "animation_frame"}:
|
| 2491 |
return False
|
|
|
|
| 2503 |
if height_ratio < 0.72:
|
| 2504 |
return False
|
| 2505 |
|
| 2506 |
+
geometry = infer_top_down_subject_geometry(spec)
|
| 2507 |
+
if geometry == "humanoid" and aspect >= 1.10:
|
| 2508 |
+
return True
|
| 2509 |
+
|
| 2510 |
+
if geometry == "radial" and aspect >= 1.02:
|
| 2511 |
return True
|
| 2512 |
|
| 2513 |
description = f"{spec.description} {spec.prompt}"
|
| 2514 |
+
explicitly_wide_vehicle = geometry == "vehicle" and contains_any_term(
|
| 2515 |
description,
|
| 2516 |
+
("wide", "four-wheel", "four wheel", "six-wheel", "six wheel", "tracked"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2517 |
)
|
| 2518 |
+
if explicitly_wide_vehicle and aspect >= 0.95:
|
| 2519 |
return True
|
| 2520 |
|
| 2521 |
narrow_subject_requested = contains_any_term(
|
|
|
|
| 2840 |
elif spec.expected_subjects == 1 and has_implausibly_thin_foreground_subject(content, spec):
|
| 2841 |
warnings.append("sprite foreground silhouette is implausibly thin")
|
| 2842 |
elif spec.expected_subjects == 1 and has_front_view_like_top_down_silhouette(content, spec):
|
| 2843 |
+
warnings.append("top-down sprite silhouette conflicts with the requested overhead footprint")
|
| 2844 |
elif spec.expected_subjects == 1 and has_undersized_foreground_subject(content):
|
| 2845 |
warnings.append("foreground subject occupies too little of the output canvas")
|
| 2846 |
if spec.composition == "seamless" and image.width > 1 and image.height > 1:
|