#!/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/.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 = "20261017logo", "5427505a" # buildingbench.css as scripts/simworld_logo.py last versioned it MARK = "assets/simworld-mark.png?v=20261017logo" # the SimWorld emblem (scripts/simworld_logo.py) 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'') foot = ('') return ('\n\n\n' f'{e(title)}\n' f'\n' f'\n' f'\n' f'\n' f'\n{nav}\n' f'
\n{body}\n
\n{foot}\n' f'\n\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'' 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'{e(cap)}' if v == 0 or not first_only else "") if v == 0 and chip: img += f'{chip}' hidden = ' hidden=""' if first_only and v else "" out.append(f'{img}') return f'
{"".join(out)}
' def brief(text: str) -> str: return f'

{e(text)}

' def switcher(active: str) -> str: link = lambda key, href, text: (f'{text}' if key == active else f'{text}') return ('") 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'

Cost: {e(m["cost_basis"])}.

' if m["cost"] is None and m.get("cost_none"): return f'

No cost: {e(m["cost_none"])}.

' return "" def index_page(D: dict, logos: dict) -> str: rows = [] for i, m in enumerate(D["models"]): strip = "".join(f'' for s in STRIP) rows.append(f'
  • {i + 1}' f'{logo(logos[m["logo"]], f"G{i}")}{e(m["name"])}{e(m["org"])}' f'Score{trunc(m["score"])}' f'Median cost{money(m["cost"])}{"*" if m.get("cost_basis") else ""}' f'
  • ') names = ", ".join(D["titles"][s] for s in STRIP) body = ('
    ' '

    Every scene, every agent

    ' f'

    {e(INTRO)}

    {switcher("agent")}
    ' f'

    In leaderboard order. The strip shows the same five ' f'scenes for every agent: {e(names)}.

      {"".join(rows)}
    ') 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'{e(c["title"])}' 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'' # 300 tiles: a dot, not the logo tiles.append(f'
    {views(m, c, "", True, trunc(r["score"]))}
    {dot}' f'{e(m["name"])}' f'{money(r["cost"])}
    ') secs.append(f'

    {e(c["title"])}

    ' f'All scenes ↑
    {brief(c["brief"])}' f'
    {"".join(tiles)}
    ') body = ('
    ' '

    Every agent, scene by scene

    ' f'

    {e(INTRO)} Agents are ordered by their score on the scene; click a render for all four views.

    ' f'{switcher("scene")}
    ' f'
    {"".join(secs)}
    ') 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 = ('") stats = "".join(f'
    {k}{v}
    ' for k, v in ( ("Rank", f'{i + 1} of {len(D["models"])}'), ("Score", trunc(m["score"])), ("Detailed", trunc(m["detailed"])), ("Overview", trunc(m["overview"])), ("Physical", trunc(m["physical"])), ("Median cost", money(m["cost"])))) pills = "".join(f'{e(c["title"])}' 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'

    {e(c["title"])}

    ' f'{trunc(r["score"])}{comp}' f'{money(r["cost"])}' f'All agents on this scene →
    ' f'{brief(c["brief"])}{views(m, c, "../")}
    ') body = ('

    {logo(logos[m["logo"]], "H")}{e(m["name"])}

    ' f'

    {e(m["org"])} · Text-to-Scene re-run, October 2026 · the 20 Research Track scenes, four ' f'renders each from the evaluator\'s cameras.

    {stats}
    ' + basis_note(m) + f'
    ' f'
    {"".join(secs)}{pn}
    ') 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()