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:
-rw-r--r--source/blender/blenkernel/BKE_nla.h4
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c15
-rw-r--r--source/blender/blenkernel/intern/nla.c100
-rw-r--r--source/blender/editors/animation/anim_channels.c12
-rw-r--r--source/blender/editors/animation/anim_filter.c118
-rw-r--r--source/blender/editors/include/ED_anim_api.h6
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/screen/screen_ops.c6
-rw-r--r--source/blender/editors/space_action/action_select.c4
-rw-r--r--source/blender/editors/space_graph/graph_select.c2
-rw-r--r--source/blender/editors/space_nla/nla_channels.c2
-rw-r--r--source/blender/editors/space_nla/nla_draw.c81
-rw-r--r--source/blender/editors/space_nla/nla_edit.c137
-rw-r--r--source/blender/editors/space_nla/nla_intern.h8
-rw-r--r--source/blender/editors/space_nla/nla_ops.c56
-rw-r--r--source/blender/editors/space_nla/nla_select.c3
-rw-r--r--source/blender/makesdna/DNA_action_types.h1
-rw-r--r--source/blender/makesdna/DNA_anim_types.h11
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
19 files changed, 514 insertions, 54 deletions
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 3c3abe11da3..89e5f1af7e1 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -59,9 +59,13 @@ void BKE_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt);
short BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
+struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt);
short BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
void BKE_nla_action_pushdown(struct AnimData *adt);
+short BKE_nla_tweakmode_enter(struct AnimData *adt);
+void BKE_nla_tweakmode_exit(struct AnimData *adt);
+
#endif
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 652f733d553..dbc38d2fc7e 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -118,6 +118,9 @@ void BKE_free_animdata (ID *id)
/* unlink action (don't free, as it's in its own list) */
if (adt->action)
adt->action->id.us--;
+ /* same goes for the temporarily displaced action */
+ if (adt->tmpact)
+ adt->tmpact->id.us--;
/* free nla data */
free_nladata(&adt->nla_tracks);
@@ -151,6 +154,7 @@ AnimData *BKE_copy_animdata (AnimData *adt)
// XXX review this... it might not be optimal behaviour yet...
//id_us_plus((ID *)dadt->action);
dadt->action= copy_action(adt->action);
+ dadt->tmpact= copy_action(adt->action);
/* duplicate NLA data */
copy_nladata(&dadt->nla_tracks, &adt->nla_tracks);
@@ -595,7 +599,7 @@ static float nlastrip_get_frame (NlaStrip *strip, float cframe, short invert)
scale = (float)fabs(strip->scale); /* scale must be positive - we've got a special flag for reversing */
/* length of referenced action */
- actlength = strip->actend-strip->actstart;
+ actlength = strip->actend - strip->actstart;
if (actlength == 0.0f) actlength = 1.0f;
/* length of strip */
@@ -630,11 +634,11 @@ static float nlastrip_get_influence (NlaStrip *strip, float cframe)
// the +0.0001 factors are to combat rounding errors
if (IS_EQ(strip->blendin, 0)==0 && (cframe <= (strip->start + strip->blendin))) {
/* there is some blend-in */
- return (float)(fabs(cframe - strip->start) + 0.0001) / (strip->blendin);
+ return (float)fabs(cframe - strip->start) / (strip->blendin);
}
else if (IS_EQ(strip->blendout, 0)==0 && (cframe >= (strip->end - strip->blendout))) {
/* there is some blend-out */
- return (float)(fabs(strip->end - cframe) + 0.0001) / (strip->blendout);
+ return (float)fabs(strip->end - cframe) / (strip->blendout);
}
else {
/* in the middle of the strip, we should be full strength */
@@ -674,8 +678,8 @@ static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index
NlaEvalStrip *nes;
short side= 0;
- /* skip if track is muted */
- if (nlt->flag & NLATRACK_MUTED)
+ /* skip if track is muted or disabled */
+ if (nlt->flag & (NLATRACK_MUTED|NLATRACK_DISABLED))
return;
/* loop over strips, checking if they fall within the range */
@@ -1104,6 +1108,7 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re
* - NLA before Active Action, as Active Action behaves as 'tweaking track'
* that overrides 'rough' work in NLA
*/
+ // TODO: need to double check that this all works correctly
if ((recalc & ADT_RECALC_ANIM) || (adt->recalc & ADT_RECALC_ANIM))
{
/* evaluate NLA data */
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 6235ec58d40..84f98096364 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -583,4 +583,104 @@ void BKE_nla_action_pushdown (AnimData *adt)
}
}
+
+/* Find the active strip + track combo, and set them up as the tweaking track,
+ * and return if successful or not.
+ */
+short BKE_nla_tweakmode_enter (AnimData *adt)
+{
+ NlaTrack *nlt, *activeTrack=NULL;
+ NlaStrip *strip, *activeStrip=NULL;
+
+ /* verify that data is valid */
+ if ELEM(NULL, adt, adt->nla_tracks.first)
+ return 0;
+
+ /* if block is already in tweakmode, just leave, but we should report
+ * that this block is in tweakmode (as our returncode)
+ */
+ // FIXME: hopefully the flag is correct!
+ if (adt->flag & ADT_NLA_EDIT_ON)
+ return 1;
+
+ /* go over the tracks, finding the active one, and its active strip
+ * - if we cannot find both, then there's nothing to do
+ */
+ for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
+ /* check if active */
+ if (nlt->flag & NLATRACK_ACTIVE) {
+ /* store reference to this active track */
+ activeTrack= nlt;
+
+ /* now try to find active strip */
+ activeStrip= BKE_nlastrip_find_active(nlt);
+ break;
+ }
+ }
+ if ELEM3(NULL, activeTrack, activeStrip, activeStrip->act) {
+ printf("NLA tweakmode enter - neither active requirement found \n");
+ return 0;
+ }
+
+ /* go over all the tracks up to the active one, tagging each strip that uses the same
+ * action as the active strip, but leaving everything else alone
+ */
+ for (nlt= activeTrack->prev; nlt; nlt= nlt->prev) {
+ for (strip= nlt->strips.first; strip; strip= strip->next) {
+ if (strip->act == activeStrip->act)
+ strip->flag |= NLASTRIP_FLAG_TWEAKUSER;
+ else
+ strip->flag &= ~NLASTRIP_FLAG_TWEAKUSER; // XXX probably don't need to clear this...
+ }
+ }
+
+
+ /* go over all the tracks after AND INCLUDING the active one, tagging them as being disabled
+ * - the active track needs to also be tagged, otherwise, it'll overlap with the tweaks going on
+ */
+ for (nlt= activeTrack; nlt; nlt= nlt->next)
+ nlt->flag |= NLATRACK_DISABLED;
+
+ /* handle AnimData level changes:
+ * - 'real' active action to temp storage (no need to change user-counts)
+ * - action of active strip set to be the 'active action'
+ * - editing-flag for this AnimData block should also get turned on (for more efficient restoring)
+ */
+ adt->tmpact= adt->action;
+ adt->action= activeStrip->act;
+ adt->flag |= ADT_NLA_EDIT_ON;
+
+ /* done! */
+ return 1;
+}
+
+/* Exit tweakmode for this AnimData block */
+void BKE_nla_tweakmode_exit (AnimData *adt)
+{
+ NlaTrack *nlt;
+
+ /* verify that data is valid */
+ if ELEM(NULL, adt, adt->nla_tracks.first)
+ return;
+
+ /* hopefully the flag is correct - skip if not on */
+ if ((adt->flag & ADT_NLA_EDIT_ON) == 0)
+ return;
+
+ // TODO: need to sync the user-strip with the new state of the action!
+
+ /* for all NLA-tracks, clear the 'disabled' flag */
+ for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next)
+ nlt->flag &= ~NLATRACK_DISABLED;
+
+ /* handle AnimData level changes:
+ * - 'real' active action is restored from storage
+ * - storage pointer gets cleared (to avoid having bad notes hanging around)
+ * - editing-flag for this AnimData block should also get turned off
+ */
+ adt->action= adt->tmpact;
+ adt->tmpact= NULL;
+ adt->flag &= ~ADT_NLA_EDIT_ON;
+}
+
/* *************************************************** */
diff --git a/source/blender/editors/animation/anim_channels.c b/source/blender/editors/animation/anim_channels.c
index 658bff73978..59fb56f3c35 100644
--- a/source/blender/editors/animation/anim_channels.c
+++ b/source/blender/editors/animation/anim_channels.c
@@ -90,14 +90,13 @@
/* -------------------------- Exposed API ----------------------------------- */
/* Set the given animation-channel as the active one for the active context */
-void ANIM_set_active_channel (void *data, short datatype, int filter, void *channel_data, short channel_type)
+void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int filter, void *channel_data, short channel_type)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
/* try to build list of filtered items */
- // XXX we don't need/supply animcontext for now, since in this case, there's nothing really essential there that isn't already covered
- ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype);
+ ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
if (anim_data.first == NULL)
return;
@@ -151,8 +150,7 @@ void ANIM_set_active_channel (void *data, short datatype, int filter, void *chan
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt= (NlaTrack *)channel_data;
-
- ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE);
+ nlt->flag |= NLATRACK_ACTIVE;
}
break;
}
@@ -1474,7 +1472,7 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
/* if group is selected now, make group the 'active' one in the visible list */
if (agrp->flag & AGRP_SELECTED)
- ANIM_set_active_channel(ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
}
}
break;
@@ -1520,7 +1518,7 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
/* if F-Curve is selected now, make F-Curve the 'active' one in the visible list */
if (fcu->flag & FCURVE_SELECTED)
- ANIM_set_active_channel(ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
}
}
break;
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index ed526bd99a0..32405571b57 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -343,19 +343,33 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
/* quick macro to test if AnimData is usable for NLA */
#define ANIMDATA_HAS_NLA(id) ((id)->adt && (id)->adt->nla_tracks.first)
-/* quick macro to test for all three avove usability tests, performing the appropriate provided
+
+/* Quick macro to test for all three avove usability tests, performing the appropriate provided
* action for each when the AnimData context is appropriate.
*
- * Priority order for this goes (most important, to least): NLA, Drivers, Keyframes
+ * Priority order for this goes (most important, to least): AnimData blocks, NLA, Drivers, Keyframes.
+ *
+ * For this to work correctly, a standard set of data needs to be available within the scope that this
+ * gets called in:
+ * - ListBase anim_data;
+ * - bDopeSheet *ads;
+ * - bAnimListElem *ale;
+ * - int items;
*
* - id: ID block which should have an AnimData pointer following it immediately, to use
+ * - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
* - nlaOk: line or block of code to execute for NLA case
* - driversOk: line or block of code to execute for Drivers case
* - keysOk: line or block of code for Keyframes case
*/
-#define ANIMDATA_FILTER_CASES(id, nlaOk, driversOk, keysOk) \
+#define ANIMDATA_FILTER_CASES(id, adtOk, nlaOk, driversOk, keysOk) \
{\
- if (ads->filterflag & ADS_FILTER_ONLYNLA) {\
+ if (filter_mode & ANIMFILTER_ANIMDATA) {\
+ if ((id)->adt) {\
+ adtOk\
+ }\
+ }\
+ else if (ads->filterflag & ADS_FILTER_ONLYNLA) {\
if (ANIMDATA_HAS_NLA(id)) {\
nlaOk\
}\
@@ -376,6 +390,18 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
}
+/* quick macro to add a pointer to an AnimData block as a channel */
+#define ANIMDATA_ADD_ANIMDATA(id) \
+ {\
+ ale= make_new_animlistelem((id)->adt, ANIMTYPE_ANIMDATA, NULL, ANIMTYPE_NONE, (ID *)id);\
+ if (ale) {\
+ BLI_addtail(anim_data, ale);\
+ items++;\
+ }\
+ }
+
+
+
/* quick macro to test if a anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
#define ANIMCHANNEL_SELOK(test_func) \
( !(filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) || \
@@ -713,6 +739,11 @@ static int animdata_filter_nla (ListBase *anim_data, AnimData *adt, int filter_m
items++;
}
}
+
+ /* if we're in NLA-tweakmode, if this track was active, that means that it was the last active one */
+ // FIXME: the channels after should still get drawn, just 'differently', and after an active-action channel
+ if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_ACTIVE))
+ break;
}
}
}
@@ -890,6 +921,7 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
/* check if ok */
ANIMDATA_FILTER_CASES(ma,
+ { /* AnimData blocks - do nothing... */ },
ok=1;,
ok=1;,
ok=1;)
@@ -933,6 +965,7 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
/* add material's animation data */
if (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
ANIMDATA_FILTER_CASES(ma,
+ { /* AnimData blocks - do nothing... */ },
items += animdata_filter_nla(anim_data, ma->adt, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);,
items += animdata_filter_fcurves(anim_data, ma->adt->drivers.first, NULL, ma, ANIMTYPE_DSMAT, filter_mode, (ID *)ma);,
items += animdata_filter_action(anim_data, ma->adt->action, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);)
@@ -998,6 +1031,7 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad
if ((expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
/* filtering for channels - nla, drivers, keyframes */
ANIMDATA_FILTER_CASES(iat,
+ { /* AnimData blocks - do nothing... */ },
items+= animdata_filter_nla(anim_data, iat->adt, filter_mode, iat, type, (ID *)iat);,
items+= animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, iat, type, filter_mode, (ID *)iat);,
items += animdata_filter_action(anim_data, iat->adt->action, filter_mode, iat, type, (ID *)iat);)
@@ -1036,6 +1070,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
if (ob->adt) {
adt= ob->adt;
ANIMDATA_FILTER_CASES(ob,
+ { /* AnimData blocks - do nothing... */ },
{ /* nla */
#if 0
/* include nla-expand widget? */
@@ -1091,6 +1126,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
adt= key->adt;
ANIMDATA_FILTER_CASES(key,
+ { /* AnimData blocks - do nothing... */ },
{ /* nla */
#if 0
/* include nla-expand widget? */
@@ -1151,6 +1187,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
if ((ads->filterflag & ADS_FILTER_NOCAM) == 0) {
ANIMDATA_FILTER_CASES(ca,
+ { /* AnimData blocks - do nothing... */ },
obdata_ok= 1;,
obdata_ok= 1;,
obdata_ok= 1;)
@@ -1163,6 +1200,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
if ((ads->filterflag & ADS_FILTER_NOLAM) == 0) {
ANIMDATA_FILTER_CASES(la,
+ { /* AnimData blocks - do nothing... */ },
obdata_ok= 1;,
obdata_ok= 1;,
obdata_ok= 1;)
@@ -1175,6 +1213,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
if ((ads->filterflag & ADS_FILTER_NOCUR) == 0) {
ANIMDATA_FILTER_CASES(cu,
+ { /* AnimData blocks - do nothing... */ },
obdata_ok= 1;,
obdata_ok= 1;,
obdata_ok= 1;)
@@ -1216,6 +1255,7 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads
if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
adt= sce->adt;
ANIMDATA_FILTER_CASES(sce,
+ { /* AnimData blocks - do nothing... */ },
{ /* nla */
#if 0
/* include nla-expand widget? */
@@ -1266,9 +1306,10 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads
/* world */
if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
- /* Action, Drivers, or NLA for World */
+ /* Action, Drivers, or NLA for World */
adt= wo->adt;
ANIMDATA_FILTER_CASES(wo,
+ { /* AnimData blocks - do nothing... */ },
{ /* nla */
#if 0
/* include nla-expand widget? */
@@ -1327,6 +1368,7 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
{
Scene *sce= (Scene *)ads->source;
Base *base;
+ bAnimListElem *ale;
int items = 0;
/* check that we do indeed have a scene */
@@ -1342,11 +1384,25 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
/* check filtering-flags if ok */
ANIMDATA_FILTER_CASES(sce,
+ {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(sce);
+ sceOk=0;
+ },
sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);,
sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);,
sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);)
if (sce->world) {
ANIMDATA_FILTER_CASES(sce->world,
+ {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(sce->world);
+ worOk=0;
+ },
worOk= !(ads->filterflag & ADS_FILTER_NOWOR);,
worOk= !(ads->filterflag & ADS_FILTER_NOWOR);,
worOk= !(ads->filterflag & ADS_FILTER_NOWOR);)
@@ -1395,12 +1451,26 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
actOk= 0;
keyOk= 0;
ANIMDATA_FILTER_CASES(ob,
+ {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(ob);
+ actOk=0;
+ },
actOk= 1;,
actOk= 1;,
actOk= 1;)
if (key) {
/* shapekeys */
ANIMDATA_FILTER_CASES(key,
+ {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(key);
+ keyOk=0;
+ },
keyOk= 1;,
keyOk= 1;,
keyOk= 1;)
@@ -1419,6 +1489,13 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
/* if material has relevant animation data, break */
ANIMDATA_FILTER_CASES(ma,
+ {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(ma);
+ matOk=0;
+ },
matOk= 1;,
matOk= 1;,
matOk= 1;)
@@ -1435,6 +1512,13 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
Camera *ca= (Camera *)ob->data;
dataOk= 0;
ANIMDATA_FILTER_CASES(ca,
+ if ((ads->filterflag & ADS_FILTER_NOCAM)==0) {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(ca);
+ dataOk=0;
+ },
dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);,
dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);,
dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);)
@@ -1445,11 +1529,35 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
Lamp *la= (Lamp *)ob->data;
dataOk= 0;
ANIMDATA_FILTER_CASES(la,
+ if ((ads->filterflag & ADS_FILTER_NOLAM)==0) {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(la);
+ dataOk=0;
+ },
dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);,
dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);,
dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);)
}
break;
+ case OB_CURVE: /* ------- Curve ---------- */
+ {
+ Curve *cu= (Curve *)ob->data;
+ dataOk= 0;
+ ANIMDATA_FILTER_CASES(cu,
+ if ((ads->filterflag & ADS_FILTER_NOCUR)==0) {
+ /* for the special AnimData blocks only case, we only need to add
+ * the block if it is valid... then other cases just get skipped (hence ok=0)
+ */
+ ANIMDATA_ADD_ANIMDATA(cu);
+ dataOk=0;
+ },
+ dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);,
+ dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);,
+ dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);)
+ }
+ break;
default: /* --- other --- */
dataOk= 0;
break;
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index cdd8b5c368c..dcaabb4b369 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -107,6 +107,7 @@ typedef struct bAnimListElem {
// XXX was ACTTYPE_*
typedef enum eAnim_ChannelType {
ANIMTYPE_NONE= 0,
+ ANIMTYPE_ANIMDATA,
ANIMTYPE_SPECIALDATA,
ANIMTYPE_SCENE,
@@ -162,6 +163,7 @@ typedef enum eAnimFilter_Flags {
ANIMFILTER_ACTGROUPED = (1<<6), /* belongs to the active actiongroup */
ANIMFILTER_CURVEVISIBLE = (1<<7), /* F-Curve is visible for editing/viewing in Graph Editor */
ANIMFILTER_ACTIVE = (1<<8), /* channel should be 'active' */ // FIXME: this is only relevant for F-Curves for now
+ ANIMFILTER_ANIMDATA = (1<<9), /* only return the underlying AnimData blocks (not the tracks, etc.) data comes from */
} eAnimFilter_Flags;
@@ -254,7 +256,7 @@ short ANIM_animdata_context_getdata(bAnimContext *ac);
void ANIM_deselect_anim_channels(void *data, short datatype, short test, short sel);
/* Set the 'active' channel of type channel_type, in the given action */
-void ANIM_set_active_channel(void *data, short datatype, int filter, void *channel_data, short channel_type);
+void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int filter, void *channel_data, short channel_type);
/* --------------- Settings and/or Defines -------------- */
@@ -308,6 +310,8 @@ void ipo_rainbow(int cur, int tot, float *out);
/* ------------- NLA-Mapping ----------------------- */
/* anim_draw.c */
+// XXX these are soon to be depreceated?
+
/* Obtain the Object providing NLA-scaling for the given channel if applicable */
struct Object *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index c2beb34e7b5..e3b6572c03a 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -118,6 +118,7 @@ int ED_operator_node_active(struct bContext *C);
int ED_operator_ipo_active(struct bContext *C);
int ED_operator_sequencer_active(struct bContext *C);
int ED_operator_image_active(struct bContext *C);
+int ED_operator_nla_active(struct bContext *C);
int ED_operator_object_active(struct bContext *C);
int ED_operator_editmesh(struct bContext *C);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index be952558b6c..db1a39ed056 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -164,6 +164,7 @@ int ED_operator_node_active(bContext *C)
return 0;
}
+// XXX rename
int ED_operator_ipo_active(bContext *C)
{
return ed_spacetype_test(C, SPACE_IPO);
@@ -179,6 +180,11 @@ int ED_operator_image_active(bContext *C)
return ed_spacetype_test(C, SPACE_IMAGE);
}
+int ED_operator_nla_active(bContext *C)
+{
+ return ed_spacetype_test(C, SPACE_NLA);
+}
+
int ED_operator_object_active(bContext *C)
{
return NULL != CTX_data_active_object(C);
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index f64cd0f707c..d8ed3fd1068 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -862,13 +862,13 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode,
bActionGroup *agrp= ale->data;
agrp->flag |= AGRP_SELECTED;
- ANIM_set_active_channel(ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
}
else if (ale->type == ANIMTYPE_FCURVE) {
FCurve *fcu= ale->data;
fcu->flag |= FCURVE_SELECTED;
- ANIM_set_active_channel(ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
}
}
else if (ac->datatype == ANIMCONT_GPENCIL) {
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index bb923ca6f95..21320b60ead 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -722,7 +722,7 @@ static void mouse_graph_keys (bAnimContext *ac, int mval[], short select_mode, s
/* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
if (fcu->flag & FCURVE_SELECTED) {
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
- ANIM_set_active_channel(ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
}
}
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index a839ccbf3d6..8db85ffa0b1 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -349,7 +349,7 @@ static void mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sh
/* if NLA-Track is selected now, make NLA-Track the 'active' one in the visible list */
if (nlt->flag & NLATRACK_SELECTED)
- ANIM_set_active_channel(ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
}
}
break;
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 85bf733df87..6c4c64ea272 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -137,7 +137,7 @@ static void nla_draw_strip (AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2
/* only need to draw here if there's no strip before since
* it only applies in such a situation
*/
- if (strip->prev) {
+ if (strip->prev == NULL) {
/* set the drawing color to the color of the strip, but with very faint alpha */
glColor4f(color[0], color[1], color[2], 0.15f);
@@ -563,15 +563,20 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
else
special= ICON_LAYER_USED;
- if (nlt->flag & NLATRACK_MUTED)
- mute = ICON_MUTE_IPO_ON;
- else
- mute = ICON_MUTE_IPO_OFF;
-
- if (EDITABLE_NLT(nlt))
- protect = ICON_UNLOCKED;
- else
- protect = ICON_LOCKED;
+ /* if this track is active and we're tweaking it, don't draw these toggles */
+ // TODO: need a special macro for this...
+ if ( ((nlt->flag & NLATRACK_ACTIVE) && (nlt->flag & NLATRACK_DISABLED)) == 0 )
+ {
+ if (nlt->flag & NLATRACK_MUTED)
+ mute = ICON_MUTE_IPO_ON;
+ else
+ mute = ICON_MUTE_IPO_OFF;
+
+ if (EDITABLE_NLT(nlt))
+ protect = ICON_UNLOCKED;
+ else
+ protect = ICON_LOCKED;
+ }
sel = SEL_NLT(nlt);
strcpy(name, nlt->name);
@@ -636,18 +641,29 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
}
else if (group == 5) {
/* Action Line */
- if (ale->data)
- glColor3f(0.8f, 0.2f, 0.0f); // reddish color - hardcoded for now
- else
- glColor3f(0.6f, 0.5f, 0.5f); // greyish-red color - hardcoded for now
-
+ AnimData *adt= BKE_animdata_from_id(ale->id);
+
+ // TODO: if tweaking some action, use the same color as for the tweaked track (quick hack done for now)
+ if (adt && (adt->flag & ADT_NLA_EDIT_ON)) {
+ // greenish color (same as tweaking strip) - hardcoded for now
+ glColor3f(0.3f, 0.95f, 0.1f);
+ }
+ else {
+ if (ale->data)
+ glColor3f(0.8f, 0.2f, 0.0f); // reddish color - hardcoded for now
+ else
+ glColor3f(0.6f, 0.5f, 0.5f); // greyish-red color - hardcoded for now
+ }
+
offset += 7 * indent;
/* only on top two corners, to show that this channel sits on top of the preceeding ones */
uiSetRoundBox((1|2));
- /* draw slightly shifted up vertically to look like it has more separtion from other channels */
- gl_round_box(GL_POLYGON, x+offset, yminc+NLACHANNEL_SKIP, (float)NLACHANNEL_NAMEWIDTH, ymaxc+NLACHANNEL_SKIP, 8);
+ /* draw slightly shifted up vertically to look like it has more separtion from other channels,
+ * but we then need to slightly shorten it so that it doesn't look like it overlaps
+ */
+ gl_round_box(GL_POLYGON, x+offset, yminc+NLACHANNEL_SKIP, (float)NLACHANNEL_NAMEWIDTH, ymaxc+NLACHANNEL_SKIP-1, 8);
/* clear group value, otherwise we cause errors... */
group = 0;
@@ -709,20 +725,29 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar)
UI_icon_draw((float)(NLACHANNEL_NAMEWIDTH-offset), ydatac, mute);
}
- /* draw action 'push-down' - only for NLA-Action lines, and only when there's an action */
+ /* draw NLA-action line 'status-icons' - only when there's an action */
if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) {
- offset += 16;
+ AnimData *adt= BKE_animdata_from_id(ale->id);
- /* XXX firstly draw a little rect to help identify that it's different from the toggles */
- glBegin(GL_LINE_LOOP);
- glVertex2f((float)NLACHANNEL_NAMEWIDTH-offset-1, y-7);
- glVertex2f((float)NLACHANNEL_NAMEWIDTH-offset-1, y+9);
- glVertex2f((float)NLACHANNEL_NAMEWIDTH-1, y+9);
- glVertex2f((float)NLACHANNEL_NAMEWIDTH-1, y-7);
- glEnd(); // GL_LINES
+ offset += 16;
- /* now draw the icon */
- UI_icon_draw((float)NLACHANNEL_NAMEWIDTH-offset, ydatac, ICON_FREEZE);
+ /* now draw some indicator icons */
+ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
+ /* 'tweaking action' - not a button */
+ UI_icon_draw((float)NLACHANNEL_NAMEWIDTH-offset, ydatac, ICON_EDIT);
+ }
+ else {
+ /* XXX firstly draw a little rect to help identify that it's different from the toggles */
+ glBegin(GL_LINE_LOOP);
+ glVertex2f((float)NLACHANNEL_NAMEWIDTH-offset-1, y-7);
+ glVertex2f((float)NLACHANNEL_NAMEWIDTH-offset-1, y+9);
+ glVertex2f((float)NLACHANNEL_NAMEWIDTH-1, y+9);
+ glVertex2f((float)NLACHANNEL_NAMEWIDTH-1, y-7);
+ glEnd(); // GL_LINES
+
+ /* 'push down' icon for normal active-actions */
+ UI_icon_draw((float)NLACHANNEL_NAMEWIDTH-offset, ydatac, ICON_FREEZE);
+ }
}
glDisable(GL_BLEND);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index ce9ae7de7a9..f7053957667 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -68,6 +68,143 @@
#include "nla_intern.h" // own include
/* *********************************************** */
+/* General Editing */
+
+/* ******************** Tweak-Mode Operators ***************************** */
+/* 'Tweak mode' allows the action referenced by the active NLA-strip to be edited
+ * as if it were the normal Active-Action of its AnimData block.
+ */
+
+static int nlaedit_enable_tweakmode_exec (bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ int ok=0;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get a list of the AnimData blocks being shown in the NLA */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* if no blocks, popup error? */
+ if (anim_data.first == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* for each AnimData block with NLA-data, try setting it in tweak-mode */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ AnimData *adt= ale->data;
+
+ /* try entering tweakmode if valid */
+ ok += BKE_nla_tweakmode_enter(adt);
+ }
+
+ /* free temp data */
+ BLI_freelistN(&anim_data);
+
+ /* if we managed to enter tweakmode on at least one AnimData block,
+ * set the flag for this in the active scene and send notifiers
+ */
+ if (ac.scene && ok) {
+ /* set editing flag */
+ ac.scene->flag |= SCE_NLA_EDIT_ON;
+
+ /* set notifier that things have changed */
+ ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
+ WM_event_add_notifier(C, NC_SCENE, NULL);
+ }
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void NLAEDIT_OT_tweakmode_enter (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Enter Tweak Mode";
+ ot->idname= "NLAEDIT_OT_tweakmode_enter";
+ ot->description= "Enter tweaking mode for the action referenced by the active strip.";
+
+ /* api callbacks */
+ ot->exec= nlaedit_enable_tweakmode_exec;
+ ot->poll= nlaop_poll_tweakmode_off;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/* ------------- */
+
+static int nlaedit_disable_tweakmode_exec (bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get a list of the AnimData blocks being shown in the NLA */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* if no blocks, popup error? */
+ if (anim_data.first == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* for each AnimData block with NLA-data, try exitting tweak-mode */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ AnimData *adt= ale->data;
+
+ /* try entering tweakmode if valid */
+ BKE_nla_tweakmode_exit(adt);
+ }
+
+ /* free temp data */
+ BLI_freelistN(&anim_data);
+
+ /* if we managed to enter tweakmode on at least one AnimData block,
+ * set the flag for this in the active scene and send notifiers
+ */
+ if (ac.scene) {
+ /* clear editing flag */
+ ac.scene->flag &= ~SCE_NLA_EDIT_ON;
+
+ /* set notifier that things have changed */
+ ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
+ WM_event_add_notifier(C, NC_SCENE, NULL);
+ }
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void NLAEDIT_OT_tweakmode_exit (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Exit Tweak Mode";
+ ot->idname= "NLAEDIT_OT_tweakmode_exit";
+ ot->description= "Exit tweaking mode for the action referenced by the active strip.";
+
+ /* api callbacks */
+ ot->exec= nlaedit_disable_tweakmode_exec;
+ ot->poll= nlaop_poll_tweakmode_on;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
/* *********************************************** */
diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h
index 448b823bd4b..a7188a7cccd 100644
--- a/source/blender/editors/space_nla/nla_intern.h
+++ b/source/blender/editors/space_nla/nla_intern.h
@@ -76,6 +76,9 @@ void NLAEDIT_OT_click_select(wmOperatorType *ot);
/* **************************************** */
/* nla_edit.c */
+void NLAEDIT_OT_tweakmode_enter(wmOperatorType *ot);
+void NLAEDIT_OT_tweakmode_exit(wmOperatorType *ot);
+
/* **************************************** */
/* nla_channels.c */
@@ -85,6 +88,11 @@ void NLA_OT_channels_click(wmOperatorType *ot);
/* **************************************** */
/* nla_ops.c */
+int nlaop_poll_tweakmode_off(bContext *C);
+int nlaop_poll_tweakmode_on (bContext *C);
+
+/* --- */
+
void nla_operatortypes(void);
void nla_keymap(wmWindowManager *wm);
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 167686c99f9..057e4b05656 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -65,6 +65,51 @@
#include "nla_intern.h" // own include
+/* ************************** poll callbacks for operators **********************************/
+
+/* tweakmode is NOT enabled */
+int nlaop_poll_tweakmode_off (bContext *C)
+{
+ Scene *scene;
+
+ /* for now, we check 2 things:
+ * 1) active editor must be NLA
+ * 2) tweakmode is currently set as a 'per-scene' flag
+ * so that it will affect entire NLA data-sets,
+ * but not all AnimData blocks will be in tweakmode for
+ * various reasons
+ */
+ if (ED_operator_nla_active(C) == 0)
+ return 0;
+
+ scene= CTX_data_scene(C);
+ if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON))
+ return 0;
+
+ return 1;
+}
+
+/* tweakmode IS enabled */
+int nlaop_poll_tweakmode_on (bContext *C)
+{
+ Scene *scene;
+
+ /* for now, we check 2 things:
+ * 1) active editor must be NLA
+ * 2) tweakmode is currently set as a 'per-scene' flag
+ * so that it will affect entire NLA data-sets,
+ * but not all AnimData blocks will be in tweakmode for
+ * various reasons
+ */
+ if (ED_operator_nla_active(C) == 0)
+ return 0;
+
+ scene= CTX_data_scene(C);
+ if ((scene == NULL) || !(scene->flag & SCE_NLA_EDIT_ON))
+ return 0;
+
+ return 1;
+}
/* ************************** registration - operator types **********************************/
@@ -77,6 +122,10 @@ void nla_operatortypes(void)
/* select */
WM_operatortype_append(NLAEDIT_OT_click_select);
WM_operatortype_append(NLAEDIT_OT_select_all_toggle);
+
+ /* edit */
+ WM_operatortype_append(NLAEDIT_OT_tweakmode_enter);
+ WM_operatortype_append(NLAEDIT_OT_tweakmode_exit);
}
/* ************************** registration - keymaps **********************************/
@@ -130,6 +179,13 @@ static void nla_keymap_main (wmWindowManager *wm, ListBase *keymap)
WM_keymap_add_item(keymap, "NLAEDIT_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "NLAEDIT_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
+ /* editing */
+ /* tweakmode
+ * - enter and exit are separate operators with the same hotkey...
+ * This works as they use different poll()'s
+ */
+ WM_keymap_add_item(keymap, "NLAEDIT_OT_tweakmode_enter", TABKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NLAEDIT_OT_tweakmode_exit", TABKEY, KM_PRESS, 0, 0);
/* transform system */
//transform_keymap_for_space(wm, keymap, SPACE_NLA);
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index 0626d9febe4..2e3d5572711 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -300,8 +300,7 @@ static void mouse_nla_strips (bAnimContext *ac, int mval[2], short select_mode)
NlaTrack *nlt= (NlaTrack *)ale->data;
nlt->flag |= NLATRACK_SELECTED;
- if (nlt->flag & NLATRACK_SELECTED)
- ANIM_set_active_channel(ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nlt, ANIMTYPE_NLATRACK);
}
}
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index e41ab5ac492..a566f733978 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -269,6 +269,7 @@ typedef enum eAction_Flags {
/* flags for evaluation/editing */
ACT_MUTED = (1<<9),
ACT_PROTECTED = (1<<10),
+ ACT_DISABLED = (1<<11),
} eAction_Flags;
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index ffc1561e7ab..c19318629f6 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -506,6 +506,9 @@ enum {
NLATRACK_SOLO = (1<<3),
/* track's settings (and strips) cannot be edited (to guard against unwanted changes) */
NLATRACK_PROTECTED = (1<<4),
+
+ /* track is not allowed to execute, usually as result of tweaking being enabled (internal flag) */
+ NLATRACK_DISABLED = (1<<10),
} eNlaTrack_Flag;
@@ -648,11 +651,15 @@ typedef struct AnimOverride {
* blocks may override local settings.
*
* This datablock should be placed immediately after the ID block where it is used, so that
- * the code which retrieves this data can do so in an easier manner. See blenkernel/internal/anim_sys.c for details.
+ * the code which retrieves this data can do so in an easier manner. See blenkernel/intern/anim_sys.c for details.
*/
typedef struct AnimData {
/* active action - acts as the 'tweaking track' for the NLA */
- bAction *action;
+ bAction *action;
+ /* temp-storage for the 'real' active action (i.e. the one used before the tweaking-action
+ * took over to be edited in the Animation Editors)
+ */
+ bAction *tmpact;
/* remapping-info for active action - should only be used if needed
* (for 'foreign' actions that aren't working correctly)
*/
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 6f88a98fee8..8acefdad9a2 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -832,6 +832,7 @@ typedef struct Scene {
/* sce->flag */
#define SCE_DS_SELECTED (1<<0)
#define SCE_DS_COLLAPSED (1<<1)
+#define SCE_NLA_EDIT_ON (1<<2)
/* return flag next_object function */