Code4Scene / scripts /harbor_live.py
KoeYe's picture
Claude Opus 5.5
Industrial Harbor card on the same live three.js viewer as the other cases
e998ba1
Raw History Blame Contribute Delete
5.3 kB
"""The Industrial Harbor card in the same live three.js viewer as the other cards (user, 2026-10-04: "你把IndustrialHarbor的threejs弄的和其他人一样啊").
GPT-6 Astra's scored harbor (EVAL gpt-6-astra-max, map scenebench_industrial_harbor__20260907_214132, the scene the viewer
Space shows) was staged and exported to GLB on serv6 (code4scene-video/scripts/export_glb_harbor.sh, with the ContainerYard,
Hangar and FactoryEnvironment packs linked from scenebench-content), then compressed as website/compress_glb.sh does for
Text-to-Scene scenes (meshopt geometry, 512 px WebP). The harbor has no case in data/site.js (no score), so its card names
its packed model itself (data-glb) and scene-cards.js reads that before looking up a case. The live scene replaces the still
(media/t2s/industrial-harbor/astra.jpg, removed); the card's link still opens the full-resolution viewer Space.
Each step asserts it found what it edits.
GLB=<compressed industrial-harbor__astra.glb> python3 scripts/harbor_live.py
"""
from __future__ import annotations
import hashlib, json, os, re, shutil, sys
from pathlib import Path
import numpy as np
from bs4 import BeautifulSoup
ROOT = Path(__file__).resolve().parent.parent
GLB = Path(os.environ["GLB"])
V = "20261004harborlive"
KEY = bytes.fromhex("5c2f9e71d3a84b06e1f7c29a38d05b64a7193ce8f2046db95e81c73a2df6904b") # website/pack_models.py
def one(found, what):
assert found, f"not found: {what}"
return found
def pack():
assert GLB.name == "industrial-harbor__astra.glb", GLB.name
a = np.frombuffer(GLB.read_bytes(), np.uint8); idx = np.arange(a.size, dtype=np.int64)
ks = np.frombuffer(KEY, np.uint8)[idx % 32] ^ ((idx // 32) * 131 & 255).astype(np.uint8)
dst = ROOT / "models" / f"{hashlib.sha256(b'c4s-model:' + GLB.name.encode()).hexdigest()[:20]}.bin"
dst.write_bytes((a ^ ks).tobytes())
url = f"models/{dst.name}?v={int(dst.stat().st_mtime)}"
print("packed", url, round(dst.stat().st_size / 1e6, 1), "MB")
return url
def progressive(url):
"""build_progressive.py's geometry-first derivative, when textures are a real share of the file (as i2s_more_cases.py)"""
sys.path.insert(0, str(ROOT / "scripts"))
import build_progressive as bp
from i2s_more_cases import texture_share
share = texture_share(ROOT / url.split("?")[0])
print("texture share", round(share, 3))
if share < 0.1:
return
shutil.copyfile(ROOT / url.split("?")[0], bp.CACHE / url.split("/")[-1].split("?")[0])
m = ROOT / "data/progressive-scenes.json"; d = json.loads(m.read_text())
d.update([bp.convert(url)]); m.write_text(json.dumps(d, indent=2) + "\n")
cu = ROOT / "scripts/progressive-card-urls.json"; cu.write_text(json.dumps(json.loads(cu.read_text()) + [url]) + "\n")
def scene_cards():
p = ROOT / "assets/scene-cards.js"; s = p.read_text()
a = " const c=window.SITE.cases.find(c=>c.id===el.dataset.case),a=c.agents.find(a=>a.key===el.dataset.agent);\n"
assert s.count(a) == 1, "mount() case lookup"
s = s.replace(a, " // a showcase card names its model itself (data-glb): it has no case, score or case-explorer entry in data/site.js\n"
" const c=el.dataset.glb?{agents:[{key:el.dataset.agent,glb:el.dataset.glb}]}:window.SITE.cases.find(c=>c.id===el.dataset.case),a=c.agents.find(a=>a.key===el.dataset.agent);\n")
p.write_text(s); print("scene-cards.js: data-glb")
CSS = """
/* the featured card's live scene (scripts/harbor_live.py) */
.case-feature .live-scene{height:auto;min-height:400px;border-radius:16px 0 0 16px}
@media(max-width:900px){.case-feature .live-scene{min-height:0;height:270px;border-radius:16px 16px 0 0}}
"""
def index(url):
p = ROOT / "index.html"
soup = BeautifulSoup(p.read_text(), "html.parser")
card = one(soup.find(class_="case-feature"), "harbor card")
shot = one(card.find(class_="feature-shot"), "harbor still")
shot.replace_with(BeautifulSoup(
f'<div class="live-scene" data-agent="astra" data-case="industrial-harbor" data-glb="{url}"><canvas aria-label="Interactive 3D scene: '
'Industrial Harbor. Drag to orbit, scroll or use plus and minus to zoom." tabindex="0"></canvas><span class="scene-loading" role="status">'
'Loading 3D scene…</span><span class="scene-hint">Drag to orbit · Scroll to zoom</span><button aria-label="Pause scene rotation" '
'class="scene-motion">Ⅱ</button></div>', "html.parser"))
one(card.find("p"), "harbor line").string = "GPT-6 Astra (max) · 3,949 actors, built in one agent session from an empty 130 m stage"
one(card.find(class_="text-button"), "harbor link").string = "Open at full texture resolution ↗"
for t in soup.find_all(["script", "link"]):
a = "src" if t.name == "script" else "href"
u = t.get(a) or ""
if re.match(r"assets/(buildingbench\.css|scene-cards\.js)", u):
t[a] = re.sub(r"\?v=.*$", "", u) + f"?v={V}"
p.write_text(str(soup)); print("index.html: harbor card on the live viewer")
css = ROOT / "assets/buildingbench.css"; s = css.read_text()
assert "scripts/harbor_live.py" not in s
css.write_text(s.rstrip("\n") + "\n" + CSS)
if __name__ == "__main__":
url = pack(); progressive(url); scene_cards(); index(url)