MIRPAMO/library/fetch.py
jing a148b4a543 MIRPAMO v0: local Mixamo — autorig + retarget via headless Blender
- autorig: landmark detection from vertex cloud (markers JSON override),
  mixamorig 22-bone skeleton fit, bone-heat weights + nearest-bone rescue
- retarget: world-space quaternion delta transfer, hip-height scale
  compensation, fuzzy/explicit bone mapping (CMU map bundled)
- smoke: procedural test humanoid + synthetic BVH -> rig -> retarget -> verify
- deploy: push to gitea, pull + smoke on m3ultra and m1ultra

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 01:26:13 +10:00

84 lines
2.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""Fetch free motion-capture libraries into library/downloads/.
Sources live in library/manifest.json. Entries marked "verified": false
have not been confirmed reachable yet — the script reports what it can and
skips what it can't, it never fails the whole run on one dead mirror.
Usage:
python3 library/fetch.py # fetch everything in the manifest
python3 library/fetch.py --only cmu_sample
python3 library/fetch.py --url https://... --name mypack # ad-hoc
"""
import argparse
import json
import os
import sys
import urllib.request
import zipfile
HERE = os.path.dirname(os.path.abspath(__file__))
DOWNLOADS = os.path.join(HERE, "downloads")
def fetch_one(name, url, unpack):
os.makedirs(DOWNLOADS, exist_ok=True)
dest_dir = os.path.join(DOWNLOADS, name)
fname = os.path.join(DOWNLOADS, os.path.basename(url.split("?")[0]) or name)
if os.path.exists(dest_dir) and os.listdir(dest_dir):
print(f"[skip] {name}: already downloaded")
return True
print(f"[get ] {name}: {url}")
try:
req = urllib.request.Request(url, headers={"User-Agent": "mirpamo/0.1"})
with urllib.request.urlopen(req, timeout=60) as r, open(fname, "wb") as f:
while True:
chunk = r.read(1 << 20)
if not chunk:
break
f.write(chunk)
except Exception as e:
print(f"[fail] {name}: {e}")
return False
if unpack and fname.endswith(".zip"):
os.makedirs(dest_dir, exist_ok=True)
with zipfile.ZipFile(fname) as z:
z.extractall(dest_dir)
os.remove(fname)
print(f"[ok ] {name}: unpacked to {dest_dir}")
else:
os.makedirs(dest_dir, exist_ok=True)
os.rename(fname, os.path.join(dest_dir, os.path.basename(fname)))
print(f"[ok ] {name}")
return True
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--only")
ap.add_argument("--url")
ap.add_argument("--name", default="adhoc")
args = ap.parse_args()
if args.url:
ok = fetch_one(args.name, args.url, unpack=True)
sys.exit(0 if ok else 1)
with open(os.path.join(HERE, "manifest.json")) as f:
manifest = json.load(f)
results = []
for entry in manifest["sources"]:
if args.only and entry["name"] != args.only:
continue
if entry.get("url", "").startswith("TODO"):
print(f"[todo] {entry['name']}: no URL yet — {entry.get('notes','')}")
continue
results.append(fetch_one(entry["name"], entry["url"],
entry.get("unpack", True)))
print(f"\n{sum(results)}/{len(results)} sources fetched")
if __name__ == "__main__":
main()