Merge branch 'blender-v4.4-release'
This commit is contained in:
Submodule lib/linux_x64 updated: 85a8dca886...eacf548b2e
@@ -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
|
||||
|
||||
@@ -13,7 +13,7 @@ __all__ = (
|
||||
)
|
||||
|
||||
import bpy
|
||||
from bpy.types import Action, ActionSlot
|
||||
from bpy.types import Action, ActionSlot, ActionChannelbag
|
||||
from dataclasses import dataclass
|
||||
|
||||
from collections.abc import (
|
||||
@@ -75,14 +75,18 @@ class BakeOptions:
|
||||
"""Bake custom properties."""
|
||||
|
||||
|
||||
def _get_channelbag_for_slot(action: Action, slot: ActionSlot):
|
||||
# This is on purpose limited to the first layer and strip. To support more
|
||||
# than 1 layer, a rewrite of this operator is needed which ideally would
|
||||
# happen in C++.
|
||||
def action_get_channelbag_for_slot(action: Action, slot: ActionSlot) -> ActionChannelbag | None:
|
||||
"""
|
||||
Returns the first channelbag found for the slot.
|
||||
In case there are multiple layers or strips they are iterated until a
|
||||
channelbag for that slot is found. In case no matching channelbag is found, returns None.
|
||||
"""
|
||||
for layer in action.layers:
|
||||
for strip in layer.strips:
|
||||
channelbag = strip.channelbag(slot)
|
||||
return channelbag
|
||||
if channelbag:
|
||||
return channelbag
|
||||
return None
|
||||
|
||||
|
||||
def _ensure_channelbag_exists(action: Action, slot: ActionSlot):
|
||||
@@ -409,7 +413,7 @@ def bake_action_iter(
|
||||
# pose
|
||||
lookup_fcurves = {}
|
||||
assert action.is_action_layered
|
||||
channelbag = _get_channelbag_for_slot(action, atd.action_slot)
|
||||
channelbag = action_get_channelbag_for_slot(action, atd.action_slot)
|
||||
if channelbag:
|
||||
# channelbag can be None if no layers or strips exist in the action.
|
||||
lookup_fcurves = {(fcurve.data_path, fcurve.array_index): fcurve for fcurve in channelbag.fcurves}
|
||||
|
||||
@@ -1202,6 +1202,11 @@ static void rna_def_grease_pencil_layer_group(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "color_tag", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_funcs(prop, "rna_group_color_tag_get", "rna_group_color_tag_set", nullptr);
|
||||
RNA_def_property_enum_items(prop, enum_layergroup_color_items);
|
||||
|
||||
prop = RNA_def_property(srna, "channel_color", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_float_sdna(prop, "GreasePencilLayerTreeNode", "color");
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_update(prop, NC_GPENCIL | NA_EDITED, nullptr);
|
||||
}
|
||||
|
||||
static void rna_def_grease_pencil_layer_groups(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
|
||||
Reference in New Issue
Block a user