Toggle a constraint property
As mentioned in this (possible duplicate) question Set inverse Child OF constraints via python , simply changing the inverse_matrix
property of a constraint does nought. However, if another property of the constraint is toggled, for example the target
it appears to work as expected, using the new value assigned to inverse_matrix
Test script, tested on simple example of single bone and default cube parent. Set cmd to 'CLEAR'
for clear and 'SET'
for set. For all child of constraints on all pose bones of the context object. AFAICT it doesn't need context.
import bpy
from mathutils import Matrix
context = bpy.context
ob = context.object
constraints = [(pb, c) for pb in ob.pose.bones
for c in pb.constraints if c.type == 'CHILD_OF']
cmd = 'CLEAR' # or 'SET'
for pb, c in constraints:
if cmd == 'CLEAR':
c.inverse_matrix = Matrix.Identity(4)
elif cmd == 'SET':
if c.target:
mw = c.target.matrix_world
c.inverse_matrix = mw.inverted()
# toggle a property
target = c.target
c.target = None
c.target = target
#pb.constraints.update()
Notes: takes into no account the owner_space
and target_space
, nor the influence
value when the script is run, which changes the calculated value for set, (have a feeling influence zero is clear)... An interpolated target matrix could be found by decomposing, lerping and slerping from identity to target.matrix_world
.
why is this so? Constraint properties that are set by a user (esp via UI) update the data appropriately on change.
An operator for each has been chosen to crunch the numbers , and handle the necessary updating. Perhaps a patch to make the python attribute update on change, not sure..