Spaces:
Running
Running
Download scripts/t2s_gallery.py from SimWorld-AI/Code4Scene: direct link, hf CLI and curl.
- Browser
- Download file 15.3 kB
-
https://huggingface.co/spaces/SimWorld-AI/Code4Scene/resolve/main/scripts/t2s_gallery.py
- Command line
-
hf download hf://spaces/SimWorld-AI/Code4Scene/scripts/t2s_gallery.py
-
curl -L -o t2s_gallery.py https://huggingface.co/spaces/SimWorld-AI/Code4Scene/resolve/main/scripts/t2s_gallery.py
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 & 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() | |