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-07-12 07:42:39 +0400
committerJoshua Leung <aligorith@gmail.com>2009-07-12 07:42:39 +0400
commitbb158ad5721b98086b77a8168a53c4901540907d (patch)
tree196393da6e84a33275d3da57af3de0e70f0bb994
parent3116062a828e24ed2e91c219ab338a38030f2f42 (diff)
2.5 - Editing Animation data (keyframes/nla-strips) using transform tools now refreshes the 3d-view in realtime.
For now, this directly sets the update flags, though this really should be calling the Depsgraph API instead.
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c12
-rw-r--r--source/blender/editors/transform/transform.c2
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_conversions.c225
-rw-r--r--source/blender/editors/transform/transform_generics.c147
5 files changed, 231 insertions, 157 deletions
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index f0c3a2c200c..387468f7160 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -413,11 +413,13 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
switch(wmn->data) {
case ND_KEYFRAME_EDIT:
case ND_KEYFRAME_PROP:
+ case ND_NLA_EDIT:
case ND_NLA_ACTCHANGE:
case ND_ANIMCHAN_SELECT:
ED_region_tag_redraw(ar);
break;
}
+ break;
case NC_SCENE:
switch(wmn->data) {
case ND_TRANSFORM:
@@ -536,6 +538,16 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
{
/* context changes */
switch(wmn->category) {
+ case NC_ANIMATION:
+ switch(wmn->data) {
+ case ND_KEYFRAME_EDIT:
+ case ND_KEYFRAME_PROP:
+ case ND_NLA_EDIT:
+ case ND_NLA_ACTCHANGE:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
case NC_SCENE:
switch(wmn->data) {
case ND_FRAME:
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 888a15e2534..d45a6f42232 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -308,7 +308,7 @@ static void viewRedrawForce(bContext *C, TransInfo *t)
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
}
else if (t->spacetype == SPACE_NLA) {
- WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_EDIT, NULL);
}
else if(t->spacetype == SPACE_NODE)
{
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 00353cfc457..db78632e76a 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -163,6 +163,8 @@ typedef struct TransDataSeq {
/* for NLA transform (stored in td->extra pointer) */
typedef struct TransDataNla {
+ ID *id; /* ID-block NLA-data is attached to */
+
struct NlaTrack *oldTrack; /* Original NLA-Track that the strip belongs to */
struct NlaTrack *nlt; /* Current NLA-Track that the strip belongs to */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 2262c6cdeaa..3d643a2dec1 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2578,28 +2578,28 @@ 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_NLATRACKS | 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
}
@@ -2607,15 +2607,15 @@ static void createTransNlaData(bContext *C, TransInfo *t)
/* 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) {
NlaTrack *nlt= (NlaTrack *)ale->data;
NlaStrip *strip;
-
+
/* make some meta-strips for chains of selected strips */
BKE_nlastrips_make_metas(&nlt->strips, 1);
-
+
/* only consider selected strips */
for (strip= nlt->strips.first; strip; strip= strip->next) {
// TODO: we can make strips have handles later on...
@@ -2628,29 +2628,29 @@ static void createTransNlaData(bContext *C, TransInfo *t)
}
}
}
-
+
/* 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...
@@ -2667,44 +2667,45 @@ static void createTransNlaData(bContext *C, TransInfo *t)
* cases, there will need to be 1 of these tdn elements in the array skipped...
*/
float center[3], yval;
-
+
/* firstly, init tdn settings */
+ tdn->id= ale->id;
tdn->oldTrack= tdn->nlt= nlt;
tdn->strip= strip;
tdn->trackIndex= BLI_findindex(&nlt->strips, strip);
-
+
yval= (float)(tdn->trackIndex * NLACHANNEL_STEP);
-
+
tdn->h1[0]= strip->start;
tdn->h1[1]= yval;
tdn->h2[0]= strip->end;
tdn->h2[1]= yval;
-
+
center[0]= (float)CFRA;
center[1]= yval;
center[2]= 0.0f;
-
+
/* set td's based on which handles are applicable */
if (FrameOnMouseSide(side, strip->start, (float)CFRA))
{
/* just set tdn to assume that it only has one handle for now */
tdn->handle= -1;
-
+
/* now, link the transform data up to this data */
if (t->mode == TFM_TRANSLATION) {
td->loc= tdn->h1;
VECCOPY(td->iloc, tdn->h1);
-
+
/* store all the other gunk that is required by transform */
VECCOPY(td->center, center);
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
-
+
td->ext= NULL; td->tdi= NULL; td->val= NULL;
-
+
td->flag |= TD_SELECTED;
td->dist= 0.0f;
-
+
Mat3One(td->mtx);
Mat3One(td->smtx);
}
@@ -2712,7 +2713,7 @@ static void createTransNlaData(bContext *C, TransInfo *t)
td->val= &tdn->h1[0];
td->ival= tdn->h1[0];
}
-
+
td->extra= tdn;
td++;
}
@@ -2720,22 +2721,22 @@ static void createTransNlaData(bContext *C, TransInfo *t)
{
/* if tdn is already holding the start handle, then we're doing both, otherwise, only end */
tdn->handle= (tdn->handle) ? 2 : 1;
-
+
/* now, link the transform data up to this data */
if (t->mode == TFM_TRANSLATION) {
td->loc= tdn->h2;
VECCOPY(td->iloc, tdn->h2);
-
+
/* store all the other gunk that is required by transform */
VECCOPY(td->center, center);
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
-
+
td->ext= NULL; td->tdi= NULL; td->val= NULL;
-
+
td->flag |= TD_SELECTED;
td->dist= 0.0f;
-
+
Mat3One(td->mtx);
Mat3One(td->smtx);
}
@@ -2743,11 +2744,11 @@ static void createTransNlaData(bContext *C, TransInfo *t)
td->val= &tdn->h2[0];
td->ival= tdn->h2[0];
}
-
+
td->extra= tdn;
td++;
}
-
+
/* if both handles were used, skip the next tdn (i.e. leave it blank) since the counting code is dumb...
* otherwise, just advance to the next one...
*/
@@ -3114,32 +3115,32 @@ static void createTransActionData(bContext *C, TransInfo *t)
Scene *scene= CTX_data_scene(C);
TransData *td = NULL;
tGPFtransdata *tfd = NULL;
-
+
bAnimContext ac;
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
int count=0;
float cfra;
char side;
-
+
/* determine what type of data we are operating on */
if (ANIM_animdata_get_context(C, &ac) == 0)
return;
-
+
/* filter data */
if (ac.datatype == ANIMCONT_GPENCIL)
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
else
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
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
}
@@ -3147,11 +3148,11 @@ static void createTransActionData(bContext *C, TransInfo *t)
/* normal transform - both sides of current frame are considered */
side = 'B';
}
-
+
/* loop 1: fully select ipo-keys and count how many BezTriples are selected */
for (ale= anim_data.first; ale; ale= ale->next) {
AnimData *adt= ANIM_nla_mapping_get(&ac, ale);
-
+
/* convert current-frame to action-time (slightly less accurate, espcially under
* higher scaling ratios, but is faster than converting all points)
*/
@@ -3159,26 +3160,26 @@ static void createTransActionData(bContext *C, TransInfo *t)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
else
cfra = (float)CFRA;
-
+
//if (ale->type == ANIMTYPE_GPLAYER)
// count += count_gplayer_frames(ale->data, side, cfra);
//else
count += count_fcurve_keys(ale->key_data, side, cfra);
}
-
+
/* 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(Action Editor)");
td= t->data;
-
+
if (ac.datatype == ANIMCONT_GPENCIL) {
if (t->mode == TFM_TIME_SLIDE) {
t->customData= MEM_callocN((sizeof(float)*2)+(sizeof(tGPFtransdata)*count), "TimeSlide + tGPFtransdata");
@@ -3191,7 +3192,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
}
else if (t->mode == TFM_TIME_SLIDE)
t->customData= MEM_callocN(sizeof(float)*2, "TimeSlide Min/Max");
-
+
/* loop 2: build transdata array */
for (ale= anim_data.first; ale; ale= ale->next) {
//if (ale->type == ANIMTYPE_GPLAYER) {
@@ -3205,7 +3206,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
//else {
AnimData *adt= ANIM_nla_mapping_get(&ac, ale);
FCurve *fcu= (FCurve *)ale->key_data;
-
+
/* convert current-frame to action-time (slightly less accurate, espcially under
* higher scaling ratios, but is faster than converting all points)
*/
@@ -3213,22 +3214,22 @@ static void createTransActionData(bContext *C, TransInfo *t)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
else
cfra = (float)CFRA;
-
+
td= FCurveToTransData(td, fcu, adt, side, cfra);
//}
}
-
+
/* check if we're supposed to be setting minx/maxx for TimeSlide */
if (t->mode == TFM_TIME_SLIDE) {
float min=999999999.0f, max=-999999999.0f;
int i;
-
+
td= (t->data + 1);
for (i=1; i < count; i+=3, td+=3) {
if (min > *(td->val)) min= *(td->val);
if (max < *(td->val)) max= *(td->val);
}
-
+
/* minx/maxx values used by TimeSlide are stored as a
* calloced 2-float array in t->customData. This gets freed
* in postTrans (T_FREE_CUSTOMDATA).
@@ -3254,18 +3255,18 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt,
* Due to NLA mapping, we apply NLA mapping to some of the verts here,
* and then that mapping will be undone after transform is done.
*/
-
+
if (adt) {
td2d->loc[0] = BKE_nla_tweakedit_remap(adt, loc[0], NLATIME_CONVERT_UNMAP);
td2d->loc[1] = loc[1];
td2d->loc[2] = 0.0f;
td2d->loc2d = loc;
-
+
td->loc = td2d->loc;
td->center[0] = BKE_nla_tweakedit_remap(adt, cent[0], NLATIME_CONVERT_UNMAP);
td->center[1] = cent[1];
td->center[2] = 0.0f;
-
+
VECCOPY(td->iloc, td->loc);
}
else {
@@ -3273,32 +3274,32 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt,
td2d->loc[1] = loc[1];
td2d->loc[2] = 0.0f;
td2d->loc2d = loc;
-
+
td->loc = td2d->loc;
VECCOPY(td->center, cent);
VECCOPY(td->iloc, td->loc);
}
-
+
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
-
+
td->ext= NULL; td->tdi= NULL; td->val= NULL;
-
+
/* store AnimData info in td->extra, for applying mapping when flushing */
td->extra= adt;
-
+
if (selected) {
td->flag |= TD_SELECTED;
td->dist= 0.0f;
}
else
td->dist= MAXFLOAT;
-
+
if (ishandle)
td->flag |= TD_NOTIMESNAP;
if (intvals)
td->flag |= TD_INTVALUES;
-
+
Mat3One(td->mtx);
Mat3One(td->smtx);
}
@@ -3308,34 +3309,34 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
Scene *scene= CTX_data_scene(C);
ARegion *ar= CTX_wm_region(C);
View2D *v2d= &ar->v2d;
-
+
TransData *td = NULL;
TransData2D *td2d = NULL;
-
+
bAnimContext ac;
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+
BezTriple *bezt, *prevbezt;
int count=0, i;
float cfra;
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 | ANIMFILTER_CURVESONLY | ANIMFILTER_CURVEVISIBLE);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* which side of the current frame should be allowed */
// XXX we still want this mode, but how to get this using standard transform too?
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
}
@@ -3343,12 +3344,12 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
/* normal transform - both sides of current frame are considered */
side = 'B';
}
-
+
/* loop 1: count how many BezTriples (specifically their verts) are selected (or should be edited) */
for (ale= anim_data.first; ale; ale= ale->next) {
AnimData *adt= ANIM_nla_mapping_get(&ac, ale);
FCurve *fcu= (FCurve *)ale->key_data;
-
+
/* convert current-frame to action-time (slightly less accurate, espcially under
* higher scaling ratios, but is faster than converting all points)
*/
@@ -3356,7 +3357,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
else
cfra = (float)CFRA;
-
+
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse */
if (fcu->bezt) {
for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
@@ -3384,30 +3385,30 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
}
}
}
-
+
/* 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 (Graph Editor)");
/* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */
t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransData2D (Graph Editor)");
-
+
td= t->data;
td2d= t->data2d;
-
+
/* loop 2: build transdata arrays */
for (ale= anim_data.first; ale; ale= ale->next) {
AnimData *adt= ANIM_nla_mapping_get(&ac, ale);
FCurve *fcu= (FCurve *)ale->key_data;
short intvals= (fcu->flag & FCURVE_INT_VALUES);
-
+
/* convert current-frame to action-time (slightly less accurate, espcially under
* higher scaling ratios, but is faster than converting all points)
*/
@@ -3415,16 +3416,16 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
else
cfra = (float)CFRA;
-
+
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */
bezt= fcu->bezt;
prevbezt= NULL;
-
+
for (i=0; i < fcu->totvert; i++, prevbezt=bezt, bezt++) {
if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
TransDataCurveHandleFlags *hdata = NULL;
short h1=1, h2=1;
-
+
/* only include handles if selected, and interpolaton mode uses beztriples */
if ( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) ) {
if (bezt->f1 & SELECT) {
@@ -3443,7 +3444,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
else
h2= 0;
}
-
+
/* only include main vert if selected */
if (bezt->f2 & SELECT) {
/* if scaling around individuals centers, do no include keyframes */
@@ -3453,10 +3454,10 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
if (hdata == NULL)
hdata = initTransDataCurveHandes(td, bezt);
}
-
+
bezt_to_transdata(td++, td2d++, adt, bezt->vec[1], bezt->vec[1], 1, 0, intvals);
}
-
+
/* special hack (must be done after initTransDataCurveHandes(), as that stores handle settings to restore...):
* - Check if we've got entire BezTriple selected and we're scaling/rotating that point,
* then check if we're using auto-handles.
@@ -3471,11 +3472,11 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
}
}
}
-
+
/* Sets handles based on the selection */
testhandles_fcurve(fcu);
}
-
+
/* cleanup temp list */
BLI_freelistN(&anim_data);
}
@@ -3502,19 +3503,19 @@ static BeztMap *bezt_to_beztmaps (BezTriple *bezts, int totvert)
BezTriple *prevbezt= NULL;
BeztMap *bezm, *bezms;
int i;
-
+
/* allocate memory for this array */
if (totvert==0 || bezts==NULL)
return NULL;
bezm= bezms= MEM_callocN(sizeof(BeztMap)*totvert, "BeztMaps");
-
+
/* assign beztriples to beztmaps */
for (i=0; i < totvert; i++, bezm++, prevbezt=bezt, bezt++) {
bezm->bezt= bezt;
-
+
bezm->oldIndex= i;
bezm->newIndex= i;
-
+
bezm->pipo= (prevbezt) ? prevbezt->ipo : bezt->ipo;
bezm->cipo= bezt->ipo;
}
@@ -3527,11 +3528,11 @@ static void sort_time_beztmaps (BeztMap *bezms, int totvert)
{
BeztMap *bezm;
int i, ok= 1;
-
+
/* keep repeating the process until nothing is out of place anymore */
while (ok) {
ok= 0;
-
+
bezm= bezms;
i= totvert;
while (i--) {
@@ -3540,13 +3541,13 @@ static void sort_time_beztmaps (BeztMap *bezms, int totvert)
if (bezm->bezt->vec[1][0] > (bezm+1)->bezt->vec[1][0]) {
bezm->newIndex++;
(bezm+1)->newIndex--;
-
+
SWAP(BeztMap, *bezm, *(bezm+1));
-
+
ok= 1;
}
}
-
+
/* do we need to check if the handles need to be swapped?
* optimisation: this only needs to be performed in the first loop
*/
@@ -3562,7 +3563,7 @@ static void sort_time_beztmaps (BeztMap *bezms, int totvert)
bezm->swapHs = -1;
}
}
-
+
bezm++;
}
}
@@ -3576,13 +3577,13 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv
TransData2D *td;
int i, j;
char *adjusted;
-
+
/* dynamically allocate an array of chars to mark whether an TransData's
* pointers have been fixed already, so that we don't override ones that are
* already done
*/
adjusted= MEM_callocN(t->total, "beztmap_adjusted_map");
-
+
/* for each beztmap item, find if it is used anywhere */
bezm= bezms;
for (i= 0; i < totvert; i++, bezm++) {
@@ -3593,7 +3594,7 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv
for (j= 0; j < t->total; j++, td++) {
/* skip item if already marked */
if (adjusted[j] != 0) continue;
-
+
/* only selected verts */
if (bezm->pipo == BEZT_IPO_BEZ) {
if (bezm->bezt->f1 & SELECT) {
@@ -3624,9 +3625,9 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv
}
}
}
-
+
}
-
+
/* free temp memory used for 'adjusted' array */
MEM_freeN(adjusted);
}
@@ -3641,25 +3642,25 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv
void remake_graph_transdata (TransInfo *t, ListBase *anim_data)
{
bAnimListElem *ale;
-
+
/* sort and reassign verts */
for (ale= anim_data->first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
-
+
if (fcu->bezt) {
BeztMap *bezm;
-
+
/* adjust transform-data pointers */
bezm= bezt_to_beztmaps(fcu->bezt, fcu->totvert);
sort_time_beztmaps(bezm, fcu->totvert);
beztmap_to_data(t, fcu, bezm, fcu->totvert);
-
+
/* free mapping stuff */
MEM_freeN(bezm);
-
+
/* re-sort actual beztriples (perhaps this could be done using the beztmaps to save time?) */
sort_time_fcurve(fcu);
-
+
/* make sure handles are all set correctly */
testhandles_fcurve(fcu);
}
@@ -3677,11 +3678,11 @@ void flushTransGraphData(TransInfo *t)
Scene *scene= t->scene;
double secf= FPS;
int a;
-
+
/* flush to 2d vector from internally used 3d vector */
for (a=0, td= t->data, td2d=t->data2d; a<t->total; a++, td++, td2d++) {
AnimData *adt= (AnimData *)td->extra; /* pointers to relevant AnimData blocks are stored in the td->extra pointers */
-
+
/* handle snapping for time values
* - we should still be in NLA-mapping timespace
* - only apply to keyframes (but never to handles)
@@ -3694,19 +3695,19 @@ void flushTransGraphData(TransInfo *t)
else
td2d->loc[0]= (float)( floor(td2d->loc[0]+0.5f) );
break;
-
+
case SACTSNAP_MARKER: /* snap to nearest marker */
td2d->loc[0]= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, td2d->loc[0]);
break;
}
}
-
- /* we need to unapply the nla-scaling from the time in some situations */
+
+ /* we need to unapply the nla-mapping from the time in some situations */
if (adt)
td2d->loc2d[0]= BKE_nla_tweakedit_remap(adt, td2d->loc[0], NLATIME_CONVERT_UNMAP);
else
td2d->loc2d[0]= td2d->loc[0];
-
+
/* if int-values only, truncate to integers */
if (td->flag & TD_INTVALUES)
td2d->loc2d[1]= (float)((int)td2d->loc[1]);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index af56079727f..560b37caf0a 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -264,6 +264,29 @@ static void editmesh_apply_to_mirror(TransInfo *t)
}
}
+/* tags the given ID block for refreshes (if applicable) due to
+ * Animation Editor editing
+ */
+static void animedit_refresh_id_tags (ID *id)
+{
+ AnimData *adt= BKE_animdata_from_id(id);
+
+ /* tag AnimData for refresh so that other views will update in realtime with these changes */
+ if (adt)
+ adt->recalc |= ADT_RECALC_ANIM;
+
+ /* if ID-block is Object, set recalc flags */
+ // TODO: this should probably go through the depsgraph instead... but for now, let's be lazy
+ switch (GS(id->name)) {
+ case ID_OB:
+ {
+ Object *ob= (Object *)id;
+ ob->recalc |= OB_RECALC;
+ }
+ break;
+ }
+}
+
/* called for updating while transform acts, once per redraw */
void recalcData(TransInfo *t)
{
@@ -281,60 +304,93 @@ void recalcData(TransInfo *t)
else if (t->spacetype==SPACE_SEQ) {
flushTransSeq(t);
}
+ else if (t->spacetype == SPACE_ACTION) {
+ SpaceAction *sact= (SpaceAction *)t->sa->spacedata.first;
+ Scene *scene;
+
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* 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;
+ 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;
+
+ ANIM_animdata_context_getdata(&ac);
+
+ /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* just tag these animdata-blocks to recalc, assuming that some data there changed */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ /* set refresh tags for objects using this animation */
+ animedit_refresh_id_tags(ale->id);
+ }
+
+ /* now free temp channels */
+ BLI_freelistN(&anim_data);
+ }
else if (t->spacetype == SPACE_IPO) {
SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first;
Scene *scene;
-
+
ListBase anim_data = {NULL, NULL};
bAnimContext ac;
int filter;
-
+
bAnimListElem *ale;
int dosort = 0;
-
-
+
+
/* 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;
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;
-
+
ANIM_animdata_context_getdata(&ac);
-
+
/* do the flush first */
flushTransGraphData(t);
-
+
/* get curves to check if a re-sort is needed */
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_CURVEVISIBLE);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
+
/* now test if there is a need to re-sort */
for (ale= anim_data.first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
-
+ AnimData *adt= BKE_animdata_from_id(ale->id);
+
/* watch it: if the time is wrong: do not correct handles yet */
if (test_time_fcurve(fcu))
dosort++;
else
calchandles_fcurve(fcu);
+
+ /* set refresh tags for objects using this animation */
+ animedit_refresh_id_tags(ale->id);
}
-
+
/* do resort and other updates? */
if (dosort) remake_graph_transdata(t, &anim_data);
- //if (sipo->showkey) update_ipokey_val();
-
+
/* now free temp channels */
BLI_freelistN(&anim_data);
-
- /* update realtime - not working? */
- if (sipo->lock) {
-
- }
}
else if (t->spacetype == SPACE_NLA) {
TransDataNla *tdn= (TransDataNla *)t->customData;
@@ -342,7 +398,7 @@ void recalcData(TransInfo *t)
Scene *scene= t->scene;
double secf= FPS;
int i;
-
+
/* for each strip we've got, perform some additional validation of the values that got set before
* using RNA to set the value (which does some special operations when setting these values to make
* sure that everything works ok)
@@ -352,42 +408,45 @@ void recalcData(TransInfo *t)
PointerRNA strip_ptr;
short pExceeded, nExceeded, iter;
int delta_y1, delta_y2;
-
+
/* if this tdn has no handles, that means it is just a dummy that should be skipped */
if (tdn->handle == 0)
continue;
-
+
+ /* set refresh tags for objects using this animation */
+ animedit_refresh_id_tags(tdn->id);
+
/* if cancelling transform, just write the values without validating, then move on */
if (t->state == TRANS_CANCEL) {
/* clear the values by directly overwriting the originals, but also need to restore
* endpoints of neighboring transition-strips
*/
-
+
/* start */
strip->start= tdn->h1[0];
-
+
if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION))
strip->prev->end= tdn->h1[0];
-
+
/* end */
strip->end= tdn->h2[0];
-
+
if ((strip->next) && (strip->next->type == NLASTRIP_TYPE_TRANSITION))
strip->next->start= tdn->h2[0];
-
+
/* flush transforms to child strips (since this should be a meta) */
BKE_nlameta_flush_transforms(strip);
-
+
/* restore to original track (if needed) */
if (tdn->oldTrack != tdn->nlt) {
/* just append to end of list for now, since strips get sorted in special_aftertrans_update() */
BLI_remlink(&tdn->nlt->strips, strip);
BLI_addtail(&tdn->oldTrack->strips, strip);
}
-
+
continue;
}
-
+
/* firstly, check if the proposed transform locations would overlap with any neighbouring strips
* (barring transitions) which are absolute barriers since they are not being moved
*
@@ -396,7 +455,7 @@ void recalcData(TransInfo *t)
for (iter=0; iter < 5; iter++) {
pExceeded= ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h1[0] < strip->prev->end));
nExceeded= ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h2[0] > strip->next->start));
-
+
if ((pExceeded && nExceeded) || (iter == 4) ) {
/* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise)
* - simply crop strip to fit within the bounds of the strips bounding it
@@ -414,21 +473,21 @@ void recalcData(TransInfo *t)
else if (nExceeded) {
/* move backwards */
float offset= tdn->h2[0] - strip->next->start;
-
+
tdn->h1[0] -= offset;
tdn->h2[0] -= offset;
}
else if (pExceeded) {
/* more forwards */
float offset= strip->prev->end - tdn->h1[0];
-
+
tdn->h1[0] += offset;
tdn->h2[0] += offset;
}
else /* all is fine and well */
break;
}
-
+
/* handle auto-snapping */
switch (snla->autosnap) {
case SACTSNAP_FRAME: /* snap to nearest frame/time */
@@ -441,35 +500,35 @@ void recalcData(TransInfo *t)
tdn->h2[0]= (float)( floor(tdn->h2[0]+0.5f) );
}
break;
-
+
case SACTSNAP_MARKER: /* snap to nearest marker */
tdn->h1[0]= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]);
tdn->h2[0]= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]);
break;
}
-
+
/* use RNA to write the values... */
// TODO: do we need to write in 2 passes to make sure that no truncation goes on?
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
-
+
RNA_float_set(&strip_ptr, "start_frame", tdn->h1[0]);
RNA_float_set(&strip_ptr, "end_frame", tdn->h2[0]);
-
+
/* flush transforms to child strips (since this should be a meta) */
BKE_nlameta_flush_transforms(strip);
-
-
+
+
/* now, check if we need to try and move track
* - we need to calculate both, as only one may have been altered by transform if only 1 handle moved
*/
delta_y1= ((int)tdn->h1[1] / NLACHANNEL_STEP - tdn->trackIndex);
delta_y2= ((int)tdn->h2[1] / NLACHANNEL_STEP - tdn->trackIndex);
-
+
if (delta_y1 || delta_y2) {
NlaTrack *track;
int delta = (delta_y2) ? delta_y2 : delta_y1;
int n;
-
+
/* move in the requested direction, checking at each layer if there's space for strip to pass through,
* stopping on the last track available or that we're able to fit in
*/
@@ -480,7 +539,7 @@ void recalcData(TransInfo *t)
/* move strip to this track */
BLI_remlink(&tdn->nlt->strips, strip);
BKE_nlatrack_add_strip(track, strip);
-
+
tdn->nlt= track;
tdn->trackIndex += (n + 1); /* + 1, since n==0 would mean that we didn't change track */
}
@@ -491,14 +550,14 @@ void recalcData(TransInfo *t)
else {
/* make delta 'positive' before using it, since we now know to go backwards */
delta= -delta;
-
+
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)) {
/* move strip to this track */
BLI_remlink(&tdn->nlt->strips, strip);
BKE_nlatrack_add_strip(track, strip);
-
+
tdn->nlt= track;
tdn->trackIndex -= (n - 1); /* - 1, since n==0 would mean that we didn't change track */
}