Image2Model / Retarget /README.md
Daankular's picture
Port MeshForge features to ZeroGPU Space: FireRed, PSHuman, Motion Search
8f1bcd9

A newer version of the Gradio SDK is available: 6.12.0

Upgrade

rig_retarget

Pure-Python rig retargeting library. No Blender required.

Based on KeeMap Blender Rig Retargeting Addon by Nick Keeline (GPL v2). All core retargeting math is a direct port of his work. Mapping JSON files are fully compatible with KeeMap.


File layout

rig_retarget/
β”œβ”€β”€ math3d.py        # Quaternion / matrix math (numpy + scipy), replaces mathutils
β”œβ”€β”€ skeleton.py      # Armature + PoseBone with FK, replaces bpy armature objects
β”œβ”€β”€ retarget.py      # Core retargeting logic β€” faithful port of KeeMapBoneOperators.py
β”œβ”€β”€ cli.py           # CLI entry point
└── io/
    β”œβ”€β”€ bvh.py       # BVH mocap reader (source animation)
    β”œβ”€β”€ gltf_io.py   # glTF/GLB reader + animation writer (UniRig destination)
    └── mapping.py   # JSON bone mapping β€” same format as KeeMap

Install

pip install numpy scipy pygltflib

CLI

# Retarget BVH onto UniRig GLB
python -m rig_retarget.cli \
    --source  motion.bvh \
    --dest    unirig_character.glb \
    --mapping radical2unirig.json \
    --output  animated_character.glb \
    --fps 30 --start 0 --frames 200 --step 1

# Auto-calculate bone correction factors and save back to the mapping file
python -m rig_retarget.cli --calc-corrections \
    --source motion.bvh \
    --dest   unirig_character.glb \
    --mapping mymap.json

Python API

from rig_retarget.io.bvh     import load_bvh
from rig_retarget.io.gltf_io import load_gltf, write_gltf_animation
from rig_retarget.io.mapping  import load_mapping
from rig_retarget.retarget    import transfer_animation, calc_all_corrections

# Load
settings, bone_items = load_mapping("my_map.json")
src_anim = load_bvh("motion.bvh")
dst_arm  = load_gltf("unirig_char.glb")

# Optional: auto-calc corrections at first frame
src_anim.apply_frame(0)
calc_all_corrections(bone_items, src_anim.armature, dst_arm, settings)

# Transfer
settings.number_of_frames_to_apply = src_anim.num_frames
keyframes = transfer_animation(src_anim, dst_arm, bone_items, settings)

# Write output GLB
write_gltf_animation("unirig_char.glb", dst_arm, keyframes, "output.glb")

Mapping JSON format

100% compatible with KeeMap's .json files. Use KeeMap in Blender to create and tune mappings, then use this library offline for batch processing.

Key fields per bone:

Field Description
SourceBoneName Bone name in the source rig (BVH joint name)
DestinationBoneName Bone name in the UniRig skeleton (glTF node name)
set_bone_rotation Drive rotation from source
set_bone_position Drive position from source
bone_rotation_application_axis Mask axes: X Y Z XY XZ YZ XYZ
bone_transpose_axis Swap axes: NONE ZYX ZXY XZY YZX YXZ
CorrectionFactorX/Y/Z Euler correction (radians)
postion_type SINGLE_BONE_OFFSET or POLE
position_pole_distance IK pole distance

Blender β†’ pure-Python mapping

Blender rig_retarget
bpy.data.objects[name] Armature + load_gltf() / load_bvh()
arm.pose.bones[name] arm.get_bone(name) β†’ PoseBone
bone.matrix (pose space) bone.matrix_armature
arm.matrix_world arm.world_matrix
arm.convert_space(...) arm.world_matrix @ bone.matrix_armature
bone.rotation_quaternion bone.pose_rotation_quat
bone.location bone.pose_location
bone.keyframe_insert(...) returned in keyframes list from transfer_frame()
bpy.context.scene.frame_set(i) src_anim.apply_frame(i)
mathutils.Quaternion np.ndarray [w,x,y,z] + math3d.*
mathutils.Matrix np.ndarray (4,4)

Limitations / TODO

  • glTF source animation reading not yet implemented (BVH only for now). Add io/gltf_anim_reader.py reading gltf.animations[0] sampler data.
  • FBX source support: use pyassimp or bpy offline with --background.
  • IK solving: pole bone positioning is FK-only; a full IK solver (FABRIK/CCD) would improve accuracy for limb targets.
  • Quaternion mode twist bones: parity with Blender not guaranteed for complex twist rigs.