Anim: allow appending bone collections with liboverrides

This commit is contained in:
Sybren A. Stüvel
2023-09-12 15:00:05 +02:00
parent 63f2a416b2
commit f1c65c9635
4 changed files with 88 additions and 1 deletions

View File

@@ -74,6 +74,17 @@ void ANIM_armature_runtime_free(struct bArmature *armature);
*/
struct BoneCollection *ANIM_armature_bonecoll_new(struct bArmature *armature, const char *name);
/**
* Add a bone collection to the Armature.
*
* NOTE: this should not typically be used. It is only used by the library overrides system to
* apply override operations.
*/
struct BoneCollection *ANIM_armature_bonecoll_insert_copy_after(
struct bArmature *armature,
struct BoneCollection *anchor,
const struct BoneCollection *bcoll_to_copy);
/**
* Remove a bone collection from the armature.
*/

View File

@@ -7,6 +7,7 @@
*/
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_map.hh"
#include "BLI_math_color.h"
#include "BLI_string.h"
@@ -113,6 +114,31 @@ BoneCollection *ANIM_armature_bonecoll_new(bArmature *armature, const char *name
return bcoll;
}
BoneCollection *ANIM_armature_bonecoll_insert_copy_after(bArmature *armature,
BoneCollection *anchor,
const BoneCollection *bcoll_to_copy)
{
BoneCollection *bcoll = static_cast<BoneCollection *>(MEM_dupallocN(bcoll_to_copy));
/* Remap the bone pointers to the given armature, as `bcoll_to_copy` will
* likely be owned by another copy of the armature. */
BLI_duplicatelist(&bcoll->bones, &bcoll->bones);
BKE_armature_bone_hash_make(armature);
LISTBASE_FOREACH (BoneCollectionMember *, member, &bcoll->bones) {
member->bone = BKE_armature_find_bone_name(armature, member->bone->name);
}
if (bcoll_to_copy->prop) {
bcoll->prop = IDP_CopyProperty_ex(bcoll_to_copy->prop,
0 /*do_id_user ? 0 : LIB_ID_CREATE_NO_USER_REFCOUNT*/);
}
BLI_insertlinkafter(&armature->collections, anchor, bcoll);
bonecoll_ensure_name_unique(armature, bcoll);
return bcoll;
}
static void armature_bonecoll_active_clear(bArmature *armature)
{
armature->runtime.active_collection_index = -1;

View File

@@ -66,6 +66,27 @@ static bool bone_collection_poll(bContext *C)
return true;
}
static bool bone_collection_add_poll(bContext *C)
{
Object *ob = ED_object_context(C);
if (ob == nullptr) {
return false;
}
if (ob->type != OB_ARMATURE) {
CTX_wm_operator_poll_msg_set(C, "Bone collections can only be added to an Armature");
return false;
}
if (ID_IS_LINKED(ob->data)) {
CTX_wm_operator_poll_msg_set(
C, "Cannot add bone collections to a linked Armature without an override");
return false;
}
return true;
}
static bool active_bone_collection_poll(bContext *C)
{
if (!bone_collection_poll(C)) {
@@ -109,7 +130,7 @@ void ARMATURE_OT_collection_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = bone_collection_add_exec;
ot->poll = bone_collection_poll;
ot->poll = bone_collection_add_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;

View File

@@ -299,6 +299,31 @@ static void rna_EditBone_collections_begin(CollectionPropertyIterator *iter, Poi
rna_iterator_listbase_begin(iter, &bone_collection_refs, nullptr);
}
/* Armature.collections library override support. */
static bool rna_Armature_collections_override_apply(Main *bmain,
RNAPropertyOverrideApplyContext &rnaapply_ctx)
{
PointerRNA *ptr_dst = &rnaapply_ctx.ptr_dst;
PropertyRNA *prop_dst = rnaapply_ctx.prop_dst;
PointerRNA *ptr_item_dst = &rnaapply_ctx.ptr_item_dst;
PointerRNA *ptr_item_src = &rnaapply_ctx.ptr_item_src;
IDOverrideLibraryPropertyOperation *opop = rnaapply_ctx.liboverride_operation;
if (opop->operation != LIBOVERRIDE_OP_INSERT_AFTER) {
printf("Unsupported RNA override operation on armature collections, ignoring\n");
return false;
}
bArmature *arm_dst = (bArmature *)ptr_dst->owner_id;
BoneCollection *bcoll_anchor = static_cast<BoneCollection *>(ptr_item_dst->data);
BoneCollection *bcoll_src = static_cast<BoneCollection *>(ptr_item_src->data);
ANIM_armature_bonecoll_insert_copy_after(arm_dst, bcoll_anchor, bcoll_src);
RNA_property_update_main(bmain, nullptr, ptr_dst, prop_dst);
return true;
}
static char *rna_BoneColor_path_posebone(const PointerRNA *ptr)
{
/* Find the bPoseChan that owns this BoneColor. */
@@ -1907,6 +1932,10 @@ static void rna_def_armature(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, nullptr, "collections", nullptr);
RNA_def_property_struct_type(prop, "BoneCollection");
RNA_def_property_ui_text(prop, "Bone Collections", "");
RNA_def_property_override_funcs(
prop, nullptr, nullptr, "rna_Armature_collections_override_apply");
RNA_def_property_override_flag(
prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY | PROPOVERRIDE_LIBRARY_INSERTION);
rna_def_armature_collections(brna, prop);
/* Enum values */