diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/transform/transform.c | 57 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 5 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 564 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 126 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_ops.c | 8 |
5 files changed, 284 insertions, 476 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index a55d46f9a64..bac5febbee3 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -376,52 +376,6 @@ static void viewRedrawForce(bContext *C, TransInfo *t) if (G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0); else force_draw(0); } - else if (t->spacetype == SPACE_ACTION) { - if (G.saction->lock) { - short context; - - /* we ignore the pointer this function returns (not needed) */ - get_action_context(&context); - - if (context == ACTCONT_ACTION) - force_draw_plus(SPACE_VIEW3D, 0); - else if (context == ACTCONT_SHAPEKEY) - force_draw_all(0); - else - force_draw(0); - } - else { - force_draw(0); - } - } - else if (t->spacetype == SPACE_NLA) { - if (G.snla->lock) - force_draw_all(0); - else - force_draw(0); - } - else if (t->spacetype == SPACE_IPO) { - /* update realtime */ - if (G.sipo->lock) { - if (G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE) - force_draw_plus(SPACE_BUTS, 0); - else if (G.sipo->blocktype==ID_CA) - force_draw_plus(SPACE_VIEW3D, 0); - else if (G.sipo->blocktype==ID_KE) - force_draw_plus(SPACE_VIEW3D, 0); - else if (G.sipo->blocktype==ID_PO) - force_draw_plus(SPACE_VIEW3D, 0); - else if (G.sipo->blocktype==ID_OB) - force_draw_plus(SPACE_VIEW3D, 0); - else if (G.sipo->blocktype==ID_SEQ) - force_draw_plus(SPACE_SEQ, 0); - else - force_draw(0); - } - else { - force_draw(0); - } - } #endif } @@ -1111,8 +1065,15 @@ void initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) initTimeScale(t); break; case TFM_TIME_EXTEND: - /* now that transdata has been made, do like for TFM_TIME_TRANSLATE */ - initTimeTranslate(t); + /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation + * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION + * (for Graph Editor only since it uses 'standard' transforms to get 2D movement) + * depending on which editor this was called from + */ + if (t->spacetype == SPACE_IPO) + initTranslation(t); + else + initTimeTranslate(t); break; case TFM_BAKE_TIME: initBakeTime(t); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index a7017df5439..c3696da757c 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -331,6 +331,7 @@ typedef struct TransInfo { #define TD_SKIP (1 << 11) /* don't transform this data */ #define TD_BEZTRIPLE (1 << 12) /* if this is a bez triple, we need to restore the handles, if this is set transdata->misc.hdata needs freeing */ #define TD_NO_LOC (1 << 13) /* when this is set, don't apply translation changes to this element */ +#define TD_NOTIMESNAP (1 << 14) /* for Graph Editor autosnap, indicates that point should not undergo autosnapping */ /* transsnap->status */ #define SNAP_ON 1 @@ -441,8 +442,10 @@ void drawPropCircle(TransInfo *t); /*********************** transform_conversions.c ********** */ struct ListBase; + void flushTransGPactionData(TransInfo *t); -void flushTransIpoData(TransInfo *t); +void flushTransGraphData(TransInfo *t); +void remake_graph_transdata(TransInfo *t, struct ListBase *anim_data); void flushTransUVs(TransInfo *t); void flushTransParticles(TransInfo *t); int clipUVTransform(TransInfo *t, float *vec, int resize); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 8532dda02aa..80cc870d28d 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -3125,12 +3125,12 @@ static void createTransActionData(bContext *C, TransInfo *t) /* ********************* GRAPH EDITOR ************************* */ -#if 0 // GRAPH EDIT TO PORT + /* Helper function for make_ipo_transdata, which is reponsible for associating * source data with transform data */ -static void bezt_to_transdata (TransData *td, TransData2D *td2d, float *loc, float *cent, short selected, short ishandle, short onlytime) +static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, float *loc, float *cent, short selected, short ishandle) { /* New location from td gets dumped onto the old-location of td2d, which then * gets copied to the actual data at td2d->loc2d (bezt->vec[n]) @@ -3139,15 +3139,15 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, float *loc, flo * and then that scaling will be undone after transform is done. */ - if (NLA_IPO_SCALED) { - td2d->loc[0] = get_action_frame_inv(OBACT, loc[0]); + if (nob) { + td2d->loc[0] = get_action_frame_inv(nob, loc[0]); td2d->loc[1] = loc[1]; td2d->loc[2] = 0.0f; td2d->loc2d = loc; /*td->flag = 0;*/ /* can be set beforehand, else make sure its set to 0 */ td->loc = td2d->loc; - td->center[0] = get_action_frame_inv(OBACT, cent[0]); + td->center[0] = get_action_frame_inv(nob, cent[0]); td->center[1] = cent[1]; td->center[2] = 0.0f; @@ -3177,207 +3177,185 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, float *loc, flo else td->dist= MAXFLOAT; - if (onlytime) - td->flag |= TD_TIMEONLY; - if (ishandle) td->flag |= TD_NOTIMESNAP; Mat3One(td->mtx); Mat3One(td->smtx); } - -/* This function is called by createTransIpoData and remake_ipo_transdata to - * create the TransData and TransData2D arrays for transform. The costly counting - * stage is only performed for createTransIpoData case, and is indicated by t->total==-1; - */ -void make_ipo_transdata (TransInfo *t) + +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; - EditIpo *ei; + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + BezTriple *bezt, *prevbezt; - int a, b; - - /* countsel and propmode are used for proportional edit, which is not yet available */ - int count=0/*, countsel=0*/; - /*int propmode = t->flag & T_PROP_EDIT;*/ - - /* count data and allocate memory (if needed) */ - if (t->total == 0) { - /* count data first */ - if (totipo_vertsel) { - /* we're probably in editmode, so only selected verts */ - if (G.v2d->around == V3D_LOCAL) { - /* we're in editmode, but we need to count the number of selected handles only */ - ei= G.sipo->editipo; - for (a=0; a<G.sipo->totipo; a++, ei++) { - if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu)) { - IpoCurve *icu= ei->icu; - - if (icu->bezt) { - bezt= icu->bezt; - for (b=0; b < icu->totvert; b++, bezt++) { - if (bezt->ipo == IPO_BEZ) { - if (bezt->f1 & SELECT) count++; - if (bezt->f2 & SELECT) count++; - } - else if (bezt->f2 & SELECT) count++; - } + 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 + } + else { + /* 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) { + Object *nob= NULL; //ANIM_nla_mapping_get(&ac, ale); // XXX we don't handle NLA mapping for now here... + 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) + */ + if (nob) + cfra = get_action_frame(nob, (float)CFRA); + 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++) { + if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) { + if (v2d->around == V3D_LOCAL) { + /* for local-pivot we only need to count the number of selected handles only, so that centerpoitns don't + * don't get moved wrong + */ + if (bezt->ipo == BEZT_IPO_BEZ) { + if (bezt->f1 & SELECT) count++; + if (bezt->f3 & SELECT) count++; } + else if (bezt->f2 & SELECT) count++; } - } - if (count==0) return; - } - else - count= totipo_vertsel; - } - else if (totipo_edit==0 && totipo_sel!=0) { - /* we're not in editmode, so entire curves get moved */ - ei= G.sipo->editipo; - for (a=0; a<G.sipo->totipo; a++, ei++) { - if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) { - IpoCurve *icu= ei->icu; - - if (icu->bezt) { - if (icu->ipo == IPO_MIXED) { - bezt= icu->bezt; - for (b=0; b < icu->totvert; b++, bezt++) { - if (bezt->ipo == IPO_BEZ) count += 3; - else count++; - } + else { + /* for 'norma' pivots */ + if (bezt->ipo == BEZT_IPO_BEZ) { + if (bezt->f1 & SELECT) count++; + if (bezt->f2 & SELECT) count++; + if (bezt->f3 & SELECT) count++; } - else if (icu->ipo == IPO_BEZ) - count+= 3*icu->totvert; - else - count+= icu->totvert; + else if (bezt->f2 & SELECT) count++; } - else - count+= icu->totvert; } } - if (count==0) return; } - else { - /* this case should not happen */ - return; - } - - /* memory allocation */ - /*t->total= (propmode)? count: countsel;*/ - t->total= count; - t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (IPO 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 (IPO Editor)"); } + /* 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; - /* add verts */ - if (totipo_vertsel) { - /* we're probably in editmode, so only selected verts */ - ei= G.sipo->editipo; - for (a=0; a<G.sipo->totipo; a++, ei++) { - /* only consider those curves that are visible and are being edited/used for showkeys */ - if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - if ((ei->flag & IPO_EDIT) || (G.sipo->showkey)) { - IpoCurve *icu= ei->icu; - - if (icu->bezt) { - short onlytime= (ei->disptype==IPO_DISPBITS) ? 1 : (G.sipo->showkey) ? 1 : 0; - - bezt= icu->bezt; - prevbezt= NULL; - - for (b=0; b < icu->totvert; b++, prevbezt=bezt, bezt++) { - TransDataCurveHandleFlags *hdata = NULL; - short h1=1, h2=1; - - /* only include handles if selected, and interpolaton mode uses beztriples */ - if ( (!prevbezt && (bezt->ipo==IPO_BEZ)) || (prevbezt && (prevbezt->ipo==IPO_BEZ)) ) { - if (bezt->f1 & SELECT) { - hdata = initTransDataCurveHandes(td, bezt); - bezt_to_transdata(td++, td2d++, bezt->vec[0], bezt->vec[1], 1, 1, onlytime); - } - else - h1= 0; - } - if (bezt->ipo==IPO_BEZ) { - if (bezt->f3 & SELECT) { - if (hdata==NULL) - hdata = initTransDataCurveHandes(td, bezt); - bezt_to_transdata(td++, td2d++, bezt->vec[2], bezt->vec[1], 1, 1, onlytime); - } - else - h2= 0; - } - - /* only include main vert if selected */ - if (bezt->f2 & SELECT) { - /* if scaling around individuals centers, do no include keyframes */ - if (G.v2d->around != V3D_LOCAL) { - /* if handles were not selected, store their selection status */ - if (!(bezt->f1 & SELECT) && !(bezt->f3 & SELECT)) { - if (hdata == NULL) - hdata = initTransDataCurveHandes(td, bezt); - } - - bezt_to_transdata(td++, td2d++, bezt->vec[1], bezt->vec[1], 1, 0, onlytime); - } - - /* 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. - * - If so, change them auto-handles to aligned handles so that handles get affected too - */ - if ((bezt->h1 == HD_AUTO) && (bezt->h2 == HD_AUTO) && ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { - if (h1 && h2) { - bezt->h1= HD_ALIGN; - bezt->h2= HD_ALIGN; - } - } - } - } - - /* Sets handles based on the selection */ - testhandles_ipocurve(ei->icu); + /* loop 2: build transdata arrays */ + cfra = (float)CFRA; + + for (ale= anim_data.first; ale; ale= ale->next) { + Object *nob= NULL; //ANIM_nla_mapping_get(&ac, ale); // XXX we don't handle NLA mapping here yet + FCurve *fcu= (FCurve *)ale->key_data; + + /* 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) { + hdata = initTransDataCurveHandes(td, bezt); + bezt_to_transdata(td++, td2d++, nob, bezt->vec[0], bezt->vec[1], 1, 1); } + else + h1= 0; + } + if (bezt->ipo == BEZT_IPO_BEZ) { + if (bezt->f3 & SELECT) { + if (hdata==NULL) + hdata = initTransDataCurveHandes(td, bezt); + bezt_to_transdata(td++, td2d++, nob, bezt->vec[2], bezt->vec[1], 1, 1); + } + else + h2= 0; } - } - } - } - else if (totipo_edit==0 && totipo_sel!=0) { - /* we're not in editmode, so entire curves get moved */ - ei= G.sipo->editipo; - for (a=0; a<G.sipo->totipo; a++, ei++) { - /* only include curves that are visible and selected */ - if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) { - IpoCurve *icu= ei->icu; - if (icu->bezt) { - short onlytime= (ei->disptype==IPO_DISPBITS) ? 1 : (G.sipo->showkey) ? 1 : 0; - - bezt= icu->bezt; - prevbezt= NULL; - - for (b=0; b < icu->totvert; b++, prevbezt=bezt, bezt++) { - /* only include handles if interpolation mode is bezier is relevant */ - if ( (!prevbezt && (bezt->ipo==IPO_BEZ)) || (prevbezt && (prevbezt->ipo==IPO_BEZ)) ) - bezt_to_transdata(td++, td2d++, bezt->vec[0], bezt->vec[1], 1, 1,onlytime); - if (bezt->ipo==IPO_BEZ) - bezt_to_transdata(td++, td2d++, bezt->vec[2], bezt->vec[1], 1, 1, onlytime); + /* only include main vert if selected */ + if (bezt->f2 & SELECT) { + /* if scaling around individuals centers, do no include keyframes */ + if (v2d->around != V3D_LOCAL) { + /* if handles were not selected, store their selection status */ + if (!(bezt->f1 & SELECT) && !(bezt->f3 & SELECT)) { + if (hdata == NULL) + hdata = initTransDataCurveHandes(td, bezt); + } - /* always include the main handle */ - bezt_to_transdata(td++, td2d++, bezt->vec[1], bezt->vec[1], 1, 0, onlytime); + bezt_to_transdata(td++, td2d++, nob, bezt->vec[1], bezt->vec[1], 1, 0); + } + + /* 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. + * - If so, change them auto-handles to aligned handles so that handles get affected too + */ + if ((bezt->h1 == HD_AUTO) && (bezt->h2 == HD_AUTO) && ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { + if (h1 && h2) { + bezt->h1= HD_ALIGN; + bezt->h2= HD_ALIGN; + } } } } } + + /* Sets handles based on the selection */ + testhandles_fcurve(fcu); } + + + /* cleanup temp list */ + BLI_freelistN(&anim_data); } + /* ------------------------ */ /* struct for use in re-sorting BezTriples during IPO transform */ @@ -3390,7 +3368,7 @@ typedef struct BeztMap { } BeztMap; -/* This function converts an IpoCurve's BezTriple array to a BeztMap array +/* This function converts an FCurve's BezTriple array to a BeztMap array * NOTE: this allocates memory that will need to get freed later */ static BeztMap *bezt_to_beztmaps (BezTriple *bezts, int totvert) @@ -3465,10 +3443,10 @@ static void sort_time_beztmaps (BeztMap *bezms, int totvert) } } -/* This function firstly adjusts the pointers that the transdata has to each BezTriple*/ -static void beztmap_to_data (TransInfo *t, EditIpo *ei, BeztMap *bezms, int totvert) +/* This function firstly adjusts the pointers that the transdata has to each BezTriple */ +static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert) { - BezTriple *bezts = ei->icu->bezt; + BezTriple *bezts = fcu->bezt; BeztMap *bezm; TransData2D *td; int i, j; @@ -3491,40 +3469,9 @@ static void beztmap_to_data (TransInfo *t, EditIpo *ei, BeztMap *bezms, int totv /* skip item if already marked */ if (adjusted[j] != 0) continue; - if (totipo_vertsel) { - /* only selected verts */ - if (bezm->pipo == IPO_BEZ) { - if (bezm->bezt->f1 & SELECT) { - if (td->loc2d == bezm->bezt->vec[0]) { - if (bezm->swapHs == 1) - td->loc2d= (bezts + bezm->newIndex)->vec[2]; - else - td->loc2d= (bezts + bezm->newIndex)->vec[0]; - adjusted[j] = 1; - } - } - } - if (bezm->cipo == IPO_BEZ) { - if (bezm->bezt->f3 & SELECT) { - if (td->loc2d == bezm->bezt->vec[2]) { - if (bezm->swapHs == 1) - td->loc2d= (bezts + bezm->newIndex)->vec[0]; - else - td->loc2d= (bezts + bezm->newIndex)->vec[2]; - adjusted[j] = 1; - } - } - } - if (bezm->bezt->f2 & SELECT) { - if (td->loc2d == bezm->bezt->vec[1]) { - td->loc2d= (bezts + bezm->newIndex)->vec[1]; - adjusted[j] = 1; - } - } - } - else { - /* whole curve */ - if (bezm->pipo == IPO_BEZ) { + /* only selected verts */ + if (bezm->pipo == BEZT_IPO_BEZ) { + if (bezm->bezt->f1 & SELECT) { if (td->loc2d == bezm->bezt->vec[0]) { if (bezm->swapHs == 1) td->loc2d= (bezts + bezm->newIndex)->vec[2]; @@ -3533,7 +3480,9 @@ static void beztmap_to_data (TransInfo *t, EditIpo *ei, BeztMap *bezms, int totv adjusted[j] = 1; } } - if (bezm->cipo == IPO_BEZ) { + } + if (bezm->cipo == BEZT_IPO_BEZ) { + if (bezm->bezt->f3 & SELECT) { if (td->loc2d == bezm->bezt->vec[2]) { if (bezm->swapHs == 1) td->loc2d= (bezts + bezm->newIndex)->vec[0]; @@ -3542,6 +3491,8 @@ static void beztmap_to_data (TransInfo *t, EditIpo *ei, BeztMap *bezms, int totv adjusted[j] = 1; } } + } + if (bezm->bezt->f2 & SELECT) { if (td->loc2d == bezm->bezt->vec[1]) { td->loc2d= (bezts + bezm->newIndex)->vec[1]; adjusted[j] = 1; @@ -3558,171 +3509,76 @@ static void beztmap_to_data (TransInfo *t, EditIpo *ei, BeztMap *bezms, int totv /* This function is called by recalcData during the Transform loop to recalculate * the handles of curves and sort the keyframes so that the curves draw correctly. * It is only called if some keyframes have moved out of order. + * + * anim_data is the list of channels (F-Curves) retrieved already containing the + * channels to work on. It should not be freed here as it may still need to be used. */ -void remake_ipo_transdata (TransInfo *t) -{ - EditIpo *ei; - int a; - - /* sort and reassign verts */ - ei= G.sipo->editipo; - for (a=0; a<G.sipo->totipo; a++, ei++) { - if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - if (ei->icu->bezt) { - BeztMap *bezm; - - /* adjust transform-data pointers */ - bezm= bezt_to_beztmaps(ei->icu->bezt, ei->icu->totvert); - sort_time_beztmaps(bezm, ei->icu->totvert); - beztmap_to_data(t, ei, bezm, ei->icu->totvert); - - /* re-sort actual beztriples (perhaps this could be done using the beztmaps to save time?) */ - sort_time_ipocurve(ei->icu); - - /* free mapping stuff */ - MEM_freeN(bezm); - - /* make sure handles are all set correctly */ - testhandles_ipocurve(ei->icu); - } - } - } - - /* remake ipokeys */ - if (G.sipo->showkey) make_ipokey(); -} -#endif // GRAPHEDIT TO PORT - -static void createTransGraphEditData(bContext *C, TransInfo *t) +void remake_graph_transdata (TransInfo *t, ListBase *anim_data) { - Scene *scene= CTX_data_scene(C); - TransData *td = 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 */ - 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 */ - 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: fully select ipo-keys and count how many BezTriples are selected */ - for (ale= anim_data.first; ale; ale= ale->next) { - Object *nob= 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) - */ - if (nob) - cfra = get_action_frame(nob, (float)CFRA); - else - cfra = (float)CFRA; - - 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 (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) { - Object *nob= ANIM_nla_mapping_get(&ac, ale); + /* sort and reassign verts */ + for (ale= anim_data->first; ale; ale= ale->next) { 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) - */ - if (nob) - cfra = get_action_frame(nob, (float)CFRA); - else - cfra = (float)CFRA; - - td= FCurveToTransData(td, fcu, nob, side, cfra); // XXX... this doesn't do points! - } - - /* 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); + 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); + + /* re-sort actual beztriples (perhaps this could be done using the beztmaps to save time?) */ + sort_time_fcurve(fcu); + + /* free mapping stuff */ + MEM_freeN(bezm); + + /* make sure handles are all set correctly */ + testhandles_fcurve(fcu); } - - /* 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). - */ - *((float *)(t->customData)) = min; - *((float *)(t->customData) + 1) = max; } - - /* cleanup temp list */ - BLI_freelistN(&anim_data); } - /* this function is called on recalcData to apply the transforms applied * to the transdata on to the actual keyframe data */ -void flushTransIpoData(TransInfo *t) +void flushTransGraphData(TransInfo *t) { -#if 0 // TRANSFORM_FIX_ME - TransData2D *td; + SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; + TransData *td; + TransData2D *td2d; int a; /* flush to 2d vector from internally used 3d vector */ - for (a=0, td= t->data2d; a<t->total; a++, td++) { - // FIXME: autosnap needs to be here... + for (a=0, td= t->data, td2d=t->data2d; a<t->total; a++, td++, td2d++) { + /* handle snapping for time values + * - we should still be in NLA-mapping timespace + * - only apply to keyframes (but never to handles) + */ + if ((td->flag & TD_NOTIMESNAP)==0) { + switch (sipo->autosnap) { + case SACTSNAP_FRAME: /* snap to nearest frame */ + td2d->loc[0]= (float)( floor(td2d->loc[0]+0.5f) ); + break; + + case SACTSNAP_MARKER: /* snap to nearest marker */ + //td2d->loc[0]= (float)find_nearest_marker_time(td2d->loc[0]); + break; + } + } /* we need to unapply the nla-scaling from the time in some situations */ - if (NLA_IPO_SCALED) - td->loc2d[0]= get_action_frame(OBACT, td->loc[0]); - else - td->loc2d[0]= td->loc[0]; + //if (NLA_IPO_SCALED) + // td2d->loc2d[0]= get_action_frame(OBACT, td2d->loc[0]); + //else + td2d->loc2d[0]= td2d->loc[0]; /* when the icu that point comes from is a bitflag holder, don't allow adjusting values */ - if ((t->data[a].flag & TD_TIMEONLY)==0) - td->loc2d[1]= td->loc[1]; + if ((td->flag & TD_TIMEONLY)==0) + td2d->loc2d[1]= td2d->loc[1]; } -#endif } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index a2a8d318546..520efab96de 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -34,6 +34,7 @@ #include "BLO_sys_types.h" // for intptr_t support +#include "DNA_anim_types.h" #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_constraint_types.h" @@ -71,6 +72,7 @@ #include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_depsgraph.h" +#include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_group.h" #include "BKE_lattice.h" @@ -81,12 +83,12 @@ #include "BKE_utildefines.h" #include "BKE_context.h" +#include "ED_anim_api.h" #include "ED_armature.h" #include "ED_view3d.h" #include "ED_mesh.h" #include "ED_space_api.h" -//#include "BSE_editaction_types.h" //#include "BDR_unwrapper.h" #include "BLI_arithb.h" @@ -347,76 +349,6 @@ void recalcData(TransInfo *t) } } } - else if (t->spacetype == SPACE_IPO) { - EditIpo *ei; - int dosort = 0; - int a; - - /* do the flush first */ - flushTransIpoData(t); - - /* now test if there is a need to re-sort */ - ei= G.sipo->editipo; - for (a=0; a<G.sipo->totipo; a++, ei++) { - if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) { - - /* watch it: if the time is wrong: do not correct handles */ - if (test_time_ipocurve(ei->icu)) { - dosort++; - } else { - calchandles_ipocurve(ei->icu); - } - } - } - - /* do resort and other updates? */ - if (dosort) remake_ipo_transdata(t); - if (G.sipo->showkey) update_ipokey_val(); - - calc_ipo(G.sipo->ipo, (float)CFRA); - - /* update realtime - not working? */ - if (G.sipo->lock) { - if (G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE) { - do_ipo(G.sipo->ipo); - } - else if(G.sipo->blocktype==ID_CA) { - do_ipo(G.sipo->ipo); - } - else if(G.sipo->blocktype==ID_KE) { - Object *ob= OBACT; - if(ob) { - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - } - } - else if(G.sipo->blocktype==ID_PO) { - Object *ob= OBACT; - if(ob && ob->pose) { - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - } - } - else if(G.sipo->blocktype==ID_OB) { - Object *ob= OBACT; - Base *base= FIRSTBASE; - - /* only if this if active object has this ipo in an action (assumes that current ipo is in action) */ - if ((ob) && (ob->ipoflag & OB_ACTION_OB) && (G.sipo->pin==0)) { - ob->ctime= -1234567.0f; - DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); - } - - while(base) { - if(base->object->ipo==G.sipo->ipo) { - do_ob_ipo(base->object); - base->object->recalc |= OB_RECALC_OB; - } - base= base->next; - } - DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0); - } - } - } else if (t->obedit) { if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { Curve *cu= t->obedit->data; @@ -458,6 +390,58 @@ void recalcData(TransInfo *t) else if (t->spacetype==SPACE_SEQ) { flushTransSeq(t); } + 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; + + /* 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; + + /* watch it: if the time is wrong: do not correct handles yet */ + if (test_time_fcurve(fcu)) + dosort++; + else + calchandles_fcurve(fcu); + } + + /* 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->obedit) { if (t->obedit->type == OB_MESH) { if(t->spacetype==SPACE_IMAGE) { diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 0969152422b..260f7fdf03e 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -278,8 +278,12 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0); RNA_int_set(km->ptr, "mode", TFM_TRANSLATION); - //km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0); - //RNA_int_set(km->ptr, "mode", TFM_ROTATION); + // XXX the 'mode' identifier here is not quite right + 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", RKEY, KM_PRESS, 0, 0); + RNA_int_set(km->ptr, "mode", TFM_ROTATION); km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0); RNA_int_set(km->ptr, "mode", TFM_RESIZE); |