Copy Pose Bone's Matrix

Hi, I could use some help to figure this out.

I am trying to copy an armature’s pose while the action is in ‘REPLACE’, change the blend type to ‘ADD’ and paste that exact same pose.

Strangely, even though the copied matrix corresponds to the initial pose, checking the bone’s matrix on the python console I get a different result.
Using the copy and past pose operators results in the same issue.

It seems to have something to do with the underlying pose but I cannot figure what exactly.

Here is my code:

import bpy

obj = bpy.data.objects['Armature']
pbone = obj.pose.bones['Bone']

#COPY POSE
print(obj.animation_data.action_blend_type) #should be 'REPLACE'
initialMatrix = pbone.matrix.copy()
print(pbone.matrix)
print(initialMatrix)

#change blend type to additive
obj.animation_data.action_blend_type = 'ADD'
print(obj.animation_data.action_blend_type)

#PASTE POSE
pbone.matrix = initialMatrix
print(pbone.matrix)
print(initialMatrix)
1 Like

After some more tests I think one of the issues is that the bone’s matrix does not update until after the script is finished.
Adding the following line of code to refresh the viewport right after changing the blend type to ‘ADD’, gives the expected result for my example.
bpy.ops.wm.redraw_timer(type=‘DRAW_WIN_SWAP’, iterations=1)

But unfortunately refreshing the viewport doesn’t work for the project I want to use this in. So I am still looking for solutions.

Scratch that last part. The reason it did not work for my project was because of how I added keyframes directly on the fcurves with fcurve.keyframe_points.add() instead of using pbone.keyframe_insert().

Refreshing the viewport basically evaluates the animation data, and this is what makes things work for you. Changing the animation data doesn’t immediately cause this evaluation. You could try getting an evaluated copy of the object:

depsgraph = bpy.context.view_layer.depsgraph
obj_eval = obj.evaluated_get(depsgraph)
print(obj_eval.pose.bones['Bone'].matrix)
2 Likes