1
$\begingroup$

I'm stuck at the part of my loop where the empty gets constrained to the bone. I don't know how to refer to the bones and empties I want to constrain since their names vary as the loop runs. Here's what I have so far:

##Loop that runs on every bone in rig
for bone in metarig:
    ## print each bones name
    print (bone.name)
    ##create Cubeshaped Empty of radius 0.6 at origin
    makeEmpty = bpy.ops.object.empty_add(type='CUBE', location=(0, 0, 0), radius=(0.1))
    ##rename newly created empty
    bpy.context.selected_objects[0].name = ("empty_A_" + (bone.name))

Up to here above code works, when I end the loop here I get all my empties named correctly.

The Next command errors out: I'm trying to define the Constraint owner and targets without using explicit names, since this is a loop? What's the correct way? I also tried calling it by its name ("empty_A_" + (bone.name)) that doesn't work.

## Create reference for current empty
    emptyobj = bpy.context.selected_objects[0]
## also tried referring to it by its name, the following also errors out
    emptyobj = bpy.context.("empty_A_" + (bone.name))

## then I want to do this, not sure if this will work since I'm stuck at the above line,
    targetbone = bone
    myConstraint = emptyobj.constraints.new(type='CHILD_OF')
    myConstraint.target = targetbone

Any guidance would be greatly appreciated, been stuck on this for a while now :(.

$\endgroup$

1 Answer 1

0
$\begingroup$

Script for 2.8

Test Script:

Select your armature object in object mode. Adds an empty at each pose bone location. Creates a child of constraint for each.

As it is for 2.8 uses @ for matrix multiplication. For prior, globally replace @ with *

import bpy

context = bpy.context
ob = context.object
mw = ob.matrix_world

mts = []
for pb in ob.pose.bones:
    bpy.ops.object.empty_add(location = (mw @ pb.matrix).translation)
    #bpy.ops.object.empty_add()
    mt = context.object
    mt.name = "MT_%s" % pb.name
    cl = mt.constraints.new(type='CHILD_OF')
    cl.target = ob
    cl.subtarget = pb.name  

    mwi = (mw @ pb.matrix).inverted()
    cl.inverse_matrix = mwi

Notes:

  • after an add object operator, the newly added object is context.object or context.active_object. Do not rely on it being context.selected_objects[0]
  • The target for the constraint is the armature object, the subtarget is the bone, by name.
$\endgroup$
1
  • $\begingroup$ out of curiosity, why is it necessary to specify the armature as a target ? isn't the bone by name enough since we're already inside the armature object when we run the script ? $\endgroup$
    – mehdianim
    Jan 23, 2019 at 15:23

You must log in to answer this question.

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