| |
| from __future__ import annotations |
|
|
| import argparse |
| import hashlib |
| from pathlib import Path |
|
|
| from _common import ensure_dir, read_json, write_json, write_jsonl, write_npy_f4, write_solid_png |
|
|
|
|
| def parse_args() -> argparse.Namespace: |
| parser = argparse.ArgumentParser(description="Materialize selected-view render artifacts.") |
| parser.add_argument("--selected", type=Path, required=True, help="selected_viewpoints.json.") |
| parser.add_argument("--output-dir", type=Path, default=Path("outputs/tiny"), help="Run output directory.") |
| parser.add_argument("--tiny", action="store_true", help="Write deterministic placeholder render artifacts.") |
| parser.add_argument("--width", type=int, default=64) |
| parser.add_argument("--height", type=int, default=32) |
| return parser.parse_args() |
|
|
|
|
| def color_from_id(candidate_id: str) -> tuple[int, int, int]: |
| digest = hashlib.sha256(candidate_id.encode("utf-8")).digest() |
| return tuple(48 + int(digest[i]) % 176 for i in range(3)) |
|
|
|
|
| def rel(path: Path, base: Path) -> str: |
| try: |
| return str(path.relative_to(base)) |
| except ValueError: |
| return str(path) |
|
|
|
|
| def main() -> None: |
| args = parse_args() |
| if not args.tiny: |
| raise SystemExit("Real rendering is handled by pipelines/run_full_pipeline.py. Use --tiny for smoke-test artifacts.") |
|
|
| selected_doc = read_json(args.selected) |
| render_dir = ensure_dir(args.output_dir / "renders") |
| rows = [] |
| for item in selected_doc.get("selected_viewpoints", []): |
| cid = str(item["candidate_id"]) |
| stem = f"{int(item['rank']):03d}_{cid}" |
| rgb_path = render_dir / f"{stem}_rgb.png" |
| depth_path = render_dir / f"{stem}_depth.npy" |
| pose_path = render_dir / f"{stem}_pose.json" |
| write_solid_png(rgb_path, args.width, args.height, color_from_id(cid)) |
| write_npy_f4(depth_path, args.height, args.width, 1.0 + 0.05 * int(item["rank"])) |
| write_json( |
| pose_path, |
| { |
| "candidate_id": cid, |
| "position": item.get("position", [0.0, 0.0, 0.0]), |
| "yaw_deg": item.get("yaw_deg", 0.0), |
| "coordinate_frame": "right-handed, x-right, y-up, z-forward", |
| }, |
| ) |
| rows.append( |
| { |
| "candidate_id": cid, |
| "rgb": rel(rgb_path, args.output_dir), |
| "depth": rel(depth_path, args.output_dir), |
| "pose": rel(pose_path, args.output_dir), |
| "valid": True, |
| "invalid_reason": "", |
| } |
| ) |
| write_jsonl(render_dir / "validity.jsonl", rows) |
| print(f"Wrote {len(rows)} tiny render records to {render_dir}") |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|