#!/usr/bin/env python3 """LOD post-pass: run the remesh op over every *-rigid.glb hero in the garments library. LODs land in library/garments/lod/-lod.glb — a subdirectory so wardrobegod's scan() doesn't double-list every item. Heroes are never touched. Heartbeat: ~/.jobs/lod-pass.json """ import json, os, subprocess, time LIB = os.path.expanduser("~/Documents/wardrobegod/library/garments") LOD = os.path.join(LIB, "lod") OPS = os.path.expanduser("~/Documents/wardrobegod/blender_ops.py") BLENDER = "/Applications/Blender.app/Contents/MacOS/Blender" TARGET = "6000" HB = os.path.expanduser("~/.jobs/lod-pass.json") os.makedirs(LOD, exist_ok=True) os.makedirs(os.path.dirname(HB), exist_ok=True) heroes = sorted(f for f in os.listdir(LIB) if f.endswith("-rigid.glb") and not f.endswith(".raw.glb")) results = [] state = {"job": "lod-pass", "status": "running", "total": len(heroes), "done": 0, "failed": 0, "skipped": 0, "current": "", "results": results} def hb(): state["updated"] = time.strftime("%Y-%m-%d %H:%M:%S") json.dump(state, open(HB, "w"), indent=1) for f in heroes: out = os.path.join(LOD, f.replace("-rigid.glb", "-lod.glb")) state["current"] = f hb() if os.path.exists(out) and os.path.getsize(out) > 1000: state["skipped"] += 1 continue row = {"file": f} results.append(row) try: r = subprocess.run([BLENDER, "-b", "--python", OPS, "--", "remesh", os.path.join(LIB, f), out, TARGET], capture_output=True, text=True, timeout=1200) line = [l for l in r.stdout.splitlines() if "remeshed" in l] ok = os.path.exists(out) and os.path.getsize(out) > 1000 row["note"] = line[0] if line else (r.stdout[-150:] + r.stderr[-100:]) if ok: row["kb"] = os.path.getsize(out) // 1024 state["done"] += 1 else: state["failed"] += 1 except Exception as e: row["error"] = str(e)[:200] state["failed"] += 1 hb() state["status"] = "done" state["current"] = "" hb() print(json.dumps({k: state[k] for k in ("done", "failed", "skipped", "total")}))