Code4Scene / scripts /t2s_gallery.py
KoeYe's picture
Claude Opus 5.5
Text-to-Scene: four more finished runs (19 configurations); Xiaomi mark; open-weights tags
0c7052b verified
Raw History Blame Contribute Delete
15.3 kB
#!/usr/bin/env python3
"""The Text-to-Scene gallery: what every shown configuration built on each of the 20 scenes (user, 2026-10-16:
"gallery可以放上去").
The internal leaderboard's gallery, rebuilt for this site: the evaluator's four candidate renders per model and case
(the benchmark's own cameras, 1280x720), with the case score and cost. Only the configurations on the leaderboard
(data/t2s-sandbox.json, written by scripts/t2s_sandbox_round.py, so run that first); nothing internal (paths, judge
notes, clips) is carried over. Pages:
gallery/index.html the agents, in leaderboard order, each with a strip of fixed scenes
gallery/cases.html scene by scene: every agent's view-0 render, best first; a click shows all four views
gallery/model/<key>.html one agent: its 20 scenes, each with the four renders, score, components and cost
Renders are re-encoded as WebP (1280 px at q72, 480 px thumbnails at q70): about 120 kB a view instead of 260 kB,
with no visible difference at full size. Encoding is incremental.
python3 scripts/t2s_gallery.py --src ../t2s-src
"""
from __future__ import annotations
import argparse
import html
import json
import math
import re
import shutil
from concurrent.futures import ProcessPoolExecutor
from pathlib import Path
from PIL import Image
ROOT = Path(__file__).resolve().parent.parent
OUT = ROOT / "gallery"
V = "20261016t2s"
STRIP = ["blue-city", "cyberpunk", "egyptian-temple", "nordic-harbour", "winter-town"] # the same five for everyone
CSS_V, PAPER_CSS = V, "5427505a"
e = html.escape
def trunc(x: float, n: int = 3) -> str:
return f"{math.floor(x * 10 ** n + 1e-9) / 10 ** n:.{n}f}"
def money(x):
return f"${x:.2f}" if x is not None else "–"
# ---- renders -------------------------------------------------------------------------------------------------
def encode(job):
src, full, thumb = job
if full.exists() and thumb.exists() and full.stat().st_mtime >= src.stat().st_mtime:
return 0
full.parent.mkdir(parents=True, exist_ok=True)
im = Image.open(src).convert("RGB")
im.save(full, "WEBP", quality=72, method=6)
t = im.resize((480, round(480 * im.height / im.width)), Image.LANCZOS)
t.save(thumb, "WEBP", quality=70, method=6)
return 1
def renders(src: Path, D: dict, internal: dict) -> None:
jobs, keep = [], set()
for m in D["models"]:
for c in D["cases"]:
for v in range(4):
s = src / "img" / internal[m["name"]] / c["id"] / f"v{v}.jpg"
assert s.exists(), s
full = OUT / "img" / m["key"] / c["slug"] / f"v{v}.webp"
thumb = full.with_name(f"v{v}_t.webp")
jobs.append((s, full, thumb))
keep |= {full, thumb}
with ProcessPoolExecutor() as ex:
n = sum(ex.map(encode, jobs, chunksize=8))
for f in (OUT / "img").rglob("*.webp"): # a configuration that left the leaderboard
if f not in keep:
f.unlink()
for d in sorted((OUT / "img").rglob("*"), reverse=True):
if d.is_dir() and not any(d.iterdir()):
d.rmdir()
print(f"renders: {n} encoded, {len(jobs) - n} unchanged")
# ---- pages ---------------------------------------------------------------------------------------------------
def page(root: str, title: str, desc: str, body: str) -> str:
nav = (f'<header class="site-header"><div class="brand"><a aria-label="Code4Scene home" class="brand-home" href="{root}index.html#top">'
'<svg aria-hidden="true" fill="none" viewbox="0 0 30 32"><path d="M15 2 27 9v14l-12 7L3 23V9L15 2Z M3 9l12 7 12-7 M15 16v14 '
'M9 5.5l12 7v14 M21 5.5l-12 7v14" stroke="currentColor" stroke-linejoin="round" stroke-width="1.6"></path></svg>'
'<span>Code4Scene</span></a><a class="brand-by" href="https://simworld.org/">by SimWorld</a></div>'
f'<nav aria-label="Main navigation"><a href="{root}index.html#top">Benchmark</a><a href="{root}index.html#leaderboard">Leaderboard</a>'
f'<a href="{root}index.html#cases">Visualization</a><a class="nav-active" href="{root}gallery/index.html">Gallery</a>'
'<a href="https://arxiv.org/abs/2609.36777" rel="noopener" target="_blank">Paper ↗</a>'
'<a href="https://github.com/SimWorld-AI/Code4Scene" rel="noopener" target="_blank">Github ↗</a></nav></header>')
foot = ('<footer><p>Code4Scene · UC San Diego &amp; UC Berkeley · <a href="https://arxiv.org/abs/2609.36777" rel="noopener" '
'target="_blank">arXiv:2609.36777</a> · <a href="https://github.com/SimWorld-AI/Code4Scene" rel="noopener" target="_blank">'
'GitHub</a> · <a href="https://simworld.org/" rel="noopener" target="_blank">SimWorld Home</a></p></footer>')
return ('<!DOCTYPE html>\n<html lang="en"><head>\n<meta charset="utf-8"/><meta content="width=device-width,initial-scale=1" name="viewport"/>\n'
f'<title>{e(title)}</title><meta content="{e(desc)}" name="description"/>\n'
f'<link href="{root}assets/code4scene-mark.svg" rel="icon"/>\n'
f'<link href="{root}assets/paper.css?v={PAPER_CSS}" rel="stylesheet"/>\n'
f'<link href="{root}assets/buildingbench.css?v={CSS_V}" rel="stylesheet"/>\n'
f'<link href="{root}assets/gallery.css?v={V}" rel="stylesheet"/>\n'
f'</head><body class="gallery-page"><a class="skip-link" href="#main">Skip to the gallery</a>\n{nav}\n'
f'<main class="page-main" id="main">\n{body}\n</main>\n{foot}\n'
f'<script defer src="{root}assets/gallery.js?v={V}"></script>\n</body></html>\n')
def logo(svg: str, uid: str) -> str:
for gid in set(re.findall(r'id="([^"]+)"', svg)):
svg = svg.replace(f'id="{gid}"', f'id="{gid}{uid}"').replace(f"url(#{gid})", f"url(#{gid}{uid})")
return f'<span class="logo" aria-hidden="true">{svg}</span>'
def views(m: dict, c: dict, prefix: str, first_only: bool = False, chip: str = "") -> str:
"""The four renders as thumbnails linking to full size; gallery.js opens them in a viewer, grouped per agent and
scene. first_only: show view 1 and keep the other three as links the viewer steps through; chip: a score on it."""
group = f"{m['key']}/{c['slug']}"
out = []
for v in range(4):
base = f"{prefix}img/{m['key']}/{c['slug']}/v{v}"
cap = f"{m['name']} · {c['title']} · view {v + 1} of 4 · score {trunc(m['cases'][c['id']]['score'])}"
img = (f'<img alt="{e(cap)}" decoding="async" height="270" loading="lazy" src="{base}_t.webp?v={V}" width="480"/>'
if v == 0 or not first_only else "")
if v == 0 and chip:
img += f'<span class="gal-chip">{chip}</span>'
hidden = ' hidden=""' if first_only and v else ""
out.append(f'<a class="gimg" data-group="{e(group)}" data-caption="{e(cap)}" href="{base}.webp?v={V}"{hidden}>{img}</a>')
return f'<div class="{"gal-first" if first_only else "gal-views"}">{"".join(out)}</div>'
def brief(text: str) -> str:
return f'<p class="gal-brief">{e(text)}</p>'
def switcher(active: str) -> str:
link = lambda key, href, text: (f'<a aria-current="page" class="on" href="{href}">{text}</a>' if key == active
else f'<a href="{href}">{text}</a>')
return ('<nav aria-label="Browse the gallery" class="gal-switch">' + link("agent", "index.html", "By agent")
+ link("scene", "cases.html", "By scene") + "</nav>")
INTRO = ("What each configuration built on the 20 Research Track scenes in the October 2026 Text-to-Scene re-run, as the "
"evaluator saw it: four renders per scene from the benchmark's own cameras, with the case score and the agent's cost. "
"Scores are truncated to three decimals; a case without a valid scene scores 0.")
def basis_tip(m: dict) -> str:
why = m.get("cost_basis") or (m.get("cost_none") if m["cost"] is None else None)
return f' title="{e(m["name"])}: {e(why)}"' if why else ""
def basis_note(m: dict) -> str:
if m.get("cost_basis"):
return f'<p class="gal-note gal-basis">Cost: {e(m["cost_basis"])}.</p>'
if m["cost"] is None and m.get("cost_none"):
return f'<p class="gal-note gal-basis">No cost: {e(m["cost_none"])}.</p>'
return ""
def index_page(D: dict, logos: dict) -> str:
rows = []
for i, m in enumerate(D["models"]):
strip = "".join(f'<img alt="" decoding="async" height="270" loading="lazy" src="img/{m["key"]}/{s}/v0_t.webp?v={V}" width="480"/>'
for s in STRIP)
rows.append(f'<li><a class="gal-agent" href="model/{m["key"]}.html"><span class="rk">{i + 1}</span>'
f'<span class="who">{logo(logos[m["logo"]], f"G{i}")}<span><b>{e(m["name"])}</b><small>{e(m["org"])}</small></span></span>'
f'<span class="num"><small>Score</small><b>{trunc(m["score"])}</b></span>'
f'<span class="num"{basis_tip(m)}><small>Median cost</small>{money(m["cost"])}{"*" if m.get("cost_basis") else ""}</span>'
f'<span class="strip" aria-hidden="true">{strip}</span></a></li>')
names = ", ".join(D["titles"][s] for s in STRIP)
body = ('<section class="gal-top"><div class="container"><span class="section-label">Gallery</span>'
'<h1 class="section-title">Every scene, every agent</h1>'
f'<p class="section-desc">{e(INTRO)}</p>{switcher("agent")}</div></section>'
f'<section class="gal-body"><div class="container"><p class="gal-note">In leaderboard order. The strip shows the same five '
f'scenes for every agent: {e(names)}.</p><ol class="gal-agents">{"".join(rows)}</ol></div></section>')
return page("../", "Code4Scene · Gallery", "Every Text-to-Scene output of the October 2026 re-run, by agent.", body)
def cases_page(D: dict, logos: dict) -> str:
pills = "".join(f'<a href="#{c["slug"]}">{e(c["title"])}</a>' for c in D["cases"])
secs = []
for c in D["cases"]:
ranked = sorted(D["models"], key=lambda m: -m["cases"][c["id"]]["score"])
tiles = []
for j, m in enumerate(ranked):
r = m["cases"][c["id"]]
dot = f'<i aria-hidden="true" class="dot" style="background:{m["colour"]}"></i>' # 300 tiles: a dot, not the logo
tiles.append(f'<figure class="gal-tile">{views(m, c, "", True, trunc(r["score"]))}<figcaption>{dot}'
f'<a class="who" href="model/{m["key"]}.html#{c["slug"]}">{e(m["name"])}</a>'
f'<small>{money(r["cost"])}</small></figcaption></figure>')
secs.append(f'<section class="gal-case" id="{c["slug"]}"><div class="gal-case-head"><h2>{e(c["title"])}</h2>'
f'<a class="gal-up" href="#top-pills">All scenes ↑</a></div>{brief(c["brief"])}'
f'<div class="gal-grid">{"".join(tiles)}</div></section>')
body = ('<section class="gal-top"><div class="container"><span class="section-label">Gallery</span>'
'<h1 class="section-title">Every agent, scene by scene</h1>'
f'<p class="section-desc">{e(INTRO)} Agents are ordered by their score on the scene; click a render for all four views.</p>'
f'{switcher("scene")}<nav aria-label="Scenes" class="gal-pills" id="top-pills">{pills}</nav></div></section>'
f'<section class="gal-body"><div class="container">{"".join(secs)}</div></section>')
return page("../", "Code4Scene · Gallery by scene", "Every agent's Text-to-Scene output on each of the 20 scenes.", body)
def model_page(D: dict, i: int, logos: dict) -> str:
m = D["models"][i]
prev_, next_ = D["models"][i - 1] if i else None, D["models"][i + 1] if i + 1 < len(D["models"]) else None
pn = ('<nav aria-label="Other agents" class="gal-pn">'
+ (f'<a href="{prev_["key"]}.html">← {e(prev_["name"])}</a>' if prev_ else "<span></span>")
+ (f'<a href="{next_["key"]}.html">{e(next_["name"])} →</a>' if next_ else "<span></span>") + "</nav>")
stats = "".join(f'<div><small>{k}</small><b>{v}</b></div>' for k, v in (
("Rank", f'{i + 1} <span>of {len(D["models"])}</span>'), ("Score", trunc(m["score"])), ("Detailed", trunc(m["detailed"])),
("Overview", trunc(m["overview"])), ("Physical", trunc(m["physical"])), ("Median cost", money(m["cost"]))))
pills = "".join(f'<a href="#{c["slug"]}">{e(c["title"])}</a>' for c in D["cases"])
secs = []
for c in D["cases"]:
r = m["cases"][c["id"]]
comp = f'Detailed {trunc(r["detailed"])} · Overview {trunc(r["overview"])} · Physical {trunc(r["physical"])}'
secs.append(f'<section class="gal-case" id="{c["slug"]}"><div class="gal-case-head"><h2>{e(c["title"])}</h2>'
f'<span class="gal-score">{trunc(r["score"])}</span><span class="gal-comp">{comp}</span>'
f'<span class="gal-cost">{money(r["cost"])}</span>'
f'<a class="gal-up" href="../cases.html#{c["slug"]}">All agents on this scene →</a></div>'
f'{brief(c["brief"])}{views(m, c, "../")}</section>')
body = ('<section class="gal-top"><div class="container"><nav aria-label="Breadcrumb" class="gal-crumb"><a href="../index.html">Gallery</a> / '
f'<span>{e(m["name"])}</span></nav><h1 class="section-title gal-name">{logo(logos[m["logo"]], "H")}{e(m["name"])}</h1>'
f'<p class="section-desc">{e(m["org"])} · Text-to-Scene re-run, October 2026 · the 20 Research Track scenes, four '
f'renders each from the evaluator\'s cameras.</p><div class="gal-stats">{stats}</div>'
+ basis_note(m) +
f'<nav aria-label="Scenes" class="gal-pills">{pills}</nav></div></section>'
f'<section class="gal-body"><div class="container">{"".join(secs)}{pn}</div></section>')
return page("../../", f"Code4Scene · {m['name']} · Gallery",
f"What {m['name']} built on each of the 20 Text-to-Scene scenes, with scores and costs.", body)
def main() -> None:
ap = argparse.ArgumentParser(description=__doc__.split("\n")[0])
ap.add_argument("--src", type=Path, required=True)
a = ap.parse_args()
D = json.loads((ROOT / "data/t2s-sandbox.json").read_text())
D["titles"] = {c["slug"]: c["title"] for c in D["cases"]}
internal = {m["name"]: m["key"] for m in json.loads((a.src / "data.json").read_text())["models"]}
import subprocess
logos = json.loads(subprocess.run(
["node", "-e", "global.window={};eval(require('fs').readFileSync(process.argv[1],'utf8'));"
"process.stdout.write(JSON.stringify(window.SITE.logos))", str(ROOT / "data/site.js")],
capture_output=True, text=True, check=True).stdout)
OUT.mkdir(exist_ok=True)
renders(a.src, D, internal)
(OUT / "index.html").write_text(index_page(D, logos))
(OUT / "cases.html").write_text(cases_page(D, logos))
md = OUT / "model"
if md.exists():
shutil.rmtree(md)
md.mkdir()
for i, m in enumerate(D["models"]):
(md / f"{m['key']}.html").write_text(model_page(D, i, logos))
print(f"gallery: {len(D['models'])} agents x {len(D['cases'])} scenes, {len(D['models']) + 2} pages")
if __name__ == "__main__":
main()