#!/usr/bin/env python3 """Render the six L129 b96dd73 mouth views against the L130 meshes.""" from __future__ import annotations import hashlib import html import json import re import subprocess import time from pathlib import Path ROOT = Path(__file__).resolve().parents[4] SOURCE = ROOT / "Saved/Linux/l129/captures/mouth-closeups/before" SAVED = ROOT / "Saved/Linux/l130/captures/mouth-closeups" CAPTURES = ROOT / "Standalone/Research/WorldAssemblerM3/Linux130/captures/mouth-closeups" DATA = ROOT / "Standalone/data/owner_world.json" HEADLESS = ROOT / "Saved/Linux/l130/bin/VoxelForgeCoreHeadless-l130-clang" RENDERER = ROOT / "Saved/Linux/l130/bin/VoxelForgeOffscreenCapture-l130-clang" HEADLESS_CONFIG = re.compile( r"^\[HeadlessConfig\].*?camera_m=\(([^)]*)\) camera_rotation_deg=\(([^)]*)\)", re.M) SCENE = re.compile(r"^\[OffscreenScene\].*?height_center_m=(-?[\d.]+)", re.M) DRAWN = re.compile(r"drawn_triangles=(\d+)") def wrapped(command: list[str]) -> list[str]: return ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--", "timeout", "1740s", *map(str, command)] def run(label: str, command: list[str], log: Path) -> str: started = time.monotonic() log.parent.mkdir(parents=True, exist_ok=True) with log.open("w", encoding="utf-8") as output: result = subprocess.run(wrapped(command), cwd=ROOT, stdout=output, stderr=subprocess.STDOUT, check=False, timeout=1740) content = log.read_text(encoding="utf-8", errors="replace") if result.returncode: raise SystemExit(f"{label} failed exit={result.returncode}: {log}") print(f"[L130MouthProcess] {label} elapsed_s={time.monotonic()-started:.2f}", flush=True) return content def parse_vector(text: str) -> tuple[float, ...]: return tuple(float(value) for value in text.split(",")) def sha256(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() def main() -> int: if any(not path.is_file() for path in (DATA, HEADLESS, RENDERER)): raise SystemExit("missing L130 mouth capture input") (CAPTURES / "b96dd73").mkdir(parents=True, exist_ok=True) (CAPTURES / "L130").mkdir(parents=True, exist_ok=True) rows = [] for source_log in sorted(SOURCE.glob("*-mouth-mesh.log")): name = source_log.name.removesuffix("-mesh.log") source_render = SOURCE / f"{name}-render.log" baseline_mesh = SOURCE / f"{name}.vfmesh" if not all(path.is_file() for path in (source_render, baseline_mesh)): raise SystemExit(f"missing b96dd73 source artifact for {name}") config = HEADLESS_CONFIG.search(source_log.read_text()) scene = SCENE.search(source_render.read_text()) if config is None or scene is None: raise SystemExit(f"missing camera metadata for {name}") camera = parse_vector(config.group(1)) yaw, pitch = parse_vector(config.group(2)) height_center = float(scene.group(1)) camera_arg = ",".join(f"{value:.6f}" for value in (*camera, yaw, pitch)) candidate_mesh = SAVED / "L130" / f"{name}.vfmesh" candidate_mesh.parent.mkdir(parents=True, exist_ok=True) run(f"{name}-mesh", [HEADLESS, DATA, "--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline", "--workers=12", "--clip-radius=3", "--max-clip-level=0", "--max-level=0", "--force-generate", "--recipe=surface-world", f"--camera={camera_arg}", "--render-distance-chunks=1", f"--mesh-export={candidate_mesh}"], SAVED / "L130" / f"{name}-mesh.log") if not candidate_mesh.is_file() or candidate_mesh.stat().st_size == 0: raise SystemExit(f"empty L130 mesh for {name}") render_args = ["--size=1920x1080", f"--camera-m={','.join(f'{value:.6f}' for value in camera)}", f"--yaw-deg={yaw:.6f}", f"--pitch-deg={pitch:.6f}", "--shade=readable", "--headlamp=on", "--height-tint=on", f"--height-center-m={height_center:.6f}", "--height-range-m=32"] images = {} draw_counts = {} for variant, mesh in (("b96dd73", baseline_mesh), ("L130", candidate_mesh)): image = CAPTURES / variant / f"{name}.png" render_log = SAVED / variant / f"{name}-render.log" content = run(f"{name}-{variant}-render", [RENDERER, mesh, image, *render_args], render_log) drawn = DRAWN.search(content) if drawn is None or int(drawn.group(1)) <= 0 or not image.is_file(): raise SystemExit(f"render has no visible triangles for {name}/{variant}") images[variant] = image draw_counts[variant] = int(drawn.group(1)) equal = images["b96dd73"].read_bytes() == images["L130"].read_bytes() row = {"name": name, "camera_m": camera, "yaw_deg": yaw, "pitch_deg": pitch, "height_center_m": height_center, "source_mesh": str(baseline_mesh.relative_to(ROOT)), "candidate_mesh": str(candidate_mesh.relative_to(ROOT)), "baseline_png": str(images["b96dd73"].relative_to(ROOT)), "candidate_png": str(images["L130"].relative_to(ROOT)), "baseline_sha256": sha256(images["b96dd73"]), "candidate_sha256": sha256(images["L130"]), "byte_identical": equal, "drawn_triangles": draw_counts} rows.append(row) print(f"[L130MouthCompare] {name} byte_identical={equal} " f"sha256={row['candidate_sha256']}", flush=True) if len(rows) != 6: raise SystemExit(f"expected six L129 mouth views, found {len(rows)}") (CAPTURES / "summary.json").write_text(json.dumps(rows, indent=2) + "\n") sections = [] for row in rows: name = html.escape(row["name"]) sections.append(f"

{name}

byte identical: " f"{str(row['byte_identical']).lower()}

" f"
b96dd73 source mesh
" f"
L130 reach units
" "
") page = ("L130 mouth closeups" "" "

L129 mouth closeups: b96dd73 vs L130

" + "\n".join(sections)) (CAPTURES / "COMPARE.html").write_text(page) return 0 if all(row["byte_identical"] for row in rows) else 1 if __name__ == "__main__": raise SystemExit(main())