diff --git a/README.md b/README.md index d1b87e3..91ac6f4 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,54 @@ -# Damn Simple Pose Library +# Yet Another Pose Library -In Blender 3.x, a new Asset-based Pose system was introduced. That's fine and dandy, but it was not (and still is not as of Jan 2025) ready to replace the old Action-based Pose Library system. +For Blender 3.5 - 4.3 (4.1 recommended). -The former Pose Library was deprecated and gutted rapidly during Blender 3.x, leaving legacy users high and dry. This addon brings the feature back as best as it can in a modern panel. Most, if not all existing Pose Libraries should work without any modifications, little new is introduced outside of string suffixes and mitigations (read further). +During the Blender 3.x releases, a new Asset-based Pose system was introduced. That's fine and dandy, but it was not (and still is not as of Jan 2025) ready to replace the old Action-based Pose Library system. The former Pose Library was quickly deprecated and removed, leaving legacy users high and dry. -## Features +This addon brings the Legacy Pose Library back as best as it can in a modern panel, and tries to stick as close to the old system as possible. Most, if not all existing Pose Libraries should work without any modifications. Little new is introduced outside of UI enhancements and handling for new data. + +These excellent addons also address this removal in their own ways, check them out: +- [Sakura Poselib](https://github.com/kafuji/Sakura_Poselib) +- [gret](https://github.com/greisane/gret?tab=readme-ov-file#animation-actions-panel) +- [Amarillo's Pose Library](https://github.com/AmarilloArts/Amarillos-Pose-Library) + +## Old Features + +- The Pose Library list panel is ported from Armature Data Properties to a Sidebar (N) panel. -- Supports Blender 3.3 - 4.3 (4.1 recommended). -- New panel interface for interacting with pose libraries, inspired by [gret's Actions Panel feature](https://github.com/greisane/gret?tab=readme-ov-file#animation-actions-panel). - - The older Pose Library list layout is provided as option. - Operators and data property [that were removed in 3.5](https://projects.blender.org/blender/blender/issues/93406) are ported from C to Python: - - `dspl.apply_pose` - - `dspl.browse_poses` - - `dspl.create_pose_library` - - `dspl.convert_pose_library` - - `dspl.add_pose` - - `dspl.move_pose` - - `dspl.remove_pose` - - `dspl.rename_pose` - - `dspl.unlink_pose_library` + - `yapl.apply_pose` + - `yapl.browse_poses` + - `yapl.create_pose_library` + - `yapl.convert_pose_library` + - `yapl.add_pose` + - `yapl.move_pose` + - `yapl.remove_pose` + - `yapl.rename_pose` + - `yapl.unlink_pose_library` - `Object.pose_library` +## New Features + +- New panel interface for interacting with pose libraries, inspired by [gret's Actions Panel feature](https://github.com/greisane/gret?tab=readme-ov-file#animation-actions-panel). + - Hover over buttons for tooltips + +- Operator to protect potentially-orphaned pose data (read Considerations) + - `yapl.protect_orphan_pose_library` + ## Installation -1. [Download the repository as a zip](https://git.bkspl.me/breakingspell/DamnSimplePoseLibrary/archive/develop.zip), or otherwise clone the repository. +1. [Download the repository as a zip](https://git.bkspl.me/breakingspell/YetAnotherPoseLibrary/archive/develop.zip), or otherwise clone the repository. 2. Install as an Add-on in Blender via Install -> Zip, and enable. 3. Optionally configure the suffix strings to fit your workflow, and whether the orhpan checker should run at startup. ## Usage 1. Open Sidebar (`N`), and choose the `Pose` tab. -2. Select existing Pose Library from drop-down, or create a new library. +2. Select an Armature Object, or an Object parented to an Armature. +3. Select existing Pose Library from drop-down, or create a new library. -### Hotkeys: +### 3D View Hotkeys: - `Shift + L` - Add/Replace Pose - `Alt + L` - Browse Poses with Arrow Keys -### Menu Controls +### New Panel Controls - `Single click` - Apply Pose - `Shift + Click` - Rename Pose - `Alt + Click` - Remove Pose @@ -43,6 +58,6 @@ The former Pose Library was deprecated and gutted rapidly during Blender 3.x, le ## Considerations - Opening older scenes will cause existing Pose Libraries to unlink from their former targets and fall into orphan state. They can be re-linked and will retain their link when saved afterwards, but would otherwise disappear if saved without linking or protecting the datablock. - This is due to the core DNA type `poselib` having been removed, so objects will drop the data. [There is no way to prevent this](https://developer.blender.org/docs/features/core/rna/#internals) as Python ID properties cannot be present at program runtime, only once the add-on is initialized. - - To mitgate, an operator is provided to protect orphaned pose libraries: `dspl.protect_orphan_pose_library`. + - To mitgate, an operator is provided to protect orphaned pose libraries: `yapl.protect_orphan_pose_library`. - This add-on was made much easier by the `pose_markers` property being retained for converting old pose libraries to the new asset system. If they decide to remove that property as well, there will be a need to improvise an index-based lookup. diff --git a/__init__.py b/__init__.py index 77a0df3..d5afdd3 100644 --- a/__init__.py +++ b/__init__.py @@ -2,11 +2,11 @@ import bpy from . import gui, operators, common, keymaps bl_info = \ { - "name": "Damn Simple Pose Library", + "name": "Yet Another Pose Library", "author": "breakingspell", "version": (0, 1, 0), "blender": (3, 6, 0), - "description": "Re-implement Pose Library", + "description": "Re-implement 3.x legacy Pose Library", "category": "Object Data", } @@ -22,13 +22,13 @@ if _need_reload: operators = importlib.reload(operators) -class dsplSettings(bpy.types.PropertyGroup): +class yaplSettings(bpy.types.PropertyGroup): new_menu: bpy.props.BoolProperty( name="New Menu", description="Toggle New Menu", default=True) edit_mode: bpy.props.BoolProperty( name="Edit Mode", description="Toggle Edit Mode", default=False) -classes = dsplSettings +classes = yaplSettings def pose_libraries_poll(self, action): if getattr(action, "pose_markers", None): @@ -36,15 +36,15 @@ def pose_libraries_poll(self, action): def register(): from bpy.utils import register_class - register_class(dsplSettings) + register_class(yaplSettings) bpy.types.Object.pose_library = bpy.props.PointerProperty( name="Active Pose Library", description="", type=bpy.types.Action, override={'LIBRARY_OVERRIDABLE'}, poll=pose_libraries_poll) - bpy.types.Scene.dsplSettings = bpy.props.PointerProperty( - type=dsplSettings, override={'LIBRARY_OVERRIDABLE'}) + bpy.types.Scene.yaplSettings = bpy.props.PointerProperty( + type=yaplSettings, override={'LIBRARY_OVERRIDABLE'}) gui.register() operators.register() @@ -52,9 +52,9 @@ def register(): def unregister(): from bpy.utils import unregister_class - unregister_class(dsplSettings) + unregister_class(yaplSettings) - del bpy.types.Scene.dsplSettings + del bpy.types.Scene.yaplSettings del bpy.types.Object.pose_library keymaps.unregister() diff --git a/common.py b/common.py index 090f453..880683d 100644 --- a/common.py +++ b/common.py @@ -2,7 +2,7 @@ import bpy import mathutils -def getArmatureData(context): +def get_armature_data(context): try: arm_object = context.active_object if arm_object and arm_object.type == "ARMATURE": @@ -15,18 +15,18 @@ def getArmatureData(context): return None, None -def getArmatureAction(context): +def get_armature_action(context): try: - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(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): +def search_pose_marker(context, posename, type): try: - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) if type == "marker": return pose_library.pose_markers.get(posename, None) if type == "frame": @@ -37,8 +37,8 @@ def searchPoseMarker(context, posename, type): pass -def findFcurve(context, bone_name, transform, index_int): - arm_object, pose_library = getArmatureData(context) +def find_fcurve(context, bone_name, transform, index_int): + arm_object, pose_library = get_armature_data(context) pose_markers = pose_library.pose_markers active_frame = pose_markers.active.frame @@ -50,8 +50,8 @@ def findFcurve(context, bone_name, transform, index_int): return None -def createFcurve(context, bone_name, transform, index_int): - arm_object, pose_library = getArmatureData(context) +def create_fcurve(context, bone_name, transform, index_int): + arm_object, pose_library = get_armature_data(context) pose_markers = pose_library.pose_markers try: @@ -62,8 +62,8 @@ def createFcurve(context, bone_name, transform, index_int): pass -def createKeyframe(context, bone_name, transform, index_int, new_marker, loc): - arm_object, pose_library = getArmatureData(context) +def create_keyframe(context, bone_name, transform, index_int, new_marker, loc): + arm_object, pose_library = get_armature_data(context) pose_markers = pose_library.pose_markers try: @@ -74,7 +74,7 @@ def createKeyframe(context, bone_name, transform, index_int, new_marker, loc): pass -def setKeyframesFromBones(context, arm_object, new_marker): +def set_keyframes_from_bones(context, arm_object, new_marker): none_selected = True for bone in arm_object.pose.bones: if bone.bone.select: @@ -93,53 +93,53 @@ def setKeyframesFromBones(context, arm_object, new_marker): elif bone.rotation_mode == "QUATERNION": rot_mode = "rotation_quaternion" else: - self.report({'WARNING'}, "DSPL: Unsupported bone: " + bone.name + ": " + bone.rotation_mode) + self.report({'WARNING'}, "YAPL: 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) + create_fcurve(context, bone_name, "location", 0) + create_fcurve(context, bone_name, "location", 1) + create_fcurve(context, bone_name, "location", 2) + create_keyframe(context, bone_name, "location", 0, new_marker, loc_x) + create_keyframe(context, bone_name, "location", 1, new_marker, loc_y) + create_keyframe(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) + create_fcurve(context, bone_name, rot_mode, 0) + create_fcurve(context, bone_name, rot_mode, 1) + create_fcurve(context, bone_name, rot_mode, 2) + create_fcurve(context, bone_name, rot_mode, 3) + create_keyframe(context, bone_name, rot_mode, 0, new_marker, rot_w) + create_keyframe(context, bone_name, rot_mode, 1, new_marker, rot_x) + create_keyframe(context, bone_name, rot_mode, 2, new_marker, rot_y) + create_keyframe(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) + create_fcurve(context, bone_name, rot_mode, 0) + create_fcurve(context, bone_name, rot_mode, 1) + create_fcurve(context, bone_name, rot_mode, 2) + create_keyframe(context, bone_name, rot_mode, 0, new_marker, rot_x) + create_keyframe(context, bone_name, rot_mode, 1, new_marker, rot_y) + create_keyframe(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) + create_fcurve(context, bone_name, "scale", 0) + create_fcurve(context, bone_name, "scale", 1) + create_fcurve(context, bone_name, "scale", 2) + create_keyframe(context, bone_name, "scale", 0, new_marker, scl_x) + create_keyframe(context, bone_name, "scale", 1, new_marker, scl_y) + create_keyframe(context, bone_name, "scale", 2, new_marker, scl_z) -def setBonesfromKeyframes(context, arm_object, active_marker): +def set_bones_from_keyframes(context, arm_object, active_marker): none_selected = True for bone in arm_object.pose.bones: if bone.bone.select: @@ -158,24 +158,24 @@ def setBonesfromKeyframes(context, arm_object, active_marker): elif bone.rotation_mode == "QUATERNION": rot_mode = "rotation_quaternion" else: - self.report({'WARNING'}, "DSPL: Unsupported bone: " + bone.name + ": " + bone.rotation_mode) + self.report({'WARNING'}, "YAPL: 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 + loc_x = find_fcurve(context, bone_name, "location", 0) or 0.0 + loc_y = find_fcurve(context, bone_name, "location", 1) or 0.0 + loc_z = find_fcurve(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 + rot_w = find_fcurve(context, bone_name, rot_mode, 0) or 1.0 + rot_x = find_fcurve(context, bone_name, rot_mode, 1) or 0.0 + rot_y = find_fcurve(context, bone_name, rot_mode, 2) or 0.0 + rot_z = find_fcurve(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 + rot_x = find_fcurve(context, bone_name, rot_mode, 0) or 0.0 + rot_y = find_fcurve(context, bone_name, rot_mode, 1) or 0.0 + rot_z = find_fcurve(context, bone_name, rot_mode, 2) or 0.0 + scl_x = find_fcurve(context, bone_name, "scale", 0) or 1.0 + scl_y = find_fcurve(context, bone_name, "scale", 1) or 1.0 + scl_z = find_fcurve(context, bone_name, "scale", 2) or 1.0 bone.location = mathutils.Vector((loc_x, loc_y, loc_z)) if bone.rotation_mode == "XYZ": diff --git a/gui.py b/gui.py index 52467e3..05bab0b 100644 --- a/gui.py +++ b/gui.py @@ -2,9 +2,9 @@ import bpy from .common import * -class DATA_PT_DSPLPanel(bpy.types.Panel): - bl_label = "Damn Simple Pose Library" - bl_id = "DATA_PT_DSPLPanel" +class DATA_PT_YaplPanel(bpy.types.Panel): + bl_label = "Yet Another Pose Library" + bl_id = "DATA_PT_YaplPanel" bl_space_type = 'VIEW_3D' bl_region_type = 'UI' bl_category = 'Pose' @@ -14,14 +14,14 @@ class DATA_PT_DSPLPanel(bpy.types.Panel): return len(bpy.context.selected_objects) def draw(self, context): - dspl_panel_layout = self.layout - dsplsettings = bpy.context.scene.dsplSettings + yapl_panel_layout = self.layout + yaplsettings = bpy.context.scene.yaplSettings # Detect Armature object and parent - armature_layout = dspl_panel_layout.column(align=True) + armature_layout = yapl_panel_layout.column(align=True) active_obj = context.active_object - arm_object, pose_library = getArmatureData(context) - pose_library_action = getArmatureAction(context) + arm_object, pose_library = get_armature_data(context) + pose_library_action = get_armature_action(context) if arm_object: if arm_object == active_obj: @@ -33,35 +33,35 @@ class DATA_PT_DSPLPanel(bpy.types.Panel): if pose_library or pose_library_action: if pose_library and not pose_library_action: armature_layout.template_ID( - arm_object, "pose_library", new="dspl.create_pose_library", unlink="dspl.unlink_pose_library") + arm_object, "pose_library", new="yapl.create_pose_library", unlink="yapl.unlink_pose_library") elif pose_library_action and not pose_library: armature_layout.template_ID( - arm_object.animation_data, "action", new="dspl.create_pose_library") + arm_object.animation_data, "action", new="yapl.create_pose_library") armature_layout.label( text="Pose Library detected as Action") armature_layout.label( text="You should convert to avoid problems") armature_layout.operator( - "dspl.convert_pose_library", icon='PLUGIN', text="Convert to Pose Library") + "yapl.convert_pose_library", icon='PLUGIN', text="Convert to Pose Library") elif pose_library and pose_library_action: armature_layout.template_ID( - arm_object, "pose_library", new="dspl.create_pose_library") + arm_object, "pose_library", new="yapl.create_pose_library") armature_layout.label(text="Pose Library is opened as Action") armature_layout.label(text="Keyframes will affect pose") armature_layout.operator( - "dspl.convert_pose_library", icon='PLUGIN', text="Unlink from Action") + "yapl.convert_pose_library", icon='PLUGIN', text="Unlink from Action") # List poses in pose library if pose_library: - pose_box_layout = dspl_panel_layout.column() + pose_box_layout = yapl_panel_layout.column() # Menu switcher pose_box_menu_switcher_layout = pose_box_layout.row() pose_box_menu_switcher_layout.prop( - dsplsettings, "new_menu", icon='PMARKER_ACT', text="New Menu", toggle=True) + yaplsettings, "new_menu", icon='PMARKER_ACT', text="New Menu", toggle=True) # Quick controls quick_pose_controls_layout = pose_box_layout.column() @@ -71,16 +71,16 @@ class DATA_PT_DSPLPanel(bpy.types.Panel): quick_apply_layout = quick_pose_controls_layout.split( align=True) quick_apply_layout.operator( - "dspl.browse_poses", icon='CON_ARMATURE', text="Browse") - if dsplsettings.new_menu == False: + "yapl.browse_poses", icon='CON_ARMATURE', text="Browse") + if yaplsettings.new_menu == False: quick_apply_layout.operator( - "dspl.apply_pose", icon='ARMATURE_DATA', text="Apply Pose").posename = pose_library.pose_markers.active.name + "yapl.apply_pose", icon='ARMATURE_DATA', text="Apply Pose").posename = pose_library.pose_markers.active.name else: - quick_apply_layout.prop(dsplsettings, + quick_apply_layout.prop(yaplsettings, "edit_mode", icon='GREASEPENCIL', text="Edit", toggle=True) # New menu - if dsplsettings.new_menu == True: + if yaplsettings.new_menu == True: pose_button_layout = pose_box_layout.row() pose_button_entries_layout = pose_button_layout.column(align=True) for pm in pose_library.pose_markers: @@ -88,27 +88,27 @@ class DATA_PT_DSPLPanel(bpy.types.Panel): # Selected indicator selected = pm.frame == pose_library.pose_markers.active.frame - if dsplsettings.edit_mode == False: + if yaplsettings.edit_mode == False: row.label(text="", icon='PMARKER_ACT' if selected else 'PMARKER_SEL') # Pose operator buttons - if dsplsettings.edit_mode == True: - row.operator('dspl.rename_pose', text=pm.name).posename = pm.name + if yaplsettings.edit_mode == True: + row.operator('yapl.rename_pose', text=pm.name).posename = pm.name else: - row.operator('dspl.apply_pose', text=pm.name).posename = pm.name + row.operator('yapl.apply_pose', text=pm.name).posename = pm.name - if dsplsettings.edit_mode == True: - movebuttondown = row.operator("dspl.move_pose", icon='TRIA_DOWN', text="") + if yaplsettings.edit_mode == True: + movebuttondown = row.operator("yapl.move_pose", icon='TRIA_DOWN', text="") movebuttondown.direction = "DOWN" movebuttondown.posename = pm.name - movebuttonup = row.operator("dspl.move_pose", icon='TRIA_UP', text="") + movebuttonup = row.operator("yapl.move_pose", icon='TRIA_UP', text="") movebuttonup.direction = "UP" movebuttonup.posename = pm.name - row.operator("dspl.remove_pose", icon='REMOVE', text="").posename = pm.name + row.operator("yapl.remove_pose", icon='REMOVE', text="").posename = pm.name # Old menu - elif dsplsettings.new_menu == False: + elif yaplsettings.new_menu == False: pose_list_layout = pose_box_layout.column() # Pose list @@ -123,20 +123,20 @@ class DATA_PT_DSPLPanel(bpy.types.Panel): "wm.call_menu", icon='ADD', text="").name = "OBJECT_MT_AddPoseMenu" if pose_library.pose_markers.active: pose_ops_layout.operator( - "dspl.remove_pose", icon='REMOVE', text="") + "yapl.remove_pose", icon='REMOVE', text="") pose_ops_layout.operator( - "dspl.apply_pose", icon='ARMATURE_DATA', text="" + "yapl.apply_pose", icon='ARMATURE_DATA', text="" ).posename = pose_library.pose_markers.active.name pose_ops_layout.operator( - "dspl.move_pose", icon='TRIA_UP', text="").direction = "UP" + "yapl.move_pose", icon='TRIA_UP', text="").direction = "UP" pose_ops_layout.operator( - "dspl.move_pose", icon='TRIA_DOWN', text="").direction = "DOWN" + "yapl.move_pose", icon='TRIA_DOWN', text="").direction = "DOWN" else: armature_layout.label( text="No Action or Pose Library detected") armature_layout.template_ID( - arm_object, "pose_library", new="dspl.create_pose_library") + arm_object, "pose_library", new="yapl.create_pose_library") else: armature_layout.label(text="No armature or parent selected") @@ -147,13 +147,13 @@ class OBJECT_MT_AddPoseMenu(bpy.types.Menu): bl_label = "Add Pose" def draw(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) - dspl_add_menu_layout = self.layout - dspl_add_menu_layout.operator( - "dspl.add_pose", icon='ADD', text="Add New Pose") + yapl_add_menu_layout = self.layout + yapl_add_menu_layout.operator( + "yapl.add_pose", icon='ADD', text="Add New Pose") if len(pose_library.pose_markers): - dspl_add_menu_layout.menu( + yapl_add_menu_layout.menu( "OBJECT_MT_ReplacePoseMenu", text="Replace Existing Pose", icon="DECORATE_OVERRIDE") @@ -162,17 +162,17 @@ class OBJECT_MT_ReplacePoseMenu(bpy.types.Menu): bl_label = "Add Pose" def draw(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) - dspl_replace_menu_layout = self.layout + yapl_replace_menu_layout = self.layout for pm in pose_library.pose_markers: - op = dspl_replace_menu_layout.operator("dspl.add_pose", text=pm.name, icon="PMARKER") + op = yapl_replace_menu_layout.operator("yapl.add_pose", text=pm.name, icon="PMARKER") op.replace = True op.posename = pm.name classes = ( - DATA_PT_DSPLPanel, + DATA_PT_YaplPanel, OBJECT_MT_AddPoseMenu, OBJECT_MT_ReplacePoseMenu, ) diff --git a/keymaps.py b/keymaps.py index cfd3be6..193dc85 100644 --- a/keymaps.py +++ b/keymaps.py @@ -15,7 +15,7 @@ def register_keymaps(): # Browse Poses km = wm.keyconfigs.addon.keymaps.new(name='Pose', space_type='EMPTY') - kmi = km.keymap_items.new('dspl.browse_poses', 'L', 'PRESS', alt=True) + kmi = km.keymap_items.new('yapl.browse_poses', 'L', 'PRESS', alt=True) addon_keymaps.append((km, kmi)) def unregister_keymaps(): diff --git a/operators.py b/operators.py index e161cc4..7391d33 100644 --- a/operators.py +++ b/operators.py @@ -6,14 +6,14 @@ from .common import * # Operator to create a new pose library -class DSPL_OT_CreatePoseLibrary(bpy.types.Operator): - bl_idname = "dspl.create_pose_library" +class YAPL_OT_CreatePoseLibrary(bpy.types.Operator): + bl_idname = "yapl.create_pose_library" bl_label = "Create Pose Library" bl_description = "Create Pose Library" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) arm_object.pose_library = bpy.data.actions.new( name=arm_object.name + "_PoseLib") arm_object.pose_library.use_fake_user = True @@ -24,14 +24,14 @@ class DSPL_OT_CreatePoseLibrary(bpy.types.Operator): # Operator to convert an action to pose library -class DSPL_OT_ConvertPoseLibrary(bpy.types.Operator): - bl_idname = "dspl.convert_pose_library" +class YAPL_OT_ConvertPoseLibrary(bpy.types.Operator): + bl_idname = "yapl.convert_pose_library" bl_label = "Convert Pose Library" bl_description = "Convert Pose Library" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) if pose_library is None: arm_object.pose_library = arm_object.animation_data.action arm_object.animation_data.action = None @@ -42,17 +42,17 @@ class DSPL_OT_ConvertPoseLibrary(bpy.types.Operator): # Operator to add keyframes and marker to pose library -class DSPL_OT_AddPose(bpy.types.Operator): - bl_idname = "dspl.add_pose" +class YAPL_OT_AddPose(bpy.types.Operator): + bl_idname = "yapl.add_pose" bl_label = "Add Pose" bl_description = "Add Pose" bl_options = {'REGISTER', 'UNDO'} posename: bpy.props.StringProperty(default="Pose") - replace: bpy.props.BoolProperty(name="Replace", description="Replace existing pose", default=False, options={'SKIP_SAVE'}) + replace: bpy.props.BoolProperty(name="Replace", description="Replace existing pose", default=False, options={'SKIP_SAVE', 'HIDDEN'}) def execute(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) if self.replace == False: pose_markers = pose_library.pose_markers new_name = self.posename @@ -80,12 +80,12 @@ class DSPL_OT_AddPose(bpy.types.Operator): pose_markers.new(name=pose_name) pose_markers[pose_name].frame = new_marker - setKeyframesFromBones(context, arm_object, new_marker) + set_keyframes_from_bones(context, arm_object, new_marker) pose_library.pose_markers.active = pose_markers[pose_name] bpy.context.area.tag_redraw() - self.report({'INFO'}, "DSPL: Added " + pose_markers[new_name].name + " to frame " + str(pose_markers[new_name].frame)) + self.report({'INFO'}, "YAPL: Added " + pose_markers[new_name].name + " to frame " + str(pose_markers[new_name].frame)) else: pose_markers = pose_library.pose_markers @@ -105,9 +105,9 @@ class DSPL_OT_AddPose(bpy.types.Operator): new_marker = target_frame - setKeyframesFromBones(context, arm_object, new_marker) + set_keyframes_from_bones(context, arm_object, new_marker) - self.report({'INFO'}, "DSPL: Replaced " + pose_markers[new_name].name + " on frame " + str(pose_markers[new_name].frame)) + self.report({'INFO'}, "YAPL: Replaced " + pose_markers[new_name].name + " on frame " + str(pose_markers[new_name].frame)) return {'FINISHED'} @@ -115,8 +115,8 @@ class DSPL_OT_AddPose(bpy.types.Operator): # Operator to remove keyframes and marker -class DSPL_OT_RemovePose(bpy.types.Operator): - bl_idname = "dspl.remove_pose" +class YAPL_OT_RemovePose(bpy.types.Operator): + bl_idname = "yapl.remove_pose" bl_label = "Remove Pose" bl_description = "Remove Pose" bl_options = {'REGISTER', 'UNDO'} @@ -124,10 +124,10 @@ class DSPL_OT_RemovePose(bpy.types.Operator): posename: bpy.props.StringProperty() def execute(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) pose_markers = pose_library.pose_markers if self.posename: - pose_library.pose_markers.active_index = searchPoseMarker(context, posename=self.posename, type="index") + pose_library.pose_markers.active_index = search_pose_marker(context, posename=self.posename, type="index") active_index = pose_library.pose_markers.active_index else: active_index = pose_markers.active_index @@ -155,7 +155,7 @@ class DSPL_OT_RemovePose(bpy.types.Operator): pose_library.pose_markers.active = next_marker pose_library.pose_markers.active_index = next_index - self.report({'INFO'}, "DSPL: Removed " + self.posename) + self.report({'INFO'}, "YAPL: Removed " + self.posename) return {'FINISHED'} @@ -163,8 +163,8 @@ class DSPL_OT_RemovePose(bpy.types.Operator): # Operator to rename the current pose -class DSPL_OT_RenamePose(bpy.types.Operator): - bl_idname = "dspl.rename_pose" +class YAPL_OT_RenamePose(bpy.types.Operator): + bl_idname = "yapl.rename_pose" bl_label = "Rename Pose" bl_description = "Rename Pose" bl_options = {'REGISTER', 'UNDO'} @@ -173,12 +173,12 @@ class DSPL_OT_RenamePose(bpy.types.Operator): pose_new_name: bpy.props.StringProperty() def execute(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) pose_markers = pose_library.pose_markers active_marker = pose_markers.active if self.posename: - target_marker = searchPoseMarker(context, posename=self.posename, type="marker") + target_marker = search_pose_marker(context, posename=self.posename, type="marker") else: target_marker = active_marker @@ -186,7 +186,7 @@ class DSPL_OT_RenamePose(bpy.types.Operator): target_marker.name = self.pose_new_name context.area.tag_redraw() - self.report({'INFO'}, "DSPL: Renamed " + self.posename + " to " + self.pose_new_name + " on frame " + str(active_marker.frame)) + self.report({'INFO'}, "YAPL: Renamed " + self.posename + " to " + self.pose_new_name + " on frame " + str(active_marker.frame)) return {'FINISHED'} else: @@ -201,8 +201,8 @@ class DSPL_OT_RenamePose(bpy.types.Operator): # Operator to reorder pose markers -class DSPL_OT_MovePose(bpy.types.Operator): - bl_idname = "dspl.move_pose" +class YAPL_OT_MovePose(bpy.types.Operator): + bl_idname = "yapl.move_pose" bl_label = "Move Pose" bl_description = "Move pose" bl_options = {'REGISTER', 'UNDO'} @@ -211,12 +211,12 @@ class DSPL_OT_MovePose(bpy.types.Operator): posename: bpy.props.StringProperty(name="Pose Name", default="", options={'SKIP_SAVE'}) def execute(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) pose_markers = pose_library.pose_markers if self.posename: - active_index = searchPoseMarker(context, posename=self.posename, type="index") - active_marker = searchPoseMarker(context, posename=self.posename, type="marker") + active_index = search_pose_marker(context, posename=self.posename, type="index") + active_marker = search_pose_marker(context, posename=self.posename, type="marker") active_frame = active_marker.frame active_posename = active_marker.name else: @@ -251,8 +251,8 @@ class DSPL_OT_MovePose(bpy.types.Operator): # Operator to apply a pose from active marker -class DSPL_OT_ApplyPose(bpy.types.Operator): - bl_idname = "dspl.apply_pose" +class YAPL_OT_ApplyPose(bpy.types.Operator): + bl_idname = "yapl.apply_pose" bl_label = "Apply Pose" bl_description = "Apply Pose (Ctrl+Click to select, Shift+Click to rename, Alt+Click to remove)" bl_options = {'REGISTER', 'UNDO'} @@ -261,39 +261,39 @@ class DSPL_OT_ApplyPose(bpy.types.Operator): def execute(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) pose_markers = pose_library.pose_markers if self.posename: - active_marker = searchPoseMarker(context, posename=self.posename, type="marker") + active_marker = search_pose_marker(context, posename=self.posename, type="marker") active_frame = active_marker.frame active_posename = active_marker.name - pose_library.pose_markers.active_index = searchPoseMarker(context, posename=self.posename, type="index") + pose_library.pose_markers.active_index = search_pose_marker(context, posename=self.posename, type="index") else: active_index = pose_markers.active_index active_marker = pose_markers.active active_frame = active_marker.frame active_posename = active_marker.name - setBonesfromKeyframes(context, arm_object, active_marker) + set_bones_from_keyframes(context, arm_object, active_marker) - self.report({'INFO'}, "DSPL: Applied " + active_posename) + self.report({'INFO'}, "YAPL: Applied " + active_posename) return {'FINISHED'} def invoke(self, context, event): if event.ctrl: # Select - arm_object, pose_library = getArmatureData(context) - pose_library.pose_markers.active_index = searchPoseMarker(context, posename=self.posename, type="index") + arm_object, pose_library = get_armature_data(context) + pose_library.pose_markers.active_index = search_pose_marker(context, posename=self.posename, type="index") return {'FINISHED'} elif event.alt: # Remove - bpy.ops.dspl.remove_pose(posename = self.posename) + bpy.ops.yapl.remove_pose(posename = self.posename) return {'FINISHED'} elif event.shift: # Rename - bpy.ops.dspl.rename_pose('INVOKE_DEFAULT', posename = self.posename) + bpy.ops.yapl.rename_pose('INVOKE_DEFAULT', posename = self.posename) return {'FINISHED'} else: return self.execute(context) @@ -302,8 +302,8 @@ class DSPL_OT_ApplyPose(bpy.types.Operator): # Operator to preview up and down pose list -class DSPL_OT_BrowsePoses(bpy.types.Operator): - bl_idname = "dspl.browse_poses" +class YAPL_OT_BrowsePoses(bpy.types.Operator): + bl_idname = "yapl.browse_poses" bl_label = "Browse Poses" bl_description = "Browse Poses" bl_options = {'REGISTER', 'UNDO'} @@ -330,13 +330,13 @@ class DSPL_OT_BrowsePoses(bpy.types.Operator): self.pose_library.pose_markers.active_index = len(self.pose_library.pose_markers) - 1 else: self.pose_library.pose_markers.active_index = self.pose_library.pose_markers.active_index - 1 - bpy.ops.dspl.apply_pose() + bpy.ops.yapl.apply_pose() elif event.type in {'RIGHT_ARROW', 'DOWN_ARROW'}: if self.pose_library.pose_markers.active_index + 1 >= len(self.pose_library.pose_markers): self.pose_library.pose_markers.active_index = 0 else: self.pose_library.pose_markers.active_index = self.pose_library.pose_markers.active_index + 1 - bpy.ops.dspl.apply_pose() + bpy.ops.yapl.apply_pose() if event.type in {'LEFTMOUSE', 'RET', 'NUMPAD_ENTER'}: bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') @@ -354,18 +354,18 @@ class DSPL_OT_BrowsePoses(bpy.types.Operator): def invoke(self, context, event): bpy.context.area.tag_redraw() - self.arm_object, self.pose_library = getArmatureData(context) + self.arm_object, self.pose_library = get_armature_data(context) if self.pose_library is None: - self.report({'WARNING'}, "DSPL: Pose Library not active") + self.report({'WARNING'}, "YAPL: Pose Library not active") return {'CANCELLED'} self.arm_object.pose.backup_create(self.pose_library) self.backup_index = self.pose_library.pose_markers.active_index - bpy.ops.dspl.apply_pose() + bpy.ops.yapl.apply_pose() if context.area.type == 'VIEW_3D': - self.report({'INFO'}, "DSPL: Browsing Poses") + self.report({'INFO'}, "YAPL: Browsing Poses") args = (self, context) self._handle = bpy.types.SpaceView3D.draw_handler_add(self.draw_callback_px, args, 'WINDOW', 'POST_PIXEL') context.window_manager.modal_handler_add(self) @@ -376,14 +376,14 @@ class DSPL_OT_BrowsePoses(bpy.types.Operator): # Operator to unlink a pose library and mark for removal -class DSPL_OT_UnlinkPoseLibrary(bpy.types.Operator): - bl_idname = "dspl.unlink_pose_library" +class YAPL_OT_UnlinkPoseLibrary(bpy.types.Operator): + bl_idname = "yapl.unlink_pose_library" bl_label = "Unlink Pose Library" bl_description = "Unlink Pose Library" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): - arm_object, pose_library = getArmatureData(context) + arm_object, pose_library = get_armature_data(context) try: arm_object.pose_library = None @@ -399,8 +399,8 @@ class DSPL_OT_UnlinkPoseLibrary(bpy.types.Operator): # Operator to protect orphaned legacy pose libraries -class DSPL_OT_ProtectOrphanPoseLibrary(bpy.types.Operator): - bl_idname = "dspl.protect_orphan_pose_library" +class YAPL_OT_ProtectOrphanPoseLibrary(bpy.types.Operator): + bl_idname = "yapl.protect_orphan_pose_library" bl_label = "Protect Orphaned Pose Libraries" bl_description = "Protect Orphaned Pose Libraries" bl_options = {'REGISTER', 'UNDO'} @@ -436,23 +436,23 @@ class DSPL_OT_ProtectOrphanPoseLibrary(bpy.types.Operator): if orphaned_act: for act in orphaned_act: if "_loc" in act.name or "PoseLib" in act.name: - self.report({'INFO'}, "DSPL: Protecting orphaned action: " + act.name) + self.report({'INFO'}, "YAPL: Protecting orphaned action: " + act.name) act.use_fake_user = True return {'FINISHED'} classes = ( - DSPL_OT_CreatePoseLibrary, - DSPL_OT_ConvertPoseLibrary, - DSPL_OT_AddPose, - DSPL_OT_RemovePose, - DSPL_OT_RenamePose, - DSPL_OT_MovePose, - DSPL_OT_ApplyPose, - DSPL_OT_BrowsePoses, - DSPL_OT_UnlinkPoseLibrary, - DSPL_OT_ProtectOrphanPoseLibrary + YAPL_OT_CreatePoseLibrary, + YAPL_OT_ConvertPoseLibrary, + YAPL_OT_AddPose, + YAPL_OT_RemovePose, + YAPL_OT_RenamePose, + YAPL_OT_MovePose, + YAPL_OT_ApplyPose, + YAPL_OT_BrowsePoses, + YAPL_OT_UnlinkPoseLibrary, + YAPL_OT_ProtectOrphanPoseLibrary ) register, unregister = bpy.utils.register_classes_factory(classes)