- pipeline/strip_skin.py: with-skin Mixamo FBX -> anim-only, normalises numbered bone namespaces (mixamorigN: -> mixamorig:) - render_moves.py --self-anim renders actions baked into the char file (MIRPAMO retarget output) - phrtt2-nsfw + daphne rigged via MIRPAMO autorig (clean weights); 17-clip kit retargeted but pose quality poor — retarget stage needs a bonemap/markers tuning pass before these ship as fighters Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
46 lines
1.5 KiB
Python
46 lines
1.5 KiB
Python
# Blender headless: convert with-skin Mixamo FBX clips to anim-only FBX
|
|
# (deletes meshes, keeps armature+action). MIRPAMO's retarget mapper needs
|
|
# anim-only sources.
|
|
#
|
|
# Usage: Blender -b --python pipeline/strip_skin.py -- --clips "a.fbx,b.fbx" --out dir
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import bpy
|
|
|
|
|
|
def parse_args():
|
|
argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--clips", required=True)
|
|
ap.add_argument("--out", required=True)
|
|
return ap.parse_args(argv)
|
|
|
|
|
|
args = parse_args()
|
|
out = Path(args.out).expanduser()
|
|
out.mkdir(parents=True, exist_ok=True)
|
|
for clip in args.clips.split(","):
|
|
clip = Path(clip).expanduser()
|
|
dest = out / clip.name
|
|
if dest.exists():
|
|
print("SKIP", clip.name)
|
|
continue
|
|
bpy.ops.wm.read_factory_settings(use_empty=True)
|
|
bpy.ops.import_scene.fbx(filepath=str(clip), use_anim=True)
|
|
for o in list(bpy.data.objects):
|
|
if o.type == "MESH":
|
|
bpy.data.objects.remove(o, do_unlink=True)
|
|
# normalise numbered Mixamo namespaces (mixamorig7: -> mixamorig:) so
|
|
# downstream mappers (MIRPAMO retarget) match by exact name
|
|
import re
|
|
for o in bpy.data.objects:
|
|
if o.type == "ARMATURE":
|
|
for b in o.data.bones:
|
|
b.name = re.sub(r"^mixamorig\d+:", "mixamorig:", b.name)
|
|
bpy.ops.export_scene.fbx(filepath=str(dest), use_selection=False,
|
|
add_leaf_bones=False, bake_anim=True)
|
|
print("STRIPPED", clip.name)
|
|
print("DONE")
|