2.5 - Editing Animation data (keyframes/nla-strips) using transform tools now refresh...
authorJoshua Leung <aligorith@gmail.com>
Sun, 12 Jul 2009 03:42:39 +0000 (03:42 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sun, 12 Jul 2009 03:42:39 +0000 (03:42 +0000)
For now, this directly sets the update flags, though this really should be calling the Depsgraph API instead.

source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c

index f0c3a2c..387468f 100644 (file)
@@ -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:
index 888a15e..d45a6f4 100644 (file)
@@ -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)
        {
index 00353cf..db78632 100644 (file)
@@ -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 */
        
index 2262c6c..3d643a2 100644 (file)
@@ -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]);
index af56079..560b37c 100644 (file)
@@ -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 */
                                                }