WIP: Animation: operators to update the pose library #104673
@ -139,6 +139,20 @@ class POSELIB_OT_create_pose_asset(PoseAssetCreator, Operator):
|
|||||||
self.report({'WARNING'}, tip_("Action %s marked Fake User to prevent loss") % action.name)
|
self.report({'WARNING'}, tip_("Action %s marked Fake User to prevent loss") % action.name)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_action(context: Context) -> Action | None:
|
||||||
|
"""Get the current action from the asset browser or the asset view."""
|
||||||
|
|
||||||
|
if context.asset_library_ref and context.asset_file_handle and context.asset_file_handle.id_type == 'ACTION':
|
||||||
|
context_id = context.asset_file_handle.local_id
|
||||||
|
else:
|
||||||
|
context_id = getattr(context, "id", None)
|
||||||
|
|
||||||
|
if not isinstance(context_id, Action):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return context_id
|
||||||
|
|
||||||
|
|
||||||
class POSELIB_OT_replace_pose_asset(Operator):
|
class POSELIB_OT_replace_pose_asset(Operator):
|
||||||
bl_idname = "poselib.replace_pose_asset"
|
bl_idname = "poselib.replace_pose_asset"
|
||||||
bl_label = "Replace Pose Asset"
|
bl_label = "Replace Pose Asset"
|
||||||
@ -149,7 +163,7 @@ class POSELIB_OT_replace_pose_asset(Operator):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context: Context) -> bool:
|
def poll(cls, context: Context) -> bool:
|
||||||
if not isinstance(getattr(context, "id", None), Action):
|
if not _get_action(context):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if context.object is None or context.object.mode != "POSE":
|
if context.object is None or context.object.mode != "POSE":
|
||||||
@ -165,19 +179,21 @@ class POSELIB_OT_replace_pose_asset(Operator):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def execute(self, context: Context) -> Set[str]:
|
def execute(self, context: Context) -> Set[str]:
|
||||||
pose_name = context.id.name # This will not use this name entirely, but it'll be made unique.
|
original_pose: Action = _get_action(context)
|
||||||
|
|
||||||
|
pose_name = original_pose.name # This will not use this name entirely, but it'll be made unique.
|
||||||
asset = pose_creation.create_pose_asset_from_context(context, pose_name)
|
asset = pose_creation.create_pose_asset_from_context(context, pose_name)
|
||||||
if not asset:
|
if not asset:
|
||||||
self.report({"WARNING"}, "No keyframes were found for this pose")
|
self.report({"WARNING"}, "No keyframes were found for this pose")
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
# Copy the asset metadata to the newly created asset.
|
# Copy the asset metadata to the newly created asset.
|
||||||
asset.asset_data = context.id.asset_data
|
asset.asset_data = original_pose.asset_data
|
||||||
|
|
||||||
self._activate_asset_in_browser(context, asset)
|
self._activate_asset_in_browser(context, asset)
|
||||||
|
|
||||||
# Delete the old asset
|
# Delete the old asset
|
||||||
bpy.data.actions.remove(context.id)
|
bpy.data.actions.remove(original_pose)
|
||||||
# Now that the old name has become available, rename the asset to it.
|
# Now that the old name has become available, rename the asset to it.
|
||||||
asset.name = pose_name
|
asset.name = pose_name
|
||||||
|
|
||||||
@ -214,7 +230,7 @@ class POSELIB_OT_update_pose_asset(Operator):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context: Context) -> bool:
|
def poll(cls, context: Context) -> bool:
|
||||||
if not isinstance(getattr(context, "id", None), Action):
|
if not _get_action(context):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if context.object is None or context.object.mode != "POSE":
|
if context.object is None or context.object.mode != "POSE":
|
||||||
@ -231,7 +247,8 @@ class POSELIB_OT_update_pose_asset(Operator):
|
|||||||
|
|
||||||
def execute(self, context: Context) -> Set[str]:
|
def execute(self, context: Context) -> Set[str]:
|
||||||
# Make sure the new keys are on the same frame as the old keys.
|
# Make sure the new keys are on the same frame as the old keys.
|
||||||
storage_frame_nr = self._find_frame_number(context)
|
original_pose: Action = _get_action(context)
|
||||||
|
storage_frame_nr = self._find_frame_number(original_pose, context.scene.frame_current)
|
||||||
|
|
||||||
params = pose_creation.params_for_selected_bones(
|
params = pose_creation.params_for_selected_bones(
|
||||||
context,
|
context,
|
||||||
@ -247,7 +264,6 @@ class POSELIB_OT_update_pose_asset(Operator):
|
|||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
original_pose: Action = context.id
|
|
||||||
was_updated = self._update_pose_asset(original_pose, new_pose)
|
was_updated = self._update_pose_asset(original_pose, new_pose)
|
||||||
finally:
|
finally:
|
||||||
# Clean up by removing the temporary pose Action.
|
# Clean up by removing the temporary pose Action.
|
||||||
@ -306,12 +322,11 @@ class POSELIB_OT_update_pose_asset(Operator):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _find_frame_number(context: Context) -> float:
|
def _find_frame_number(action: Action, fallback_frame: float) -> float:
|
||||||
original_pose: Action = context.id
|
assert isinstance(action, Action), f"expected an Action, got {action}"
|
||||||
assert isinstance(original_pose, Action), f"expected an Action, got {original_pose}"
|
if action.fcurves and action.fcurves[0].keyframe_points:
|
||||||
if original_pose.fcurves and original_pose.fcurves[0].keyframe_points:
|
return action.fcurves[0].keyframe_points[0].co.x
|
||||||
return original_pose.fcurves[0].keyframe_points[0].co.x
|
return fallback_frame
|
||||||
return context.scene.frame_current
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_new_fcurve(action: Action, fcu_to_copy: FCurve) -> None:
|
def _create_new_fcurve(action: Action, fcu_to_copy: FCurve) -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user