diff --git a/source/blender/animrig/intern/bone_collections.cc b/source/blender/animrig/intern/bone_collections.cc index 3461b6a978b..d6b31f2e44d 100644 --- a/source/blender/animrig/intern/bone_collections.cc +++ b/source/blender/animrig/intern/bone_collections.cc @@ -26,6 +26,7 @@ #include "BKE_animsys.h" #include "BKE_idprop.h" #include "BKE_lib_id.h" +#include "BKE_lib_override.hh" #include "ANIM_armature_iter.hh" #include "ANIM_bone_collections.hh" @@ -287,7 +288,14 @@ bool ANIM_armature_bonecoll_is_editable(const bArmature *armature, const BoneCol if (ID_IS_LINKED(armature) && !is_override) { return false; } + + if (is_override && BKE_lib_override_library_is_system_defined(nullptr, &armature->id)) { + /* A system override is still not editable. */ + return false; + } + if (is_override && (bcoll->flags & BONE_COLLECTION_OVERRIDE_LIBRARY_LOCAL) == 0) { + /* This particular collection was not added in the local override, so not editable. */ return false; } return true; diff --git a/source/blender/editors/armature/bone_collections.cc b/source/blender/editors/armature/bone_collections.cc index 552d2372517..8c054654d2d 100644 --- a/source/blender/editors/armature/bone_collections.cc +++ b/source/blender/editors/armature/bone_collections.cc @@ -17,6 +17,7 @@ #include "BKE_action.h" #include "BKE_context.hh" #include "BKE_layer.h" +#include "BKE_lib_override.hh" #include "BKE_report.h" #include "BLT_translation.h" @@ -63,6 +64,13 @@ static bool bone_collection_add_poll(bContext *C) return false; } + if (BKE_lib_override_library_is_system_defined(nullptr, reinterpret_cast(ob->data))) { + CTX_wm_operator_poll_msg_set(C, + "Cannot add bone collections to a linked Armature with a system " + "override; explicitly create an override on the Armature"); + return false; + } + return true; } @@ -80,8 +88,14 @@ static bool active_bone_collection_poll(bContext *C) } bArmature *armature = static_cast(ob->data); - BoneCollection *bcoll = armature->runtime.active_collection; + if (BKE_lib_override_library_is_system_defined(nullptr, &armature->id)) { + CTX_wm_operator_poll_msg_set(C, + "Cannot update a linked Armature with a system override; " + "explicitly create an override on the Armature"); + return false; + } + BoneCollection *bcoll = armature->runtime.active_collection; if (bcoll == nullptr) { CTX_wm_operator_poll_msg_set(C, "Armature has no active bone collection, select one first"); return false; @@ -387,6 +401,12 @@ static bool bone_collection_assign_poll(bContext *C) C, "Cannot edit bone collections on linked Armatures without override"); return false; } + if (BKE_lib_override_library_is_system_defined(nullptr, &armature->id)) { + CTX_wm_operator_poll_msg_set(C, + "Cannot edit bone collections on a linked Armature with a system " + "override; explicitly create an override on the Armature"); + return false; + } /* The target bone collection can be specified by name in an operator property, but that's not * available here. So just allow in the poll function, and do the final check in the execute. */ @@ -484,6 +504,12 @@ static bool bone_collection_create_and_assign_poll(bContext *C) C, "Cannot edit bone collections on linked Armatures without override"); return false; } + if (BKE_lib_override_library_is_system_defined(nullptr, &armature->id)) { + CTX_wm_operator_poll_msg_set(C, + "Cannot edit bone collections on a linked Armature with a system " + "override; explicitly create an override on the Armature"); + return false; + } return true; } @@ -951,11 +977,19 @@ static bool move_to_collection_poll(bContext *C) return false; } - if (ID_IS_LINKED(ob->data) && !ID_IS_OVERRIDE_LIBRARY(ob->data)) { + const bArmature *armature = static_cast(ob->data); + if (ID_IS_LINKED(armature) && !ID_IS_OVERRIDE_LIBRARY(armature)) { CTX_wm_operator_poll_msg_set(C, "This needs a local Armature or an override"); return false; } + if (BKE_lib_override_library_is_system_defined(nullptr, &armature->id)) { + CTX_wm_operator_poll_msg_set(C, + "Cannot update a linked Armature with a system override; " + "explicitly create an override on the Armature"); + return false; + } + /* Ideally this would also check the target bone collection to move/assign to. * However, that requires access to the operator properties, and those are not * available in the poll function. */