0
$\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$
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$
  • $\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 '19 at 15:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.