Merge branch 'blender-v4.4-release'

This commit is contained in:
Sebastian Parborg
2025-02-27 15:16:37 +01:00
5 changed files with 57 additions and 15 deletions

View File

@@ -272,8 +272,8 @@ class POSELIB_OT_pose_asset_select_bones(PoseAssetUser, Operator):
flipped: BoolProperty(name="Flipped", default=False) # type: ignore
def use_pose(self, context: Context, pose_asset: Action) -> Set[str]:
arm_object: Object = context.object
pose_usage.select_bones(arm_object, pose_asset, select=self.select, flipped=self.flipped)
for object in context.selected_objects:
pose_usage.select_bones(object, pose_asset, select=self.select, flipped=self.flipped)
if self.select:
msg = tip_("Selected bones from %s") % pose_asset.name
else:

View File

@@ -9,26 +9,59 @@ Pose Library - usage functions.
from typing import Set
import re
import bpy
from bpy_extras import anim_utils
from bpy.types import (
Action,
Object,
ActionSlot,
)
def _find_best_slot(action: Action, object: Object) -> ActionSlot | None:
"""
Trying to find a slot that is the best match for the given object.
The best slot is either
the slot of the given object if that exists in the action,
or the first slot of type object
"""
if not action.slots:
return None
# For the selection code, the object doesn't need to be animated yet, so anim_data may be None.
anim_data = object.animation_data
# last_slot_identifier will equal to the current slot identifier if one is assigned.
if anim_data and anim_data.last_slot_identifier in action.slots:
return action.slots[anim_data.last_slot_identifier]
for slot in action.slots:
if slot.target_id_type == 'OBJECT':
return slot
return None
def select_bones(arm_object: Object, action: Action, *, select: bool, flipped: bool) -> None:
pose_bone_re = re.compile(r'pose.bones\["([^"]+)"\]')
pose = arm_object.pose
if not pose:
return
slot = _find_best_slot(action, arm_object)
if not slot:
return
seen_bone_names: Set[str] = set()
channelbag = anim_utils.action_get_channelbag_for_slot(action, slot)
if not channelbag:
return
for fcurve in action.fcurves:
pose_bone_re = re.compile(r'pose.bones\["([^"]+)"\]')
for fcurve in channelbag.fcurves:
data_path: str = fcurve.data_path
match = pose_bone_re.match(data_path)
if not match:
regex_match = pose_bone_re.match(data_path)
if not regex_match:
continue
bone_name = match.group(1)
bone_name = regex_match.group(1)
if bone_name in seen_bone_names:
continue