diff options
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r-- | source/blender/editors/animation/anim_channels_edit.c | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index ba3796ad245..124992bed71 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -49,6 +49,7 @@ #include "BKE_gpencil.h" #include "BKE_lib_id.h" #include "BKE_mask.h" +#include "BKE_nla.h" #include "BKE_scene.h" #include "DEG_depsgraph.h" @@ -1063,18 +1064,27 @@ static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible, eAnim_ChannelType type) { ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale, *ale_next; - int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); + eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | + ANIMFILTER_LIST_CHANNELS); /* get all visible channels */ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* now, only keep the ones that are of the types we are interested in */ - for (ale = anim_data.first; ale; ale = ale_next) { - ale_next = ale->next; - + LISTBASE_FOREACH_MUTABLE (bAnimListElem *, ale, &anim_data) { if (ale->type != type) { BLI_freelinkN(&anim_data, ale); + continue; + } + + if (type == ANIMTYPE_NLATRACK) { + NlaTrack *nlt = (NlaTrack *)ale->data; + + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No re-arrangement of non-local tracks of override data. */ + BLI_freelinkN(&anim_data, ale); + continue; + } } } @@ -1146,6 +1156,7 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn { AnimChanRearrangeFp rearrange_func; ListBase anim_data_visible = {NULL, NULL}; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ac->obact); /* hack: invert mode so that functions will work in right order */ mode *= -1; @@ -1156,6 +1167,29 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn return; } + /* In liboverride case, we need to extract non-local NLA tracks from current anim data before we + * can perform the move, and add then back afterwards. It's the only way to prevent them from + * being affected by the reordering. + * + * Note that both override apply code for NLA tracks collection, and NLA editing code, are + * responsible to ensure that non-local tracks always remain first in the list. */ + ListBase extracted_nonlocal_nla_tracks = {NULL, NULL}; + if (is_liboverride) { + NlaTrack *nla_track; + for (nla_track = adt->nla_tracks.first; nla_track != NULL; nla_track = nla_track->next) { + if (!BKE_nlatrack_is_nonlocal_in_liboverride(&ac->obact->id, nla_track)) { + break; + } + } + if (nla_track != NULL && nla_track->prev != NULL) { + extracted_nonlocal_nla_tracks.first = adt->nla_tracks.first; + extracted_nonlocal_nla_tracks.last = nla_track->prev; + adt->nla_tracks.first = nla_track; + nla_track->prev->next = NULL; + nla_track->prev = NULL; + } + } + /* Filter visible data. */ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK); @@ -1163,6 +1197,14 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn rearrange_animchannel_islands( &adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible); + /* Add back non-local NLA tracks at the begining of the animation data's list. */ + if (!BLI_listbase_is_empty(&extracted_nonlocal_nla_tracks)) { + BLI_assert(is_liboverride); + ((NlaTrack *)extracted_nonlocal_nla_tracks.last)->next = adt->nla_tracks.first; + ((NlaTrack *)adt->nla_tracks.first)->prev = extracted_nonlocal_nla_tracks.last; + adt->nla_tracks.first = extracted_nonlocal_nla_tracks.first; + } + /* free temp data */ BLI_freelistN(&anim_data_visible); } |