A few years ago I used to be using a little script found here in order to reset every "Stretch to" constraints of an armature, in pose mode, even on unselected/offlayered bones :
import bpy
for b in bpy.context.active_object.pose.bones:
for c in b.constraints:
if c.type == "STRETCH_TO":
c.rest_length = 0
It has been very useful, especially when you drastically edit the bones positions of an already finished rig (i.e. when you reuse the same rig for similar but different models).
I would like a very similar script, but with "set inverse" for CHILD_OF constraint. But I barely know Blender's API and every try haven't got anything working nor going the right direction.
My last attempt looked like that:
import bpy
for b in bpy.context.active_object.pose.bones:
for c in b.constraints:
if c.type == "CHILD_OF":
context_py = bpy.context.copy()
context_py["constraint"] = constraint
bpy.ops.constraint.childof_set_inverse(context_py, constraint="Child Of")
And got this error:
Traceback (most recent call last):
File "\Text", line 7, in <module>
NameError: name 'constraint' is not defined
I also got this proposition from another guy:
import bpy
for b in bpy.context.active_object.pose.bones:
for c in b.constraints:
if c.type == "CHILD_OF" and c.target is not None:
c.inverse_matrix = c.target.matrix_world.inverted()
With this one, no errors returned, it executes properly but simply doesn’t affects the rig.
If someone could help me, that would be kind.
Edit: this is one of the tracks if followed, but hasn't worked for me. Also, it looks like it's for object mode and for active selection only, while I'm going for pose mode and effect on the whole armature.
EDIT 2: SOLUTION
A big thank to Konybravo for this piece of code:
import bpy
ob = bpy.context.active_object
# Take a copy of current layers
org_layers = ob.data.layers[:]
# Show all layers
for i in range(len(org_layers)):
ob.data.layers[i] = True
for b in ob.pose.bones:
for c in b.constraints:
if c.type == "CHILD_OF":
context_py = bpy.context.copy()
context_py["constraint"] = c
ob.data.bones.active = b.bone
bpy.ops.constraint.childof_set_inverse(context_py, constraint="Child Of", owner='BONE')
# Reset back to orginal layer state
for i in range(len(org_layers)):
ob.data.layers[i] = org_layers[i]
Working straight away, even on bones hidden in a layer. Yay \o/ And thank y'all for helping me those days.
constraint
is not recognized, because you named it justc
(for c in b.constraints:
). So change your code to:context_py["constraint"] = c
$\endgroup$python import bpy for b in bpy.context.active_object.pose.bones: for c in b.constraints: if c.type == "CHILD_OF": context_py = bpy.context.copy() context_py["constraint"] = c bpy.ops.constraint.childof_set_inverse(context_py, constraint="Child Of", owner='BONE')
And it works, but only on the active bone. How can I make it work on the whole armature ? Even on offlayered bones ? $\endgroup$context_py["active_pose_bone"] = b
in pose bone loop. $\endgroup$