Merge branch 'blender-v4.4-release'
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user