Fix #139509: Slot assignment is lost when loading file saved in tweak mode

The issue was that the `AnimData.tmp_slot_handle` had no RNA property associated with it
and so it couldn't be saved in the lib override.

The fix is to add the property. To ensure the correct code is called, most of the previous code
was replaced with a call to `blender::animrig::assign_tmpaction`

Pull Request: https://projects.blender.org/blender/blender/pulls/141395
This commit is contained in:
Christoph Lendenfeld
2025-07-17 11:35:18 +02:00
committed by Christoph Lendenfeld
parent c19218e423
commit e80ceb52df
3 changed files with 19 additions and 73 deletions

View File

@@ -75,11 +75,6 @@ AnimData *BKE_animdata_ensure_id(ID *id);
*/
bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act);
/**
* Same as BKE_animdata_set_action(), except sets `tmpact` instead of `action`.
*/
bool BKE_animdata_set_tmpact(ReportList *reports, ID *id, bAction *act);
bool BKE_animdata_action_editable(const AnimData *adt);
/**

View File

@@ -119,71 +119,6 @@ AnimData *BKE_animdata_ensure_id(ID *id)
return nullptr;
}
/* Action / `tmpact` Setter shared code -------------------------
*
* Both the action and `tmpact` setter functions have essentially
* identical semantics, because `tmpact` is just a place to temporarily
* store the main action during tweaking. This function contains the
* shared code between those two setter functions, setting the action
* of the passed `act_slot` to `act`.
*
* Preconditions:
* - `id` and `act_slot` must be non-null (but the pointer `act_slot`
* points to can be null).
* - `id` must have animation data.
* - `act_slot` must be a pointer to either the `action` or `tmpact`
* field of `id`'s animation data.
*/
static bool animdata_set_action(ReportList *reports, ID *id, bAction **act_slot, bAction *act)
{
/* Action must have same type as owner. */
if (!BKE_animdata_action_ensure_idroot(id, act)) {
/* Cannot set to this type. */
BKE_reportf(
reports,
RPT_ERROR,
"Could not set action '%s' onto ID '%s', as it does not have suitably rooted paths "
"for this purpose",
act->id.name + 2,
id->name);
return false;
}
if (*act_slot == act) {
/* Don't bother reducing and increasing the user count when there is nothing changing. */
return true;
}
/* Unassign current action. */
if (*act_slot) {
id_us_min((ID *)*act_slot);
*act_slot = nullptr;
}
if (act == nullptr) {
return true;
}
*act_slot = act;
id_us_plus((ID *)*act_slot);
return true;
}
/* Tmpact Setter --------------------------------------- */
bool BKE_animdata_set_tmpact(ReportList *reports, ID *id, bAction *act)
{
AnimData *adt = BKE_animdata_from_id(id);
if (adt == nullptr) {
BKE_report(reports, RPT_WARNING, "No AnimData to set tmpact on");
return false;
}
return animdata_set_action(reports, id, &adt->tmpact, act);
}
/* Action Setter --------------------------------------- */
bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)

View File

@@ -227,8 +227,14 @@ static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value, ReportLis
static void rna_AnimData_tmpact_set(PointerRNA *ptr, PointerRNA value, ReportList *reports)
{
ID *ownerId = ptr->owner_id;
BKE_animdata_set_tmpact(reports, ownerId, static_cast<bAction *>(value.data));
ID *owner_id = ptr->owner_id;
AnimData *adt = (AnimData *)ptr->data;
BLI_assert(adt != nullptr);
bAction *action = static_cast<bAction *>(value.data);
if (!blender::animrig::assign_tmpaction(action, {*owner_id, *adt})) {
BKE_report(reports, RPT_WARNING, "Failed to set tmpact");
}
}
static void rna_AnimData_tweakmode_set(PointerRNA *ptr, const bool value)
@@ -1695,7 +1701,17 @@ static void rna_def_animdata(BlenderRNA *brna)
prop, nullptr, "rna_AnimData_tmpact_set", nullptr, "rna_Action_id_poll");
RNA_def_property_ui_text(prop,
"Tweak Mode Action Storage",
"Slot to temporarily hold the main action while in tweak mode");
"Storage to temporarily hold the main action while in tweak mode");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_dependency_update");
/* Temporary action slot for tweak mode. Just like `action_slot_handle` this is needed for
* library overrides to work.*/
prop = RNA_def_property(srna, "action_slot_handle_tweak_storage", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, nullptr, "tmp_slot_handle");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_EDITABLE);
RNA_def_property_ui_text(prop,
"Tweak Mode Action Slot Storage",
"Storage to temporarily hold the main action slot while in tweak mode");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_dependency_update");
/* Drivers */