Files
AIGame/Tools/model_tools/bl_clean_tokenrig_mixamo41.py

35 lines
1.8 KiB
Python

"""Controlled local-influence cleanup of TokenRig-41 hand weights only."""
import json
import sys
from pathlib import Path
import bpy
folder=Path(sys.argv[sys.argv.index('--')+1])
bpy.ops.wm.open_mainfile(filepath=str(folder/'tokenrig_mixamo41.blend'))
arm=next(o for o in bpy.context.scene.objects if o.type=='ARMATURE')
mesh=next(o for o in bpy.context.scene.objects if o.type=='MESH')
height=max((mesh.matrix_world@v.co).z for v in mesh.data.vertices)
changes=[]
for v in mesh.data.vertices:
p=mesh.matrix_world@v.co
if not (abs(p.x)>height*.255 and height*.55<p.z<height*.67):
continue
side='Left' if p.x*(arm.matrix_world@arm.data.bones['mixamorig:LeftHand'].head_local).x>0 else 'Right'
old={mesh.vertex_groups[g.group].name:g.weight for g in v.groups}
allowed={n:w for n,w in old.items() if n in (f'mixamorig:{side}Arm',f'mixamorig:{side}ForeArm') or n.startswith(f'mixamorig:{side}Hand')}
total=sum(allowed.values())
rejected=sum(w for n,w in old.items() if n not in allowed)
assert total>1e-8
for g in list(v.groups):
mesh.vertex_groups[g.group].remove([v.index])
for n,w in allowed.items():
mesh.vertex_groups[n].add([v.index],w/total,'REPLACE')
if rejected>.001:
changes.append({'vertex':v.index,'removed':rejected,'old':old})
(folder/'local_cleanup.json').write_text(json.dumps({'method':'CampGuide-specific T-pose hand-region whitelist; same-side Arm/ForeArm/Hand/fingers only; renormalize; no reference weights',
'changed_vertices_over_0_001':len(changes),'changes':changes},indent=2),encoding='utf-8')
bpy.ops.wm.save_as_mainfile(filepath=str(folder/'tokenrig_mixamo41_local.blend'),compress=True)
bpy.ops.export_scene.gltf(filepath=str(folder/'tokenrig_mixamo41_local.glb'),export_format='GLB',export_skins=True,export_animations=False,export_def_bones=False)
print('LOCAL_CLEANUP',len(changes))