"""Render recorded probe geometry for inspection; this is not a desktop screenshot. Usage: python render_probe.py PROBE_STDOUT_JSONL NEW_OUTPUT_DIRECTORY Uses one scale across every result for each fixture; input geometry is unchanged. """ from pathlib import Path import hashlib import json import sys from PIL import Image, ImageDraw, ImageFont def geometries(value, name=""): if not isinstance(value, dict): return if "routed_edges" in value and "projected_nodes" in value: yield name, value return for key, child in value.items(): yield from geometries(child, f"{name}.{key}".strip(".")) source, output = map(Path, sys.argv[1:]) output.mkdir(parents=True, exist_ok=False) font = ImageFont.truetype("C:/Windows/Fonts/arial.ttf", 13) files = [] for line in source.read_text(encoding="utf-8").splitlines(): item = json.loads(line) fixture = item.get("fixture") if not fixture: continue variants = list(geometries(item)) if not variants: continue largest_width = max(g["drawing_bounds"]["size"]["width"] for _, g in variants) largest_height = max(g["drawing_bounds"]["size"]["height"] for _, g in variants) scale = min(1.0, 1140 / max(1, largest_width), 690 / max(1, largest_height)) for name, geometry in variants: canvas = Image.new("RGB", (1200, 800), "white") draw = ImageDraw.Draw(canvas) origin = geometry["drawing_bounds"]["position"] def point(position): return (30 + (position["x"] - origin["x"]) * scale, 70 + (position["y"] - origin["y"]) * scale) def rectangle(position, size): x, y = point(position) return x, y, x + size["width"] * scale, y + size["height"] * scale draw.text((20, 12), f"{fixture} / {name} | geometry only, not native UI", font=font, fill="black") draw.text((20, 32), f"Fixed fixture scale {scale:.4f}; text below identifies bounds, not glyph measurements", font=font, fill="black") for node in sorted(geometry["projected_nodes"], key=lambda n: (n["depth"], n["id"])): box = rectangle(node["position"], node["size"]) draw.rectangle(box, fill="#eef2f6", outline="#687787", width=1) draw.text((box[0] + 3, box[1] + 3), node["id"][-5:], font=font, fill="#334155") for edge in geometry["routed_edges"]: points = [point(p) for p in edge["points"]] if len(points) > 1: draw.line(points, fill="#245c88", width=2) label = edge["label"] if label["text"]: box = rectangle(label["position"], label["size"]) draw.rectangle(box, outline="#ad5715", width=1) target = output / f"{fixture}-{name.replace('.', '-')}.png" canvas.save(target) files.append({"name": target.name, "bytes": target.stat().st_size, "sha256": hashlib.sha256(target.read_bytes()).hexdigest(), "scale": scale}) (output / "manifest.json").write_text(json.dumps({ "input_sha256": hashlib.sha256(source.read_bytes()).hexdigest(), "renderer_sha256": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), "scope": "Offline schematic of recorded core geometry; no native or font-rendering acceptance.", "images": files}, indent=2) + "\n", encoding="utf-8") print(f"Rendered {len(files)} geometry records without modifying the probe output.")