#!/usr/bin/env python3 """Export v24 ring meshes at matching LOD windows and retain old controls.""" import csv import re import subprocess import time from pathlib import Path ROOT = Path(__file__).resolve().parents[4] OUT = ROOT / "Saved/Linux/l37" BIN = OUT / "bin/VoxelForgeCoreHeadless-l37-final-clang" OWNER = ROOT / "Standalone/data/owner_world.json" TERRACE = ROOT / "Standalone/Research/WorldAssemblerM3/Linux32/AuditRingTerraceL32.py" RING_SET = ROOT / "Standalone/Research/WorldAssemblerM3/Linux32/AuditRingSetL32.py" STAMP = re.compile( r"^\[WorldAssemblerRecipeAudit\] requested=([^ ]+) actual=([^ ]+).*status=PASS$", re.M) EXPORT = re.compile(r"^\[MeshSceneExport\].*status=PASS", re.M) TERRACE_RESULT = re.compile(r"^\[RingTerraceAudit\].*status=(PASS|FAIL)$", re.M) SET_RESULT = re.compile(r"^\[RingSetAudit\].*status=(PASS|FAIL)$", re.M) rows = [] failed = False FI_CENTERS = ((56, -72), (72, -72), (56, -88), (40, -72), (24, 24), (104, 24), (72, -88), (120, 24), (104, 8), (24, -24)) SW_CENTERS = ((-136, 136), (-56, 152), (-152, 120), (-136, 120), (-152, 104), (-136, 104), (-40, 152)) LOD_CENTERS = { "fi-floor": { 2: (16, -144), 3: (224, -160), 4: (-448, 448), 5: (-128, -640), 6: (-1792, 1280), 7: (3584, 1536), 8: (3072, 7168), }, "sw-ceiling": { 2: (16, -144), 3: (224, -160), 4: (-448, 448), 5: (-128, -640), 6: (-1792, 1280), 7: (2560, -512), 8: (3072, 7168), }, } def run(name, command): log = OUT / f"ring-{name}.log" wrapped = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--", "timeout", "1800s", *map(str, command)] started = time.monotonic() try: with log.open("w", encoding="utf-8") as stream: result = subprocess.run(wrapped, cwd=ROOT, stdout=stream, stderr=subprocess.STDOUT, timeout=1800, check=False) except subprocess.TimeoutExpired: result = None elapsed = time.monotonic() - started output = log.read_text(encoding="utf-8", errors="replace") code = result.returncode if result is not None else "TIMEOUT" print(f"[L37RingStep] name={name} elapsed={elapsed:.1f}s exit={code} log={log}", flush=True) return result, output, elapsed def export(label, recipe, max_level, camera): mesh = OUT / f"ring-owner-{label}-v24.vfmesh" command = [BIN, OWNER, "--workers=12", "--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline", "--force-generate", "--clip-radius=3", "--max-clip-level=8", f"--max-level={max_level}", f"--recipe={recipe}"] if camera: command.append(f"--camera={camera}") command.append(f"--mesh-export={mesh}") result, output, elapsed = run(f"export-{label}", command) stamps = STAMP.findall(output) ok = (result is not None and result.returncode == 0 and stamps == [(recipe, recipe)] and EXPORT.search(output) and mesh.is_file()) print(f"[L37RingExport] scene={label} recipe={recipe} stamp={stamps} " f"bytes={mesh.stat().st_size if mesh.exists() else 0} " f"status={'PASS' if ok else 'FAIL'}", flush=True) return mesh, elapsed, ok def terrace(label, recipe, surface, mesh, lod, height_min, height_max, center=(64, -32), radius=32): result, output, elapsed = run(f"{label}-lod{lod}", ["python3", TERRACE, mesh, f"--surface={surface}", "--center", str(center[0]), str(center[1]), f"--radius={radius}", f"--lod={lod}", f"--height-min-m={height_min}", f"--height-max-m={height_max}"]) statuses = TERRACE_RESULT.findall(output) ok = (result is not None and result.returncode == 0 and statuses == ["PASS"]) rows.append((label, recipe, surface, lod, elapsed, ok)) print(f"[L37RingAuditRun] scene={label} recipe={recipe} surface={surface} " f"lod={lod} center={center} radius={radius} " f"status={'PASS' if ok else 'FAIL'}", flush=True) return ok def lod1_set(label, recipe, surface, mesh, centers, height_min, height_max): command = ["python3", RING_SET, mesh, f"--surface={surface}"] for x, y in centers: command.extend(("--center", str(x), str(y))) command.extend(("--radius=8", "--lod=1", f"--height-min-m={height_min}", f"--height-max-m={height_max}")) result, output, elapsed = run(f"{label}-lod1-set", command) statuses = SET_RESULT.findall(output) ok = (result is not None and result.returncode == 0 and statuses == ["PASS"]) rows.append((label, recipe, surface, 1, elapsed, ok)) print(f"[L37RingAuditRun] scene={label} recipe={recipe} surface={surface} " f"lod=1 windows={len(centers)} status={'PASS' if ok else 'FAIL'}", flush=True) return ok for label, recipe, surface, window_min, window_max, camera0, camera1, centers in ( ("fi-floor", "floating-islands", "floor", -122.0, -117.0, "64,-32,-115,0,-45", "64,-32,-115,0,-45", FI_CENTERS), ("sw-ceiling", "surface-world", "ceiling", -132.0, -124.0, "64,-32,-136,0,45", "-96,128,-136,0,45", SW_CENTERS)): low_mesh, _, low_ok = export(f"{label}-lod0", recipe, 0, camera0) failed |= not low_ok if low_ok: failed |= not terrace(label, recipe, surface, low_mesh, 0, window_min, window_max) detail_mesh, _, detail_ok = export(f"{label}-lod1", recipe, 1, camera1) failed |= not detail_ok if detail_ok: set_min, set_max = ((-121.625, -117.375) if label == "fi-floor" else (-128.375, -124.125)) failed |= not lod1_set(label, recipe, surface, detail_mesh, centers, set_min, set_max) full_mesh, _, full_ok = export(f"{label}-lod2-8", recipe, 8, None) failed |= not full_ok if full_ok: for lod in range(2, 9): center = LOD_CENTERS[label][lod] radius = 4 * (1 << lod) failed |= not terrace(label, recipe, surface, full_mesh, lod, window_min, window_max, center, radius) # Keep the established L30 terrace and L31 flat-surface negative controls live. controls = ( ("l30-terrace", ROOT / "Saved/Linux/l32/fi-floor-l30-camera-negative.vfmesh", -130.0, -110.0), ("l31-flat", ROOT / "Saved/Linux/l31/fi-floor-v19.vfmesh", -122.0, -117.0), ) for name, mesh, height_min, height_max in controls: result, output, _ = run(f"control-{name}", ["python3", TERRACE, mesh, "--surface=floor", "--center", "64", "-32", "--radius=32", "--lod=0", f"--height-min-m={height_min}", f"--height-max-m={height_max}"]) statuses = TERRACE_RESULT.findall(output) detected = (result is not None and result.returncode == 1 and statuses == ["FAIL"]) failed |= not detected print(f"[L37RingControl] name={name} detected={detected} " f"status={'PASS' if detected else 'FAIL'}", flush=True) summary = OUT / "ring-audits-l37.csv" with summary.open("w", newline="", encoding="utf-8") as stream: writer = csv.writer(stream) writer.writerow(("scene", "recipe", "surface", "lod", "elapsed_seconds", "status")) writer.writerows((label, recipe, surface, lod, f"{elapsed:.3f}", "PASS" if ok else "FAIL") for label, recipe, surface, lod, elapsed, ok in rows) print(f"[L37RingSummary] runs={len(rows)} pass={sum(row[-1] for row in rows)} " f"fail={sum(not row[-1] for row in rows)} controls=2 " f"status={'FAIL' if failed else 'PASS'} summary={summary}", flush=True) raise SystemExit(1 if failed or len(rows) != 18 else 0)