wardrobegod/tools/lod_pass.py
type-two 2854182cf9 socket-kit slot picker: /api/kit + /api/kit/assemble + bench tab; LOD post-pass runner
Assemble any of the 53 kit rigs parts cross-rig from the UI; genitals slot
same-rig additive only. LODs land in library/garments/lod/ (subdir keeps
scan() from double-listing).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-01 10:29:06 +10:00

60 lines
2.1 KiB
Python

#!/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/<name>-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")}))