From ffb98fc02be32a6aeb888cfaaf6aaf412174f018 Mon Sep 17 00:00:00 2001 From: Blazer Silving Date: Sun, 19 Jan 2025 03:17:45 -0600 Subject: [PATCH] Function to select bones in pose --- common.py | 433 ++++++++++++++++++++++++++------------------------- operators.py | 13 +- 2 files changed, 232 insertions(+), 214 deletions(-) diff --git a/common.py b/common.py index 3987db2..d53fcbb 100644 --- a/common.py +++ b/common.py @@ -1,212 +1,223 @@ -import bpy -import mathutils - - -def getArmatureData(context): - try: - arm_object = context.active_object - if arm_object and arm_object.type == "ARMATURE": - return arm_object, getattr(arm_object, "pose_library", None) - elif arm_object and arm_object.parent and arm_object.parent.type == "ARMATURE": - return arm_object.parent, getattr(arm_object.parent, "pose_library", None) - else: - return None, None - except: - return None, None - - -def getArmatureAction(context): - try: - arm_object, pose_library = getArmatureData(context) - if getattr(arm_object.animation_data.action, "pose_markers", None): - return getattr(arm_object.animation_data, "action", None) - except: - pass - - -def searchPoseMarker(context, posename, type): - try: - arm_object, pose_library = getArmatureData(context) - if type == "marker": - return pose_library.pose_markers.get(posename, None) - if type == "frame": - return pose_library.pose_markers.get(posename, None).frame - if type == "index": - return pose_library.pose_markers.find(posename) - except: - pass - - -def findFcurve(context, bone_name, transform, index_int): - arm_object, pose_library = getArmatureData(context) - pose_markers = pose_library.pose_markers - active_frame = pose_markers.active.frame - - fcurve_object = pose_library.fcurves.find( - 'pose.bones["'+bone_name+'"].'+transform+'', index=index_int) - if hasattr(fcurve_object, 'evaluate'): - return fcurve_object.evaluate(active_frame) - else: - return None - - -def createFcurve(context, bone_name, transform, index_int): - arm_object, pose_library = getArmatureData(context) - pose_markers = pose_library.pose_markers - - try: - pose_library.fcurves.new( - 'pose.bones["'+bone_name+'"].'+transform+'', index=index_int, action_group=bone_name) - return - except: - pass - - -def findKeyframe(context, bone, active_frame): - arm_object, pose_library = getArmatureData(context) - - for fcu in pose_library.fcurves: - if fcu.data_path.startswith('pose.bones["'+bone.name+'"]'): - for kp in fcu.keyframe_points: - if kp.co.x == active_frame: - return fcu.data_path - - -def createKeyframe(context, bone_name, transform, index_int, new_marker, loc): - arm_object, pose_library = getArmatureData(context) - pose_markers = pose_library.pose_markers - - try: - pose_library.fcurves.find( - 'pose.bones["'+bone_name+'"].'+transform+'', index=index_int).keyframe_points.insert(new_marker, loc) - return - except: - pass - - -def setKeyframesFromBones(context, arm_object, new_marker): - none_selected = True - for bone in arm_object.pose.bones: - if bone.bone.select: - none_selected = False - - for bone in arm_object.pose.bones: - if bone.bone.select or none_selected == True: - bone_name = bone.name - - if bone.rotation_mode == "XYZ": - rot_mode = "rotation_euler" - elif bone.rotation_mode == "YZX": - rot_mode = "rotation_euler" - elif bone.rotation_mode == "ZXY": - rot_mode = "rotation_euler" - elif bone.rotation_mode == "QUATERNION": - rot_mode = "rotation_quaternion" - else: - self.report({'WARNING'}, "DSPL: Unsupported bone: " + bone.name + ": " + bone.rotation_mode) - rot_mode = None - - loc_x = bone.location[0] - loc_y = bone.location[1] - loc_z = bone.location[2] - createFcurve(context, bone_name, "location", 0) - createFcurve(context, bone_name, "location", 1) - createFcurve(context, bone_name, "location", 2) - createKeyframe(context, bone_name, "location", 0, new_marker, loc_x) - createKeyframe(context, bone_name, "location", 1, new_marker, loc_y) - createKeyframe(context, bone_name, "location", 2, new_marker, loc_z) - if rot_mode == "rotation_quaternion": - rot_w = bone.rotation_quaternion[0] - rot_x = bone.rotation_quaternion[1] - rot_y = bone.rotation_quaternion[2] - rot_z = bone.rotation_quaternion[3] - createFcurve(context, bone_name, rot_mode, 0) - createFcurve(context, bone_name, rot_mode, 1) - createFcurve(context, bone_name, rot_mode, 2) - createFcurve(context, bone_name, rot_mode, 3) - createKeyframe(context, bone_name, rot_mode, 0, new_marker, rot_w) - createKeyframe(context, bone_name, rot_mode, 1, new_marker, rot_x) - createKeyframe(context, bone_name, rot_mode, 2, new_marker, rot_y) - createKeyframe(context, bone_name, rot_mode, 3, new_marker, rot_z) - elif rot_mode == "rotation_euler": - rot_x = bone.rotation_euler[0] - rot_y = bone.rotation_euler[1] - rot_z = bone.rotation_euler[2] - createFcurve(context, bone_name, rot_mode, 0) - createFcurve(context, bone_name, rot_mode, 1) - createFcurve(context, bone_name, rot_mode, 2) - createKeyframe(context, bone_name, rot_mode, 0, new_marker, rot_x) - createKeyframe(context, bone_name, rot_mode, 1, new_marker, rot_y) - createKeyframe(context, bone_name, rot_mode, 2, new_marker, rot_z) - scl_x = bone.scale[0] - scl_y = bone.scale[1] - scl_z = bone.scale[2] - createFcurve(context, bone_name, "scale", 0) - createFcurve(context, bone_name, "scale", 1) - createFcurve(context, bone_name, "scale", 2) - createKeyframe(context, bone_name, "scale", 0, new_marker, scl_x) - createKeyframe(context, bone_name, "scale", 1, new_marker, scl_y) - createKeyframe(context, bone_name, "scale", 2, new_marker, scl_z) - - -def setBonesfromKeyframes(context, arm_object, active_marker): - none_selected = True - for bone in arm_object.pose.bones: - if bone.bone.select: - none_selected = False - - for bone in arm_object.pose.bones: - if bone.bone.select or none_selected == True: - bone_name = bone.name - - if findKeyframe(context, bone, active_marker.frame) is None: - continue - - if bone.rotation_mode == "XYZ": - rot_mode = "rotation_euler" - elif bone.rotation_mode == "YZX": - rot_mode = "rotation_euler" - elif bone.rotation_mode == "ZXY": - rot_mode = "rotation_euler" - elif bone.rotation_mode == "QUATERNION": - rot_mode = "rotation_quaternion" - else: - self.report({'WARNING'}, "DSPL: Unsupported bone: " + bone.name + ": " + bone.rotation_mode) - rot_mode = None - - loc_x = findFcurve(context, bone_name, "location", 0) or 0.0 - loc_y = findFcurve(context, bone_name, "location", 1) or 0.0 - loc_z = findFcurve(context, bone_name, "location", 2) or 0.0 - if rot_mode == "rotation_quaternion": - rot_w = findFcurve(context, bone_name, rot_mode, 0) or 1.0 - rot_x = findFcurve(context, bone_name, rot_mode, 1) or 0.0 - rot_y = findFcurve(context, bone_name, rot_mode, 2) or 0.0 - rot_z = findFcurve(context, bone_name, rot_mode, 3) or 0.0 - elif rot_mode == "rotation_euler": - rot_x = findFcurve(context, bone_name, rot_mode, 0) or 0.0 - rot_y = findFcurve(context, bone_name, rot_mode, 1) or 0.0 - rot_z = findFcurve(context, bone_name, rot_mode, 2) or 0.0 - scl_x = findFcurve(context, bone_name, "scale", 0) or 1.0 - scl_y = findFcurve(context, bone_name, "scale", 1) or 1.0 - scl_z = findFcurve(context, bone_name, "scale", 2) or 1.0 - - bone.location = mathutils.Vector((loc_x, loc_y, loc_z)) - if bone.rotation_mode == "XYZ": - bone.rotation_euler = mathutils.Euler( - (rot_x, rot_y, rot_z)) - elif bone.rotation_mode == "YZX": - bone.rotation_euler = mathutils.Euler( - (rot_x, rot_y, rot_z)) - elif bone.rotation_mode == "ZXY": - bone.rotation_euler = mathutils.Euler( - (rot_z, rot_x, rot_y)) - elif bone.rotation_mode == "YXZ": - bone.rotation_euler = mathutils.Euler( - (rot_y, rot_x, rot_z)) - elif bone.rotation_mode == "XZY": - bone.rotation_euler = mathutils.Euler( - (rot_x, rot_z, rot_y)) - elif rot_mode == "rotation_quaternion": - bone.rotation_quaternion = mathutils.Quaternion( - (rot_w, rot_x, rot_y, rot_z)) +import bpy +import mathutils + + +def getArmatureData(context): + try: + arm_object = context.active_object + if arm_object and arm_object.type == "ARMATURE": + return arm_object, getattr(arm_object, "pose_library", None) + elif arm_object and arm_object.parent and arm_object.parent.type == "ARMATURE": + return arm_object.parent, getattr(arm_object.parent, "pose_library", None) + else: + return None, None + except: + return None, None + + +def getArmatureAction(context): + try: + arm_object, pose_library = getArmatureData(context) + if getattr(arm_object.animation_data.action, "pose_markers", None): + return getattr(arm_object.animation_data, "action", None) + except: + pass + + +def searchPoseMarker(context, posename, type): + try: + arm_object, pose_library = getArmatureData(context) + if type == "marker": + return pose_library.pose_markers.get(posename, None) + if type == "frame": + return pose_library.pose_markers.get(posename, None).frame + if type == "index": + return pose_library.pose_markers.find(posename) + except: + pass + + +def selectBonesinPose(context, posename, active_marker): + try: + arm_object, pose_library = getArmatureData(context) + for bone in arm_object.pose.bones: + bone.bone.select = False + if findKeyframe(context, bone, active_marker.frame): + bone.bone.select = True + except: + pass + + +def findFcurve(context, bone_name, transform, index_int): + arm_object, pose_library = getArmatureData(context) + pose_markers = pose_library.pose_markers + active_frame = pose_markers.active.frame + + fcurve_object = pose_library.fcurves.find( + 'pose.bones["'+bone_name+'"].'+transform+'', index=index_int) + if hasattr(fcurve_object, 'evaluate'): + return fcurve_object.evaluate(active_frame) + else: + return None + + +def createFcurve(context, bone_name, transform, index_int): + arm_object, pose_library = getArmatureData(context) + pose_markers = pose_library.pose_markers + + try: + pose_library.fcurves.new( + 'pose.bones["'+bone_name+'"].'+transform+'', index=index_int, action_group=bone_name) + return + except: + pass + + +def findKeyframe(context, bone, active_frame): + arm_object, pose_library = getArmatureData(context) + + for fcu in pose_library.fcurves: + if fcu.data_path.startswith('pose.bones["'+bone.name+'"]'): + for kp in fcu.keyframe_points: + if kp.co.x == active_frame: + return fcu.data_path + + +def createKeyframe(context, bone_name, transform, index_int, new_marker, loc): + arm_object, pose_library = getArmatureData(context) + pose_markers = pose_library.pose_markers + + try: + pose_library.fcurves.find( + 'pose.bones["'+bone_name+'"].'+transform+'', index=index_int).keyframe_points.insert(new_marker, loc) + return + except: + pass + + +def setKeyframesFromBones(context, arm_object, new_marker): + none_selected = True + for bone in arm_object.pose.bones: + if bone.bone.select: + none_selected = False + + for bone in arm_object.pose.bones: + if bone.bone.select or none_selected == True: + bone_name = bone.name + + if bone.rotation_mode == "XYZ": + rot_mode = "rotation_euler" + elif bone.rotation_mode == "YZX": + rot_mode = "rotation_euler" + elif bone.rotation_mode == "ZXY": + rot_mode = "rotation_euler" + elif bone.rotation_mode == "QUATERNION": + rot_mode = "rotation_quaternion" + else: + self.report({'WARNING'}, "DSPL: Unsupported bone: " + bone.name + ": " + bone.rotation_mode) + rot_mode = None + + loc_x = bone.location[0] + loc_y = bone.location[1] + loc_z = bone.location[2] + createFcurve(context, bone_name, "location", 0) + createFcurve(context, bone_name, "location", 1) + createFcurve(context, bone_name, "location", 2) + createKeyframe(context, bone_name, "location", 0, new_marker, loc_x) + createKeyframe(context, bone_name, "location", 1, new_marker, loc_y) + createKeyframe(context, bone_name, "location", 2, new_marker, loc_z) + if rot_mode == "rotation_quaternion": + rot_w = bone.rotation_quaternion[0] + rot_x = bone.rotation_quaternion[1] + rot_y = bone.rotation_quaternion[2] + rot_z = bone.rotation_quaternion[3] + createFcurve(context, bone_name, rot_mode, 0) + createFcurve(context, bone_name, rot_mode, 1) + createFcurve(context, bone_name, rot_mode, 2) + createFcurve(context, bone_name, rot_mode, 3) + createKeyframe(context, bone_name, rot_mode, 0, new_marker, rot_w) + createKeyframe(context, bone_name, rot_mode, 1, new_marker, rot_x) + createKeyframe(context, bone_name, rot_mode, 2, new_marker, rot_y) + createKeyframe(context, bone_name, rot_mode, 3, new_marker, rot_z) + elif rot_mode == "rotation_euler": + rot_x = bone.rotation_euler[0] + rot_y = bone.rotation_euler[1] + rot_z = bone.rotation_euler[2] + createFcurve(context, bone_name, rot_mode, 0) + createFcurve(context, bone_name, rot_mode, 1) + createFcurve(context, bone_name, rot_mode, 2) + createKeyframe(context, bone_name, rot_mode, 0, new_marker, rot_x) + createKeyframe(context, bone_name, rot_mode, 1, new_marker, rot_y) + createKeyframe(context, bone_name, rot_mode, 2, new_marker, rot_z) + scl_x = bone.scale[0] + scl_y = bone.scale[1] + scl_z = bone.scale[2] + createFcurve(context, bone_name, "scale", 0) + createFcurve(context, bone_name, "scale", 1) + createFcurve(context, bone_name, "scale", 2) + createKeyframe(context, bone_name, "scale", 0, new_marker, scl_x) + createKeyframe(context, bone_name, "scale", 1, new_marker, scl_y) + createKeyframe(context, bone_name, "scale", 2, new_marker, scl_z) + + +def setBonesfromKeyframes(context, arm_object, active_marker): + none_selected = True + for bone in arm_object.pose.bones: + if bone.bone.select: + none_selected = False + + for bone in arm_object.pose.bones: + if bone.bone.select or none_selected == True: + bone_name = bone.name + + if findKeyframe(context, bone, active_marker.frame) is None: + continue + + if bone.rotation_mode == "XYZ": + rot_mode = "rotation_euler" + elif bone.rotation_mode == "YZX": + rot_mode = "rotation_euler" + elif bone.rotation_mode == "ZXY": + rot_mode = "rotation_euler" + elif bone.rotation_mode == "QUATERNION": + rot_mode = "rotation_quaternion" + else: + self.report({'WARNING'}, "DSPL: Unsupported bone: " + bone.name + ": " + bone.rotation_mode) + rot_mode = None + + loc_x = findFcurve(context, bone_name, "location", 0) or 0.0 + loc_y = findFcurve(context, bone_name, "location", 1) or 0.0 + loc_z = findFcurve(context, bone_name, "location", 2) or 0.0 + if rot_mode == "rotation_quaternion": + rot_w = findFcurve(context, bone_name, rot_mode, 0) or 1.0 + rot_x = findFcurve(context, bone_name, rot_mode, 1) or 0.0 + rot_y = findFcurve(context, bone_name, rot_mode, 2) or 0.0 + rot_z = findFcurve(context, bone_name, rot_mode, 3) or 0.0 + elif rot_mode == "rotation_euler": + rot_x = findFcurve(context, bone_name, rot_mode, 0) or 0.0 + rot_y = findFcurve(context, bone_name, rot_mode, 1) or 0.0 + rot_z = findFcurve(context, bone_name, rot_mode, 2) or 0.0 + scl_x = findFcurve(context, bone_name, "scale", 0) or 1.0 + scl_y = findFcurve(context, bone_name, "scale", 1) or 1.0 + scl_z = findFcurve(context, bone_name, "scale", 2) or 1.0 + + bone.location = mathutils.Vector((loc_x, loc_y, loc_z)) + if bone.rotation_mode == "XYZ": + bone.rotation_euler = mathutils.Euler( + (rot_x, rot_y, rot_z)) + elif bone.rotation_mode == "YZX": + bone.rotation_euler = mathutils.Euler( + (rot_x, rot_y, rot_z)) + elif bone.rotation_mode == "ZXY": + bone.rotation_euler = mathutils.Euler( + (rot_z, rot_x, rot_y)) + elif bone.rotation_mode == "YXZ": + bone.rotation_euler = mathutils.Euler( + (rot_y, rot_x, rot_z)) + elif bone.rotation_mode == "XZY": + bone.rotation_euler = mathutils.Euler( + (rot_x, rot_z, rot_y)) + elif rot_mode == "rotation_quaternion": + bone.rotation_quaternion = mathutils.Quaternion( + (rot_w, rot_x, rot_y, rot_z)) bone.scale = mathutils.Vector((scl_x, scl_y, scl_z)) \ No newline at end of file diff --git a/operators.py b/operators.py index e161cc4..e4e3c82 100644 --- a/operators.py +++ b/operators.py @@ -254,7 +254,7 @@ class DSPL_OT_MovePose(bpy.types.Operator): class DSPL_OT_ApplyPose(bpy.types.Operator): bl_idname = "dspl.apply_pose" bl_label = "Apply Pose" - bl_description = "Apply Pose (Ctrl+Click to select, Shift+Click to rename, Alt+Click to remove)" + bl_description = "Apply Pose (Ctrl+Click to select bones, Shift+Click to rename, Alt+Click to remove)" bl_options = {'REGISTER', 'UNDO'} posename: bpy.props.StringProperty() @@ -283,9 +283,16 @@ class DSPL_OT_ApplyPose(bpy.types.Operator): def invoke(self, context, event): if event.ctrl: - # Select + # Select bones arm_object, pose_library = getArmatureData(context) - pose_library.pose_markers.active_index = searchPoseMarker(context, posename=self.posename, type="index") + active_marker = searchPoseMarker(context, posename=self.posename, type="marker") + + arm_object.select = True + bpy.context.view_layer.objects.active = arm_object + bpy.ops.object.mode_set(mode='POSE') + selectBonesinPose(context, self.posename, active_marker) + + self.execute(context) return {'FINISHED'} elif event.alt: # Remove