Moving constraint to top of stack

Hello, I am trying to add a constraint to a bone, then move it to the top of the stack. I can successfully add the constraint, but I can’t get it to move. I’ve tried using the bpy.ops.constraints.move_up(constraint="", owner=‘OBJECT’), but I can’t figure out what arguments to use. Everything I’ve tried gives me this error:

  File "C:\Program Files\Blender Foundation\Blender\2.70\scripts\modules\bpy\ops.py", line 185, in __call__
    C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
  File "C:\Program Files\Blender Foundation\Blender\2.70\scripts\modules\bpy\ops.py", line 142, in _parse_args
    raise ValueError("1-3 args execution context is supported")
ValueError: 1-3 args execution context is supported

What arguments do I need to use for this to work? Thanks!

I still can’t get it working. What is the exact line of code to move “con” up the stack?

The “_name” in was too much, this should work:

import bpy
ob = bpy.context.object

con = ob.constraints['FOOBAR']

ctx = bpy.context.copy()
ctx['constraint'] = con

while ob.constraints[0] != con:
    bpy.ops.constraint.move_up(ctx, constraint=con.name)

It stopped erroring, but it still wont move the constraint up. I tried using those same arguments in bpy.ops.constraint.childof_set_inverse(), since the documentation list this same arguments, but it gives the error “Could not find constraint data for Child-Of Set Inverse”.

how do you retrieve the constraint reference?

I’m creating the constraint, so “con = bone.constraints.new(‘CHILD_OF’)”.

Why not just create all your constraints in the correct order instead of making them as you go and trying to re-order them?

For bone constraints, owner must be ‘BONE’ for the move_up() operator:

import bpy
ob = bpy.context.object

con = ob.pose.bones[0].constraints['FOOBAR']

ctx = bpy.context.copy()
ctx['constraint'] = con

while ob.pose.bones[0].constraints[0] != con:
    bpy.ops.constraint.move_up(ctx, constraint=con.name, owner='BONE')

@Atom - Some of the bones have other constraints on them already, so I need to move the new constraints to the top.
@CoDEmanX - Oh, I didn’t realize there was a difference. I’ll try that when I get back to my computer and let you know if it works.

It works for one bone now, but I’m trying to get it to work for multiple selected bones. If I select more than one bone the loop will get stuck (I assume because it’s only checking the active bone?). I am using a for loop to go through bpy.context.selected_pose_bones. Also, bpy.ops.constraint.childof_set_inverse() seems to ignore what the current frame is, so the inverse is not getting set correctly. Thank you so much for your help so far!

Line “con = pbone.constraints.get(constraint_name)” is giving me the error “‘Bone’ object has no attribute ‘constraints’”. I need to get the poseBone instead, but I’m not sure how to without using context.

My code works fine in 2.70, not sure why you’re getting an error

I’m using 2.70. I ran “print(pbone)” and it says that it’s a poseBone, I ran “print(dir(pbone))” and “constraints” is in the list, but when I try “pbone.constraints.new()” I get that error :confused:

I fixed that, so now all the constraints get added correctly, but using the set inverse work around doesn’t set the inverse correctly.

What’s the code? You might need to adapt it for pose bones.

The line of code I’m using is “con.inverse_matrix = con.target.matrix_world.inverted()”. I also tried with and without inverting on that, and with “.matrix_basis” and “.matrix_local”.

are there any parent relationships or other modifiers changing the object transformation?

It’s an empty created from a track, so it has a follow track constraint.

you should compare matrices, bone / object matrices and what they are if you use the operator to set the matrix. The problem might be the difference between bone space and object space.