Merge remote-tracking branch 'origin/blender-v4.5-release'

This commit is contained in:
Sybren A. Stüvel
2025-07-08 17:11:59 +02:00

View File

@@ -1038,15 +1038,31 @@ static void override_idtemplate_menu()
#define NOT_RNA_NULL(assignment) ((assignment).data != nullptr)
/**
* Construct a PointerRNA that points to pchan->bone.
*
* Pose bones are owned by an Object, whereas `pchan->bone` is owned by the Armature, so this
* doesn't just remap the pointer's `data` field, but also its `owner_id`.
*/
static PointerRNA rnapointer_pchan_to_bone(const PointerRNA &pchan_ptr)
{
bPoseChannel *pchan = static_cast<bPoseChannel *>(pchan_ptr.data);
BLI_assert(GS(pchan_ptr.owner_id->name) == ID_OB);
Object *object = reinterpret_cast<Object *>(pchan_ptr.owner_id);
BLI_assert(GS(static_cast<ID *>(object->data)->name) == ID_AR);
bArmature *armature = static_cast<bArmature *>(object->data);
return RNA_pointer_create_discrete(&armature->id, &RNA_Bone, pchan->bone);
}
static void ui_context_selected_bones_via_pose(bContext *C, blender::Vector<PointerRNA> *r_lb)
{
blender::Vector<PointerRNA> lb = CTX_data_collection_get(C, "selected_pose_bones");
if (!lb.is_empty()) {
for (PointerRNA &ptr : lb) {
bPoseChannel *pchan = static_cast<bPoseChannel *>(ptr.data);
ptr = RNA_pointer_create_discrete(ptr.owner_id, &RNA_Bone, pchan->bone);
}
for (PointerRNA &ptr : lb) {
ptr = rnapointer_pchan_to_bone(ptr);
}
*r_lb = std::move(lb);
@@ -1109,9 +1125,8 @@ bool UI_context_copy_to_selected_list(bContext *C,
*r_lb = CTX_data_collection_get(C, "selected_pose_bones");
}
else {
bPoseChannel *pchan = static_cast<bPoseChannel *>(owner_ptr.data);
owner_ptr = RNA_pointer_create_discrete(owner_ptr.owner_id, &RNA_Bone, pchan->bone);
idpath = RNA_path_from_struct_to_idproperty(&owner_ptr,
PointerRNA bone_ptr = rnapointer_pchan_to_bone(owner_ptr);
idpath = RNA_path_from_struct_to_idproperty(&bone_ptr,
static_cast<const IDProperty *>(ptr->data));
if (idpath) {
ui_context_selected_bones_via_pose(C, r_lb);
@@ -1121,13 +1136,14 @@ bool UI_context_copy_to_selected_list(bContext *C,
if (!idpath) {
/* Check the active EditBone if in edit mode. */
idpath = RNA_path_from_struct_to_idproperty(&owner_ptr,
static_cast<const IDProperty *>(ptr->data));
if (NOT_RNA_NULL(
owner_ptr = CTX_data_pointer_get_type_silent(C, "active_bone", &RNA_EditBone)) &&
idpath)
owner_ptr = CTX_data_pointer_get_type_silent(C, "active_bone", &RNA_EditBone)))
{
*r_lb = CTX_data_collection_get(C, "selected_editable_bones");
idpath = RNA_path_from_struct_to_idproperty(&owner_ptr,
static_cast<const IDProperty *>(ptr->data));
if (idpath) {
*r_lb = CTX_data_collection_get(C, "selected_editable_bones");
}
}
/* Add other simple cases here (Node, NodeSocket, Sequence, ViewLayer etc). */
@@ -1146,6 +1162,9 @@ bool UI_context_copy_to_selected_list(bContext *C,
*r_lb = CTX_data_collection_get(C, "selected_pose_bones");
}
else if (RNA_struct_is_a(ptr->type, &RNA_Bone)) {
/* "selected_bones" or "selected_editable_bones" will only yield anything in Armature Edit
* mode. In other modes, it'll be empty, and the only way to get the selected bones is via
* "selected_pose_bones". */
ui_context_selected_bones_via_pose(C, r_lb);
}
else if (RNA_struct_is_a(ptr->type, &RNA_BoneColor)) {