#!/usr/bin/env python3 """Generate a small self-contained data HTML viewer (Three.js loads from CDN).""" import argparse, base64, io, json, sys from pathlib import Path import numpy as np from PIL import Image ROOT=Path(__file__).resolve().parents[1] parser=argparse.ArgumentParser(description=__doc__) parser.add_argument("--height",type=Path,default=ROOT/"outputs/gamus_aligned_height.npy") parser.add_argument("--rgb",type=Path,default=ROOT/"gamus_rgb.png") parser.add_argument("--output",type=Path,default=ROOT/"outputs/terrain_viewer.html") parser.add_argument("--max-size",type=int,default=256) args=parser.parse_args() def abs_path(p): return p if p.is_absolute() else (Path.cwd()/p).resolve() try: h=np.load(abs_path(args.height),allow_pickle=False).astype(np.float32) h=Image.fromarray(h).resize((args.max_size,args.max_size),Image.Resampling.BILINEAR) h=np.asarray(h,dtype=np.float32) image=Image.open(abs_path(args.rgb)).convert("RGB").resize((args.max_size,args.max_size),Image.Resampling.BILINEAR) buf=io.BytesIO(); image.save(buf,format="PNG"); texture=base64.b64encode(buf.getvalue()).decode() payload=json.dumps(h.flatten().tolist(),separators=(",",":")) html=f'''DepthWizard terrain preview
DepthWizard terrain preview
Sample-fitted GAMUS surface — not deployment-calibrated elevation
Drag: rotate · wheel: zoom · W/A/S/D: fly · click: inspect height
Height exaggeration
''' out=abs_path(args.output);out.parent.mkdir(parents=True,exist_ok=True);out.write_text(html) print(f"Viewer: {out}\nGrid: {args.max_size} × {args.max_size}; surface range {float(h.min()):.3f}–{float(h.max()):.3f}") except Exception as exc: parser.exit(1,f"Error: {exc}\n")