Anim: Remove legacy pose library conversion
Remove the operators to convert a legacy pose library (from Blender 2.93 and older) to the current system (introduced in Blender 3.0). The removal is mostly because the pose markers do not play well with slotted Actions. The conversion code was never updated for those, and by now it's easier to remove them than to update the code to the current data model. Technically it was still possible to create a legacy pose library (an Action with pose markers) in current versions of Blender, and then use this operator to convert that to a modern pose library. I don't know of anybody doing that, though. This is part of #146586 Pull Request: https://projects.blender.org/blender/blender/pulls/147061
This commit is contained in:
@@ -23,7 +23,7 @@ bl_info = {
|
||||
from typing import List, Tuple
|
||||
|
||||
_need_reload = "operators" in locals()
|
||||
from . import gui, keymaps, operators, conversion
|
||||
from . import gui, keymaps, operators
|
||||
|
||||
if _need_reload:
|
||||
import importlib
|
||||
@@ -31,7 +31,6 @@ if _need_reload:
|
||||
gui = importlib.reload(gui)
|
||||
keymaps = importlib.reload(keymaps)
|
||||
operators = importlib.reload(operators)
|
||||
conversion = importlib.reload(conversion)
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2021-2023 Blender Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Pose Library - Conversion of old pose libraries.
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
from collections.abc import Collection
|
||||
|
||||
if "pose_creation" not in locals():
|
||||
from . import pose_creation
|
||||
else:
|
||||
import importlib
|
||||
|
||||
pose_creation = importlib.reload(pose_creation)
|
||||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
Action,
|
||||
TimelineMarker,
|
||||
)
|
||||
|
||||
|
||||
def convert_old_poselib(old_poselib: Action) -> Collection[Action]:
|
||||
"""Convert an old-style pose library to a set of pose Actions.
|
||||
|
||||
Old pose libraries were one Action with multiple pose markers. Each pose
|
||||
marker will be converted to an Action by itself and marked as asset.
|
||||
"""
|
||||
|
||||
pose_assets = [action for marker in old_poselib.pose_markers if (action := convert_old_pose(old_poselib, marker))]
|
||||
|
||||
# Mark all Actions as assets in one go. Ideally this would be done on an
|
||||
# appropriate frame in the scene (to set up things like the background
|
||||
# colour), but the old-style poselib doesn't contain such information. All
|
||||
# we can do is just render on the current frame.
|
||||
context_override = {'selected_ids': pose_assets}
|
||||
with bpy.context.temp_override(**context_override):
|
||||
bpy.ops.asset.mark()
|
||||
|
||||
return pose_assets
|
||||
|
||||
|
||||
def convert_old_pose(old_poselib: Action, marker: TimelineMarker) -> Optional[Action]:
|
||||
"""Convert an old-style pose library pose to a pose action."""
|
||||
|
||||
frame: int = marker.frame
|
||||
action: Optional[Action] = None
|
||||
|
||||
for fcurve in old_poselib.fcurves:
|
||||
key = pose_creation.find_keyframe(fcurve, frame)
|
||||
if not key:
|
||||
continue
|
||||
|
||||
if action is None:
|
||||
action = bpy.data.actions.new(marker.name)
|
||||
|
||||
pose_creation.create_single_key_fcurve(action, fcurve, key)
|
||||
|
||||
return action
|
||||
@@ -28,6 +28,7 @@ class VIEW3D_MT_pose_modify(Menu):
|
||||
layout.operator("poselib.asset_modify", text="Add Selected Bones").mode = "ADD"
|
||||
layout.operator("poselib.asset_modify", text="Remove Selected Bones").mode = "REMOVE"
|
||||
|
||||
|
||||
class PoseLibraryPanel:
|
||||
@classmethod
|
||||
def pose_library_panel_poll(cls, context: Context) -> bool:
|
||||
@@ -132,8 +133,6 @@ class DOPESHEET_PT_asset_panel(PoseLibraryPanel, Panel):
|
||||
row.operator("poselib.restore_previous_action", text="", icon='LOOP_BACK')
|
||||
col.operator("poselib.copy_as_asset", icon="COPYDOWN")
|
||||
|
||||
layout.operator("poselib.convert_old_poselib")
|
||||
|
||||
|
||||
def pose_library_list_item_asset_menu(self: UIList, context: Context) -> None:
|
||||
layout = self.layout
|
||||
|
||||
@@ -288,75 +288,8 @@ class POSELIB_OT_pose_asset_select_bones(PoseAssetUser, Operator):
|
||||
return tip_("Deselect those bones that are used in this pose")
|
||||
|
||||
|
||||
class POSELIB_OT_convert_old_poselib(Operator):
|
||||
bl_idname = "poselib.convert_old_poselib"
|
||||
bl_label = "Convert Legacy Pose Library"
|
||||
bl_description = "Create a pose asset for each pose marker in the current action"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context: Context) -> bool:
|
||||
action = context.object and context.object.animation_data and context.object.animation_data.action
|
||||
if not action:
|
||||
cls.poll_message_set("Active object has no Action")
|
||||
return False
|
||||
if not action.pose_markers:
|
||||
cls.poll_message_set(tip_("Action %r is not a legacy pose library") % action.name)
|
||||
return False
|
||||
return True
|
||||
|
||||
def execute(self, context: Context) -> Set[str]:
|
||||
from . import conversion
|
||||
|
||||
old_poselib = context.object.animation_data.action
|
||||
new_actions = conversion.convert_old_poselib(old_poselib)
|
||||
|
||||
if not new_actions:
|
||||
self.report({'ERROR'}, "Unable to convert to pose assets")
|
||||
return {'CANCELLED'}
|
||||
|
||||
self.report({'INFO'}, tip_("Converted %d poses to pose assets") % len(new_actions))
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class POSELIB_OT_convert_old_object_poselib(Operator):
|
||||
bl_idname = "poselib.convert_old_object_poselib"
|
||||
bl_label = "Convert Legacy Pose Library"
|
||||
bl_description = "Create a pose asset for each pose marker in this legacy pose library data-block"
|
||||
|
||||
# Mark this one as "internal", as it converts `context.object.pose_library`
|
||||
# instead of its current animation Action.
|
||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context: Context) -> bool:
|
||||
action = context.object and context.object.pose_library
|
||||
if not action:
|
||||
cls.poll_message_set("Active object has no pose library Action")
|
||||
return False
|
||||
if not action.pose_markers:
|
||||
cls.poll_message_set(tip_("Action %r is not a legacy pose library") % action.name)
|
||||
return False
|
||||
return True
|
||||
|
||||
def execute(self, context: Context) -> Set[str]:
|
||||
from . import conversion
|
||||
|
||||
old_poselib = context.object.pose_library
|
||||
new_actions = conversion.convert_old_poselib(old_poselib)
|
||||
|
||||
if not new_actions:
|
||||
self.report({'ERROR'}, "Unable to convert to pose assets")
|
||||
return {'CANCELLED'}
|
||||
|
||||
self.report({'INFO'}, tip_("Converted %d poses to pose assets") % len(new_actions))
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
classes = (
|
||||
ASSET_OT_assign_action,
|
||||
POSELIB_OT_convert_old_poselib,
|
||||
POSELIB_OT_convert_old_object_poselib,
|
||||
POSELIB_OT_copy_as_asset,
|
||||
POSELIB_OT_paste_asset,
|
||||
POSELIB_OT_pose_asset_select_bones,
|
||||
|
||||
@@ -91,8 +91,6 @@ class PoseActionCreator:
|
||||
|
||||
def _create_new_action(self) -> Action:
|
||||
dst_action = bpy.data.actions.new(self.params.new_asset_name)
|
||||
if self.params.src_action:
|
||||
dst_action.id_root = self.params.src_action.id_root
|
||||
dst_action.user_clear() # actions.new() sets users=1, but marking as asset also increments user count.
|
||||
return dst_action
|
||||
|
||||
|
||||
Reference in New Issue
Block a user