Skip to content

Instantly share code, notes, and snippets.

@FreshlyBrewedCode
Created May 12, 2021 13:45
Show Gist options
  • Save FreshlyBrewedCode/26327e26b976b2a0fc886779ec11f542 to your computer and use it in GitHub Desktop.
Save FreshlyBrewedCode/26327e26b976b2a0fc886779ec11f542 to your computer and use it in GitHub Desktop.
Blender Auto Rig Hierarchy Operator
import bpy
from mathutils import Vector, Matrix
#Create the armature
def create_armature(object, collection):
armature_data = bpy.data.armatures.new(object.name)
armature = bpy.data.objects.new(object.name, armature_data)
armature.matrix_basis = object.matrix_basis
collection.objects.link(armature)
return armature
#Create the bones
def bone_from_hierarchy(object, armature, parent_bone = None):
#Create a bone parented and disconnect to its parent
bone = armature.data.edit_bones.new(object.name)
bone.parent = parent_bone
bone.use_connect = False
#Get its transformation matrix inside the armature from the object matrix
matrix = armature.matrix_world.inverted() @ object.matrix_world
#Place head and tail
bone.head = matrix @ Vector()
bone.tail = matrix @ Vector((0.0, 0.0, 1.0))
if 'stop_rig' in object.keys():
return
#Recurse through the children objects
for child in object.children:
bone_from_hierarchy(child, armature, bone)
#Parent the objects to the armarture
def parent_from_hierarchy(object, armature):
name = object.name
#Get the pose bone
bone = armature.pose.bones[name]
#Keep the object position
matrix_world = object.matrix_world.copy()
#Parent it
object.parent = armature
object.parent_type = 'BONE'
object.parent_bone = name
#Make so we can unparent and keep object's position
bone_matrix = Matrix.Translation(bone.tail - bone.head) @ bone.matrix
object.matrix_parent_inverse = (armature.matrix_world @ bone_matrix).inverted()
#Assigns its position
object.matrix_world = matrix_world
if 'stop_rig' in object.keys():
return
#Recurse through the children
for child in object.children:
parent_from_hierarchy(child, armature)
def make_bone_hierarchy(object):
if object:
armature = create_armature(object, object.users_collection[0])
#Enter edit mode for the armature in order to create edit bones
bpy.context.view_layer.objects.active = armature
bpy.ops.object.mode_set(mode='EDIT')
bone_from_hierarchy(object, armature)
#Back to object mode
bpy.ops.object.mode_set(mode='OBJECT')
#bpy.context.view_layer.objects.active = object
#Parent the objects to the armature
parent_from_hierarchy(object, armature)
def main(context):
root = context.active_object
make_bone_hierarchy(root)
class SimpleOperator(bpy.types.Operator):
"""Tooltip"""
bl_idname = "object.auto_rig_hierarchy"
bl_label = "Auto Rig Hierarchy"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
main(context)
return {'FINISHED'}
def register():
bpy.utils.register_class(SimpleOperator)
def unregister():
bpy.utils.unregister_class(SimpleOperator)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment