Michael Rabinovich Cursor commited on
Commit ·
1a5a9a2
1
Parent(s): f07f508
leaderboard: axis gizmo on task render grids; bump cadgenbench
Browse filestasks.py overlays the shared XYZ orientation gizmo on the editing task's
starting-shape render grid (imported from cadgenbench.common.axes_gizmo).
Bump CADGENBENCH_SHA to 193f2f5 so the Space's report generator picks up the
gizmo + headline-pill changes and tasks.py can import the helper.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Dockerfile +1 -1
- tasks.py +19 -3
Dockerfile
CHANGED
|
@@ -41,7 +41,7 @@ RUN pip install --no-cache-dir -r /tmp/requirements.txt \
|
|
| 41 |
# image rebuild picks up the latest code (pre-v1: always-updated). Lock
|
| 42 |
# to a specific commit SHA at the v1 release so published scores are
|
| 43 |
# reproducible (see space-setup/post-gt-swap.md Stage F).
|
| 44 |
-
ARG CADGENBENCH_SHA=
|
| 45 |
# Cache-bust the install below whenever the tracked ref moves: the
|
| 46 |
# GitHub commits endpoint's response changes with each new commit on
|
| 47 |
# `main`, so BuildKit re-fetches and invalidates the cached pip layer.
|
|
|
|
| 41 |
# image rebuild picks up the latest code (pre-v1: always-updated). Lock
|
| 42 |
# to a specific commit SHA at the v1 release so published scores are
|
| 43 |
# reproducible (see space-setup/post-gt-swap.md Stage F).
|
| 44 |
+
ARG CADGENBENCH_SHA=193f2f5
|
| 45 |
# Cache-bust the install below whenever the tracked ref moves: the
|
| 46 |
# GitHub commits endpoint's response changes with each new commit on
|
| 47 |
# `main`, so BuildKit re-fetches and invalidates the cached pip layer.
|
tasks.py
CHANGED
|
@@ -47,6 +47,8 @@ from pathlib import Path
|
|
| 47 |
|
| 48 |
import yaml
|
| 49 |
|
|
|
|
|
|
|
| 50 |
logger = logging.getLogger(__name__)
|
| 51 |
|
| 52 |
# Canonical render views shown in the input / ground-truth grids, in
|
|
@@ -115,14 +117,23 @@ def _views_grid(url_for) -> str:
|
|
| 115 |
``url_for(view)`` returns the image URL for a given view. Missing
|
| 116 |
renders hide themselves via the ``onerror`` hook, so an absent view
|
| 117 |
leaves no gap rather than a broken-image icon.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
"""
|
| 119 |
parts = ['<div class="images">']
|
| 120 |
for v in VIEWS:
|
| 121 |
url = url_for(v)
|
|
|
|
|
|
|
| 122 |
parts.append(
|
| 123 |
-
f'<div class="view"><
|
|
|
|
| 124 |
f'src="{html.escape(url, quote=True)}" alt="{v}" '
|
| 125 |
-
f'onerror="taskImgFail(this)">
|
|
|
|
| 126 |
)
|
| 127 |
parts.append("</div>")
|
| 128 |
return "\n".join(parts)
|
|
@@ -462,9 +473,14 @@ h2 { margin-top: 0; }
|
|
| 462 |
.images { display: flex; gap: 12px; flex-wrap: wrap; margin: 8px 0;
|
| 463 |
justify-content: center; }
|
| 464 |
.view { text-align: center; }
|
|
|
|
| 465 |
.view img { max-height: 260px; border: 1px solid #ddd; border-radius: 4px;
|
| 466 |
-
background: #fff; }
|
| 467 |
.view span { display: block; font-size: 0.72em; color: #888; margin-top: 4px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 468 |
.input-img { display: block; margin: 0 auto; max-height: 620px; max-width: 100%;
|
| 469 |
border: 1px solid #ddd; border-radius: 6px; }
|
| 470 |
|
|
|
|
| 47 |
|
| 48 |
import yaml
|
| 49 |
|
| 50 |
+
from cadgenbench.common.axes_gizmo import gizmo_svg
|
| 51 |
+
|
| 52 |
logger = logging.getLogger(__name__)
|
| 53 |
|
| 54 |
# Canonical render views shown in the input / ground-truth grids, in
|
|
|
|
| 117 |
``url_for(view)`` returns the image URL for a given view. Missing
|
| 118 |
renders hide themselves via the ``onerror`` hook, so an absent view
|
| 119 |
leaves no gap rather than a broken-image icon.
|
| 120 |
+
|
| 121 |
+
Each tile carries a small orientation gizmo overlaid in the corner (see
|
| 122 |
+
:func:`cadgenbench.common.axes_gizmo.gizmo_svg`) so the world X/Y/Z
|
| 123 |
+
directions the editing prompts refer to are readable. The gizmo is keyed off
|
| 124 |
+
the view name and is part-independent, so no per-fixture render is needed.
|
| 125 |
"""
|
| 126 |
parts = ['<div class="images">']
|
| 127 |
for v in VIEWS:
|
| 128 |
url = url_for(v)
|
| 129 |
+
giz = gizmo_svg(v)
|
| 130 |
+
giz_html = f'<span class="axis-giz">{giz}</span>' if giz else ""
|
| 131 |
parts.append(
|
| 132 |
+
f'<div class="view"><span class="imgwrap">'
|
| 133 |
+
f'<img loading="lazy" decoding="async" '
|
| 134 |
f'src="{html.escape(url, quote=True)}" alt="{v}" '
|
| 135 |
+
f'onerror="taskImgFail(this)">{giz_html}</span>'
|
| 136 |
+
f"<span>{v}</span></div>"
|
| 137 |
)
|
| 138 |
parts.append("</div>")
|
| 139 |
return "\n".join(parts)
|
|
|
|
| 473 |
.images { display: flex; gap: 12px; flex-wrap: wrap; margin: 8px 0;
|
| 474 |
justify-content: center; }
|
| 475 |
.view { text-align: center; }
|
| 476 |
+
.view .imgwrap { position: relative; display: inline-block; line-height: 0; }
|
| 477 |
.view img { max-height: 260px; border: 1px solid #ddd; border-radius: 4px;
|
| 478 |
+
background: #fff; display: block; }
|
| 479 |
.view span { display: block; font-size: 0.72em; color: #888; margin-top: 4px; }
|
| 480 |
+
/* Orientation gizmo overlaid in the corner of each render tile (pinned to the
|
| 481 |
+
image via the inline-block wrapper). */
|
| 482 |
+
.axis-giz { position: absolute; left: 4px; bottom: 4px; pointer-events: none;
|
| 483 |
+
line-height: 0; }
|
| 484 |
.input-img { display: block; margin: 0 auto; max-height: 620px; max-width: 100%;
|
| 485 |
border: 1px solid #ddd; border-radius: 6px; }
|
| 486 |
|