diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_nla.h | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 52 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels_edit.c | 52 | ||||
-rw-r--r-- | source/blender/editors/object/object_add.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_data.c | 11 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_channels.c | 17 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_edit.c | 99 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_convert.c | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_convert_nla.c | 16 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access_compare_override.c | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_animation.c | 70 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nla.c | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_rna.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 2 |
16 files changed, 305 insertions, 68 deletions
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 8671324fab1..16d48024d07 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -60,9 +60,13 @@ struct NlaTrack *BKE_nlatrack_copy(struct Main *bmain, const int flag); void BKE_nla_tracks_copy(struct Main *bmain, ListBase *dst, ListBase *src, const int flag); -struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt, struct NlaTrack *prev); +struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt, + struct NlaTrack *prev, + bool is_liboverride); struct NlaStrip *BKE_nlastrip_new(struct bAction *act); -struct NlaStrip *BKE_nlastack_add_strip(struct AnimData *adt, struct bAction *act); +struct NlaStrip *BKE_nlastack_add_strip(struct AnimData *adt, + struct bAction *act, + const bool is_liboverride); struct NlaStrip *BKE_nla_add_soundstrip(struct Main *bmain, struct Scene *scene, struct Speaker *speaker); @@ -95,10 +99,14 @@ void BKE_nlatrack_solo_toggle(struct AnimData *adt, struct NlaTrack *nlt); bool BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end); void BKE_nlatrack_sort_strips(struct NlaTrack *nlt); -bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip); +bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, + struct NlaStrip *strip, + const bool is_liboverride); bool BKE_nlatrack_get_bounds(struct NlaTrack *nlt, float bounds[2]); +bool BKE_nlatrack_is_nonlocal_in_liboverride(const struct ID *id, const struct NlaTrack *nlt); + /* ............ */ struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt); @@ -124,11 +132,11 @@ void BKE_nla_validate_state(struct AnimData *adt); /* ............ */ bool BKE_nla_action_is_stashed(struct AnimData *adt, struct bAction *act); -bool BKE_nla_action_stash(struct AnimData *adt); +bool BKE_nla_action_stash(struct AnimData *adt, const bool is_liboverride); /* ............ */ -void BKE_nla_action_pushdown(struct AnimData *adt); +void BKE_nla_action_pushdown(struct AnimData *adt, const bool is_liboverride); bool BKE_nla_tweakmode_enter(struct AnimData *adt); void BKE_nla_tweakmode_exit(struct AnimData *adt); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 9696d920640..6a852df95c6 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1999,12 +1999,12 @@ static void nlastrips_to_animdata(ID *id, ListBase *strips) } /* try to add this strip to the current NLA-Track (i.e. the 'last' one on the stack atm) */ - if (BKE_nlatrack_add_strip(nlt, strip) == 0) { + if (BKE_nlatrack_add_strip(nlt, strip, false) == 0) { /* trying to add to the current failed (no space), * so add a new track to the stack, and add to that... */ - nlt = BKE_nlatrack_add(adt, NULL); - BKE_nlatrack_add_strip(nlt, strip); + nlt = BKE_nlatrack_add(adt, NULL, false); + BKE_nlatrack_add_strip(nlt, strip, false); } /* ensure that strip has a name */ diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 56bd83140bf..ebd9317fcf1 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -280,7 +280,7 @@ void BKE_nla_tracks_copy(Main *bmain, ListBase *dst, ListBase *src, const int fl /* Add a NLA Track to the given AnimData * - prev: NLA-Track to add the new one after */ -NlaTrack *BKE_nlatrack_add(AnimData *adt, NlaTrack *prev) +NlaTrack *BKE_nlatrack_add(AnimData *adt, NlaTrack *prev, const bool is_liboverride) { NlaTrack *nlt; @@ -293,11 +293,15 @@ NlaTrack *BKE_nlatrack_add(AnimData *adt, NlaTrack *prev) nlt = MEM_callocN(sizeof(NlaTrack), "NlaTrack"); /* set settings requiring the track to not be part of the stack yet */ - nlt->flag = NLATRACK_SELECTED; + nlt->flag = NLATRACK_SELECTED | NLATRACK_OVERRIDELIBRARY_LOCAL; nlt->index = BLI_listbase_count(&adt->nla_tracks); /* add track to stack, and make it the active one */ - if (prev) { + if (is_liboverride) { + for (; prev != NULL && (prev->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0; prev = prev->next) { + } + } + if (prev != NULL) { BLI_insertlinkafter(&adt->nla_tracks, prev, nlt); } else { @@ -359,7 +363,7 @@ NlaStrip *BKE_nlastrip_new(bAction *act) /* Add new NLA-strip to the top of the NLA stack - i.e. * into the last track if space, or a new one otherwise. */ -NlaStrip *BKE_nlastack_add_strip(AnimData *adt, bAction *act) +NlaStrip *BKE_nlastack_add_strip(AnimData *adt, bAction *act, const bool is_liboverride) { NlaStrip *strip; NlaTrack *nlt; @@ -376,12 +380,12 @@ NlaStrip *BKE_nlastack_add_strip(AnimData *adt, bAction *act) } /* firstly try adding strip to last track, but if that fails, add to a new track */ - if (BKE_nlatrack_add_strip(adt->nla_tracks.last, strip) == 0) { + if (BKE_nlatrack_add_strip(adt->nla_tracks.last, strip, is_liboverride) == 0) { /* trying to add to the last track failed (no track or no space), * so add a new track to the stack, and add to that... */ - nlt = BKE_nlatrack_add(adt, NULL); - BKE_nlatrack_add_strip(nlt, strip); + nlt = BKE_nlatrack_add(adt, NULL, is_liboverride); + BKE_nlatrack_add_strip(nlt, strip, is_liboverride); } /* automatically name it too */ @@ -1138,15 +1142,16 @@ void BKE_nlatrack_sort_strips(NlaTrack *nlt) /* Add the given NLA-Strip to the given NLA-Track, assuming that it * isn't currently attached to another one */ -bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip) +bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip, const bool is_liboverride) { /* sanity checks */ if (ELEM(NULL, nlt, strip)) { return false; } - /* do not allow adding strips if this track is locked */ - if (nlt->flag & NLATRACK_PROTECTED) { + /* Do not allow adding strips if this track is locked, or not a local one in liboverride case. */ + if (nlt->flag & NLATRACK_PROTECTED || + (is_liboverride && (nlt->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0)) { return false; } @@ -1186,6 +1191,18 @@ bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2]) return true; } +/** + * Check whether given NLA track is not local (i.e. from linked data) when the object is a library + * override. + * + * \param nlt May be NULL, in which case we consider it as a non-local track case. + */ +bool BKE_nlatrack_is_nonlocal_in_liboverride(const ID *id, const NlaTrack *nlt) +{ + return (ID_IS_OVERRIDE_LIBRARY(id) && + (nlt == NULL || (nlt->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0)); +} + /* NLA Strips -------------------------------------- */ /* Find the active NLA-strip within the given track */ @@ -1857,7 +1874,7 @@ bool BKE_nla_action_is_stashed(AnimData *adt, bAction *act) /* "Stash" an action (i.e. store it as a track/layer in the NLA, but non-contributing) * to retain it in the file for future uses */ -bool BKE_nla_action_stash(AnimData *adt) +bool BKE_nla_action_stash(AnimData *adt, const bool is_liboverride) { NlaTrack *prev_track = NULL; NlaTrack *nlt; @@ -1881,7 +1898,7 @@ bool BKE_nla_action_stash(AnimData *adt) } } - nlt = BKE_nlatrack_add(adt, prev_track); + nlt = BKE_nlatrack_add(adt, prev_track, is_liboverride); BLI_assert(nlt != NULL); /* We need to ensure that if there wasn't any previous instance, @@ -1901,7 +1918,7 @@ bool BKE_nla_action_stash(AnimData *adt) strip = BKE_nlastrip_new(adt->action); BLI_assert(strip != NULL); - BKE_nlatrack_add_strip(nlt, strip); + BKE_nlatrack_add_strip(nlt, strip, is_liboverride); BKE_nlastrip_validate_name(adt, strip); /* mark the stash track and strip so that they doesn't disturb the stack animation, @@ -1931,7 +1948,7 @@ bool BKE_nla_action_stash(AnimData *adt) * so no checks for this are performed. */ /* TODO: maybe we should have checks for this too... */ -void BKE_nla_action_pushdown(AnimData *adt) +void BKE_nla_action_pushdown(AnimData *adt, const bool is_liboverride) { NlaStrip *strip; const bool is_first = (adt) && (adt->nla_tracks.first == NULL); @@ -1952,7 +1969,7 @@ void BKE_nla_action_pushdown(AnimData *adt) } /* add a new NLA strip to the track, which references the active action */ - strip = BKE_nlastack_add_strip(adt, adt->action); + strip = BKE_nlastack_add_strip(adt, adt->action, is_liboverride); if (strip == NULL) { return; } @@ -2273,6 +2290,11 @@ void BKE_nla_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *tracks) { /* we only care about the NLA strips inside the tracks */ LISTBASE_FOREACH (NlaTrack *, nlt, tracks) { + /* If linking from a library, clear 'local' library override flag. */ + if (id->lib != NULL) { + nlt->flag &= ~NLATRACK_OVERRIDELIBRARY_LOCAL; + } + blend_lib_read_nla_strips(reader, id, &nlt->strips); } } 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); } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 4e0f6211c18..bbfdfb2532d 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1618,6 +1618,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } Object *ob = ED_object_add_type(C, OB_SPEAKER, NULL, loc, rot, false, local_view_bits); + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ob); /* to make it easier to start using this immediately in NLA, a default sound clip is created * ready to be moved around to retime the sound and/or make new sound clips @@ -1625,13 +1626,13 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) { /* create new data for NLA hierarchy */ AnimData *adt = BKE_animdata_add_id(&ob->id); - NlaTrack *nlt = BKE_nlatrack_add(adt, NULL); + NlaTrack *nlt = BKE_nlatrack_add(adt, NULL, is_liboverride); NlaStrip *strip = BKE_nla_add_soundstrip(bmain, scene, ob->data); strip->start = CFRA; strip->end += strip->start; /* hook them up */ - BKE_nlatrack_add_strip(nlt, strip); + BKE_nlatrack_add_strip(nlt, strip, is_liboverride); /* auto-name the strip, and give the track an interesting name */ BLI_strncpy(nlt->name, DATA_("SoundTrack"), sizeof(nlt->name)); diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c index e20be9c8328..3a584a7f0cb 100644 --- a/source/blender/editors/space_action/action_data.c +++ b/source/blender/editors/space_action/action_data.c @@ -240,7 +240,7 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op)) /* Perform stashing operation - But only if there is an action */ if (adt && oldact) { /* stash the action */ - if (BKE_nla_action_stash(adt)) { + if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ptr.owner_id))) { /* The stash operation will remove the user already * (and unlink the action from the AnimData action slot). * Hence, we must unset the ref to the action in the @@ -339,7 +339,8 @@ static int action_pushdown_exec(bContext *C, wmOperator *op) } /* action can be safely added */ - BKE_nla_action_pushdown(adt); + const Object *ob = CTX_data_active_object(C); + BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(ob)); /* Stop displaying this action in this editor * NOTE: The editor itself doesn't set a user... @@ -384,7 +385,8 @@ static int action_stash_exec(bContext *C, wmOperator *op) } /* stash the action */ - if (BKE_nla_action_stash(adt)) { + Object *ob = CTX_data_active_object(C); + if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ob))) { /* The stash operation will remove the user already, * so the flushing step later shouldn't double up * the user-count fixes. Hence, we must unset this ref @@ -486,7 +488,8 @@ static int action_stash_create_exec(bContext *C, wmOperator *op) } /* stash the action */ - if (BKE_nla_action_stash(adt)) { + Object *ob = CTX_data_active_object(C); + if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ob))) { bAction *new_action = NULL; /* Create new action not based on the old one diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index 561de5e82a6..9832ca975cf 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -292,7 +292,7 @@ static int mouse_nla_channels( /* TODO: make this use the operator instead of calling the function directly * however, calling the operator requires that we supply the args, * and that works with proper buttons only */ - BKE_nla_action_pushdown(adt); + BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(ale->id)); } else { /* when in tweakmode, this button becomes the toggle for mapped editing */ @@ -516,7 +516,7 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op) } /* 'push-down' action - only usable when not in TweakMode */ - BKE_nla_action_pushdown(adt); + BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(id)); struct Main *bmain = CTX_data_main(C); DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION); @@ -648,19 +648,21 @@ bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel) NlaTrack *nlt = (NlaTrack *)ale->data; AnimData *adt = ale->adt; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + /* check if just adding a new track above this one, * or whether we're adding a new one to the top of the stack that this one belongs to */ if (above_sel) { /* just add a new one above this one */ - BKE_nlatrack_add(adt, nlt); + BKE_nlatrack_add(adt, nlt, is_liboverride); ale->update = ANIM_UPDATE_DEPS; added = true; } else if ((lastAdt == NULL) || (adt != lastAdt)) { /* add one track to the top of the owning AnimData's stack, * then don't add anymore to this stack */ - BKE_nlatrack_add(adt, NULL); + BKE_nlatrack_add(adt, NULL, is_liboverride); lastAdt = adt; ale->update = ANIM_UPDATE_DEPS; added = true; @@ -698,7 +700,7 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac) /* ensure it is empty */ if (BLI_listbase_is_empty(&adt->nla_tracks)) { /* add new track to this AnimData block then */ - BKE_nlatrack_add(adt, NULL); + BKE_nlatrack_add(adt, NULL, ID_IS_OVERRIDE_LIBRARY(ale->id)); ale->update = ANIM_UPDATE_DEPS; added = true; } @@ -796,6 +798,11 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nlt = (NlaTrack *)ale->data; AnimData *adt = ale->adt; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No deletion of non-local tracks of override data. */ + continue; + } + /* if track is currently 'solo', then AnimData should have its * 'has solo' flag disabled */ diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index ed8e5ad76e9..3fa1b614a03 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -649,6 +649,7 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op) NlaTrack *nlt = (NlaTrack *)ale->data; AnimData *adt = ale->adt; NlaStrip *strip = NULL; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); /* Sanity check: only apply actions of the right type for this ID. * NOTE: in the case that this hasn't been set, @@ -671,12 +672,12 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op) strip->start = cfra; /* firstly try adding strip to our current track, but if that fails, add to a new track */ - if (BKE_nlatrack_add_strip(nlt, strip) == 0) { + if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) { /* trying to add to the current failed (no space), * so add a new track to the stack, and add to that... */ - nlt = BKE_nlatrack_add(adt, NULL); - BKE_nlatrack_add_strip(nlt, strip); + nlt = BKE_nlatrack_add(adt, NULL, is_liboverride); + BKE_nlatrack_add_strip(nlt, strip, is_liboverride); } /* auto-name it */ @@ -886,6 +887,7 @@ static int nlaedit_add_sound_exec(bContext *C, wmOperator *UNUSED(op)) AnimData *adt = ale->adt; NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); /* does this belong to speaker - assumed to live on Object level only */ if ((GS(ale->id->name) != ID_OB) || (ob->type != OB_SPEAKER)) { @@ -899,12 +901,12 @@ static int nlaedit_add_sound_exec(bContext *C, wmOperator *UNUSED(op)) strip->end += cfra; /* firstly try adding strip to our current track, but if that fails, add to a new track */ - if (BKE_nlatrack_add_strip(nlt, strip) == 0) { + if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) { /* trying to add to the current failed (no space), * so add a new track to the stack, and add to that... */ - nlt = BKE_nlatrack_add(adt, NULL); - BKE_nlatrack_add_strip(nlt, strip); + nlt = BKE_nlatrack_add(adt, NULL, is_liboverride); + BKE_nlatrack_add_strip(nlt, strip, is_liboverride); } /* auto-name it */ @@ -966,6 +968,11 @@ static int nlaedit_add_meta_exec(bContext *C, wmOperator *UNUSED(op)) AnimData *adt = ale->adt; NlaStrip *strip; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No making metastrips in non-local tracks of override data. */ + continue; + } + /* create meta-strips from the continuous chains of selected strips */ BKE_nlastrips_make_metas(&nlt->strips, 0); @@ -1030,6 +1037,11 @@ static int nlaedit_remove_meta_exec(bContext *C, wmOperator *UNUSED(op)) for (ale = anim_data.first; ale; ale = ale->next) { NlaTrack *nlt = (NlaTrack *)ale->data; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No removing metastrips from non-local tracks of override data. */ + continue; + } + /* clear all selected meta-strips, regardless of whether they are temporary or not */ BKE_nlastrips_clear_metas(&nlt->strips, 1, 0); @@ -1096,6 +1108,11 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op) NlaStrip *strip, *nstrip, *next; NlaTrack *track; + /* Note: We allow this operator in override context because it is almost always (from possible + * default user interactions) paired with the transform one, which will ensure that the new + * strip ends up in a valid (local) track. */ + + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); for (strip = nlt->strips.first; strip; strip = next) { next = strip->next; @@ -1106,13 +1123,13 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op) /* in case there's no space in the track above, * or we haven't got a reference to it yet, try adding */ - if (BKE_nlatrack_add_strip(nlt->next, nstrip) == 0) { + if (BKE_nlatrack_add_strip(nlt->next, nstrip, is_liboverride) == 0) { /* need to add a new track above the one above the current one * - if the current one is the last one, nlt->next will be NULL, which defaults to adding * at the top of the stack anyway... */ - track = BKE_nlatrack_add(adt, nlt->next); - BKE_nlatrack_add_strip(track, nstrip); + track = BKE_nlatrack_add(adt, nlt->next, is_liboverride); + BKE_nlatrack_add_strip(track, nstrip, is_liboverride); } /* deselect the original and the active flag */ @@ -1209,6 +1226,11 @@ static int nlaedit_delete_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip, *nstrip; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No deletion of strips in non-local tracks of override data. */ + continue; + } + for (strip = nlt->strips.first; strip; strip = nstrip) { nstrip = strip->next; @@ -1359,6 +1381,11 @@ static int nlaedit_split_exec(bContext *C, wmOperator *UNUSED(op)) AnimData *adt = ale->adt; NlaStrip *strip, *next; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No splitting of strips in non-local tracks of override data. */ + continue; + } + for (strip = nlt->strips.first; strip; strip = next) { next = strip->next; @@ -1502,6 +1529,12 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op) NlaStrip *strip, *stripN = NULL; NlaStrip *area = NULL, *sb = NULL; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No re-ordering of strips whithin non-local tracks of override data. */ + continue; + } /* make temporary metastrips so that entire islands of selections can be moved around */ BKE_nlastrips_make_metas(&nlt->strips, 1); @@ -1610,8 +1643,8 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op) } /* add strips back to track now */ - BKE_nlatrack_add_strip(nlt, area); - BKE_nlatrack_add_strip(nlt, sb); + BKE_nlatrack_add_strip(nlt, area, is_liboverride); + BKE_nlatrack_add_strip(nlt, sb, is_liboverride); } /* clear (temp) metastrips */ @@ -1674,11 +1707,19 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nltn = nlt->next; NlaStrip *strip, *stripn; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + /* if this track has no tracks after it, skip for now... */ if (nltn == NULL) { continue; } + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt) || + BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nltn)) { + /* No moving of strips in non-local tracks of override data. */ + continue; + } + /* for every selected strip, try to move */ for (strip = nlt->strips.first; strip; strip = stripn) { stripn = strip->next; @@ -1689,7 +1730,7 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op)) /* remove from its current track, and add to the one above * (it 'should' work, so no need to worry) */ BLI_remlink(&nlt->strips, strip); - BKE_nlatrack_add_strip(nltn, strip); + BKE_nlatrack_add_strip(nltn, strip, is_liboverride); } } } @@ -1751,11 +1792,19 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nltp = nlt->prev; NlaStrip *strip, *stripn; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + /* if this track has no tracks before it, skip for now... */ if (nltp == NULL) { continue; } + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt) || + BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nltp)) { + /* No moving of strips in non-local tracks of override data. */ + continue; + } + /* for every selected strip, try to move */ for (strip = nlt->strips.first; strip; strip = stripn) { stripn = strip->next; @@ -1766,7 +1815,7 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op)) /* remove from its current track, and add to the one above * (it 'should' work, so no need to worry) */ BLI_remlink(&nlt->strips, strip); - BKE_nlatrack_add_strip(nltp, strip); + BKE_nlatrack_add_strip(nltp, strip, is_liboverride); } } } @@ -2023,11 +2072,11 @@ static int nlaedit_apply_scale_exec(bContext *C, wmOperator *UNUSED(op)) /* strip must be selected, and must be action-clip only * (transitions don't have scale) */ if ((strip->flag & NLASTRIP_FLAG_SELECT) && (strip->type == NLASTRIP_TYPE_CLIP)) { - /* if the referenced action is used by other strips, - * make this strip use its own copy */ - if (strip->act == NULL) { + if (strip->act == NULL || ID_IS_OVERRIDE_LIBRARY(strip->act) || ID_IS_LINKED(strip->act)) { continue; } + /* if the referenced action is used by other strips, + * make this strip use its own copy */ if (strip->act->id.us > 1) { /* make a copy of the Action to work on */ bAction *act = (bAction *)BKE_id_copy(bmain, &strip->act->id); @@ -2200,6 +2249,8 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op) NlaStrip *strip, *stripn; NlaTrack *track; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + /* create meta-strips from the continuous chains of selected strips */ BKE_nlastrips_make_metas(&nlt->strips, 1); @@ -2255,10 +2306,10 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op) BLI_remlink(&tmp_strips, strip); /* in case there's no space in the current track, try adding */ - if (BKE_nlatrack_add_strip(nlt, strip) == 0) { + if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) { /* need to add a new track above the current one */ - track = BKE_nlatrack_add(adt, nlt); - BKE_nlatrack_add_strip(track, strip); + track = BKE_nlatrack_add(adt, nlt, is_liboverride); + BKE_nlatrack_add_strip(track, strip, is_liboverride); /* clear temp meta-strips on this new track, * as we may not be able to get back to it */ @@ -2375,6 +2426,11 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op) NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No adding f-modifiers to strips in non-local tracks of override data. */ + continue; + } + for (strip = nlt->strips.first; strip; strip = strip->next) { /* can F-Modifier be added to the current strip? */ if (active_only) { @@ -2552,6 +2608,11 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op) NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No pasting in non-local tracks of override data. */ + continue; + } + for (strip = nlt->strips.first; strip; strip = strip->next) { /* can F-Modifier be added to the current strip? */ if (active_only) { diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index c23ee5b771c..c81c954bd0a 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -1438,7 +1438,7 @@ void animrecord_check_state(TransInfo *t, struct Object *ob) /* only push down if action is more than 1-2 frames long */ calc_action_range(adt->action, &astart, &aend, 1); if (aend > astart + 2.0f) { - NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action); + NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action, ID_IS_OVERRIDE_LIBRARY(id)); /* clear reference to action now that we've pushed it onto the stack */ id_us_min(&adt->action->id); diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index 8f18f6a8c96..fa60a88a45b 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -462,6 +462,12 @@ void recalcData_nla(TransInfo *t) * - we need to calculate both, * as only one may have been altered by transform if only 1 handle moved. */ + /* In LibOverride case, we cannot move strips across tracks that come from the linked data. */ + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(tdn->id); + if (BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) { + continue; + } + delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); @@ -477,10 +483,11 @@ void recalcData_nla(TransInfo *t) if (delta > 0) { for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) { /* check if space in this track for the strip */ - if (BKE_nlatrack_has_space(track, strip->start, strip->end)) { + if (BKE_nlatrack_has_space(track, strip->start, strip->end) && + !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) { /* move strip to this track */ BLI_remlink(&tdn->nlt->strips, strip); - BKE_nlatrack_add_strip(track, strip); + BKE_nlatrack_add_strip(track, strip, is_liboverride); tdn->nlt = track; tdn->trackIndex++; @@ -496,10 +503,11 @@ void recalcData_nla(TransInfo *t) for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) { /* check if space in this track for the strip */ - if (BKE_nlatrack_has_space(track, strip->start, strip->end)) { + if (BKE_nlatrack_has_space(track, strip->start, strip->end) && + !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) { /* move strip to this track */ BLI_remlink(&tdn->nlt->strips, strip); - BKE_nlatrack_add_strip(track, strip); + BKE_nlatrack_add_strip(track, strip, is_liboverride); tdn->nlt = track; tdn->trackIndex--; diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index 9a31447dacd..17d41985f80 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -875,6 +875,10 @@ typedef enum eNlaTrack_Flag { /** track is not allowed to execute, * usually as result of tweaking being enabled (internal flag) */ NLATRACK_DISABLED = (1 << 10), + + /** This NLA track is added to an override ID, which means it is fully editable. + * Irrelevant in case the owner ID is not an override. */ + NLATRACK_OVERRIDELIBRARY_LOCAL = 1 << 16, } eNlaTrack_Flag; /* ************************************ */ diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 2bf4de7af60..c0b2de268cd 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -23,6 +23,7 @@ #include "MEM_guardedalloc.h" #include "DNA_ID.h" +#include "DNA_anim_types.h" #include "DNA_constraint_types.h" #include "DNA_gpencil_modifier_types.h" #include "DNA_key_types.h" @@ -84,6 +85,12 @@ bool RNA_property_overridable_get(PointerRNA *ptr, PropertyRNA *prop) return true; } } + else if (RNA_struct_is_a(ptr->type, &RNA_NlaTrack)) { + NlaTrack *nla_track = ptr->data; + if (nla_track->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) { + return true; + } + } /* If this is a RNA-defined property (real or 'virtual' IDProp), * we want to use RNA prop flag. */ return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON) && diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 0a9f2ff4819..10f86fe2671 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -587,7 +587,7 @@ static void rna_KeyingSet_paths_clear(KeyingSet *keyingset, ReportList *reports) /* needs wrapper function to push notifier */ static NlaTrack *rna_NlaTrack_new(ID *id, AnimData *adt, Main *bmain, bContext *C, NlaTrack *track) { - NlaTrack *new_track = BKE_nlatrack_add(adt, track); + NlaTrack *new_track = BKE_nlatrack_add(adt, track, ID_IS_OVERRIDE_LIBRARY(id)); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL); @@ -732,6 +732,60 @@ bool rna_AnimaData_override_apply(Main *UNUSED(bmain), return false; } +bool rna_NLA_tracks_override_apply(Main *bmain, + PointerRNA *ptr_dst, + PointerRNA *ptr_src, + PointerRNA *UNUSED(ptr_storage), + PropertyRNA *UNUSED(prop_dst), + PropertyRNA *UNUSED(prop_src), + PropertyRNA *UNUSED(prop_storage), + const int UNUSED(len_dst), + const int UNUSED(len_src), + const int UNUSED(len_storage), + PointerRNA *UNUSED(ptr_item_dst), + PointerRNA *UNUSED(ptr_item_src), + PointerRNA *UNUSED(ptr_item_storage), + IDOverrideLibraryPropertyOperation *opop) +{ + BLI_assert(opop->operation == IDOVERRIDE_LIBRARY_OP_INSERT_AFTER && + "Unsupported RNA override operation on constraints collection"); + + AnimData *anim_data_dst = (AnimData *)ptr_dst->data; + AnimData *anim_data_src = (AnimData *)ptr_src->data; + + /* Remember that insertion operations are defined and stored in correct order, which means that + * even if we insert several items in a row, we always insert first one, then second one, etc. + * So we should always find 'anchor' track in both _src *and* _dst. */ + NlaTrack *nla_track_anchor = NULL; +# if 0 + /* This is not working so well with index-based insertion, especially in case some tracks get + * added to lib linked data. So we simply add locale tracks at the end of the list always, order + * of override operations should ensure order of local tracks is preserved properly. */ + if (opop->subitem_local_index >= 0) { + nla_track_anchor = BLI_findlink(&anim_data_dst->nla_tracks, opop->subitem_local_index); + } + /* Otherwise we just insert in first position. */ +# else + nla_track_anchor = anim_data_dst->nla_tracks.last; +# endif + + NlaTrack *nla_track_src = NULL; + if (opop->subitem_local_index >= 0) { + nla_track_src = BLI_findlink(&anim_data_src->nla_tracks, opop->subitem_local_index); + } + nla_track_src = nla_track_src ? nla_track_src->next : anim_data_src->nla_tracks.first; + + BLI_assert(nla_track_src != NULL); + + NlaTrack *nla_track_dst = BKE_nlatrack_copy(bmain, nla_track_src, true, 0); + + /* This handles NULL anchor as expected by adding at head of list. */ + BLI_insertlinkafter(&anim_data_dst->nla_tracks, nla_track_anchor, nla_track_dst); + + // printf("%s: We inserted a NLA Track...\n", __func__); + return true; +} + #else /* helper function for Keying Set -> keying settings */ @@ -1251,14 +1305,19 @@ static void rna_def_animdata(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "nla_tracks", NULL); RNA_def_property_struct_type(prop, "NlaTrack"); RNA_def_property_ui_text(prop, "NLA Tracks", "NLA Tracks (i.e. Animation Layers)"); + RNA_def_property_override_flag(prop, + PROPOVERRIDE_OVERRIDABLE_LIBRARY | + PROPOVERRIDE_LIBRARY_INSERTION | PROPOVERRIDE_NO_PROP_NAME); + RNA_def_property_override_funcs(prop, NULL, NULL, "rna_NLA_tracks_override_apply"); rna_api_animdata_nla_tracks(brna, prop); + RNA_define_lib_overridable(true); + /* Active Action */ prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE); /* this flag as well as the dynamic test must be defined for this to be editable... */ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); - RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_pointer_funcs( prop, NULL, "rna_AnimData_action_set", NULL, "rna_Action_id_poll"); RNA_def_property_editable_func(prop, "rna_AnimData_action_editable"); @@ -1297,11 +1356,14 @@ static void rna_def_animdata(BlenderRNA *brna) prop = RNA_def_property(srna, "drivers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "drivers", NULL); RNA_def_property_struct_type(prop, "FCurve"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_ui_text(prop, "Drivers", "The Drivers/Expressions for this data-block"); + RNA_define_lib_overridable(false); + rna_api_animdata_drivers(brna, prop); + RNA_define_lib_overridable(true); + /* General Settings */ prop = RNA_def_property(srna, "use_nla", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ADT_NLA_EVAL_OFF); @@ -1322,6 +1384,8 @@ static void rna_def_animdata(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Pin in Graph Editor", ""); RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + RNA_define_lib_overridable(false); + /* Animation Data API */ RNA_api_animdata(srna); } diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index b0dda1237b0..b7c51eac6ef 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -607,6 +607,8 @@ static void rna_def_nlastrip(BlenderRNA *brna) RNA_def_struct_path_func(srna, "rna_NlaStrip_path"); RNA_def_struct_ui_icon(srna, ICON_NLA); /* XXX */ + RNA_define_lib_overridable(true); + /* name property */ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", ""); @@ -820,6 +822,8 @@ static void rna_def_nlastrip(BlenderRNA *brna) "Update range of frames referenced from action " "after tweaking strip and its keyframes"); RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + RNA_define_lib_overridable(false); } static void rna_api_nlatrack_strips(BlenderRNA *brna, PropertyRNA *cprop) @@ -877,10 +881,14 @@ static void rna_def_nlatrack(BlenderRNA *brna) /* strips collection */ prop = RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "NlaStrip"); + /* We do not support inserting or removing strips in overrides of tracks for now. */ + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips on this NLA-track"); rna_api_nlatrack_strips(brna, prop); + RNA_define_lib_overridable(true); + /* name property */ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", ""); @@ -920,6 +928,8 @@ static void rna_def_nlatrack(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_PROTECTED); RNA_def_property_ui_text(prop, "Locked", "NLA Track is locked"); RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + + RNA_define_lib_overridable(false); } /* --------- */ diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index eae1c7bc223..b8f6eba4d5a 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -1858,7 +1858,7 @@ int rna_property_override_diff_default(Main *bmain, is_id, is_valid_for_diffing, is_valid_for_insertion, - (RNA_property_override_flag(prop_a) & PROPOVERRIDE_LIBRARY_INSERTION) != 0, + use_collection_insertion, do_create); } # endif diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index eabb71c79d3..ff77819aae1 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2113,7 +2113,7 @@ static void rna_SpaceDopeSheetEditor_action_update(bContext *C, PointerRNA *ptr) * and the user then uses the browse menu to get back to this action, * assigning it as the active action (i.e. the stash strip gets out of sync) */ - BKE_nla_action_stash(adt); + BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(id)); } BKE_animdata_set_action(NULL, id, saction->action); |