2
$\begingroup$

I'm having technical drawings, with a lot of mechanical parts. (think of robotic arms) Initially, I have it set up as parent-child objects, chains of parent-childs. Sometimes chains as deep as 8 objects, since the base drawing wasn't blender, I had to do a lot of modification to fix all axes for all involved objects.

As I'm already a bit behind my schedule, I know animation with bones would go faster, (the other option is without bones, but making use of all relative rotations between parent & childs.

I just wonder if there is a quick way to turn hard objects into a rigged system based upon origins and the rotations in the parent-child chains. (ea I know quite good how to rig people with rigify, and in general I've used bone systems a lot, but those robotic rigs are a bit of a returning headache in my workflow especially when the drawing wasn't originally started in blender.

(note i cannot share this file).

$\endgroup$
2
  • $\begingroup$ Maybe this is useful. If you need more help you could upload a simplified version of the project, showing better the issue. blender.stackexchange.com/questions/163497/… $\endgroup$ Mar 19, 2020 at 12:19
  • $\begingroup$ i know that trick, and i use it actually quite often, also in mesh editing :) i will need to make something new for it then, but where to upload ?. $\endgroup$
    – Peter
    Mar 19, 2020 at 15:58

1 Answer 1

4
$\begingroup$

A script to create an armature, create and place each bone at the objects and child objects positions. Then it makes each object parented to the respective bones (bone parenting).

enter image description here

Note that the script will loose the previous parenting hierarchy as an object can only have one parent.

From that if you want rigged objects, not just bone parents, simply select them all and parent to the armature.

Script principles:

  • Create an armature at the parent object location with same transformations
  • Parse the object hierarchy and create an edit bone for each object, recursively
  • Parse again in object mode to make the parenting to each object

Nearly each line is commented below. But if questions, please ask.

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))

    #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

    #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)

root = bpy.context.view_layer.objects.active
make_bone_hierarchy(root)
$\endgroup$
1
  • $\begingroup$ wow thats cool !!! will use it in my next project $\endgroup$
    – Peter
    Mar 20, 2020 at 20:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .