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
diff options
context:
space:
mode:
authorBastien Montagne <mont29>2020-12-07 18:58:18 +0300
committerBastien Montagne <bastien@blender.org>2020-12-08 12:55:57 +0300
commitc0bd240ad0a17402db9d2e4799a433b81b62fca8 (patch)
tree06a0389f6ab6d3d5974caae3dc79063b3cb0524a /source/blender/editors
parent78080337f8994e685c1190190b4e37d8409b31a5 (diff)
LibOverride: Add initial support for adding new NLA tracks.
Also makes NLA tracks and strips overridable. User can either edit existing strips in existing NLA tracks (but not add or remove them), and/or add new NLA tracks after those comming from the linked data. Most of the work was as usual checking operators and adding protections against illegal operations in override context. Note that since we can only rely on indices to deal with local added tracks, we forbid any local track being before any linked/original track. Maniphest Tasks: T72629 Differential Revision: https://developer.blender.org/D9611
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c52
-rw-r--r--source/blender/editors/object/object_add.c5
-rw-r--r--source/blender/editors/space_action/action_data.c11
-rw-r--r--source/blender/editors/space_nla/nla_channels.c17
-rw-r--r--source/blender/editors/space_nla/nla_edit.c99
-rw-r--r--source/blender/editors/transform/transform_convert.c2
-rw-r--r--source/blender/editors/transform/transform_convert_nla.c16
7 files changed, 162 insertions, 40 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);
}
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--;