Reverse pose bone inherit scale via python I have some animation fcurve data provided for the case of inherit scale unchecked for pose bones.
Example: Bone03 is a child of Bone02. Inherit scale is unchecked for Bone03. At frame 1, Bone02 is not scaled (i.e. Sx, Sy, Sz = 1.0000). At frame 30, Bone02 is scaled on Y with a factor of 2 (Sy = 2.0000; Sx, Sz = 1.0000).
Since inherit scale is not checked for Bone03, it is not affected by it's parent scaling at frame 30. This is the intended result.
Problem: I need to import the blend file in Jmonkey which scales the child regardless of it's setting in Blender. The animation hence appears scaled wrongly in Jmonkey. Basically, I need to check inherit scale on the child bone and then reverse the inherit scale operation on the child bone via a python script in Blender before loading it in Jmonkey.

I've tried to copy the matrix of the child pose bone (before setting use_inherit_scale to True on the child edit bone) and then reassign it to the child pose bone. The result looks like it ignores the reassign of the original matrix and scales the child anyway. Here's the code:

import bpy

obj = bpy.context.object
scene = bpy.context.scene
bpy.ops.object.mode_set(mode='POSE')
scene.frame_set(30.0)

pb = obj.pose.bones['Bone03']
start_matrix = pb.matrix.copy()  #copy the initial pose bone matrix 
print(start_matrix)

bpy.ops.object.mode_set(mode='EDIT')
eb = obj.data.edit_bones['Bone03']
eb.use_inherit_scale = True

bpy.ops.object.mode_set(mode='POSE')
print(pb.matrix)
pb.matrix = start_matrix  #try to force reassign the start matrix

print(pb.matrix)


Here is a file with the problem demonstrated (I hope much clearer). When you open it the animation is correct (but with inherit scale unchecked). As soon as you run the script, Bone03 get's scaled wrongly.
The question: how can I force reassign the initial matrix to the pose bone, after programmatically setting use_inherit_scale = True on the edit bone?
Just a short draft. I might expand this answer later.

import bpy
from mathutils import Matrix, Vector

# for debugging purposes - visualize transforms
def create_empty(name, matrix):
    if name not in bpy.data.objects:
        empty = bpy.data.objects.new(name, None)      
        scene.objects.link(empty)
    else:
        empty = bpy.data.objects[name]

    empty.empty_draw_type = "ARROWS"
    empty.empty_draw_size = 1.0
    empty.show_x_ray = True
    empty.show_name = True

    empty.matrix_basis = matrix

# ported from blenkernel/intern/armature.c to python
# --------------------------------------------------------------------
def get_mat_offs(bone):        
    mat_offs = bone.matrix.to_4x4()
    mat_offs.translation = bone.head
    mat_offs.translation.y += bone.parent.length

    return mat_offs

def get_mat_rest(pose_bone, mat_pose_parent):
    bone = pose_bone.bone

    if pose_bone.parent:
        mat_offs = get_mat_offs(bone)

        # --------- rotscale       
        if (not bone.use_inherit_rotation and 
            not bone.use_inherit_scale):                
            mat_rotscale = bone.parent.matrix_local * mat_offs

        elif not bone.use_inherit_rotation:                        
            mat_size = Matrix.Identity(4)
            for i in range(3):
                mat_size[i][i] = mat_pose_parent.col[i].magnitude
            mat_rotscale = mat_size * bone.parent.matrix_local * mat_offs

        elif not bone.use_inherit_scale:
            mat_rotscale = mat_pose_parent.normalized() * mat_offs

        else:
            mat_rotscale = mat_pose_parent * mat_offs

        # --------- location     
        if not bone.use_local_location:
            mat_a = Matrix.Translation(
                mat_pose_parent * mat_offs.translation)

            mat_b = mat_pose_parent.copy()
            mat_b.translation = Vector()

            mat_loc = mat_a * mat_b

        elif (not bone.use_inherit_rotation or 
              not bone.use_inherit_scale):                  
            mat_loc = mat_pose_parent * mat_offs

        else:
            mat_loc = mat_rotscale.copy()

    else:    
        mat_rotscale = bone.matrix_local
        if not bone.use_local_location:
            mat_loc = Matrix.Translation(bone.matrix_local.translation)
        else:
            mat_loc = mat_rotscale.copy()      

    return mat_rotscale, mat_loc

def get_mat_pose(pose_bone, mat_pose_parent=None, mat_basis=None):
    if pose_bone.parent and not mat_pose_parent:
        mat_pose_parent = pose_bone.parent.matrix
    if not mat_basis:
        mat_basis = pose_bone.matrix_basis

    mat_rotscale, mat_loc = get_mat_rest(pose_bone, mat_pose_parent)    
    mat_pose = mat_rotscale * mat_basis
    mat_pose.translation = mat_loc * mat_basis.translation

    return mat_pose    
# --------------------------------------------------------------------

def adjust_matrix(pose_bone, mat_parent_old, mat_parent_new, preview=True):                    
    mat_pose_old = get_mat_pose(pose_bone, mat_parent_old)
    mat_rotscale_old, mat_loc_old = get_mat_rest(pose_bone, mat_parent_old)    
    pose_bone.bone.use_inherit_scale = True        
    mat_rotscale_new, mat_loc_new = get_mat_rest(pose_bone, mat_parent_new)

    mat_fix_rotscale = mat_rotscale_new.inverted() * mat_rotscale_old
    mat_fix_loc = mat_loc_new.inverted() * mat_loc_old 

    mat_basis_old = pose_bone.matrix_basis
    mat_basis_new = mat_fix_rotscale * mat_basis_old
    mat_basis_new.translation = mat_fix_loc * mat_basis_old.translation

    mat_pose_new = get_mat_pose(
        pose_bone,
        mat_parent_new,
        mat_basis_new)

    if preview:
        create_empty(pose_bone.name, mat_pose_new)  
    else:
        pose_bone.matrix_basis = mat_basis_new

    return mat_pose_old, mat_pose_new

def apply_change(parent, mat_parent_old, mat_parent_new):
    for child in parent.children:
        mat_old, mat_new = adjust_matrix(
            child, 
            mat_parent_old, 
            mat_parent_new,
            preview=True
        )                       
        apply_change(child, mat_old, mat_new)

if __name__ == "__main__":
    scene = bpy.context.scene
    obj = bpy.data.objects['Armature']
    roots = [bone for bone in obj.pose.bones if not bone.parent]

    for root in roots:
        create_empty(root.name, root.matrix)
        apply_change(root, root.matrix, root.matrix)

    obj.update_tag({'DATA'})
    scene.update()