Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/transform/transform.c57
-rw-r--r--source/blender/editors/transform/transform.h5
-rw-r--r--source/blender/editors/transform/transform_conversions.c564
-rw-r--r--source/blender/editors/transform/transform_generics.c126
-rw-r--r--source/blender/editors/transform/transform_ops.c8
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);