2
$\begingroup$

I have the following code:

import bpy

obj = bpy.data.objects["Cube"]
target = bpy.data.objects["Lamp"]
const = obj.constraints.new(type='CHILD_OF')
const.name = "Custom Const"
const.target = target

When I run this code in the default scene Cube jumps into the Lamp's position and gets Lamp's orientation (just as expected). Now I have to set inverse for the Cube. I could use something like:

C = bpy.context.copy()
C["constraint"] = const
bpy.ops.constraint.childof_set_inverse(C, constraint=const.name, owner='OBJECT')

But it looks hackish and not always works for multiple objects (at least for me). E.g.:

import bpy

objects = [bpy.data.objects["Cube"], bpy.data.objects["Camera"]]
target = bpy.data.objects["Lamp"]

for obj in objects:
    const = obj.constraints.new(type='CHILD_OF')
    const.name = "Custom Const"
    const.target = target
    C = bpy.context.copy()
    C["constraint"] = const
    bpy.ops.constraint.childof_set_inverse(C, constraint=const.name, owner='OBJECT')

So the main question is how to set inverse for a Child Of constraint without using bpy.ops? I understand that I've to do something with object's matrices but I've no idea what.

$\endgroup$
2
$\begingroup$

Try:

const.inverse_matrix = target.matrix_world.inverted()   
obj.update_tag({'OBJECT'})
bpy.context.scene.update()

This does not show up immediatly. You have to update the view / tag the region for redraw.

$\endgroup$
  • $\begingroup$ Thanks for help! But here is another question. This method works fine only if I add a constraint to an object or to a pose bone with it's armature object set to (0,0,0) location. But if I move an armature object (in the Object Mode), go to the Pose Mode and add the constraint then the pose bone jumps to another location. Looks like it ignores armature's world position. Unfortunately I can't explain it better. Here is a blend - pasteall.org/blend/32812. Open and run the script you'll see what I'm talking about $\endgroup$ – Roman Volodin Nov 13 '14 at 0:01
  • $\begingroup$ I guess I solved it: const.inverse_matrix = obj.matrix_world * target.matrix_world.inverted(). Have to check it carefully, but it works nice so far. $\endgroup$ – Roman Volodin Nov 13 '14 at 0:19
2
$\begingroup$

If the target object is an armature and a pose bone is selected then const.inverse_matrix looks like this:

matrix_final = target.matrix_world * target_bone.matrix
const.inverse_matrix = matrix_final.inverted()
$\endgroup$

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.