Animation: correct active track/strip pointers after copying NLA tracks
After copying NLA tracks from one `AnimData` to another, also ensure that the `AnimData::act_track` and `AnimData::actstrip` pointers are pointing to the copy rather than the original. This is a necessary step to allow library overrides on NLA modifiers without crashing Blender. The remapping of the pointers is done by looping over the tracks/strips and comparing pointers. Alternatively, I could update the copy functions themselves to keep track of those pointers and return them, but IMO that would produce more spaghetti (they're also used in cases where this pointer-remapping is not desired).
This commit is contained in:
parent
191664acd2
commit
46d56bd956
Notes:
blender-bot
2023-02-14 09:33:11 +01:00
Referenced by issue #93707, Dragging the NLA strip cause a crash, if the related action is in tweakmode
|
@ -58,7 +58,14 @@ struct NlaTrack *BKE_nlatrack_copy(struct Main *bmain,
|
|||
struct NlaTrack *nlt,
|
||||
const bool use_same_actions,
|
||||
const int flag);
|
||||
void BKE_nla_tracks_copy(struct Main *bmain, ListBase *dst, ListBase *src, const int flag);
|
||||
void BKE_nla_tracks_copy(struct Main *bmain, ListBase *dst, const ListBase *src, const int flag);
|
||||
|
||||
/* Copy NLA tracks from #adt_source to #adt_dest, and update the active track/strip pointers to
|
||||
* point at those copies. */
|
||||
void BKE_nla_tracks_copy_from_adt(struct Main *bmain,
|
||||
struct AnimData *adt_dest,
|
||||
const struct AnimData *adt_source,
|
||||
int flag);
|
||||
|
||||
struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt,
|
||||
struct NlaTrack *prev,
|
||||
|
|
|
@ -354,7 +354,7 @@ AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
|
|||
}
|
||||
|
||||
/* duplicate NLA data */
|
||||
BKE_nla_tracks_copy(bmain, &dadt->nla_tracks, &adt->nla_tracks, flag);
|
||||
BKE_nla_tracks_copy_from_adt(bmain, dadt, adt, flag);
|
||||
|
||||
/* duplicate drivers (F-Curves) */
|
||||
BKE_fcurves_copy(&dadt->drivers, &adt->drivers);
|
||||
|
|
|
@ -254,7 +254,7 @@ NlaTrack *BKE_nlatrack_copy(Main *bmain,
|
|||
* \param flag: Control ID pointers management, see LIB_ID_CREATE_.../LIB_ID_COPY_...
|
||||
* flags in BKE_lib_id.h
|
||||
*/
|
||||
void BKE_nla_tracks_copy(Main *bmain, ListBase *dst, ListBase *src, const int flag)
|
||||
void BKE_nla_tracks_copy(Main *bmain, ListBase *dst, const ListBase *src, const int flag)
|
||||
{
|
||||
NlaTrack *nlt, *nlt_d;
|
||||
|
||||
|
@ -275,6 +275,54 @@ void BKE_nla_tracks_copy(Main *bmain, ListBase *dst, ListBase *src, const int fl
|
|||
}
|
||||
}
|
||||
|
||||
/* Set adt_dest->actstrip to the strip with the same index as adt_source->actstrip. */
|
||||
static void update_active_strip(AnimData *adt_dest,
|
||||
NlaTrack *track_dest,
|
||||
const AnimData *adt_source,
|
||||
NlaTrack *track_source)
|
||||
{
|
||||
BLI_assert(BLI_listbase_count(&track_source->strips) == BLI_listbase_count(&track_dest->strips));
|
||||
|
||||
NlaStrip *strip_dest = track_dest->strips.first;
|
||||
LISTBASE_FOREACH (NlaStrip *, strip_source, &track_source->strips) {
|
||||
if (strip_source == adt_source->actstrip) {
|
||||
adt_dest->actstrip = strip_dest;
|
||||
}
|
||||
|
||||
strip_dest = strip_dest->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set adt_dest->act_track to the track with the same index as adt_source->act_track. */
|
||||
static void update_active_track(AnimData *adt_dest, const AnimData *adt_source)
|
||||
{
|
||||
BLI_assert(BLI_listbase_count(&adt_source->nla_tracks) ==
|
||||
BLI_listbase_count(&adt_dest->nla_tracks));
|
||||
|
||||
NlaTrack *track_dest = adt_dest->nla_tracks.first;
|
||||
LISTBASE_FOREACH (NlaTrack *, track_source, &adt_source->nla_tracks) {
|
||||
if (track_source == adt_source->act_track) {
|
||||
adt_dest->act_track = track_dest;
|
||||
/* Assumption: the active strip is on the active track. */
|
||||
update_active_strip(adt_dest, track_dest, adt_source, track_source);
|
||||
}
|
||||
|
||||
track_dest = track_dest->next;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_nla_tracks_copy_from_adt(Main *bmain,
|
||||
AnimData *adt_dest,
|
||||
const AnimData *adt_source,
|
||||
const int flag)
|
||||
{
|
||||
adt_dest->act_track = NULL;
|
||||
adt_dest->actstrip = NULL;
|
||||
|
||||
BKE_nla_tracks_copy(bmain, &adt_dest->nla_tracks, &adt_source->nla_tracks, flag);
|
||||
update_active_track(adt_dest, adt_source);
|
||||
}
|
||||
|
||||
/* Adding ------------------------------------------- */
|
||||
|
||||
/* Add a NLA Track to the given AnimData
|
||||
|
|
Loading…
Reference in New Issue