1

If I have two armatures is there a way to merge them via python that will delete the common bones, and maintain the relationships?

I have a body rig and a head rig that both have the neck and upper spine, to be able to merge them cleanly the neck and spine need to only be in one rig prior to merge or it wont work, but I don't want to loose the parenting that's present.

I'm guessing I'll have to iterate through the target armature, looking to see if each bone is in the other one then when it is, delete the one that has less children and save any relationships its not already present in the one being kept. Then merge the rigs and recreate any saved relationships?

Edit: I've worked it out, code below in case it helps anyone in future

#
# Merge exported head and body rig, you need to rename the armatures to HeadArmature and BodyArmature
#
#
import bpy
C = bpy.context
D = bpy.data

head = bpy.data.objects['HeadArmature'] body = bpy.data.objects['BodyArmature'] head_coll= head.users_collection[0] dupes = [] relate={}

for bone in head.data.bones: if bone.name in body.data.bones.keys() and bone.name!='Root': dupes.append(bone.name) relate[bone.name]=bone.children.keys()

obs = bpy.context.scene.objects["HeadArmature"]
obs.select_set(True) bpy.ops.object.mode_set(mode='EDIT') for bone in dupes: bn=head.data.edit_bones[bone] head.data.edit_bones.remove(bn)

bpy.ops.object.mode_set(mode='OBJECT')

ob = bpy.context.scene.objects["BodyArmature"] # Get the armature bpy.ops.object.select_all(action='DESELECT') # Deselect all objects bpy.context.view_layer.objects.active = ob # Make the armature the active object ob.select_set(True) # Select the armature

obs = [bpy.data.objects['BodyArmature'], bpy.data.objects['HeadArmature']]

c = {} c["object"] = bpy.data.objects['BodyArmature'] c["active_object"] = bpy.data.objects['BodyArmature'] c["selected_objects"] = obs c["selected_editable_objects"] = obs

with C.temp_override(active_object=c["active_object"], selected_editable_objects=obs): bpy.ops.object.join()

bpy.ops.object.mode_set(mode='EDIT') for bn in dupes: for bone in relate[bn]: if bone not in body.data.bones[bn].children.keys(): print(bone) #child = body.data.bones[bone] if bone!='Root': body.data.edit_bones[bone].parent = body.data.edit_bones[bn]

bpy.ops.object.mode_set(mode='OBJECT')

for obj in head_coll.objects: obj.modifiers['Armature'].object=body

used bits from these answers: Delete bones via script How to join objects with Python?

Simarilius
  • 23
  • 4

0 Answers0