2025-12-01

This commit is contained in:
2026-03-17 14:58:51 -06:00
parent 183e865f8b
commit 4b82b57113
6846 changed files with 954887 additions and 162606 deletions
+42 -18
View File
@@ -1803,7 +1803,7 @@ def reorder_bones_matrices(bones_matrices, constrained):
return re_bones_matrices
def paste_bone_matrix(bone, matrix_copied, constrained, x_filter = True):
def paste_bone_matrix(bone, matrix_copied, constrained, bones = {}, x_filter = True):
#running again separatly in case the bones are in a hierarchy and influencing each other
# for bone, matrix_copied in bones_matrices.items():
# Determine whether to use bone.matrix or bone.matrix_world
@@ -1818,10 +1818,14 @@ def paste_bone_matrix(bone, matrix_copied, constrained, x_filter = True):
if x_filter : matrix_copied = filter_matrix_properties(context, getattr(bone, matrix_attr), matrix_copied)
# bone.matrix = bone.id_data.matrix_world.inverted() @ matrix_copied
setattr(bone, matrix_attr, matrix_copied) # bone.id_data.matrix_world.inverted() @
children = set(bone.children_recursive).intersection(bones)
if children or bone in constrained:
# print(f'found children {[child.name for child in children]} in bone {bone.name}' )
context.view_layer.update()
#Check if the bone has constrainsts on it that need extra iteration
if bone not in constrained:
# filter_matrix_properties(context, bone.matrix, matrix_copied)
return
context.view_layer.update()
matrix_copied = reverse_bone_constraints(context, bone, matrix_copied)
if x_filter : matrix_copied = filter_matrix_properties(context, bone.matrix, matrix_copied)
@@ -1832,8 +1836,12 @@ def paste_bone_matrix(bone, matrix_copied, constrained, x_filter = True):
def paste_bones_matrices(bones_matrices, constrained, x_filter = True):
#running again separatly in case the bones are in a hierarchy and influencing each other
pasted_bones = set()
for bone, matrix_copied in bones_matrices.items():
paste_bone_matrix(bone, matrix_copied, constrained, x_filter)
#Get the rest of the bones to check if they are children of the current bone
bones = set(bones_matrices.keys()).difference(pasted_bones)
paste_bone_matrix(bone, matrix_copied, constrained, bones, x_filter)
pasted_bones.add(bone)
class PasteRelativeMatrix(bpy.types.Operator):
"""paste the relative matrix of the selection"""
@@ -2522,7 +2530,15 @@ class ConvertRotationMode(bpy.types.Operator):
# @classmethod
# def poll(cls, context):
# return context.object.type == 'ARMATURE'
def switch_rot_mode_keyframes(self, obj, posebone):
# Switching any rotation mode keyframes to the new rotation mode value using to_rot_mode_index
bone_path = posebone.path_from_id() + '.' if type(posebone) == bpy.types.PoseBone else ''
fcurves = get_fcurves_channelbag(obj, obj.animation_data.action)
fcu_rotation_mode = fcurves.find(data_path = bone_path + 'rotation_mode', index = 0)
if fcu_rotation_mode:
for keyframe in fcu_rotation_mode.keyframe_points:
keyframe.co[1] = self.to_rot_mode_index
def execute(self, context):
scene = context.scene
selected_bones = context.selected_pose_bones
@@ -2530,7 +2546,8 @@ class ConvertRotationMode(bpy.types.Operator):
to_rot_mode = scene.animtoolbox.rotation_mode
to_rot_mode_fcu = rot_mode_to_channel(to_rot_mode)
#Getting the index of the rotation mode we want to convert to
self.to_rot_mode_index = list(scene.animtoolbox.bl_rna.properties['rotation_mode'].enum_items.keys()).index(to_rot_mode)
#get the keyframes from the bones
for posebone in selected_bones:
@@ -2548,16 +2565,21 @@ class ConvertRotationMode(bpy.types.Operator):
keyframes = emp.get_bone_keyframes(posebone, transform)
#get all interpolations and handle types of the keyframes
handle_types = emp.get_bone_keyframes(posebone, transform, property = 'interpolation')
interpolations = handle_types[::3]
handle_left_type = handle_types[1::3]
handle_right_type = handle_types[2::3]
# rotation_mode_keyframes = emp.get_bone_keyframes(posebone, 'rotation_mode')
self.switch_rot_mode_keyframes(obj, posebone)
inbetweens = []
smartframes = sorted(set(map(lambda x: round(x, 2), keyframes[::2])))
inbetweens = add_inbetweens(smartframes)
all_frames = sorted(smartframes + inbetweens)
#get all interpolations and handle types of the keyframes
if len(smartframes) > 1:
handle_types = emp.get_bone_keyframes(posebone, transform, property = 'interpolation')
interpolations = handle_types[::3]
handle_left_type = handle_types[1::3]
handle_right_type = handle_types[2::3]
inbetweens = add_inbetweens(smartframes)
all_frames = sorted(smartframes + inbetweens)
new_path = posebone.path_from_id() + '.' + to_rot_mode_fcu
#define array length
@@ -2632,13 +2654,15 @@ class ConvertRotationMode(bpy.types.Operator):
keyframe = new_fcu.keyframe_points[-1]
keyframe.co = (frame, fcu_keyframes[new_fcu][frame])
keyframe.interpolation = interpolations[frame_index]
keyframe.handle_left_type = handle_left_type[frame_index]
keyframe.handle_right_type = handle_right_type[frame_index]
if inbetweens:
keyframe.interpolation = interpolations[frame_index]
keyframe.handle_left_type = handle_left_type[frame_index]
keyframe.handle_right_type = handle_right_type[frame_index]
new_fcu.update()
add_interpolations(new_fcurves, fcu_inbetweens)
if inbetweens:
add_interpolations(new_fcurves, fcu_inbetweens)
posebone.rotation_mode = to_rot_mode