Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2021-05-04 17:19:51 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-05-04 17:23:57 +0300
commit46d56bd9567045965a6a46e2b5205020514bbee1 (patch)
tree40197c0053179a1a906360c70b57df848956e0d7 /source
parent191664acd2c0e2e0c8ff1f92e56db5e68d6c2ca3 (diff)
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).
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_nla.h9
-rw-r--r--source/blender/blenkernel/intern/anim_data.c2
-rw-r--r--source/blender/blenkernel/intern/nla.c50
3 files changed, 58 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 16d48024d07..af238fda659 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -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,
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c
index 447ed8fbe14..68de3e93a8e 100644
--- a/source/blender/blenkernel/intern/anim_data.c
+++ b/source/blender/blenkernel/intern/anim_data.c
@@ -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);
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 97aa6b07ab0..92e21183acb 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -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