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:
authorJoshua Leung <aligorith@gmail.com>2009-06-09 15:26:45 +0400
committerJoshua Leung <aligorith@gmail.com>2009-06-09 15:26:45 +0400
commit096e2f0b5ab370fcc01a265ccf77eb71a2f03a43 (patch)
tree7a2ab25b05f68e589aacd724d9a57a9eaac48d8c /source/blender/editors
parent4b8b9b222eebbfa01566b90a00bba8a35835c671 (diff)
NLA SoC: Transform tools for NLA
This commit restores transform support for NLA. Grab, scale, 'extend', and tweak (i.e. grab by just click+dragging) are implemented. Notes: - As soon as one end of a strip touches another adjacent strip (within the same track), that end stops moving. This has been done to avoid the situation where overlapping strips within the same track (which is not allowed) might be caused by transforms. - Made some changes to the RNA setters for the strip extents so that the validation above could take place (and other necessary changes on a per-strip basis could also occur). TODO's ? - Strips cannot be transferred from track to track using transforms. I've yet to decide whether this needs to be done, or whether a separate operator will suffice. - What happens to the range of Actions used when the strips change sizes unexpectedly (i.e. the no-overlap condition above)? Currently range stays the same, but this doesn't always seem desirable?
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/space_nla/nla_ops.c4
-rw-r--r--source/blender/editors/transform/transform.c3
-rw-r--r--source/blender/editors/transform/transform.h7
-rw-r--r--source/blender/editors/transform/transform_conversions.c195
-rw-r--r--source/blender/editors/transform/transform_generics.c100
-rw-r--r--source/blender/editors/transform/transform_ops.c13
6 files changed, 228 insertions, 94 deletions
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index f59cbd9c1d4..6505b1deea3 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -54,6 +54,8 @@
#include "ED_space_api.h"
#include "ED_screen.h"
+#include "BIF_transform.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -191,7 +193,7 @@ static void nla_keymap_main (wmWindowManager *wm, ListBase *keymap)
WM_keymap_add_item(keymap, "NLAEDIT_OT_tweakmode_exit", TABKEY, KM_PRESS, 0, 0);
/* transform system */
- //transform_keymap_for_space(wm, keymap, SPACE_NLA);
+ transform_keymap_for_space(wm, keymap, SPACE_NLA);
}
/* --------------- */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 674de81a9f5..fa93d2a143d 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -319,6 +319,9 @@ static void viewRedrawForce(bContext *C, TransInfo *t)
else
ED_area_tag_redraw(t->sa);
}
+ else if (t->spacetype == SPACE_NLA) {
+ ED_area_tag_redraw(t->sa); // XXX this should use a notifier instead!
+ }
else if(t->spacetype == SPACE_NODE)
{
//ED_area_tag_redraw(t->sa);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index ee767fada58..c0a57a85033 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -161,6 +161,13 @@ typedef struct TransDataSeq {
} TransDataSeq;
+/* for NLA transform (stored in td->extra pointer) */
+typedef struct TransDataNla {
+ struct NlaStrip *strip; /* NLA-strip that handle belongs to */
+ float val; /* value for the handle that the transform tools write to */
+ int handle; /* handle-index, 0 for start, 1 for end */
+} TransDataNla;
+
typedef struct TransData {
float dist; /* Distance needed to affect element (for Proportionnal Editing) */
float rdist; /* Distance to the nearest element (for Proportionnal Editing) */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 6c7aa1ee49d..96f62f1e18e 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2559,7 +2559,140 @@ int clipUVTransform(TransInfo *t, float *vec, int resize)
return (clipx || clipy);
}
-/* ********************* ACTION/NLA EDITOR ****************** */
+/* ********************* ANIMATION EDITORS (GENERAL) ************************* */
+
+/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
+static short FrameOnMouseSide(char side, float frame, float cframe)
+{
+ /* both sides, so it doesn't matter */
+ if (side == 'B') return 1;
+
+ /* only on the named side */
+ if (side == 'R')
+ return (frame >= cframe) ? 1 : 0;
+ else
+ return (frame <= cframe) ? 1 : 0;
+}
+
+/* ********************* NLA EDITOR ************************* */
+
+static void createTransNlaData(bContext *C, TransInfo *t)
+{
+ Scene *scene= CTX_data_scene(C);
+ TransData *td = NULL;
+ TransDataNla *tdn = NULL;
+
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ int count=0;
+ char side;
+
+ /* determine what type of data we are operating on */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return;
+
+ /* filter data */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* which side of the current frame should be allowed */
+ if (t->mode == TFM_TIME_EXTEND) {
+ /* only side on which mouse is gets transformed */
+ float xmouse, ymouse;
+
+ UI_view2d_region_to_view(&ac.ar->v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
+ side = (xmouse > CFRA) ? 'R' : 'L'; // XXX use t->frame_side
+ }
+ else {
+ /* normal transform - both sides of current frame are considered */
+ side = 'B';
+ }
+
+ /* loop 1: count how many strips are selected (consider each strip as 2 points) */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ /* only if a real NLA-track */
+ if (ale->type == ANIMTYPE_NLATRACK) {
+ NlaTrack *nlt= (NlaTrack *)ale->data;
+ NlaStrip *strip;
+
+ /* only consider selected strips */
+ for (strip= nlt->strips.first; strip; strip= strip->next) {
+ // TODO: we can make strips have handles later on...
+ if (strip->flag & NLASTRIP_FLAG_SELECT) {
+ if (FrameOnMouseSide(side, strip->start, (float)CFRA)) count++;
+ if (FrameOnMouseSide(side, strip->end, (float)CFRA)) count++;
+ }
+ }
+ }
+ }
+
+ /* stop if trying to build list if nothing selected */
+ if (count == 0) {
+ /* cleanup temp list */
+ BLI_freelistN(&anim_data);
+ return;
+ }
+
+ /* allocate memory for data */
+ t->total= count;
+
+ t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(NLA Editor)");
+ td= t->data;
+ t->customData= MEM_callocN(t->total*sizeof(TransDataNla), "TransDataNla (NLA Editor)");
+ tdn= t->customData;
+
+ /* loop 2: build transdata array */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ /* only if a real NLA-track */
+ if (ale->type == ANIMTYPE_NLATRACK) {
+ NlaTrack *nlt= (NlaTrack *)ale->data;
+ NlaStrip *strip;
+
+ /* only consider selected strips */
+ for (strip= nlt->strips.first; strip; strip= strip->next) {
+ // TODO: we can make strips have handles later on...
+ if (strip->flag & NLASTRIP_FLAG_SELECT) {
+ if (FrameOnMouseSide(side, strip->start, (float)CFRA))
+ {
+ /* init the 'extra' data for NLA strip handles first */
+ tdn->strip= strip;
+ tdn->val= strip->start;
+ tdn->handle= 0;
+
+ /* now, link the transform data up to this data */
+ td->val= &tdn->val;
+ td->ival= tdn->val;
+ td->extra= tdn;
+ td++;
+ tdn++;
+ }
+ if (FrameOnMouseSide(side, strip->end, (float)CFRA))
+ {
+ /* init the 'extra' data for NLA strip handles first */
+ tdn->strip= strip;
+ tdn->val= strip->end;
+ tdn->handle= 1;
+
+ /* now, link the transform data up to this data */
+ td->val= &tdn->val;
+ td->ival= tdn->val;
+ td->extra= tdn;
+ td++;
+ tdn++;
+ }
+ }
+ }
+ }
+ }
+
+ /* cleanup temp list */
+ BLI_freelistN(&anim_data);
+}
+
+/* ********************* ACTION EDITOR ****************** */
/* Called by special_aftertrans_update to make sure selected gp-frames replace
* any other gp-frames which may reside on that frame (that are not selected).
@@ -2744,19 +2877,6 @@ static void posttrans_action_clean (bAnimContext *ac, bAction *act)
/* ----------------------------- */
-/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
-static short FrameOnMouseSide(char side, float frame, float cframe)
-{
- /* both sides, so it doesn't matter */
- if (side == 'B') return 1;
-
- /* only on the named side */
- if (side == 'R')
- return (frame >= cframe) ? 1 : 0;
- else
- return (frame <= cframe) ? 1 : 0;
-}
-
/* fully select selected beztriples, but only include if it's on the right side of cfra */
static int count_fcurve_keys(FCurve *fcu, char side, float cfra)
{
@@ -3044,8 +3164,6 @@ static void createTransActionData(bContext *C, TransInfo *t)
/* ********************* GRAPH EDITOR ************************* */
-
-
/* Helper function for createTransGraphEditData, which is reponsible for associating
* source data with transform data
*/
@@ -3502,7 +3620,6 @@ void flushTransGraphData(TransInfo *t)
}
}
-
/* **************** IpoKey stuff, for Object TransData ********** */
/* while transforming */
@@ -4604,6 +4721,29 @@ void special_aftertrans_update(TransInfo *t)
/* make sure all F-Curves are set correctly */
ANIM_editkeyframes_refresh(&ac);
}
+ else if (t->spacetype == SPACE_NLA) {
+ SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first;
+ Scene *scene;
+ bAnimContext ac;
+
+ /* initialise relevant anim-context 'context' data from TransInfo data */
+ /* NOTE: sync this with the code in ANIM_animdata_get_context() */
+ memset(&ac, 0, sizeof(bAnimContext));
+
+ scene= ac.scene= t->scene;
+ ob= ac.obact= OBACT;
+ ac.sa= t->sa;
+ ac.ar= t->ar;
+ ac.spacetype= (t->sa)? t->sa->spacetype : 0;
+ ac.regiontype= (t->ar)? t->ar->regiontype : 0;
+
+ if (ANIM_animdata_context_getdata(&ac) == 0)
+ return;
+
+ // XXX check on the calls below... we need some of these sanity checks
+ //synchronize_action_strips();
+ //ANIM_editkeyframes_refresh(&ac);
+ }
else if (t->obedit) {
// TRANSFORM_FIX_ME
// if (t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
@@ -4682,24 +4822,6 @@ void special_aftertrans_update(TransInfo *t)
}
}
-#if 0 // TRANSFORM_FIX_ME
- else if (t->spacetype == SPACE_NLA) {
- recalc_all_ipos(); // bad
- synchronize_action_strips();
-
- /* cleanup */
- for (base=t->scene->base.first; base; base=base->next)
- base->flag &= ~(BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA);
-
- /* after transform, remove duplicate keyframes on a frame that resulted from transform */
- if ( (G.snla->flag & SNLA_NOTRANSKEYCULL)==0 &&
- ((cancelled == 0) || (duplicate)) )
- {
- posttrans_nla_clean(t);
- }
- }
-#endif
-
clear_trans_object_base_flags(t);
#if 0 // TRANSFORM_FIX_ME
@@ -4932,8 +5054,7 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_NLA) {
t->flag |= T_POINTS|T_2D_EDIT;
- // TRANSFORM_FIX_ME
- //createTransNlaData(C, t);
+ createTransNlaData(C, t);
}
else if (t->spacetype == SPACE_SEQ) {
t->flag |= T_POINTS|T_2D_EDIT;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 171665c9282..4c9592fb27a 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -102,6 +102,8 @@
#include "BLI_editVert.h"
#include "BLI_rand.h"
+#include "RNA_access.h"
+
#include "WM_types.h"
#include "UI_resources.h"
@@ -299,61 +301,6 @@ void recalcData(TransInfo *t)
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA);
}
}
- }
- else if (t->spacetype == SPACE_NLA) {
- if (G.snla->lock) {
- for (base=G.scene->base.first; base; base=base->next) {
- if (base->flag & BA_HAS_RECALC_OB)
- base->object->recalc |= OB_RECALC_OB;
- if (base->flag & BA_HAS_RECALC_DATA)
- base->object->recalc |= OB_RECALC_DATA;
-
- if (base->object->recalc)
- base->object->ctime= -1234567.0f; // eveil!
-
- /* recalculate scale of selected nla-strips */
- if (base->object->nlastrips.first) {
- Object *bob= base->object;
- bActionStrip *strip;
-
- for (strip= bob->nlastrips.first; strip; strip= strip->next) {
- if (strip->flag & ACTSTRIP_SELECT) {
- float actlen= strip->actend - strip->actstart;
- float len= strip->end - strip->start;
-
- strip->scale= len / (actlen * strip->repeat);
- }
- }
- }
- }
-
- DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
- }
- else {
- for (base=G.scene->base.first; base; base=base->next) {
- /* recalculate scale of selected nla-strips */
- if (base->object && base->object->nlastrips.first) {
- Object *bob= base->object;
- bActionStrip *strip;
-
- for (strip= bob->nlastrips.first; strip; strip= strip->next) {
- if (strip->flag & ACTSTRIP_SELECT) {
- float actlen= strip->actend - strip->actstart;
- float len= strip->end - strip->start;
-
- /* prevent 'negative' scaling */
- if (len < 0) {
- SWAP(float, strip->start, strip->end);
- len= fabs(len);
- }
-
- /* calculate new scale */
- strip->scale= len / (actlen * strip->repeat);
- }
- }
- }
- }
- }
}
#endif
if (t->obedit) {
@@ -422,6 +369,47 @@ void recalcData(TransInfo *t)
}
}
+ else if (t->spacetype == SPACE_NLA) {
+ TransData *td= t->data;
+ int i;
+
+ /* for each point we've captured, look at its 'extra' data, which is basically a wrapper around the strip
+ * it is for + some extra storage for the values that get set, and use RNA to set this value (performing validation
+ * work so that we don't need to repeat it here)
+ */
+ for (i = 0; i < t->total; i++, td++)
+ {
+ if (td->extra)
+ {
+ TransDataNla *tdn= td->extra;
+ NlaStrip *strip= tdn->strip;
+
+ /* if we're just cancelling (i.e. the user aborted the transform),
+ * just restore the data by directly overwriting the values with the original
+ * ones (i.e. don't go through RNA), as we get some artifacts...
+ */
+ if (t->state == TRANS_CANCEL) {
+ /* write the value set by the transform tools to the appropriate property using RNA */
+ if (tdn->handle)
+ strip->end= tdn->val;
+ else
+ strip->start= tdn->val;
+ }
+ else {
+ PointerRNA strip_ptr;
+
+ /* make RNA-pointer */
+ RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
+
+ /* write the value set by the transform tools to the appropriate property using RNA */
+ if (tdn->handle)
+ RNA_float_set(&strip_ptr, "end_frame", tdn->val);
+ else
+ RNA_float_set(&strip_ptr, "start_frame", tdn->val);
+ }
+ }
+ }
+ }
else if (t->obedit) {
if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
Curve *cu= t->obedit->data;
@@ -866,7 +854,7 @@ void postTrans (TransInfo *t)
if(sima->flag & SI_LIVE_UNWRAP)
ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL);
}
- else if(t->spacetype==SPACE_ACTION) {
+ else if(ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) {
if (t->customData)
MEM_freeN(t->customData);
}
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 769001b30a8..f7ddd18452e 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -607,6 +607,19 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
break;
+ case SPACE_NLA:
+ km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
+ RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
+
+ km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
+ RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
+
+ km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
+ RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
+
+ km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
+ RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
+ break;
case SPACE_NODE:
km= WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0);