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 Answers 2

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$
2
  • $\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$ Nov 13, 2014 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$ Nov 13, 2014 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$

You must log in to answer this question.

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