Anim: add slotted Action support to animdata_copy_id_action

Instead of simply reassigning the `adt->action` and `adt->tmpact` pointers,
the code now uses the `animrig::assign_action()` and `assign_tmpaction()`.
This way the slot user maps should be properly updated.

Pull Request: https://projects.blender.org/blender/blender/pulls/128030
This commit is contained in:
Sybren A. Stüvel
2024-09-20 17:24:20 +02:00
parent 0dc71a653d
commit ee2d8ec8db
3 changed files with 38 additions and 8 deletions

View File

@@ -15,6 +15,8 @@
#include "DNA_action_types.h"
#include "DNA_anim_types.h"
#include "BKE_anim_data.hh"
#include "BLI_math_vector.hh"
#include "BLI_span.hh"
#include "BLI_string_ref.hh"
@@ -1112,6 +1114,11 @@ static_assert(sizeof(ChannelGroup) == sizeof(::bActionGroup),
*/
bool assign_action(Action *action, ID &animated_id);
/**
* Same as assign_action, except it assigns to AnimData::tmpact and tmp_slot_handle.
*/
void assign_tmpaction(Action *action, OwnedAnimData owned_adt);
/**
* Un-assign the Action assigned to this ID.
*

View File

@@ -1153,6 +1153,15 @@ bool assign_action(Action *action, ID &animated_id)
return true;
}
void assign_tmpaction(Action *action, OwnedAnimData owned_adt)
{
generic_assign_action(owned_adt.owner_id,
action,
owned_adt.adt.tmpact,
owned_adt.adt.tmp_slot_handle,
owned_adt.adt.tmp_slot_name);
}
void unassign_action(ID &animated_id)
{
assign_action(nullptr, animated_id);

View File

@@ -462,19 +462,33 @@ static void animdata_copy_id_action(Main *bmain,
const bool set_newid,
const bool do_linked_id)
{
using namespace blender::animrig;
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
if (adt->action && (do_linked_id || !ID_IS_LINKED(adt->action))) {
id_us_min((ID *)adt->action);
adt->action = static_cast<bAction *>(
set_newid ? ID_NEW_SET(adt->action, BKE_id_copy(bmain, &adt->action->id)) :
BKE_id_copy(bmain, &adt->action->id));
bAction *cloned_action = reinterpret_cast<bAction *>(BKE_id_copy(bmain, &adt->action->id));
if (set_newid) {
ID_NEW_SET(adt->action, cloned_action);
}
/* The Action was cloned, so this should find the same-named slot automatically. */
const slot_handle_t orig_slot_handle = adt->slot_handle;
assign_action(&cloned_action->wrap(), *id);
BLI_assert(orig_slot_handle == adt->slot_handle);
UNUSED_VARS_NDEBUG(orig_slot_handle);
}
if (adt->tmpact && (do_linked_id || !ID_IS_LINKED(adt->tmpact))) {
id_us_min((ID *)adt->tmpact);
adt->tmpact = static_cast<bAction *>(
set_newid ? ID_NEW_SET(adt->tmpact, BKE_id_copy(bmain, &adt->tmpact->id)) :
BKE_id_copy(bmain, &adt->tmpact->id));
bAction *cloned_action = reinterpret_cast<bAction *>(BKE_id_copy(bmain, &adt->tmpact->id));
if (set_newid) {
ID_NEW_SET(adt->tmpact, cloned_action);
}
/* The Action was cloned, so this should find the same-named slot automatically. */
const slot_handle_t orig_slot_handle = adt->tmp_slot_handle;
assign_tmpaction(&cloned_action->wrap(), {*id, *adt});
BLI_assert(orig_slot_handle == adt->tmp_slot_handle);
UNUSED_VARS_NDEBUG(orig_slot_handle);
}
}
bNodeTree *ntree = blender::bke::node_tree_from_id(id);