diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-07-16 10:27:37 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-07-16 10:27:37 +0400 |
commit | 0b1649b2b86b52b44bdabf8e3542d8adffb55623 (patch) | |
tree | 542e10220a719f2a54e8afbee7b11195b6dac344 /source/blender/editors/transform | |
parent | 3bade135035dacfdb4a3833f3fac3bf5811ce7de (diff) | |
parent | 0bfc98706ef93f90bd74b195b98c36c7dcea94dd (diff) |
merge with 2.5 at r21568
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/Makefile | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.c | 1319 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 58 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_constraints.c | 207 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 1441 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 584 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_input.c | 61 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_manipulator.c | 1109 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_ndofinput.c | 11 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_numinput.c | 1 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_ops.c | 265 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_orientations.c | 106 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 22 |
13 files changed, 2735 insertions, 2451 deletions
diff --git a/source/blender/editors/transform/Makefile b/source/blender/editors/transform/Makefile index bc3e08a2ae8..607038b413b 100644 --- a/source/blender/editors/transform/Makefile +++ b/source/blender/editors/transform/Makefile @@ -1,5 +1,5 @@ # -# $Id: Makefile 14 2002-10-13 15:57:19Z hans $ +# $Id$ # # ***** BEGIN GPL LICENSE BLOCK ***** # diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 674de81a9f5..c62ea07e398 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -45,6 +45,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_action_types.h" /* for some special action-editor settings */ #include "DNA_constraint_types.h" @@ -76,9 +77,9 @@ //#include "BIF_editmesh.h" //#include "BIF_editsima.h" //#include "BIF_editparticle.h" -//#include "BIF_editaction.h" -#include "BKE_action.h" /* get_action_frame */ +#include "BKE_action.h" +#include "BKE_nla.h" //#include "BKE_bad_level_calls.h"/* popmenu and error */ #include "BKE_bmesh.h" #include "BKE_context.h" @@ -89,7 +90,6 @@ #include "BKE_utildefines.h" #include "BKE_context.h" -//#include "BSE_editaction_types.h" //#include "BSE_view.h" #include "ED_image.h" @@ -123,7 +123,7 @@ void setTransformViewMatrices(TransInfo *t) { if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = t->ar->regiondata; - + Mat4CpyMat4(t->viewmat, rv3d->viewmat); Mat4CpyMat4(t->viewinv, rv3d->viewinv); Mat4CpyMat4(t->persmat, rv3d->persmat); @@ -137,7 +137,7 @@ void setTransformViewMatrices(TransInfo *t) Mat4One(t->persinv); t->persp = V3D_ORTHO; } - + calculateCenter2D(t); } @@ -152,23 +152,23 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy) else if(t->spacetype==SPACE_IMAGE) { View2D *v2d = t->view; float divx, divy, aspx, aspy; - + ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); - + divx= v2d->mask.xmax-v2d->mask.xmin; divy= v2d->mask.ymax-v2d->mask.ymin; - + vec[0]= aspx*(v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; vec[1]= aspy*(v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; vec[2]= 0.0f; } - else if(t->spacetype==SPACE_IPO) { + else if(ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) { View2D *v2d = t->view; float divx, divy; - + divx= v2d->mask.xmax-v2d->mask.xmin; divy= v2d->mask.ymax-v2d->mask.ymin; - + vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx) / (divx); vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy) / (divy); vec[2]= 0.0f; @@ -176,10 +176,10 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy) else if(t->spacetype==SPACE_NODE) { View2D *v2d = &t->ar->v2d; float divx, divy; - + divx= v2d->mask.xmax-v2d->mask.xmin; divy= v2d->mask.ymax-v2d->mask.ymin; - + vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; vec[2]= 0.0f; @@ -205,23 +205,23 @@ void projectIntView(TransInfo *t, float *vec, int *adr) } else if(t->spacetype==SPACE_IMAGE) { float aspx, aspy, v[2]; - + ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); v[0]= vec[0]/aspx; v[1]= vec[1]/aspy; - + UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1); } - else if(t->spacetype==SPACE_IPO) { + else if(ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) { int out[2] = {0, 0}; - - UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1); + + UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1); adr[0]= out[0]; adr[1]= out[1]; } else if(t->spacetype==SPACE_SEQ) { /* XXX not tested yet, but should work */ int out[2] = {0, 0}; - + UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1); adr[0]= out[0]; adr[1]= out[1]; @@ -236,14 +236,14 @@ void projectFloatView(TransInfo *t, float *vec, float *adr) } else if(t->spacetype==SPACE_IMAGE) { int a[2]; - + projectIntView(t, vec, a); adr[0]= a[0]; adr[1]= a[1]; } - else if(t->spacetype==SPACE_IPO) { + else if(ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) { int a[2]; - + projectIntView(t, vec, a); adr[0]= a[0]; adr[1]= a[1]; @@ -296,28 +296,19 @@ static void viewRedrawForce(bContext *C, TransInfo *t) { if (t->spacetype == SPACE_VIEW3D) { - /* Do we need more refined tags? */ + /* Do we need more refined tags? */ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); } else if (t->spacetype == SPACE_ACTION) { - SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; - - // TRANSFORM_FIX_ME - if (saction->lock) { - // whole window... - } - else - ED_area_tag_redraw(t->sa); + //SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); } else if (t->spacetype == SPACE_IPO) { - SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; - - // TRANSFORM_FIX_ME - if (sipo->lock) { - // whole window... - } - else - ED_area_tag_redraw(t->sa); + //SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; + 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_NLA_EDIT, NULL); } else if(t->spacetype == SPACE_NODE) { @@ -343,7 +334,7 @@ static void viewRedrawForce(bContext *C, TransInfo *t) static void viewRedrawPost(TransInfo *t) { ED_area_headerprint(t->sa, NULL); - + #if 0 // TRANSFORM_FIX_ME if(t->spacetype==SPACE_VIEW3D) { allqueue(REDRAWBUTSOBJECT, 0); @@ -374,7 +365,7 @@ void BIF_selectOrientation() { char *str_menu = BIF_menustringTransformOrientation("Orientation"); val= pupmenu(str_menu); MEM_freeN(str_menu); - + if(val >= 0) { G.vd->twmode = val; } @@ -390,18 +381,18 @@ static void view_editmove(unsigned short event) /* Ctrl: Scroll right */ /* Alt-Shift: Rotate up */ /* Alt-Ctrl: Rotate right */ - + /* only work in 3D window for now * In the end, will have to send to event to a 2D window handler instead */ if (Trans.flag & T_2D_EDIT) return; - + switch(event) { case WHEELUPMOUSE: - + if( G.qual & LR_SHIFTKEY ) { - if( G.qual & LR_ALTKEY ) { + if( G.qual & LR_ALTKEY ) { G.qual &= ~LR_SHIFTKEY; persptoetsen(PAD2); G.qual |= LR_SHIFTKEY; @@ -409,23 +400,23 @@ static void view_editmove(unsigned short event) persptoetsen(PAD2); } } else if( G.qual & LR_CTRLKEY ) { - if( G.qual & LR_ALTKEY ) { + if( G.qual & LR_ALTKEY ) { G.qual &= ~LR_CTRLKEY; persptoetsen(PAD4); G.qual |= LR_CTRLKEY; } else { persptoetsen(PAD4); } - } else if(U.uiflag & USER_WHEELZOOMDIR) + } else if(U.uiflag & USER_WHEELZOOMDIR) persptoetsen(PADMINUS); else persptoetsen(PADPLUSKEY); - + refresh = 1; break; case WHEELDOWNMOUSE: if( G.qual & LR_SHIFTKEY ) { - if( G.qual & LR_ALTKEY ) { + if( G.qual & LR_ALTKEY ) { G.qual &= ~LR_SHIFTKEY; persptoetsen(PAD8); G.qual |= LR_SHIFTKEY; @@ -433,18 +424,18 @@ static void view_editmove(unsigned short event) persptoetsen(PAD8); } } else if( G.qual & LR_CTRLKEY ) { - if( G.qual & LR_ALTKEY ) { + if( G.qual & LR_ALTKEY ) { G.qual &= ~LR_CTRLKEY; persptoetsen(PAD6); G.qual |= LR_CTRLKEY; } else { persptoetsen(PAD6); } - } else if(U.uiflag & USER_WHEELZOOMDIR) + } else if(U.uiflag & USER_WHEELZOOMDIR) persptoetsen(PADPLUSKEY); else persptoetsen(PADMINUS); - + refresh = 1; break; } @@ -454,6 +445,7 @@ static void view_editmove(unsigned short event) #endif } +#if 0 static char *transform_to_undostr(TransInfo *t) { switch (t->mode) { @@ -500,6 +492,7 @@ static char *transform_to_undostr(TransInfo *t) } return "Transform"; } +#endif /* ************************************************* */ @@ -507,19 +500,19 @@ void transformEvent(TransInfo *t, wmEvent *event) { float mati[3][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}; char cmode = constraintModeToChar(t); - + t->redraw |= handleMouseInput(t, &t->mouse, event); if (event->type == MOUSEMOVE) { t->mval[0] = event->x - t->ar->winrct.xmin; t->mval[1] = event->y - t->ar->winrct.ymin; - + t->redraw = 1; - + applyMouseInput(t, &t->mouse, t->mval, t->values); } - + if (event->val) { switch (event->type){ /* enforce redraw of transform when modifiers are used */ @@ -528,7 +521,7 @@ void transformEvent(TransInfo *t, wmEvent *event) t->modifiers |= MOD_SNAP_GEARS; t->redraw = 1; break; - + case LEFTSHIFTKEY: case RIGHTSHIFTKEY: t->modifiers |= MOD_CONSTRAINT_PLANE; @@ -539,7 +532,7 @@ void transformEvent(TransInfo *t, wmEvent *event) if ((t->spacetype==SPACE_VIEW3D) && event->alt) { #if 0 // TRANSFORM_FIX_ME short mval[2]; - + getmouseco_sc(mval); BIF_selectOrientation(); calc_manipulator_stats(curarea); @@ -551,7 +544,7 @@ void transformEvent(TransInfo *t, wmEvent *event) t->state = TRANS_CONFIRM; } break; - + case MIDDLEMOUSE: if ((t->flag & T_NO_CONSTRAINT)==0) { /* exception for switching to dolly, or trackball, in camera view */ @@ -584,19 +577,16 @@ void transformEvent(TransInfo *t, wmEvent *event) } break; case ESCKEY: - case RIGHTMOUSE: - printf("cancelled\n"); t->state = TRANS_CANCEL; break; - case LEFTMOUSE: case PADENTER: case RETKEY: t->state = TRANS_CONFIRM; break; case GKEY: /* only switch when... */ - if( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) { - resetTransRestrictions(t); + if( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) { + resetTransRestrictions(t); restoreTransObjects(t); initTranslation(t); initSnapping(t, NULL); // need to reinit after mode change @@ -605,8 +595,8 @@ void transformEvent(TransInfo *t, wmEvent *event) break; case SKEY: /* only switch when... */ - if( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) { - resetTransRestrictions(t); + if( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) { + resetTransRestrictions(t); restoreTransObjects(t); initResize(t); initSnapping(t, NULL); // need to reinit after mode change @@ -616,9 +606,9 @@ void transformEvent(TransInfo *t, wmEvent *event) case RKEY: /* only switch when... */ if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { - - resetTransRestrictions(t); - + + resetTransRestrictions(t); + if (t->mode == TFM_ROTATION) { restoreTransObjects(t); initTrackball(t); @@ -778,10 +768,10 @@ void transformEvent(TransInfo *t, wmEvent *event) // viewmoveNDOF(1); // break; } - + // Numerical input events t->redraw |= handleNumInput(&(t->num), event); - + // NDof input events switch(handleNDofInput(&(t->ndof), event)) { @@ -796,7 +786,7 @@ void transformEvent(TransInfo *t, wmEvent *event) if (t->options & CTX_NDOF) { /* Cancel on pure NDOF transform */ - t->state = TRANS_CANCEL; + t->state = TRANS_CANCEL; } else { @@ -814,16 +804,22 @@ void transformEvent(TransInfo *t, wmEvent *event) case NDOF_REFRESH: t->redraw = 1; break; - + } - + // Snapping events t->redraw |= handleSnapping(t, event); - + //arrows_move_cursor(event->type); } else { switch (event->type){ + case RIGHTMOUSE: + t->state = TRANS_CANCEL; + break; + case LEFTMOUSE: + t->state = TRANS_CONFIRM; + break; case LEFTSHIFTKEY: case RIGHTSHIFTKEY: t->modifiers &= ~MOD_CONSTRAINT_PLANE; @@ -833,7 +829,7 @@ void transformEvent(TransInfo *t, wmEvent *event) case LEFTCTRLKEY: case RIGHTCTRLKEY: t->modifiers &= ~MOD_SNAP_GEARS; - /* no redraw on release modifier keys! this makes sure you can assign the 'grid' still + /* no redraw on release modifier keys! this makes sure you can assign the 'grid' still after releasing modifer key */ //t->redraw = 1; break; @@ -844,15 +840,15 @@ void transformEvent(TransInfo *t, wmEvent *event) t->redraw = 1; } break; - case LEFTMOUSE: - case RIGHTMOUSE: - if(WM_modal_tweak_exit(event, t->event_type)) -// if (t->options & CTX_TWEAK) - t->state = TRANS_CONFIRM; - break; +// case LEFTMOUSE: +// case RIGHTMOUSE: +// if(WM_modal_tweak_exit(event, t->event_type)) +//// if (t->options & CTX_TWEAK) +// t->state = TRANS_CONFIRM; +// break; } } - + // Per transform event, if present if (t->handleEvent) t->redraw |= t->handleEvent(t, event); @@ -866,7 +862,7 @@ int calculateTransformCenter(bContext *C, wmEvent *event, int centerMode, float t->state = TRANS_RUNNING; t->options = CTX_NONE; - + t->mode = TFM_DUMMY; initTransInfo(C, t, NULL, event); // internal data, mouse, vectors @@ -880,10 +876,10 @@ int calculateTransformCenter(bContext *C, wmEvent *event, int centerMode, float } else { success = 1; - + calculateCenter(t); - - // Copy center from constraint center. Transform center can be local + + // Copy center from constraint center. Transform center can be local VECCOPY(vec, t->con.center); } @@ -891,9 +887,9 @@ int calculateTransformCenter(bContext *C, wmEvent *event, int centerMode, float /* aftertrans does insert ipos and action channels, and clears base flags, doesnt read transdata */ special_aftertrans_update(t); - + MEM_freeN(t); - + return success; } @@ -912,28 +908,28 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size) length = -length; size = -size; case RIGHT: - glBegin(GL_LINES); - glVertex2s( offset, 0); - glVertex2s( offset + length, 0); - glVertex2s( offset + length, 0); - glVertex2s( offset + length - size, -size); - glVertex2s( offset + length, 0); + glBegin(GL_LINES); + glVertex2s( offset, 0); + glVertex2s( offset + length, 0); + glVertex2s( offset + length, 0); + glVertex2s( offset + length - size, -size); + glVertex2s( offset + length, 0); glVertex2s( offset + length - size, size); - glEnd(); + glEnd(); break; case DOWN: offset = -offset; length = -length; size = -size; case UP: - glBegin(GL_LINES); - glVertex2s( 0, offset); - glVertex2s( 0, offset + length); - glVertex2s( 0, offset + length); - glVertex2s(-size, offset + length - size); - glVertex2s( 0, offset + length); + glBegin(GL_LINES); + glVertex2s( 0, offset); + glVertex2s( 0, offset + length); + glVertex2s( 0, offset + length); + glVertex2s(-size, offset + length - size); + glVertex2s( 0, offset + length); glVertex2s( size, offset + length - size); - glEnd(); + glEnd(); break; } } @@ -945,22 +941,22 @@ static void drawArrowHead(ArrowDirection d, short size) case LEFT: size = -size; case RIGHT: - glBegin(GL_LINES); - glVertex2s( 0, 0); - glVertex2s( -size, -size); - glVertex2s( 0, 0); + glBegin(GL_LINES); + glVertex2s( 0, 0); + glVertex2s( -size, -size); + glVertex2s( 0, 0); glVertex2s( -size, size); - glEnd(); + glEnd(); break; case DOWN: size = -size; case UP: - glBegin(GL_LINES); - glVertex2s( 0, 0); - glVertex2s(-size, -size); - glVertex2s( 0, 0); + glBegin(GL_LINES); + glVertex2s( 0, 0); + glVertex2s(-size, -size); + glVertex2s( 0, 0); glVertex2s( size, -size); - glEnd(); + glEnd(); break; } } @@ -969,15 +965,15 @@ static void drawArc(float size, float angle_start, float angle_end, int segments { float delta = (angle_end - angle_start) / segments; float angle; - + glBegin(GL_LINE_STRIP); - + for( angle = angle_start; angle < angle_end; angle += delta) { glVertex2f( cosf(angle) * size, sinf(angle) * size); } glVertex2f( cosf(angle_end) * size, sinf(angle_end) * size); - + glEnd(); } @@ -986,7 +982,7 @@ void drawHelpline(const struct bContext *C, TransInfo *t) if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR)) { float vecrot[3], cent[2]; - + VECCOPY(vecrot, t->center); if(t->flag & T_EDIT) { Object *ob= t->obedit; @@ -996,9 +992,9 @@ void drawHelpline(const struct bContext *C, TransInfo *t) Object *ob=t->poseobj; if(ob) Mat4MulVecfl(ob->obmat, vecrot); } - + projectFloatView(t, vecrot, cent); // no overflow in extreme cases - + glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); @@ -1007,16 +1003,16 @@ void drawHelpline(const struct bContext *C, TransInfo *t) glPushMatrix(); ED_region_pixelspace(t->ar); - + switch(t->helpline) { case HLP_SPRING: UI_ThemeColor(TH_WIRE); - + setlinestyle(3); - glBegin(GL_LINE_STRIP); - glVertex2sv(t->mval); - glVertex2fv(cent); + glBegin(GL_LINE_STRIP); + glVertex2sv(t->mval); + glVertex2fv(cent); glEnd(); glTranslatef(t->mval[0], t->mval[1], 0); @@ -1044,7 +1040,7 @@ void drawHelpline(const struct bContext *C, TransInfo *t) glTranslatef(t->mval[0], t->mval[1], 0); glLineWidth(3.0); - glBegin(GL_LINES); + glBegin(GL_LINES); drawArrow(UP, 5, 10, 5); drawArrow(DOWN, 5, 10, 5); glLineWidth(1.0); @@ -1057,27 +1053,27 @@ void drawHelpline(const struct bContext *C, TransInfo *t) float delta_angle = MIN2(15 / dist, M_PI/4); float spacing_angle = MIN2(5 / dist, M_PI/12); UI_ThemeColor(TH_WIRE); - + setlinestyle(3); - glBegin(GL_LINE_STRIP); - glVertex2sv(t->mval); - glVertex2fv(cent); + glBegin(GL_LINE_STRIP); + glVertex2sv(t->mval); + glVertex2fv(cent); glEnd(); - + glTranslatef(cent[0], cent[1], 0); - + setlinestyle(0); glLineWidth(3.0); drawArc(dist, angle - delta_angle, angle - spacing_angle, 10); drawArc(dist, angle + spacing_angle, angle + delta_angle, 10); - + glPushMatrix(); glTranslatef(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0); glRotatef(180 / M_PI * (angle - delta_angle), 0, 0, 1); - + drawArrowHead(DOWN, 5); - + glPopMatrix(); glTranslatef(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0); @@ -1092,32 +1088,32 @@ void drawHelpline(const struct bContext *C, TransInfo *t) { char col[3], col2[3]; UI_GetThemeColor3ubv(TH_GRID, col); - + glTranslatef(t->mval[0], t->mval[1], 0); - + glLineWidth(3.0); - + UI_make_axis_color(col, col2, 'x'); glColor3ubv((GLubyte *)col2); - + drawArrow(RIGHT, 5, 10, 5); drawArrow(LEFT, 5, 10, 5); - + UI_make_axis_color(col, col2, 'y'); glColor3ubv((GLubyte *)col2); - + drawArrow(UP, 5, 10, 5); drawArrow(DOWN, 5, 10, 5); glLineWidth(1.0); break; } } - + glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); - + glEnable(GL_DEPTH_TEST); } } @@ -1125,7 +1121,7 @@ void drawHelpline(const struct bContext *C, TransInfo *t) void drawTransform(const struct bContext *C, struct ARegion *ar, void *arg) { TransInfo *t = arg; - + drawConstraint(C, t); drawPropCircle(C, t); drawSnapping(C, t); @@ -1134,7 +1130,7 @@ void drawTransform(const struct bContext *C, struct ARegion *ar, void *arg) void saveTransform(bContext *C, TransInfo *t, wmOperator *op) { - Scene *sce = CTX_data_scene(C); + ToolSettings *ts = CTX_data_tool_settings(C); int constraint_axis[3] = {0, 0, 0}; int proportional = 0; @@ -1171,10 +1167,10 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) { RNA_boolean_set(op->ptr, "mirror", t->flag & T_MIRROR); } - + if (RNA_struct_find_property(op->ptr, "constraint_axis")) { - RNA_int_set(op->ptr, "constraint_orientation", t->current_orientation); + RNA_enum_set(op->ptr, "constraint_orientation", t->current_orientation); if (t->con.mode & CON_APPLY) { @@ -1195,13 +1191,13 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) // XXX If modal, save settings back in scene if (t->flag & T_MODAL) { - sce->prop_mode = t->prop_mode; - sce->proportional = proportional; + ts->prop_mode = t->prop_mode; + ts->proportional = proportional; if(t->spacetype == SPACE_VIEW3D) { View3D *v3d = t->view; - + v3d->twmode = t->current_orientation; } } @@ -1216,7 +1212,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->state = TRANS_RUNNING; t->options = options; - + t->mode = mode; if (!initTransInfo(C, t, op, event)) // internal data, mouse, vectors @@ -1228,7 +1224,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int { //calc_manipulator_stats(curarea); initTransformOrientation(C, t); - + t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST); } else if(t->spacetype == SPACE_IMAGE) { @@ -1251,10 +1247,10 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int /* EVIL2: we gave as argument also texture space context bit... was cleared */ /* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */ mode = t->mode; - + calculatePropRatio(t); calculateCenter(t); - + initMouseInput(t, &t->mouse, t->center2d, t->imval); switch (mode) { @@ -1318,13 +1314,13 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int case TFM_TIME_SCALE: initTimeScale(t); break; - case TFM_TIME_EXTEND: + case TFM_TIME_EXTEND: /* 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 + * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement) + * depending on which editor this was called from */ - if (t->spacetype == SPACE_IPO) + if ELEM(t->spacetype, SPACE_IPO, SPACE_NLA) initTranslation(t); else initTimeTranslate(t); @@ -1376,11 +1372,11 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int if (constraint_axis[2]) { t->con.mode |= CON_AXIS2; } - - setUserConstraint(t, t->con.mode, "%s"); + + setUserConstraint(t, t->con.mode, "%s"); } } - + return 1; } @@ -1399,7 +1395,7 @@ void transformApply(bContext *C, TransInfo *t) t->redraw = 0; } - /* If auto confirm is on, break after one pass */ + /* If auto confirm is on, break after one pass */ if (t->options & CTX_AUTOCONFIRM) { t->state = TRANS_CONFIRM; @@ -1416,7 +1412,7 @@ void transformApply(bContext *C, TransInfo *t) int transformEnd(bContext *C, TransInfo *t) { int exit_code = OPERATOR_RUNNING_MODAL; - + if (t->state != TRANS_RUNNING) { /* handle restoring objects */ @@ -1429,16 +1425,16 @@ int transformEnd(bContext *C, TransInfo *t) { exit_code = OPERATOR_FINISHED; } - + /* free data */ postTrans(t); - + /* aftertrans does insert keyframes, and clears base flags, doesnt read transdata */ special_aftertrans_update(t); - + /* send events out for redraws */ viewRedrawPost(t); - + /* Undo as last, certainly after special_trans_update! */ if(t->state == TRANS_CANCEL) { @@ -1452,7 +1448,7 @@ int transformEnd(bContext *C, TransInfo *t) viewRedrawForce(C, t); } - + return exit_code; } @@ -1460,13 +1456,15 @@ int transformEnd(bContext *C, TransInfo *t) void initManipulator(int mode) { + printf("init manipulator mode %d\n", mode); + #if 0 // TRANSFORM_FIX_ME Trans.state = TRANS_RUNNING; Trans.options = CTX_NONE; - + Trans.mode = mode; - + /* automatic switch to scaling bone envelopes */ if(mode==TFM_RESIZE && t->obedit && t->obedit->type==OB_ARMATURE) { bArmature *arm= t->obedit->data; @@ -1487,7 +1485,7 @@ void initManipulator(int mode) /* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */ /* EVIL2: we gave as argument also texture space context bit... was cleared */ mode = Trans.mode; - + calculatePropRatio(&Trans); calculateCenter(&Trans); @@ -1510,7 +1508,7 @@ void initManipulator(int mode) #endif } -void ManipulatorTransform() +void ManipulatorTransform() { #if 0 // TRANSFORM_FIX_ME int mouse_moved = 0; @@ -1523,9 +1521,9 @@ void ManipulatorTransform() Trans.redraw = 1; /* initial draw */ while (Trans.state == TRANS_RUNNING) { - + getmouseco_areawin(mval); - + if (mval[0] != pmval[0] || mval[1] != pmval[1]) { Trans.redraw = 1; } @@ -1539,7 +1537,7 @@ void ManipulatorTransform() } Trans.redraw = 0; } - + /* essential for idling subloop */ if( qtest()==0) PIL_sleep_ms(2); @@ -1564,9 +1562,9 @@ void ManipulatorTransform() Trans.flag |= T_SHIFT_MOD; Trans.redraw = 1; } - else Trans.flag &= ~T_SHIFT_MOD; + else Trans.flag &= ~T_SHIFT_MOD; break; - + case ESCKEY: case RIGHTMOUSE: Trans.state = TRANS_CANCEL; @@ -1624,23 +1622,23 @@ void ManipulatorTransform() Trans.redraw= 1; break; } - + // Numerical input events Trans.redraw |= handleNumInput(&(Trans.num), event); } } } - + if(Trans.state == TRANS_CANCEL) { restoreTransObjects(&Trans); } - + /* free data, reset vars */ postTrans(&Trans); - + /* aftertrans does insert ipos and action channels, and clears base flags */ special_aftertrans_update(&Trans); - + /* send events out for redraws */ viewRedrawPost(&Trans); @@ -1686,21 +1684,21 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu { /* quaternions get limited with euler... */ /* this function only does the delta rotation */ - + if(protectflag) { float eul[3], oldeul[3], quat1[4]; - + QUATCOPY(quat1, quat); QuatToEul(quat, eul); QuatToEul(oldquat, oldeul); - + if(protectflag & OB_LOCK_ROTX) eul[0]= oldeul[0]; if(protectflag & OB_LOCK_ROTY) eul[1]= oldeul[1]; if(protectflag & OB_LOCK_ROTZ) eul[2]= oldeul[2]; - + EulToQuat(eul, quat); /* quaternions flip w sign to accumulate rotations correctly */ if( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) { @@ -1717,8 +1715,8 @@ static void constraintTransLim(TransInfo *t, TransData *td) bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT); bConstraintOb cob; bConstraint *con; - - /* Make a temporary bConstraintOb for using these limit constraints + + /* Make a temporary bConstraintOb for using these limit constraints * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ @@ -1733,22 +1731,22 @@ static void constraintTransLim(TransInfo *t, TransData *td) else { VECCOPY(cob.matrix[3], td->loc); } - + /* Evaluate valid constraints */ for (con= td->con; con; con= con->next) { float tmat[4][4]; - + /* only consider constraint if enabled */ if (con->flag & CONSTRAINT_DISABLE) continue; if (con->enforce == 0.0f) continue; - + /* only use it if it's tagged for this purpose (and the right type) */ if (con->type == CONSTRAINT_TYPE_LOCLIMIT) { bLocLimitConstraint *data= con->data; - - if ((data->flag2 & LIMIT_TRANSFORM)==0) + + if ((data->flag2 & LIMIT_TRANSFORM)==0) continue; - + /* do space conversions */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1759,10 +1757,10 @@ static void constraintTransLim(TransInfo *t, TransData *td) /* skip... incompatable spacetype */ continue; } - + /* do constraint */ cti->evaluate_constraint(con, &cob, NULL); - + /* convert spaces again */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1771,7 +1769,7 @@ static void constraintTransLim(TransInfo *t, TransData *td) } } } - + /* copy results from cob->matrix */ if (td->tdi) { TransDataIpokey *tdi= td->tdi; @@ -1791,8 +1789,8 @@ static void constraintRotLim(TransInfo *t, TransData *td) bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT); bConstraintOb cob; bConstraint *con; - - /* Make a temporary bConstraintOb for using these limit constraints + + /* Make a temporary bConstraintOb for using these limit constraints * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ @@ -1808,11 +1806,11 @@ static void constraintRotLim(TransInfo *t, TransData *td) /* ipo-keys eulers */ TransDataIpokey *tdi= td->tdi; float eul[3]; - + eul[0]= tdi->rotx[0]; eul[1]= tdi->roty[0]; eul[2]= tdi->rotz[0]; - + EulToMat4(eul, cob.matrix); } else { @@ -1822,22 +1820,22 @@ static void constraintRotLim(TransInfo *t, TransData *td) else return; } - + /* Evaluate valid constraints */ for (con= td->con; con; con= con->next) { /* only consider constraint if enabled */ if (con->flag & CONSTRAINT_DISABLE) continue; if (con->enforce == 0.0f) continue; - + /* we're only interested in Limit-Rotation constraints */ if (con->type == CONSTRAINT_TYPE_ROTLIMIT) { bRotLimitConstraint *data= con->data; float tmat[4][4]; - + /* only use it if it's tagged for this purpose */ - if ((data->flag2 & LIMIT_TRANSFORM)==0) + if ((data->flag2 & LIMIT_TRANSFORM)==0) continue; - + /* do space conversions */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1848,10 +1846,10 @@ static void constraintRotLim(TransInfo *t, TransData *td) /* skip... incompatable spacetype */ continue; } - + /* do constraint */ cti->evaluate_constraint(con, &cob, NULL); - + /* convert spaces again */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1860,7 +1858,7 @@ static void constraintRotLim(TransInfo *t, TransData *td) } } } - + /* copy results from cob->matrix */ if (td->flag & TD_USEQUAT) { /* quats */ @@ -1870,9 +1868,9 @@ static void constraintRotLim(TransInfo *t, TransData *td) /* ipo-keys eulers */ TransDataIpokey *tdi= td->tdi; float eul[3]; - + Mat4ToEul(cob.matrix, eul); - + tdi->rotx[0]= eul[0]; tdi->roty[0]= eul[1]; tdi->rotz[0]= eul[2]; @@ -1890,8 +1888,8 @@ static void constraintSizeLim(TransInfo *t, TransData *td) bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT); bConstraintOb cob; bConstraint *con; - - /* Make a temporary bConstraintOb for using these limit constraints + + /* Make a temporary bConstraintOb for using these limit constraints * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ @@ -1899,12 +1897,12 @@ static void constraintSizeLim(TransInfo *t, TransData *td) if (td->tdi) { TransDataIpokey *tdi= td->tdi; float size[3]; - + size[0]= tdi->sizex[0]; size[1]= tdi->sizey[0]; size[2]= tdi->sizez[0]; SizeToMat4(size, cob.matrix); - } + } else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { /* scale val and reset size */ return; // TODO: fix this case @@ -1913,25 +1911,25 @@ static void constraintSizeLim(TransInfo *t, TransData *td) /* Reset val if SINGLESIZE but using a constraint */ if (td->flag & TD_SINGLESIZE) return; - + SizeToMat4(td->ext->size, cob.matrix); } - + /* Evaluate valid constraints */ for (con= td->con; con; con= con->next) { /* only consider constraint if enabled */ if (con->flag & CONSTRAINT_DISABLE) continue; if (con->enforce == 0.0f) continue; - + /* we're only interested in Limit-Scale constraints */ if (con->type == CONSTRAINT_TYPE_SIZELIMIT) { bSizeLimitConstraint *data= con->data; float tmat[4][4]; - + /* only use it if it's tagged for this purpose */ - if ((data->flag2 & LIMIT_TRANSFORM)==0) + if ((data->flag2 & LIMIT_TRANSFORM)==0) continue; - + /* do space conversions */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1942,10 +1940,10 @@ static void constraintSizeLim(TransInfo *t, TransData *td) /* skip... incompatable spacetype */ continue; } - + /* do constraint */ cti->evaluate_constraint(con, &cob, NULL); - + /* convert spaces again */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1954,18 +1952,18 @@ static void constraintSizeLim(TransInfo *t, TransData *td) } } } - + /* copy results from cob->matrix */ if (td->tdi) { TransDataIpokey *tdi= td->tdi; float size[3]; - + Mat4ToSize(cob.matrix, size); - + tdi->sizex[0]= size[0]; tdi->sizey[0]= size[1]; tdi->sizez[0]= size[2]; - } + } else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { /* scale val and reset size */ return; // TODO: fix this case @@ -1974,7 +1972,7 @@ static void constraintSizeLim(TransInfo *t, TransData *td) /* Reset val if SINGLESIZE but using a constraint */ if (td->flag & TD_SINGLESIZE) return; - + Mat4ToSize(cob.matrix, td->ext->size); } } @@ -1982,15 +1980,15 @@ static void constraintSizeLim(TransInfo *t, TransData *td) /* ************************** WARP *************************** */ -void initWarp(TransInfo *t) +void initWarp(TransInfo *t) { float max[3], min[3]; int i; - + t->mode = TFM_WARP; t->transform = Warp; t->handleEvent = handleEventWarp; - + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO); t->idx_max = 0; @@ -1998,9 +1996,9 @@ void initWarp(TransInfo *t) t->snap[0] = 0.0f; t->snap[1] = 5.0f; t->snap[2] = 1.0f; - + t->flag |= T_NO_CONSTRAINT; - + /* we need min/max in view space */ for(i = 0; i < t->total; i++) { float center[3]; @@ -2015,11 +2013,11 @@ void initWarp(TransInfo *t) VECCOPY(min, center); } } - + t->center[0]= (min[0]+max[0])/2.0f; t->center[1]= (min[1]+max[1])/2.0f; t->center[2]= (min[2]+max[2])/2.0f; - + if (max[0] == min[0]) max[0] += 0.1; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */ t->val= (max[0]-min[0])/2.0f; /* t->val is X dimension projected boundbox */ } @@ -2027,7 +2025,7 @@ void initWarp(TransInfo *t) int handleEventWarp(TransInfo *t, wmEvent *event) { int status = 0; - + if (event->type == MIDDLEMOUSE && event->val) { // Use customData pointer to signal warp direction @@ -2035,10 +2033,10 @@ int handleEventWarp(TransInfo *t, wmEvent *event) t->customData = (void*)1; else t->customData = 0; - + status = 1; } - + return status; } @@ -2048,7 +2046,7 @@ int Warp(TransInfo *t, short mval[2]) float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3]; int i; char str[50]; - + curs= give_cursor(t->scene, t->view); /* * gcursor is the one used for helpline. @@ -2061,7 +2059,7 @@ int Warp(TransInfo *t, short mval[2]) * into account if in Edit mode. */ VECCOPY(cursor, curs); - VECCOPY(gcursor, cursor); + VECCOPY(gcursor, cursor); if (t->flag & T_EDIT) { VecSubf(cursor, cursor, t->obedit->obmat[3]); VecSubf(gcursor, gcursor, t->obedit->obmat[3]); @@ -2072,7 +2070,7 @@ int Warp(TransInfo *t, short mval[2]) /* amount of degrees for warp */ circumfac = 360.0f * t->values[0]; - + if (t->customData) /* non-null value indicates reversed input */ { circumfac *= -1; @@ -2080,22 +2078,22 @@ int Warp(TransInfo *t, short mval[2]) snapGrid(t, &circumfac); applyNumInput(&t->num, &circumfac); - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); - + sprintf(str, "Warp: %s", c); } else { /* default header print */ sprintf(str, "Warp: %.3f", circumfac); } - + circumfac*= (float)(-M_PI/360.0); - + for(i = 0; i < t->total; i++, td++) { float loc[3]; if (td->flag & TD_NOACTION) @@ -2103,65 +2101,65 @@ int Warp(TransInfo *t, short mval[2]) if (td->flag & TD_SKIP) continue; - + /* translate point to center, rotate in such a way that outline==distance */ VECCOPY(vec, td->iloc); Mat3MulVecfl(td->mtx, vec); Mat4MulVecfl(t->viewmat, vec); VecSubf(vec, vec, t->viewmat[3]); - + dist= vec[0]-cursor[0]; - + /* t->val is X dimension projected boundbox */ - phi0= (circumfac*dist/t->val); - + phi0= (circumfac*dist/t->val); + vec[1]= (vec[1]-cursor[1]); - + co= (float)cos(phi0); si= (float)sin(phi0); loc[0]= -si*vec[1]+cursor[0]; loc[1]= co*vec[1]+cursor[1]; loc[2]= vec[2]; - + Mat4MulVecfl(t->viewinv, loc); VecSubf(loc, loc, t->viewinv[3]); Mat3MulVecfl(td->smtx, loc); - + VecSubf(loc, loc, td->iloc); VecMulf(loc, td->factor); VecAddf(td->loc, td->iloc, loc); } recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } /* ************************** SHEAR *************************** */ -void initShear(TransInfo *t) +void initShear(TransInfo *t) { t->mode = TFM_SHEAR; t->transform = Shear; t->handleEvent = handleEventShear; - + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->flag |= T_NO_CONSTRAINT; } int handleEventShear(TransInfo *t, wmEvent *event) { int status = 0; - + if (event->type == MIDDLEMOUSE && event->val) { // Use customData pointer to signal Shear direction @@ -2175,15 +2173,15 @@ int handleEventShear(TransInfo *t, wmEvent *event) initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); t->customData = 0; } - + status = 1; } - + return status; } -int Shear(TransInfo *t, short mval[2]) +int Shear(TransInfo *t, short mval[2]) { TransData *td = t->data; float vec[3]; @@ -2213,18 +2211,18 @@ int Shear(TransInfo *t, short mval[2]) /* default header print */ sprintf(str, "Shear: %.3f %s", value, t->proptext); } - + Mat3One(smat); - + // Custom data signals shear direction if (t->customData == 0) smat[1][0] = value; else smat[0][1] = value; - + Mat3MulMat3(tmat, smat, persmat); Mat3MulMat3(totmat, persinv, tmat); - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -2261,13 +2259,13 @@ int Shear(TransInfo *t, short mval[2]) /* ************************** RESIZE *************************** */ -void initResize(TransInfo *t) +void initResize(TransInfo *t) { t->mode = TFM_RESIZE; t->transform = Resize; - + initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP); - + t->flag |= T_NULL_ONE; t->num.flag |= NUM_NULL_ONE; t->num.flag |= NUM_AFFECT_ALL; @@ -2275,7 +2273,7 @@ void initResize(TransInfo *t) t->flag |= T_NO_ZERO; t->num.flag |= NUM_NO_ZERO; } - + t->idx_max = 2; t->num.idx_max = 2; t->snap[0] = 0.0f; @@ -2321,18 +2319,18 @@ static void headerResize(TransInfo *t, float vec[3], char *str) { static void TransMat3ToSize( float mat[][3], float smat[][3], float *size) { float vec[3]; - + VecCopyf(vec, mat[0]); size[0]= Normalize(vec); VecCopyf(vec, mat[1]); size[1]= Normalize(vec); VecCopyf(vec, mat[2]); size[2]= Normalize(vec); - + /* first tried with dotproduct... but the sign flip is crucial */ - if( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0]; - if( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1]; - if( VECSIGNFLIP(mat[2], smat[2]) ) size[2]= -size[2]; + if( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0]; + if( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1]; + if( VECSIGNFLIP(mat[2], smat[2]) ) size[2]= -size[2]; } @@ -2358,8 +2356,8 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { VECCOPY(center, td->center); } else if (t->flag & T_EDIT) { - - if(t->around==V3D_LOCAL && (t->scene->selectmode & SCE_SELECT_FACE)) { + + if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { VECCOPY(center, td->center); } else { @@ -2376,7 +2374,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { if (td->ext) { float fsize[3]; - + if (t->flag & (T_OBJECT|T_TEXTURE|T_POSE)) { float obsizemat[3][3]; // Reorient the size mat to fit the oriented object. @@ -2388,28 +2386,28 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { else { Mat3ToSize(tmat, fsize); } - + protectedSizeBits(td->protectflag, fsize); - + if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't resize objects itself /* handle ipokeys? */ if(td->tdi) { TransDataIpokey *tdi= td->tdi; /* calculate delta size (equal for size and dsize) */ - + vec[0]= (tdi->oldsize[0])*(fsize[0] -1.0f) * td->factor; vec[1]= (tdi->oldsize[1])*(fsize[1] -1.0f) * td->factor; vec[2]= (tdi->oldsize[2])*(fsize[2] -1.0f) * td->factor; - + add_tdi_poin(tdi->sizex, tdi->oldsize, vec[0]); add_tdi_poin(tdi->sizey, tdi->oldsize+1, vec[1]); add_tdi_poin(tdi->sizez, tdi->oldsize+2, vec[2]); - - } + + } else if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){ /* scale val and reset size */ *td->val = td->ival * fsize[0] * td->factor; - + td->ext->size[0] = td->ext->isize[0]; td->ext->size[1] = td->ext->isize[1]; td->ext->size[2] = td->ext->isize[2]; @@ -2418,16 +2416,16 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { /* Reset val if SINGLESIZE but using a constraint */ if (td->flag & TD_SINGLESIZE) *td->val = td->ival; - + td->ext->size[0] = td->ext->isize[0] * (fsize[0]) * td->factor; td->ext->size[1] = td->ext->isize[1] * (fsize[1]) * td->factor; td->ext->size[2] = td->ext->isize[2] * (fsize[2]) * td->factor; } } - + constraintSizeLim(t, td); } - + /* For individual element center, Editmode need to use iloc */ if (t->flag & T_POINTS) VecSubf(vec, td->iloc, center); @@ -2457,11 +2455,11 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]); } else VecAddf(td->loc, td->iloc, vec); - + constraintTransLim(t, td); } -int Resize(TransInfo *t, short mval[2]) +int Resize(TransInfo *t, short mval[2]) { TransData *td; float size[3], mat[3][3]; @@ -2478,7 +2476,7 @@ int Resize(TransInfo *t, short mval[2]) { ratio = t->values[0]; } - + size[0] = size[1] = size[2] = ratio; snapGrid(t, size); @@ -2504,7 +2502,7 @@ int Resize(TransInfo *t, short mval[2]) } Mat3CpyMat3(t->mat, mat); // used in manipulator - + headerResize(t, size, str); for(i = 0, td=t->data; i < t->total; i++, td++) { @@ -2513,7 +2511,7 @@ int Resize(TransInfo *t, short mval[2]) if (td->flag & TD_SKIP) continue; - + ElementResize(t, td, mat); } @@ -2537,14 +2535,14 @@ int Resize(TransInfo *t, short mval[2]) /* ************************** TOSPHERE *************************** */ -void initToSphere(TransInfo *t) +void initToSphere(TransInfo *t) { TransData *td = t->data; int i; t->mode = TFM_TOSPHERE; t->transform = ToSphere; - + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO); t->idx_max = 0; @@ -2552,10 +2550,10 @@ void initToSphere(TransInfo *t) t->snap[0] = 0.0f; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->num.flag |= NUM_NULL_ONE | NUM_NO_NEGATIVE; t->flag |= T_NO_CONSTRAINT; - + // Calculate average radius for(i = 0 ; i < t->total; i++, td++) { t->val += VecLenf(t->center, td->iloc); @@ -2564,7 +2562,7 @@ void initToSphere(TransInfo *t) t->val /= (float)t->total; } -int ToSphere(TransInfo *t, short mval[2]) +int ToSphere(TransInfo *t, short mval[2]) { float vec[3]; float ratio, radius; @@ -2595,8 +2593,8 @@ int ToSphere(TransInfo *t, short mval[2]) /* default header print */ sprintf(str, "To Sphere: %.4f %s", ratio, t->proptext); } - - + + for(i = 0 ; i < t->total; i++, td++) { float tratio; if (td->flag & TD_NOACTION) @@ -2615,7 +2613,7 @@ int ToSphere(TransInfo *t, short mval[2]) VecAddf(td->loc, t->center, vec); } - + recalcData(t); @@ -2627,23 +2625,23 @@ int ToSphere(TransInfo *t, short mval[2]) /* ************************** ROTATION *************************** */ -void initRotation(TransInfo *t) +void initRotation(TransInfo *t) { t->mode = TFM_ROTATION; t->transform = Rotation; - + initMouseInputMode(t, &t->mouse, INPUT_ANGLE); - + t->ndof.axis = 16; /* Scale down and flip input for rotation */ t->ndof.factor[0] = -0.2f; - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = (float)((5.0/180)*M_PI); t->snap[2] = t->snap[1] * 0.2f; - + if (t->flag & T_2D_EDIT) t->flag |= T_NO_CONSTRAINT; } @@ -2652,7 +2650,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short float vec[3], totmat[3][3], smat[3][3]; float eul[3], fmat[3][3], quat[4]; float *center = t->center; - + /* local constraint shouldn't alter center */ if (around == V3D_LOCAL) { if (t->flag & (T_OBJECT|T_POSE)) { @@ -2660,19 +2658,19 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short } else { /* !TODO! Make this if not rely on G */ - if(around==V3D_LOCAL && (t->scene->selectmode & SCE_SELECT_FACE)) { + if(around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { center = td->center; } } } - + if (t->flag & T_POINTS) { Mat3MulMat3(totmat, mat, td->mtx); Mat3MulMat3(smat, td->smtx, totmat); - + VecSubf(vec, td->iloc, center); Mat3MulVecfl(smat, vec); - + VecAddf(td->loc, vec, center); VecSubf(vec,td->loc,td->iloc); @@ -2682,10 +2680,10 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short if(td->flag & TD_USEQUAT) { Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); Mat3ToQuat(fmat, quat); // Actual transform - + if(td->ext->quat){ QuatMul(td->ext->quat, quat, td->ext->iquat); - + /* is there a reason not to have this here? -jahka */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } @@ -2693,11 +2691,11 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short } /** * HACK WARNING - * + * * This is some VERY ugly special case to deal with pose mode. - * + * * The problem is that mtx and smtx include each bone orientation. - * + * * That is needed to rotate each bone properly, HOWEVER, to calculate * the translation component, we only need the actual armature object's * matrix (and inverse). That is not all though. Once the proper translation @@ -2706,65 +2704,65 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short else if (t->flag & T_POSE) { float pmtx[3][3], imtx[3][3]; - // Extract and invert armature object matrix + // Extract and invert armature object matrix Mat3CpyMat4(pmtx, t->poseobj->obmat); Mat3Inv(imtx, pmtx); - + if ((td->flag & TD_NO_LOC) == 0) { VecSubf(vec, td->center, center); - + Mat3MulVecfl(pmtx, vec); // To Global space Mat3MulVecfl(mat, vec); // Applying rotation Mat3MulVecfl(imtx, vec); // To Local space - + VecAddf(vec, vec, center); /* vec now is the location where the object has to be */ - + VecSubf(vec, vec, td->center); // Translation needed from the initial location - + Mat3MulVecfl(pmtx, vec); // To Global space Mat3MulVecfl(td->smtx, vec);// To Pose space - + protectedTransBits(td->protectflag, vec); - + VecAddf(td->loc, td->iloc, vec); - + constraintTransLim(t, td); } - + /* rotation */ if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself /* euler or quaternion? */ if (td->flag & TD_USEQUAT) { Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); - + Mat3ToQuat(fmat, quat); // Actual transform - + QuatMul(td->ext->quat, quat, td->ext->iquat); /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } else { float eulmat[3][3]; - + Mat3MulMat3(totmat, mat, td->mtx); Mat3MulMat3(smat, td->smtx, totmat); - + /* calculate the total rotatation in eulers */ VECCOPY(eul, td->ext->irot); EulToMat3(eul, eulmat); - + /* mat = transform, obmat = bone rotation */ Mat3MulMat3(fmat, smat, eulmat); - + Mat3ToCompatibleEul(fmat, eul, td->ext->rot); - + /* and apply (to end result only) */ protectedRotateBits(td->protectflag, eul, td->ext->irot); VECCOPY(td->ext->rot, eul); } - + constraintRotLim(t, td); } } @@ -2778,9 +2776,9 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* vec now is the location where the object has to be */ VecSubf(vec, vec, td->center); Mat3MulVecfl(td->smtx, vec); - + protectedTransBits(td->protectflag, vec); - + if(td->tdi) { TransDataIpokey *tdi= td->tdi; add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]); @@ -2789,8 +2787,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short } else VecAddf(td->loc, td->iloc, vec); } - - + + constraintTransLim(t, td); /* rotation */ @@ -2799,34 +2797,34 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short if (td->flag & TD_USEQUAT) { Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); Mat3ToQuat(fmat, quat); // Actual transform - + QuatMul(td->ext->quat, quat, td->ext->iquat); /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } else { float obmat[3][3]; - + /* are there ipo keys? */ if(td->tdi) { TransDataIpokey *tdi= td->tdi; float current_rot[3]; float rot[3]; - + /* current IPO value for compatible euler */ current_rot[0] = (tdi->rotx) ? tdi->rotx[0] : 0.0f; current_rot[1] = (tdi->roty) ? tdi->roty[0] : 0.0f; current_rot[2] = (tdi->rotz) ? tdi->rotz[0] : 0.0f; VecMulf(current_rot, (float)(M_PI_2 / 9.0)); - + /* calculate the total rotatation in eulers */ VecAddf(eul, td->ext->irot, td->ext->drot); EulToMat3(eul, obmat); /* mat = transform, obmat = object rotation */ Mat3MulMat3(fmat, mat, obmat); - + Mat3ToCompatibleEul(fmat, eul, current_rot); - + /* correct back for delta rot */ if(tdi->flag & TOB_IPODROT) { VecSubf(rot, eul, td->ext->irot); @@ -2834,12 +2832,12 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short else { VecSubf(rot, eul, td->ext->drot); } - + VecMulf(rot, (float)(9.0/M_PI_2)); VecSubf(rot, rot, tdi->oldrot); - + protectedRotateBits(td->protectflag, rot, tdi->oldrot); - + add_tdi_poin(tdi->rotx, tdi->oldrot, rot[0]); add_tdi_poin(tdi->roty, tdi->oldrot+1, rot[1]); add_tdi_poin(tdi->rotz, tdi->oldrot+2, rot[2]); @@ -2847,37 +2845,37 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short else { Mat3MulMat3(totmat, mat, td->mtx); Mat3MulMat3(smat, td->smtx, totmat); - + /* calculate the total rotatation in eulers */ VecAddf(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */ EulToMat3(eul, obmat); /* mat = transform, obmat = object rotation */ Mat3MulMat3(fmat, smat, obmat); - + Mat3ToCompatibleEul(fmat, eul, td->ext->rot); - + /* correct back for delta rot */ VecSubf(eul, eul, td->ext->drot); - + /* and apply */ protectedRotateBits(td->protectflag, eul, td->ext->irot); VECCOPY(td->ext->rot, eul); } } - + constraintRotLim(t, td); } } } -static void applyRotation(TransInfo *t, float angle, float axis[3]) +static void applyRotation(TransInfo *t, float angle, float axis[3]) { TransData *td = t->data; float mat[3][3]; int i; VecRotToMat3(axis, angle, mat); - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) @@ -2885,7 +2883,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) if (td->flag & TD_SKIP) continue; - + if (t->con.applyRot) { t->con.applyRot(t, td, axis, NULL); VecRotToMat3(axis, angle * td->factor, mat); @@ -2898,7 +2896,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) } } -int Rotation(TransInfo *t, short mval[2]) +int Rotation(TransInfo *t, short mval[2]) { char str[64]; @@ -2914,13 +2912,13 @@ int Rotation(TransInfo *t, short mval[2]) final = t->values[0]; applyNDofInput(&t->ndof, &final); - + snapGrid(t, &final); if (t->con.applyRot) { t->con.applyRot(t, NULL, axis, &final); } - + applySnapping(t, &final); if (hasNumInput(&t->num)) { @@ -2935,7 +2933,7 @@ int Rotation(TransInfo *t, short mval[2]) /* Clamp between -180 and 180 */ while (final >= 180.0) final -= 360.0; - + while (final <= -180.0) final += 360.0; @@ -2950,9 +2948,9 @@ int Rotation(TransInfo *t, short mval[2]) // TRANSFORM_FIX_ME // t->values[0] = final; // used in manipulator // Mat3CpyMat3(t->mat, mat); // used in manipulator - + applyRotation(t, final, axis); - + recalcData(t); ED_area_headerprint(t->sa, str); @@ -2963,13 +2961,13 @@ int Rotation(TransInfo *t, short mval[2]) /* ************************** TRACKBALL *************************** */ -void initTrackball(TransInfo *t) +void initTrackball(TransInfo *t) { t->mode = TFM_TRACKBALL; t->transform = Trackball; - + initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL); - + t->ndof.axis = 40; /* Scale down input for rotation */ t->ndof.factor[0] = 0.2f; @@ -2980,7 +2978,7 @@ void initTrackball(TransInfo *t) t->snap[0] = 0.0f; t->snap[1] = (float)((5.0/180)*M_PI); t->snap[2] = t->snap[1] * 0.2f; - + t->flag |= T_NO_CONSTRAINT; } @@ -2992,7 +2990,7 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a VecRotToMat3(axis1, angles[0], smat); VecRotToMat3(axis2, angles[1], totmat); - + Mat3MulMat3(mat, smat, totmat); for(i = 0 ; i < t->total; i++, td++) { @@ -3001,46 +2999,46 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a if (td->flag & TD_SKIP) continue; - + if (t->flag & T_PROP_EDIT) { VecRotToMat3(axis1, td->factor * angles[0], smat); VecRotToMat3(axis2, td->factor * angles[1], totmat); - + Mat3MulMat3(mat, smat, totmat); } - + ElementRotation(t, td, mat, t->around); } } -int Trackball(TransInfo *t, short mval[2]) +int Trackball(TransInfo *t, short mval[2]) { char str[128]; float axis1[3], axis2[3]; float mat[3][3], totmat[3][3], smat[3][3]; float phi[2]; - + VECCOPY(axis1, t->persinv[0]); VECCOPY(axis2, t->persinv[1]); Normalize(axis1); Normalize(axis2); - + phi[0] = t->values[0]; phi[1] = t->values[1]; - + applyNDofInput(&t->ndof, phi); - + snapGrid(t, phi); - + if (hasNumInput(&t->num)) { char c[40]; - + applyNumInput(&t->num, phi); - + outputNumInput(&(t->num), c); - + sprintf(str, "Trackball: %s %s %s", &c[0], &c[20], t->proptext); - + phi[0] *= (float)(M_PI / 180.0); phi[1] *= (float)(M_PI / 180.0); } @@ -3050,34 +3048,34 @@ int Trackball(TransInfo *t, short mval[2]) VecRotToMat3(axis1, phi[0], smat); VecRotToMat3(axis2, phi[1], totmat); - + Mat3MulMat3(mat, smat, totmat); - + // TRANSFORM_FIX_ME //Mat3CpyMat3(t->mat, mat); // used in manipulator - + applyTrackball(t, axis1, axis2, phi); - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } /* ************************** TRANSLATION *************************** */ - -void initTranslation(TransInfo *t) + +void initTranslation(TransInfo *t) { t->mode = TFM_TRANSLATION; t->transform = Translation; - + initMouseInputMode(t, &t->mouse, INPUT_VECTOR); t->idx_max = (t->flag & T_2D_EDIT)? 1: 2; t->num.flag = 0; t->num.idx_max = t->idx_max; - + t->ndof.axis = (t->flag & T_2D_EDIT)? 1|2: 1|2|4; if(t->spacetype == SPACE_VIEW3D) { @@ -3103,7 +3101,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) { char distvec[20]; char autoik[20]; float dist; - + if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); dist = VecLength(t->num.val); @@ -3124,10 +3122,10 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) { sprintf(distvec, "%.4e", dist); else sprintf(distvec, "%.4f", dist); - + if(t->flag & T_AUTOIK) { - short chainlen= t->scene->toolsettings->autoik_chainlen; - + short chainlen= t->settings->autoik_chainlen; + if(chainlen) sprintf(autoik, "AutoIK-Len: %d", chainlen); else @@ -3164,10 +3162,10 @@ static void applyTranslation(TransInfo *t, float vec[3]) { for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + /* handle snapping rotation before doing the translation */ if (usingSnappingNormal(t)) { @@ -3178,22 +3176,22 @@ static void applyTranslation(TransInfo *t, float vec[3]) { float quat[4]; float mat[3][3]; float angle; - + Crossf(axis, original_normal, t->tsnap.snapNormal); angle = saacos(Inpf(original_normal, t->tsnap.snapNormal)); - + AxisAngleToQuat(quat, axis, angle); - + QuatToMat3(quat, mat); - + ElementRotation(t, td, mat, V3D_LOCAL); } else { float mat[3][3]; - + Mat3One(mat); - + ElementRotation(t, td, mat, V3D_LOCAL); } } @@ -3205,12 +3203,12 @@ static void applyTranslation(TransInfo *t, float vec[3]) { else { VECCOPY(tvec, vec); } - + Mat3MulVecfl(td->smtx, tvec); VecMulf(tvec, td->factor); - + protectedTransBits(td->protectflag, tvec); - + /* transdata ipokey */ if(td->tdi) { TransDataIpokey *tdi= td->tdi; @@ -3219,17 +3217,17 @@ static void applyTranslation(TransInfo *t, float vec[3]) { add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]); } else VecAddf(td->loc, td->iloc, tvec); - + constraintTransLim(t, td); } } /* uses t->vec to store actual translation in */ -int Translation(TransInfo *t, short mval[2]) +int Translation(TransInfo *t, short mval[2]) { float tvec[3]; char str[250]; - + if (t->con.mode & CON_APPLY) { float pvec[3] = {0.0f, 0.0f, 0.0f}; applySnapping(t, t->values); @@ -3245,11 +3243,11 @@ int Translation(TransInfo *t, short mval[2]) { removeAspectRatio(t, t->values); } - + applySnapping(t, t->values); headerTranslation(t, t->values, str); } - + applyTranslation(t, t->values); /* evil hack - redo translation if clipping needed */ @@ -3265,7 +3263,7 @@ int Translation(TransInfo *t, short mval[2]) /* ************************** SHRINK/FATTEN *************************** */ -void initShrinkFatten(TransInfo *t) +void initShrinkFatten(TransInfo *t) { // If not in mesh edit mode, fallback to Resize if (t->obedit==NULL || t->obedit->type != OB_MESH) { @@ -3274,22 +3272,22 @@ void initShrinkFatten(TransInfo *t) else { t->mode = TFM_SHRINKFATTEN; t->transform = ShrinkFatten; - + initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 1.0f; t->snap[2] = t->snap[1] * 0.1f; - + t->flag |= T_NO_CONSTRAINT; } } -int ShrinkFatten(TransInfo *t, short mval[2]) +int ShrinkFatten(TransInfo *t, short mval[2]) { float vec[3]; float distance; @@ -3315,8 +3313,8 @@ int ShrinkFatten(TransInfo *t, short mval[2]) /* default header print */ sprintf(str, "Shrink/Fatten: %.4f %s", distance, t->proptext); } - - + + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3340,11 +3338,11 @@ int ShrinkFatten(TransInfo *t, short mval[2]) /* ************************** TILT *************************** */ -void initTilt(TransInfo *t) +void initTilt(TransInfo *t) { t->mode = TFM_TILT; t->transform = Tilt; - + initMouseInputMode(t, &t->mouse, INPUT_ANGLE); t->ndof.axis = 16; @@ -3356,13 +3354,13 @@ void initTilt(TransInfo *t) t->snap[0] = 0.0f; t->snap[1] = (float)((5.0/180)*M_PI); t->snap[2] = t->snap[1] * 0.2f; - + t->flag |= T_NO_CONSTRAINT; } -int Tilt(TransInfo *t, short mval[2]) +int Tilt(TransInfo *t, short mval[2]) { TransData *td = t->data; int i; @@ -3371,7 +3369,7 @@ int Tilt(TransInfo *t, short mval[2]) float final; final = t->values[0]; - + applyNDofInput(&t->ndof, &final); snapGrid(t, &final); @@ -3417,72 +3415,72 @@ void initCurveShrinkFatten(TransInfo *t) { t->mode = TFM_CURVE_SHRINKFATTEN; t->transform = CurveShrinkFatten; - + initMouseInputMode(t, &t->mouse, INPUT_SPRING); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->flag |= T_NO_CONSTRAINT; } -int CurveShrinkFatten(TransInfo *t, short mval[2]) +int CurveShrinkFatten(TransInfo *t, short mval[2]) { TransData *td = t->data; float ratio; int i; char str[50]; - + ratio = t->values[0]; - + snapGrid(t, &ratio); - + applyNumInput(&t->num, &ratio); - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); sprintf(str, "Shrink/Fatten: %s", c); } else { sprintf(str, "Shrink/Fatten: %3f", ratio); } - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; if (td->flag & TD_SKIP) continue; - + if(td->val) { //*td->val= ratio; *td->val= td->ival*ratio; if (*td->val <= 0.0f) *td->val = 0.0001f; } } - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } /* ************************** PUSH/PULL *************************** */ -void initPushPull(TransInfo *t) +void initPushPull(TransInfo *t) { t->mode = TFM_PUSHPULL; t->transform = PushPull; - + initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); - + t->ndof.axis = 4; /* Flip direction */ t->ndof.factor[0] = -1.0f; @@ -3495,7 +3493,7 @@ void initPushPull(TransInfo *t) } -int PushPull(TransInfo *t, short mval[2]) +int PushPull(TransInfo *t, short mval[2]) { float vec[3], axis[3]; float distance; @@ -3504,7 +3502,7 @@ int PushPull(TransInfo *t, short mval[2]) TransData *td = t->data; distance = t->values[0]; - + applyNDofInput(&t->ndof, &distance); snapGrid(t, &distance); @@ -3523,11 +3521,11 @@ int PushPull(TransInfo *t, short mval[2]) /* default header print */ sprintf(str, "Push/Pull: %.4f%s %s", distance, t->con.text, t->proptext); } - + if (t->con.applyRot && t->con.mode & CON_APPLY) { t->con.applyRot(t, NULL, axis, NULL); } - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3563,11 +3561,11 @@ int PushPull(TransInfo *t, short mval[2]) /* ************************** BEVEL **************************** */ -void initBevel(TransInfo *t) +void initBevel(TransInfo *t) { t->transform = Bevel; t->handleEvent = handleEventBevel; - + initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); t->mode = TFM_BEVEL; @@ -3636,7 +3634,7 @@ int Bevel(TransInfo *t, short mval[2]) mode = (G.editBMesh->options & BME_BEVEL_VERT) ? "verts only" : "normal"; distance = t->values[0] / 4; /* 4 just seemed a nice value to me, nothing special */ - + distance = fabs(distance); snapGrid(t, &distance); @@ -3655,7 +3653,7 @@ int Bevel(TransInfo *t, short mval[2]) /* default header print */ sprintf(str, "Bevel - Dist: %.4f, Mode: %s (MMB to toggle))", distance, mode); } - + if (distance < 0) distance = -distance; for(i = 0 ; i < t->total; i++, td++) { if (td->axismtx[1][0] > 0 && distance > td->axismtx[1][0]) { @@ -3676,23 +3674,23 @@ int Bevel(TransInfo *t, short mval[2]) /* ************************** BEVEL WEIGHT *************************** */ -void initBevelWeight(TransInfo *t) +void initBevelWeight(TransInfo *t) { t->mode = TFM_BWEIGHT; t->transform = BevelWeight; - + initMouseInputMode(t, &t->mouse, INPUT_SPRING); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->flag |= T_NO_CONSTRAINT; } -int BevelWeight(TransInfo *t, short mval[2]) +int BevelWeight(TransInfo *t, short mval[2]) { TransData *td = t->data; float weight; @@ -3726,7 +3724,7 @@ int BevelWeight(TransInfo *t, short mval[2]) else sprintf(str, "Bevel Weight: %.3f %s", weight, t->proptext); } - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3747,23 +3745,23 @@ int BevelWeight(TransInfo *t, short mval[2]) /* ************************** CREASE *************************** */ -void initCrease(TransInfo *t) +void initCrease(TransInfo *t) { t->mode = TFM_CREASE; t->transform = Crease; - + initMouseInputMode(t, &t->mouse, INPUT_SPRING); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->flag |= T_NO_CONSTRAINT; } -int Crease(TransInfo *t, short mval[2]) +int Crease(TransInfo *t, short mval[2]) { TransData *td = t->data; float crease; @@ -3797,7 +3795,7 @@ int Crease(TransInfo *t, short mval[2]) else sprintf(str, "Crease: %.3f %s", crease, t->proptext); } - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -3825,9 +3823,9 @@ void initBoneSize(TransInfo *t) { t->mode = TFM_BONESIZE; t->transform = BoneSize; - + initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP); - + t->idx_max = 2; t->num.idx_max = 2; t->num.flag |= NUM_NULL_ONE; @@ -3851,7 +3849,7 @@ static void headerBoneSize(TransInfo *t, float vec[3], char *str) { if (t->con.mode & CON_APPLY) { if (t->num.idx_max == 0) sprintf(str, "ScaleB: %s%s %s", &tvec[0], t->con.text, t->proptext); - else + else sprintf(str, "ScaleB: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); } else { @@ -3859,18 +3857,18 @@ static void headerBoneSize(TransInfo *t, float vec[3], char *str) { } } -static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3]) +static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3]) { float tmat[3][3], smat[3][3], oldy; float sizemat[3][3]; - + Mat3MulMat3(smat, mat, td->mtx); Mat3MulMat3(tmat, td->smtx, smat); - + if (t->con.applySize) { t->con.applySize(t, td, tmat); } - + /* we've tucked the scale in loc */ oldy= td->iloc[1]; SizeToMat3(td->iloc, sizemat); @@ -3879,14 +3877,14 @@ static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3]) td->loc[1]= oldy; } -int BoneSize(TransInfo *t, short mval[2]) +int BoneSize(TransInfo *t, short mval[2]) { TransData *td = t->data; float size[3], mat[3][3]; float ratio; int i; char str[60]; - + // TRANSFORM_FIX_ME MOVE TO MOUSE INPUT /* for manipulator, center handle, the scaling can't be done relative to center */ if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) @@ -3897,40 +3895,40 @@ int BoneSize(TransInfo *t, short mval[2]) { ratio = t->values[0]; } - + size[0] = size[1] = size[2] = ratio; - + snapGrid(t, size); - + if (hasNumInput(&t->num)) { applyNumInput(&t->num, size); constraintNumInput(t, size); } - + SizeToMat3(size, mat); - + if (t->con.applySize) { t->con.applySize(t, NULL, mat); } - + Mat3CpyMat3(t->mat, mat); // used in manipulator - + headerBoneSize(t, size, str); - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; if (td->flag & TD_SKIP) continue; - + ElementBoneSize(t, td, mat); } - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -3941,9 +3939,9 @@ void initBoneEnvelope(TransInfo *t) { t->mode = TFM_BONE_ENVELOPE; t->transform = BoneEnvelope; - + initMouseInputMode(t, &t->mouse, INPUT_SPRING); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; @@ -3953,37 +3951,37 @@ void initBoneEnvelope(TransInfo *t) t->flag |= T_NO_CONSTRAINT; } -int BoneEnvelope(TransInfo *t, short mval[2]) +int BoneEnvelope(TransInfo *t, short mval[2]) { TransData *td = t->data; float ratio; int i; char str[50]; - + ratio = t->values[0]; - + snapGrid(t, &ratio); - + applyNumInput(&t->num, &ratio); - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); sprintf(str, "Envelope: %s", c); } else { sprintf(str, "Envelope: %3f", ratio); } - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; if (td->flag & TD_SKIP) continue; - + if (td->val) { /* if the old/original value was 0.0f, then just use ratio */ if (td->ival) @@ -3992,11 +3990,11 @@ int BoneEnvelope(TransInfo *t, short mval[2]) *td->val= ratio; } } - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -4007,7 +4005,7 @@ void initBoneRoll(TransInfo *t) { t->mode = TFM_BONE_ROLL; t->transform = BoneRoll; - + initMouseInputMode(t, &t->mouse, INPUT_ANGLE); t->idx_max = 0; @@ -4015,11 +4013,11 @@ void initBoneRoll(TransInfo *t) t->snap[0] = 0.0f; t->snap[1] = (float)((5.0/180)*M_PI); t->snap[2] = t->snap[1] * 0.2f; - + t->flag |= T_NO_CONSTRAINT; } -int BoneRoll(TransInfo *t, short mval[2]) +int BoneRoll(TransInfo *t, short mval[2]) { TransData *td = t->data; int i; @@ -4045,18 +4043,18 @@ int BoneRoll(TransInfo *t, short mval[2]) else { sprintf(str, "Roll: %.2f", 180.0*final/M_PI); } - + /* set roll values */ - for (i = 0; i < t->total; i++, td++) { + for (i = 0; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; if (td->flag & TD_SKIP) continue; - + *(td->val) = td->ival - final; } - + recalcData(t); ED_area_headerprint(t->sa, str); @@ -4066,11 +4064,11 @@ int BoneRoll(TransInfo *t, short mval[2]) /* ************************** BAKE TIME ******************* */ -void initBakeTime(TransInfo *t) +void initBakeTime(TransInfo *t) { t->transform = BakeTime; initMouseInputMode(t, &t->mouse, INPUT_NONE); - + t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; @@ -4078,15 +4076,15 @@ void initBakeTime(TransInfo *t) t->snap[2] = t->snap[1] * 0.1f; } -int BakeTime(TransInfo *t, short mval[2]) +int BakeTime(TransInfo *t, short mval[2]) { TransData *td = t->data; float time; int i; char str[50]; - + float fac = 0.1f; - + if(t->mouse.precision) { /* calculate ratio for shiftkey pos, and for total, and blend these for precision */ time= (float)(t->center2d[0] - t->mouse.precision_mval[0]) * fac; @@ -4118,7 +4116,7 @@ int BakeTime(TransInfo *t, short mval[2]) else sprintf(str, "Time: %.3f %s", time, t->proptext); } - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -4142,7 +4140,7 @@ int BakeTime(TransInfo *t, short mval[2]) /* ************************** MIRROR *************************** */ -void initMirror(TransInfo *t) +void initMirror(TransInfo *t) { t->transform = Mirror; initMouseInputMode(t, &t->mouse, INPUT_NONE); @@ -4153,7 +4151,7 @@ void initMirror(TransInfo *t) } } -int Mirror(TransInfo *t, short mval[2]) +int Mirror(TransInfo *t, short mval[2]) { TransData *td; float size[3], mat[3][3]; @@ -4169,47 +4167,47 @@ int Mirror(TransInfo *t, short mval[2]) /* if an axis has been selected */ if (t->con.mode & CON_APPLY) { size[0] = size[1] = size[2] = -1; - + SizeToMat3(size, mat); - + if (t->con.applySize) { t->con.applySize(t, NULL, mat); } - + sprintf(str, "Mirror%s", t->con.text); - + for(i = 0, td=t->data; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + ElementResize(t, td, mat); } - + recalcData(t); - + ED_area_headerprint(t->sa, str); } else { size[0] = size[1] = size[2] = 1; - + SizeToMat3(size, mat); - + for(i = 0, td=t->data; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; - + if (td->flag & TD_SKIP) continue; - + ElementResize(t, td, mat); } - + recalcData(t); - + ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)"); } @@ -4218,12 +4216,12 @@ int Mirror(TransInfo *t, short mval[2]) /* ************************** ALIGN *************************** */ -void initAlign(TransInfo *t) +void initAlign(TransInfo *t) { t->flag |= T_NO_CONSTRAINT; - + t->transform = Align; - + initMouseInputMode(t, &t->mouse, INPUT_NONE); } @@ -4239,37 +4237,37 @@ int Align(TransInfo *t, short mval[2]) for(i = 0 ; i < t->total; i++, td++) { float mat[3][3], invmat[3][3]; - + if (td->flag & TD_NOACTION) break; if (td->flag & TD_SKIP) continue; - + /* around local centers */ if (t->flag & (T_OBJECT|T_POSE)) { VECCOPY(t->center, td->center); } else { - if(t->scene->selectmode & SCE_SELECT_FACE) { + if(t->settings->selectmode & SCE_SELECT_FACE) { VECCOPY(t->center, td->center); } } Mat3Inv(invmat, td->axismtx); - - Mat3MulMat3(mat, t->spacemtx, invmat); + + Mat3MulMat3(mat, t->spacemtx, invmat); ElementRotation(t, td, mat, t->around); } /* restoring original center */ VECCOPY(t->center, center); - + recalcData(t); ED_area_headerprint(t->sa, "Align"); - + return 1; } @@ -4278,37 +4276,37 @@ int Align(TransInfo *t, short mval[2]) /* ---------------- Special Helpers for Various Settings ------------- */ -/* This function returns the snapping 'mode' for Animation Editors only +/* This function returns the snapping 'mode' for Animation Editors only * We cannot use the standard snapping due to NLA-strip scaling complexities. */ // XXX these modifier checks should be keymappable static short getAnimEdit_SnapMode(TransInfo *t) { short autosnap= SACTSNAP_OFF; - + /* currently, some of these are only for the action editor */ if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; - + if (saction) autosnap= saction->autosnap; } else if (t->spacetype == SPACE_IPO) { SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; - + if (sipo) autosnap= sipo->autosnap; } else if (t->spacetype == SPACE_NLA) { SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first; - + if (snla) autosnap= snla->autosnap; } else { // TRANSFORM_FIX_ME This needs to use proper defines for t->modifiers // // FIXME: this still toggles the modes... -// if (ctrl) +// if (ctrl) // autosnap= SACTSNAP_STEP; // else if (shift) // autosnap= SACTSNAP_FRAME; @@ -4317,41 +4315,41 @@ static short getAnimEdit_SnapMode(TransInfo *t) // else autosnap= SACTSNAP_OFF; } - + return autosnap; } /* This function is used for testing if an Animation Editor is displaying * its data in frames or seconds (and the data needing to be edited as such). - * Returns 1 if in seconds, 0 if in frames + * Returns 1 if in seconds, 0 if in frames */ static short getAnimEdit_DrawTime(TransInfo *t) { short drawtime; - + /* currently, some of these are only for the action editor */ if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; - + drawtime = (saction->flag & SACTION_DRAWTIME)? 1 : 0; } else if (t->spacetype == SPACE_NLA) { SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first; - + drawtime = (snla->flag & SNLA_DRAWTIME)? 1 : 0; } else { drawtime = 0; } - + return drawtime; -} +} -/* This function is used by Animation Editor specific transform functions to do +/* This function is used by Animation Editor specific transform functions to do * the Snap Keyframe to Nearest Frame/Marker */ -static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, Object *ob, short autosnap) +static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, AnimData *adt, short autosnap) { /* snap key to nearest frame? */ if (autosnap == SACTSNAP_FRAME) { @@ -4359,42 +4357,42 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, Object *ob, short const short doTime= getAnimEdit_DrawTime(t); const double secf= FPS; double val; - + /* convert frame to nla-action time (if needed) */ - if (ob) - val= get_action_frame_inv(ob, *(td->val)); + if (adt) + val= BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP); else val= *(td->val); - + /* do the snapping to nearest frame/second */ if (doTime) val= (float)( floor((val/secf) + 0.5f) * secf ); else val= (float)( floor(val+0.5f) ); - + /* convert frame out of nla-action time */ - if (ob) - *(td->val)= get_action_frame(ob, val); + if (adt) + *(td->val)= BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP); else *(td->val)= val; } /* snap key to nearest marker? */ else if (autosnap == SACTSNAP_MARKER) { float val; - + /* convert frame to nla-action time (if needed) */ - if (ob) - val= get_action_frame_inv(ob, *(td->val)); + if (adt) + val= BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP); else val= *(td->val); - + /* snap to nearest marker */ // TODO: need some more careful checks for where data comes from val= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, val); - + /* convert frame out of nla-action time */ - if (ob) - *(td->val)= get_action_frame(ob, val); + if (adt) + *(td->val)= BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP); else *(td->val)= val; } @@ -4402,27 +4400,27 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, Object *ob, short /* ----------------- Translation ----------------------- */ -void initTimeTranslate(TransInfo *t) +void initTimeTranslate(TransInfo *t) { t->mode = TFM_TIME_TRANSLATE; t->transform = TimeTranslate; - + initMouseInputMode(t, &t->mouse, INPUT_NONE); /* num-input has max of (n-1) */ t->idx_max = 0; t->num.flag = 0; t->num.idx_max = t->idx_max; - + /* initialise snap like for everything else */ - t->snap[0] = 0.0f; + t->snap[0] = 0.0f; t->snap[1] = t->snap[2] = 1.0f; } -static void headerTimeTranslate(TransInfo *t, char *str) +static void headerTimeTranslate(TransInfo *t, char *str) { char tvec[60]; - + /* if numeric input is active, use results from that, otherwise apply snapping to result */ if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); @@ -4433,7 +4431,7 @@ static void headerTimeTranslate(TransInfo *t, char *str) const short doTime = getAnimEdit_DrawTime(t); const double secf= FPS; float val = t->values[0]; - + /* apply snapping + frame->seconds conversions */ if (autosnap == SACTSNAP_STEP) { if (doTime) @@ -4445,85 +4443,86 @@ static void headerTimeTranslate(TransInfo *t, char *str) if (doTime) val= val / secf; } - + sprintf(&tvec[0], "%.4f", val); } - + sprintf(str, "DeltaX: %s", &tvec[0]); } -static void applyTimeTranslate(TransInfo *t, float sval) +static void applyTimeTranslate(TransInfo *t, float sval) { TransData *td = t->data; Scene *scene = t->scene; int i; - + const short doTime= getAnimEdit_DrawTime(t); const double secf= FPS; - + const short autosnap= getAnimEdit_SnapMode(t); - + float deltax, val; - + /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */ for (i = 0 ; i < t->total; i++, td++) { - /* it is assumed that td->ob is a pointer to the object, - * whose active action is where this keyframe comes from + /* it is assumed that td->extra is a pointer to the AnimData, + * whose active action is where this keyframe comes from + * (this is only valid when not in NLA) */ - Object *ob= td->ob; - - /* check if any need to apply nla-scaling */ - if (ob) { + AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL; + + /* check if any need to apply nla-mapping */ + if (adt) { deltax = t->values[0]; - + if (autosnap == SACTSNAP_STEP) { - if (doTime) + if (doTime) deltax= (float)( floor((deltax/secf) + 0.5f) * secf ); else deltax= (float)( floor(deltax + 0.5f) ); } - - val = get_action_frame_inv(ob, td->ival); + + val = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP); val += deltax; - *(td->val) = get_action_frame(ob, val); + *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP); } else { deltax = val = t->values[0]; - + if (autosnap == SACTSNAP_STEP) { if (doTime) val= (float)( floor((deltax/secf) + 0.5f) * secf ); else val= (float)( floor(val + 0.5f) ); } - + *(td->val) = td->ival + val; } - + /* apply nearest snapping */ - doAnimEdit_SnapFrame(t, td, ob, autosnap); + doAnimEdit_SnapFrame(t, td, adt, autosnap); } } -int TimeTranslate(TransInfo *t, short mval[2]) +int TimeTranslate(TransInfo *t, short mval[2]) { View2D *v2d = (View2D *)t->view; float cval[2], sval[2]; char str[200]; - + /* calculate translation amount from mouse movement - in 'time-grid space' */ UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]); UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]); - + /* we only need to calculate effect for time (applyTimeTranslate only needs that) */ t->values[0] = cval[0] - sval[0]; - + /* handle numeric-input stuff */ t->vec[0] = t->values[0]; applyNumInput(&t->num, &t->vec[0]); t->values[0] = t->vec[0]; headerTimeTranslate(t, str); - + applyTimeTranslate(t, sval[0]); recalcData(t); @@ -4535,36 +4534,36 @@ int TimeTranslate(TransInfo *t, short mval[2]) /* ----------------- Time Slide ----------------------- */ -void initTimeSlide(TransInfo *t) +void initTimeSlide(TransInfo *t) { /* this tool is only really available in the Action Editor... */ if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; - + /* set flag for drawing stuff */ saction->flag |= SACTION_MOVING; } - + t->mode = TFM_TIME_SLIDE; t->transform = TimeSlide; t->flag |= T_FREE_CUSTOMDATA; - + initMouseInputMode(t, &t->mouse, INPUT_NONE); /* num-input has max of (n-1) */ t->idx_max = 0; t->num.flag = 0; t->num.idx_max = t->idx_max; - + /* initialise snap like for everything else */ - t->snap[0] = 0.0f; + t->snap[0] = 0.0f; t->snap[1] = t->snap[2] = 1.0f; } -static void headerTimeSlide(TransInfo *t, float sval, char *str) +static void headerTimeSlide(TransInfo *t, float sval, char *str) { char tvec[60]; - + if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); } @@ -4573,49 +4572,50 @@ static void headerTimeSlide(TransInfo *t, float sval, char *str) float maxx= *((float *)(t->customData) + 1); float cval= t->values[0]; float val; - + val= 2.0f*(cval-sval) / (maxx-minx); CLAMP(val, -1.0f, 1.0f); - + sprintf(&tvec[0], "%.4f", val); } - + sprintf(str, "TimeSlide: %s", &tvec[0]); } -static void applyTimeSlide(TransInfo *t, float sval) +static void applyTimeSlide(TransInfo *t, float sval) { TransData *td = t->data; int i; - + float minx= *((float *)(t->customData)); float maxx= *((float *)(t->customData) + 1); - + /* set value for drawing black line */ if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; float cvalf = t->values[0]; - + saction->timeslide= cvalf; } - + /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */ for (i = 0 ; i < t->total; i++, td++) { - /* it is assumed that td->ob is a pointer to the object, - * whose active action is where this keyframe comes from + /* it is assumed that td->extra is a pointer to the AnimData, + * whose active action is where this keyframe comes from + * (this is only valid when not in NLA) */ - Object *ob= td->ob; + AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL; float cval = t->values[0]; - - /* apply scaling to necessary values */ - if (ob) - cval= get_action_frame(ob, cval); - + + /* apply NLA-mapping to necessary values */ + if (adt) + cval= BKE_nla_tweakedit_remap(adt, cval, NLATIME_CONVERT_UNMAP); + /* only apply to data if in range */ if ((sval > minx) && (sval < maxx)) { float cvalc= CLAMPIS(cval, minx, maxx); float timefac; - + /* left half? */ if (td->ival < sval) { timefac= (sval - td->ival) / (sval - minx); @@ -4629,26 +4629,26 @@ static void applyTimeSlide(TransInfo *t, float sval) } } -int TimeSlide(TransInfo *t, short mval[2]) +int TimeSlide(TransInfo *t, short mval[2]) { View2D *v2d = (View2D *)t->view; float cval[2], sval[2]; float minx= *((float *)(t->customData)); float maxx= *((float *)(t->customData) + 1); char str[200]; - + /* calculate mouse co-ordinates */ UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]); UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]); - + /* t->values[0] stores cval[0], which is the current mouse-pointer location (in frames) */ t->values[0] = cval[0]; - + /* handle numeric-input stuff */ t->vec[0] = 2.0f*(cval[0]-sval[0]) / (maxx-minx); applyNumInput(&t->num, &t->vec[0]); t->values[0] = (maxx-minx) * t->vec[0] / 2.0 + sval[0]; - + headerTimeSlide(t, sval[0], str); applyTimeSlide(t, sval[0]); @@ -4661,35 +4661,35 @@ int TimeSlide(TransInfo *t, short mval[2]) /* ----------------- Scaling ----------------------- */ -void initTimeScale(TransInfo *t) +void initTimeScale(TransInfo *t) { t->mode = TFM_TIME_SCALE; t->transform = TimeScale; - + initMouseInputMode(t, &t->mouse, INPUT_NONE); t->helpline = HLP_SPRING; /* set manually because we don't use a predefined input */ t->flag |= T_NULL_ONE; t->num.flag |= NUM_NULL_ONE; - + /* num-input has max of (n-1) */ t->idx_max = 0; t->num.flag = 0; t->num.idx_max = t->idx_max; - + /* initialise snap like for everything else */ - t->snap[0] = 0.0f; + t->snap[0] = 0.0f; t->snap[1] = t->snap[2] = 1.0f; } static void headerTimeScale(TransInfo *t, char *str) { char tvec[60]; - + if (hasNumInput(&t->num)) outputNumInput(&(t->num), tvec); else sprintf(&tvec[0], "%.4f", t->values[0]); - + sprintf(str, "ScaleX: %s", &tvec[0]); } @@ -4697,74 +4697,63 @@ static void applyTimeScale(TransInfo *t) { Scene *scene = t->scene; TransData *td = t->data; int i; - + const short autosnap= getAnimEdit_SnapMode(t); const short doTime= getAnimEdit_DrawTime(t); const double secf= FPS; - - + + for (i = 0 ; i < t->total; i++, td++) { - /* it is assumed that td->ob is a pointer to the object, - * whose active action is where this keyframe comes from + /* it is assumed that td->extra is a pointer to the AnimData, + * whose active action is where this keyframe comes from + * (this is only valid when not in NLA) */ - Object *ob= td->ob; + AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL; float startx= CFRA; float fac= t->values[0]; - + if (autosnap == SACTSNAP_STEP) { if (doTime) fac= (float)( floor(fac/secf + 0.5f) * secf ); else fac= (float)( floor(fac + 0.5f) ); } - - /* check if any need to apply nla-scaling */ - if (ob) - startx= get_action_frame(ob, startx); - + + /* check if any need to apply nla-mapping */ + if (adt) + startx= BKE_nla_tweakedit_remap(adt, startx, NLATIME_CONVERT_UNMAP); + /* now, calculate the new value */ *(td->val) = td->ival - startx; *(td->val) *= fac; *(td->val) += startx; - + /* apply nearest snapping */ - doAnimEdit_SnapFrame(t, td, ob, autosnap); + doAnimEdit_SnapFrame(t, td, adt, autosnap); } } -int TimeScale(TransInfo *t, short mval[2]) +int TimeScale(TransInfo *t, short mval[2]) { float cval, sval; float deltax, startx; float width= 0.0f; char str[200]; - + sval= t->imval[0]; cval= mval[0]; - - // XXX ewww... we need a better factor! -#if 0 // TRANSFORM_FIX_ME - switch (t->spacetype) { - case SPACE_ACTION: - width= ACTWIDTH; - break; - case SPACE_NLA: - width= NLAWIDTH; - break; - } -#endif - + /* calculate scaling factor */ startx= sval-(width/2+(t->ar->winx)/2); deltax= cval-(width/2+(t->ar->winx)/2); t->values[0] = deltax / startx; - + /* handle numeric-input stuff */ t->vec[0] = t->values[0]; applyNumInput(&t->num, &t->vec[0]); t->values[0] = t->vec[0]; headerTimeScale(t, str); - + applyTimeScale(t); recalcData(t); @@ -4803,7 +4792,7 @@ void NDofTransform() maxval = val; } } - + switch(axis) { case -1: @@ -4824,7 +4813,7 @@ void NDofTransform() default: printf("ndof: what we are doing here ?"); } - + if (mode != 0) { initTransform(mode, CTX_NDOF); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index ee767fada58..db78632e76a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -30,7 +30,7 @@ #ifndef TRANSFORM_H #define TRANSFORM_H -#include "BIF_transform.h" +#include "ED_transform.h" /* ************************** Types ***************************** */ @@ -71,7 +71,7 @@ typedef struct NumInput { /* The ctrl value has different meaning: 0 : No value has been typed - + otherwise, |value| - 1 is where the cursor is located after the period Positive : number is positive Negative : number is negative @@ -100,7 +100,7 @@ typedef struct TransCon { float mtx[3][3]; /* Matrix of the Constraint space */ float imtx[3][3]; /* Inverse Matrix of the Constraint space */ float pmtx[3][3]; /* Projection Constraint Matrix (same as imtx with some axis == 0) */ - float center[3]; /* transformation center to define where to draw the view widget + float center[3]; /* transformation center to define where to draw the view widget ALWAYS in global space. Unlike the transformation center */ short imval[2]; /* initial mouse value for visual calculation */ /* the one in TransInfo is not garanty to stay the same (Rotates change it) */ @@ -138,7 +138,7 @@ typedef struct TransDataExtension { float iquat[4]; /* Initial rotation quaternion */ float *size; /* Size of the data to transform (Faculative) */ float isize[3]; /* Initial size */ - float obmat[4][4]; /* Object matrix */ + float obmat[4][4]; /* Object matrix */ } TransDataExtension; typedef struct TransData2D { @@ -158,9 +158,26 @@ typedef struct TransDataSeq { int flag; /* a copy of seq->flag that may be modified for nested strips */ short start_offset; /* use this so we can have transform data at the strips start, but apply correctly to the start frame */ short sel_flag; /* one of SELECT, SEQ_LEFTSEL and SEQ_RIGHTSEL */ - + } 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 */ + + struct NlaStrip *strip; /* NLA-strip this data represents */ + + /* dummy values for transform to write in - must have 3 elements... */ + float h1[3]; /* start handle */ + float h2[3]; /* end handle */ + + int trackIndex; /* index of track that strip is currently in */ + int handle; /* handle-index: 0 for dummy entry, -1 for start, 1 for end, 2 for both ends */ +} TransDataNla; + typedef struct TransData { float dist; /* Distance needed to affect element (for Proportionnal Editing) */ float rdist; /* Distance to the nearest element (for Proportionnal Editing) */ @@ -185,9 +202,9 @@ typedef struct TransData { typedef struct MouseInput { void (*apply)(struct TransInfo *, struct MouseInput *, short [2], float [3]); - + short imval[2]; /* initial mouse position */ - char precision; + char precision; short precision_mval[2]; /* mouse position when precision key was pressed */ int center[2]; float factor; @@ -224,7 +241,7 @@ typedef struct TransInfo { short idx_max; /* maximum index on the input vector */ float snap[3]; /* Snapping Gears */ char frame_side; /* Mouse side of the cfra, 'L', 'R' or 'B' */ - + float viewmat[4][4]; /* copy from G.vd, prevents feedback, */ float viewinv[4][4]; /* and to make sure we don't have to */ float persmat[4][4]; /* access G.vd from other space types */ @@ -233,16 +250,16 @@ typedef struct TransInfo { short around; char spacetype; /* spacetype where transforming is */ char helpline; /* helpline modes (not to be confused with hotline) */ - + float vec[3]; /* translation, to show for widget */ float mat[3][3]; /* rot/rescale, to show for widget */ - + char *undostr; /* if set, uses this string for undo */ float spacemtx[3][3]; /* orientation matrix of the current space */ char spacename[32]; /* name of the current space */ - + struct Object *poseobj; /* if t->flag & T_POSE, this denotes pose object */ - + void *customData; /* Per Transform custom data */ /*************** NEW STUFF *********************/ @@ -257,6 +274,7 @@ typedef struct TransInfo { struct ScrArea *sa; struct ARegion *ar; struct Scene *scene; + struct ToolSettings *settings; struct wmTimer *animtimer; short mval[2]; /* current mouse position */ struct Object *obedit; @@ -287,7 +305,7 @@ typedef struct TransInfo { #define T_POSE (1 << 2) #define T_TEXTURE (1 << 3) #define T_CAMERA (1 << 4) - // trans on points, having no rotation/scale + // trans on points, having no rotation/scale #define T_POINTS (1 << 6) // for manipulator exceptions, like scaling using center point, drawing help lines #define T_USES_MANIPULATOR (1 << 7) @@ -303,7 +321,7 @@ typedef struct TransInfo { #define T_V3D_ALIGN (1 << 14) /* for 2d views like uv or ipo */ -#define T_2D_EDIT (1 << 15) +#define T_2D_EDIT (1 << 15) #define T_CLIP_UV (1 << 16) #define T_FREE_CUSTOMDATA (1 << 17) @@ -480,8 +498,7 @@ void flushTransNodes(TransInfo *t); void flushTransSeq(TransInfo *t); /*********************** exported from transform_manipulator.c ********** */ -void draw_manipulator_ext(struct ScrArea *sa, int type, char axis, int col, float vec[3], float mat[][3]); -int calc_manipulator_stats(struct ScrArea *sa); +int calc_manipulator_stats(const struct bContext *C); float get_drawsize(struct ARegion *ar, float *co); /*********************** TransData Creation and General Handling *********** */ @@ -492,8 +509,9 @@ void special_aftertrans_update(TransInfo *t); void transform_autoik_update(TransInfo *t, short mode); +int count_set_pose_transflags(int *out_mode, short around, struct Object *ob); + /* auto-keying stuff used by special_aftertrans_update */ -short autokeyframe_cfra_can_key(struct Scene *scene, struct Object *ob); void autokeyframe_ob_cb_func(struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode); void autokeyframe_pose_cb_func(struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode, short targetless_ik); @@ -592,8 +610,6 @@ void calculatePropRatio(TransInfo *t); void getViewVector(TransInfo *t, float coord[3], float vec[3]); -TransInfo * BIF_GetTransInfo(void); - /*********************** NumInput ********************************/ void initNumInput(NumInput *n); @@ -630,7 +646,7 @@ int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) int addMatrixSpace(struct bContext *C, float mat[3][3], char name[]); int addObjectSpace(struct bContext *C, struct Object *ob); -void applyTransformOrientation(struct bContext *C, TransInfo *t); +void applyTransformOrientation(const struct bContext *C, TransInfo *t); #define ORIENTATION_NONE 0 @@ -639,7 +655,7 @@ void applyTransformOrientation(struct bContext *C, TransInfo *t); #define ORIENTATION_EDGE 3 #define ORIENTATION_FACE 4 -int getTransformOrientation(struct bContext *C, float normal[3], float plane[3], int activeOnly); +int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3], int activeOnly); int createSpaceNormal(float mat[3][3], float normal[3]); int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 7f47bfd25af..158ea98c090 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -183,7 +183,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) { VECCOPY(vec, t->auto_values); constraintAutoValues(t, vec); } - + if (t->con.mode & CON_AXIS0) { pvec[i++] = vec[0]; } @@ -199,10 +199,10 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) { static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3]) { float norm[3], vec[3], factor; - + if(in[0]==0.0f && in[1]==0.0f && in[2]==0.0f) return; - + /* For when view is parallel to constraint... will cause NaNs otherwise So we take vertical motion in 3D space and apply it to the constraint axis. Nice for camera grab + MMB */ @@ -212,30 +212,30 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3 /* since camera distance is quite relative, use quadratic relationship. holding shift can compensate */ if(factor<0.0f) factor*= -factor; else factor*= factor; - + VECCOPY(out, axis); Normalize(out); VecMulf(out, -factor); /* -factor makes move down going backwards */ } else { float cb[3], ab[3]; - + VECCOPY(out, axis); - + /* Get view vector on axis to define a plane */ VecAddf(vec, t->con.center, in); getViewVector(t, vec, norm); - + Crossf(vec, norm, axis); - + /* Project input vector on the plane passing on axis */ Projf(vec, in, vec); VecSubf(vec, in, vec); - + /* intersect the two lines: axis and norm */ Crossf(cb, vec, norm); Crossf(ab, axis, norm); - + VecMulf(out, Inpf(cb, ab) / Inpf(ab, ab)); } } @@ -262,7 +262,7 @@ static void planeProjection(TransInfo *t, float in[3], float out[3]) { /* * Generic callback for constant spacial constraints applied to linear motion - * + * * The IN vector in projected into the constrained space and then further * projected along the view vector. * (in perspective mode, the view vector is relative to the position on screen) @@ -274,7 +274,7 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo VECCOPY(out, in); if (!td && t->con.mode & CON_APPLY) { Mat3MulVecfl(t->con.pmtx, out); - + // With snap, a projection is alright, no need to correct for view alignment if ((t->tsnap.status & SNAP_ON) == 0) { if (getConstraintSpaceDimension(t) == 2) { @@ -284,7 +284,7 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo } else if (getConstraintSpaceDimension(t) == 1) { float c[3]; - + if (t->con.mode & CON_AXIS0) { VECCOPY(c, t->con.mtx[0]); } @@ -303,7 +303,7 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo /* * Generic callback for object based spacial constraints applied to linear motion - * + * * At first, the following is applied to the first data in the array * The IN vector in projected into the constrained space and then further * projected along the view vector. @@ -360,7 +360,7 @@ static void applyObjectConstraintVec(TransInfo *t, TransData *td, float in[3], f /* * Generic callback for constant spacial constraints applied to resize motion - * + * * */ @@ -386,7 +386,7 @@ static void applyAxisConstraintSize(TransInfo *t, TransData *td, float smat[3][3 /* * Callback for object based spacial constraints applied to resize motion - * + * * */ @@ -415,7 +415,7 @@ static void applyObjectConstraintSize(TransInfo *t, TransData *td, float smat[3] /* * Generic callback for constant spacial constraints applied to rotations - * + * * The rotation axis is copied into VEC. * * In the case of single axis constraints, the rotation axis is directly the one constrained to. @@ -457,7 +457,7 @@ static void applyAxisConstraintRot(TransInfo *t, TransData *td, float vec[3], fl /* * Callback for object based spacial constraints applied to rotations - * + * * The rotation axis is copied into VEC. * * In the case of single axis constraints, the rotation axis is directly the one constrained to. @@ -473,7 +473,7 @@ static void applyObjectConstraintRot(TransInfo *t, TransData *td, float vec[3], { if (t->con.mode & CON_APPLY) { int mode = t->con.mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2); - + /* on setup call, use first object */ if (td == NULL) { td= t->data; @@ -585,128 +585,6 @@ void setUserConstraint(TransInfo *t, int mode, const char ftext[]) { t->con.mode |= CON_USER; } -/*--------------------- EXTERNAL SETUP CALLS ------------------*/ - -void BIF_setLocalLockConstraint(char axis, char *text) { - TransInfo *t = BIF_GetTransInfo(); - - if (t->total == 0) { - return; - } - - switch (axis) { - case 'x': - setLocalConstraint(t, (CON_AXIS1|CON_AXIS2), text); - break; - case 'y': - setLocalConstraint(t, (CON_AXIS0|CON_AXIS2), text); - break; - case 'z': - setLocalConstraint(t, (CON_AXIS0|CON_AXIS1), text); - break; - } -} - -void BIF_setLocalAxisConstraint(char axis, char *text) { - TransInfo *t = BIF_GetTransInfo(); - - if (t->total == 0) { - return; - } - - switch (axis) { - case 'X': - setLocalConstraint(t, CON_AXIS0, text); - break; - case 'Y': - setLocalConstraint(t, CON_AXIS1, text); - break; - case 'Z': - setLocalConstraint(t, CON_AXIS2, text); - break; - } -} - -/* text is optional, for header print */ -void BIF_setSingleAxisConstraint(float vec[3], char *text) { - TransInfo *t = BIF_GetTransInfo(); - float space[3][3], v[3]; - - if (t->total == 0) { - return; - } - - VECCOPY(space[0], vec); - - v[0] = vec[2]; - v[1] = vec[0]; - v[2] = vec[1]; - - Crossf(space[1], vec, v); - Crossf(space[2], vec, space[1]); - Mat3Ortho(space); - - Mat3CpyMat3(t->con.mtx, space); - t->con.mode = CON_AXIS0; - - getConstraintMatrix(t); - - startConstraint(t); - - /* start copying with an offset of 1, to reserve a spot for the SPACE char */ - if(text) - { - strncpy(t->con.text+1, text, 48); /* 50 in struct */ - } - else - { - t->con.text[1] = '\0'; /* No text */ - } - - t->con.drawExtra = NULL; - t->con.applyVec = applyAxisConstraintVec; - t->con.applySize = applyAxisConstraintSize; - t->con.applyRot = applyAxisConstraintRot; - t->redraw = 1; -} - -void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text) { - TransInfo *t = BIF_GetTransInfo(); - float space[3][3]; - - if (t->total == 0) { - return; - } - - VECCOPY(space[0], vec1); - VECCOPY(space[1], vec2); - Crossf(space[2], space[0], space[1]); - Mat3Ortho(space); - - Mat3CpyMat3(t->con.mtx, space); - t->con.mode = CON_AXIS0|CON_AXIS1; - - getConstraintMatrix(t); - - startConstraint(t); - - /* start copying with an offset of 1, to reserve a spot for the SPACE char */ - if(text) - { - strncpy(t->con.text+1, text, 48); /* 50 in struct */ - } - else - { - t->con.text[1] = '\0'; /* No text */ - } - - t->con.drawExtra = NULL; - t->con.applyVec = applyAxisConstraintVec; - t->con.applySize = applyAxisConstraintSize; - t->con.applyRot = applyAxisConstraintRot; - t->redraw = 1; -} - /*----------------- DRAWING CONSTRAINTS -------------------*/ void drawConstraint(const struct bContext *C, TransInfo *t) @@ -721,10 +599,10 @@ void drawConstraint(const struct bContext *C, TransInfo *t) return; if (t->flag & T_NO_CONSTRAINT) return; - + /* nasty exception for Z constraint in camera view */ // TRANSFORM_FIX_ME -// if((t->flag & T_OBJECT) && G.vd->camera==OBACT && G.vd->persp==V3D_CAMOB) +// if((t->flag & T_OBJECT) && G.vd->camera==OBACT && G.vd->persp==V3D_CAMOB) // return; if (tc->drawExtra) { @@ -742,17 +620,17 @@ void drawConstraint(const struct bContext *C, TransInfo *t) drawLine(t, tc->center, tc->mtx[2], 'z', 0); glColor3ubv((GLubyte *)col2); - + glDisable(GL_DEPTH_TEST); setlinestyle(1); - glBegin(GL_LINE_STRIP); - glVertex3fv(tc->center); - glVertex3fv(vec); + glBegin(GL_LINE_STRIP); + glVertex3fv(tc->center); + glVertex3fv(vec); glEnd(); setlinestyle(0); // TRANSFORM_FIX_ME //if(G.vd->zbuf) - glEnable(GL_DEPTH_TEST); + glEnable(GL_DEPTH_TEST); } if (tc->mode & CON_AXIS0) { @@ -775,7 +653,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) float tmat[4][4], imat[4][4]; UI_ThemeColor(TH_GRID); - + if(t->spacetype == SPACE_VIEW3D && rv3d != NULL) { Mat4CpyMat4(tmat, rv3d->viewmat); @@ -804,20 +682,9 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) set_inverted_drawing(1); drawcircball(GL_LINE_LOOP, t->center, t->prop_size, imat); set_inverted_drawing(0); - - glPopMatrix(); - } -} -void BIF_getPropCenter(float *center) -{ - TransInfo *t = BIF_GetTransInfo(); - - if (t && t->flag & T_PROP_EDIT) { - VECCOPY(center, t->center); + glPopMatrix(); } - else - center[0] = center[1] = center[2] = 0.0f; } static void drawObjectConstraint(TransInfo *t) { @@ -839,7 +706,7 @@ static void drawObjectConstraint(TransInfo *t) { if (t->con.mode & CON_AXIS2) { drawLine(t, td->ob->obmat[3], td->axismtx[2], 'z', DRAWLIGHT); } - + td++; for(i=1;i<t->total;i++,td++) { @@ -954,12 +821,12 @@ static void setNearestAxis3d(TransInfo *t) float mvec[3], axis[3], proj[3]; float len[3]; int i, icoord[2]; - + /* calculate mouse movement */ mvec[0] = (float)(t->mval[0] - t->con.imval[0]); mvec[1] = (float)(t->mval[1] - t->con.imval[1]); mvec[2] = 0.0f; - + /* we need to correct axis length for the current zoomlevel of view, this to prevent projected values to be clipped behind the camera and to overflow the short integers. @@ -972,12 +839,12 @@ static void setNearestAxis3d(TransInfo *t) for (i = 0; i<3; i++) { VECCOPY(axis, t->con.mtx[i]); - + VecMulf(axis, zfac); /* now we can project to get window coordinate */ VecAddf(axis, axis, t->con.center); projectIntView(t, axis, icoord); - + axis[0] = (float)(icoord[0] - t->center2d[0]); axis[1] = (float)(icoord[1] - t->center2d[1]); axis[2] = 0.0f; @@ -1034,13 +901,13 @@ void setNearestAxis(TransInfo *t) /* constraint setting - depends on spacetype */ if (t->spacetype == SPACE_VIEW3D) { /* 3d-view */ - setNearestAxis3d(t); + setNearestAxis3d(t); } else { /* assume that this means a 2D-Editor */ setNearestAxis2d(t); } - + getConstraintMatrix(t); } @@ -1083,7 +950,7 @@ int isLockConstraint(TransInfo *t) { /* * Returns the dimension of the constraint space. - * + * * For that reason, the flags always needs to be set to properly evaluate here, * even if they aren't actually used in the callback function. (Which could happen * for weird constraints not yet designed. Along a path for example.) @@ -1107,7 +974,7 @@ int getConstraintSpaceDimension(TransInfo *t) Someone willing to do it criptically could do the following instead: return t->con & (CON_AXIS0|CON_AXIS1|CON_AXIS2); - + Based on the assumptions that the axis flags are one after the other and start at 1 */ } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index c90c7bfeef4..aeccaee070e 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -90,6 +90,7 @@ #include "BKE_mball.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_nla.h" #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_sequence.h" @@ -101,21 +102,17 @@ #include "BKE_report.h" #include "BKE_tessmesh.h" -//#include "BIF_editaction.h" //#include "BIF_editview.h" //#include "BIF_editlattice.h" //#include "BIF_editconstraint.h" //#include "BIF_editmesh.h" -//#include "BIF_editnla.h" //#include "BIF_editsima.h" //#include "BIF_editparticle.h" #include "BIF_gl.h" -//#include "BIF_keyframing.h" //#include "BIF_poseobject.h" //#include "BIF_meshtools.h" //#include "BIF_mywindow.h" //#include "BIF_resources.h" -#include "BIF_retopo.h" //#include "BIF_screen.h" //#include "BIF_space.h" //#include "BIF_toolbox.h" @@ -127,20 +124,16 @@ #include "ED_keyframing.h" #include "ED_keyframes_edit.h" #include "ED_object.h" +#include "ED_markers.h" #include "ED_mesh.h" +#include "ED_retopo.h" #include "ED_types.h" #include "ED_uvedit.h" #include "ED_view3d.h" #include "UI_view2d.h" -//#include "BSE_drawipo.h" //#include "BSE_edit.h" -//#include "BSE_editipo.h" -//#include "BSE_editipo_types.h" -//#include "BSE_editaction_types.h" - -//#include "BDR_drawaction.h" // list of keyframes in action //#include "BDR_editobject.h" // reset_slowparents() //#include "BDR_gpencil.h" @@ -225,7 +218,7 @@ void sort_trans_data_dist(TransInfo *t) { qsort_trans_data(t, start, t->data + t->total - 1); } -static void sort_trans_data(TransInfo *t) +static void sort_trans_data(TransInfo *t) { TransData *sel, *unsel; TransData temp; @@ -261,16 +254,16 @@ static void set_prop_dist(TransInfo *t, short with_dist) int a; for(a=0, tob= t->data; a<t->total; a++, tob++) { - + tob->rdist= 0.0f; // init, it was mallocced - + if((tob->flag & TD_SELECTED)==0) { TransData *td; int i; float dist, vec[3]; tob->rdist = -1.0f; // signal for next loop - + for (i = 0, td= t->data; i < t->total; i++, td++) { if(td->flag & TD_SELECTED) { VecSubf(vec, tob->center, td->center); @@ -288,7 +281,7 @@ static void set_prop_dist(TransInfo *t, short with_dist) if (with_dist) { tob->dist = tob->rdist; } - } + } } } @@ -303,9 +296,9 @@ static void createTransTexspace(bContext *C, TransInfo *t) Object *ob; ID *id; int *texflag; - + ob = OBACT; - + if (ob == NULL) { // Shouldn't logically happen, but still... t->total = 0; return; @@ -320,20 +313,20 @@ static void createTransTexspace(bContext *C, TransInfo *t) t->total = 1; td= t->data= MEM_callocN(sizeof(TransData), "TransTexspace"); td->ext= t->ext= MEM_callocN(sizeof(TransDataExtension), "TransTexspace"); - + td->flag= TD_SELECTED; VECCOPY(td->center, ob->obmat[3]); td->ob = ob; - + Mat3CpyMat4(td->mtx, ob->obmat); Mat3CpyMat4(td->axismtx, ob->obmat); Mat3Ortho(td->axismtx); Mat3Inv(td->smtx, td->mtx); - + if (give_obdata_texspace(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) { *texflag &= ~AUTOSPACE; } - + VECCOPY(td->iloc, td->loc); VECCOPY(td->ext->irot, td->ext->rot); VECCOPY(td->ext->isize, td->ext->size); @@ -380,7 +373,7 @@ static void createTransEdge(bContext *C, TransInfo *t) { td->loc= NULL; if (eed->f & SELECT) td->flag= TD_SELECTED; - else + else td->flag= 0; @@ -409,14 +402,14 @@ static void createTransEdge(bContext *C, TransInfo *t) { static bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan) { bConstraint *con= pchan->constraints.first; - + for(;con; con= con->next) { if(con->type==CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0)) { bKinematicConstraint *data= con->data; - - if(data->tar==NULL) + + if(data->tar==NULL) return data; - if(data->tar->type==OB_ARMATURE && data->subtarget[0]==0) + if(data->tar->type==OB_ARMATURE && data->subtarget[0]==0) return data; } } @@ -428,67 +421,67 @@ static short apply_targetless_ik(Object *ob) bPoseChannel *pchan, *parchan, *chanlist[256]; bKinematicConstraint *data; int segcount, apply= 0; - + /* now we got a difficult situation... we have to find the - target-less IK pchans, and apply transformation to the all + target-less IK pchans, and apply transformation to the all pchans that were in the chain */ - + for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) { data= has_targetless_ik(pchan); if(data && (data->flag & CONSTRAINT_IK_AUTO)) { - + /* fill the array with the bones of the chain (armature.c does same, keep it synced) */ segcount= 0; - + /* exclude tip from chain? */ if(!(data->flag & CONSTRAINT_IK_TIP)) parchan= pchan->parent; else parchan= pchan; - + /* Find the chain's root & count the segments needed */ for (; parchan; parchan=parchan->parent){ chanlist[segcount]= parchan; segcount++; - + if(segcount==data->rootbone || segcount>255) break; // 255 is weak } for(;segcount;segcount--) { Bone *bone; float rmat[4][4], tmat[4][4], imat[4][4]; - + /* pose_mat(b) = pose_mat(b-1) * offs_bone * channel * constraint * IK */ /* we put in channel the entire result of rmat= (channel * constraint * IK) */ /* pose_mat(b) = pose_mat(b-1) * offs_bone * rmat */ /* rmat = pose_mat(b) * inv( pose_mat(b-1) * offs_bone ) */ - + parchan= chanlist[segcount-1]; bone= parchan->bone; bone->flag |= BONE_TRANSFORM; /* ensures it gets an auto key inserted */ - + if(parchan->parent) { Bone *parbone= parchan->parent->bone; float offs_bone[4][4]; - + /* offs_bone = yoffs(b-1) + root(b) + bonemat(b) */ Mat4CpyMat3(offs_bone, bone->bone_mat); - + /* The bone's root offset (is in the parent's coordinate system) */ VECCOPY(offs_bone[3], bone->head); - + /* Get the length translation of parent (length along y axis) */ offs_bone[3][1]+= parbone->length; - + /* pose_mat(b-1) * offs_bone */ if(parchan->bone->flag & BONE_HINGE) { /* the rotation of the parent restposition */ Mat4CpyMat4(rmat, parbone->arm_mat); /* rmat used as temp */ - + /* the location of actual parent transform */ VECCOPY(rmat[3], offs_bone[3]); offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f; Mat4MulVecfl(parchan->parent->pose_mat, rmat[3]); - + Mat4MulMat4(tmat, offs_bone, rmat); } else if(parchan->bone->flag & BONE_NO_SCALE) { @@ -497,7 +490,7 @@ static short apply_targetless_ik(Object *ob) } else Mat4MulMat4(tmat, offs_bone, parchan->parent->pose_mat); - + Mat4Invert(imat, tmat); } else { @@ -508,16 +501,16 @@ static short apply_targetless_ik(Object *ob) } /* result matrix */ Mat4MulMat4(rmat, parchan->pose_mat, imat); - + /* apply and decompose, doesn't work for constraints or non-uniform scale well */ { float rmat3[3][3], qmat[3][3], imat[3][3], smat[3][3]; - + Mat3CpyMat4(rmat3, rmat); - + /* quaternion */ Mat3ToQuat(rmat3, parchan->quat); - + /* for size, remove rotation */ /* causes problems with some constraints (so apply only if needed) */ if (data->flag & CONSTRAINT_IK_STRETCH) { @@ -526,19 +519,19 @@ static short apply_targetless_ik(Object *ob) Mat3MulMat3(smat, rmat3, imat); Mat3ToSize(smat, parchan->size); } - + /* causes problems with some constraints (e.g. childof), so disable this */ /* as it is IK shouldn't affect location directly */ /* VECCOPY(parchan->loc, rmat[3]); */ } - + } - + apply= 1; data->flag &= ~CONSTRAINT_IK_AUTO; } - } - + } + return apply; } @@ -551,7 +544,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr VECCOPY(vec, pchan->pose_mat[3]); VECCOPY(td->center, vec); - + td->ob = ob; td->flag = TD_SELECTED; if (pchan->rotmode == PCHAN_ROT_QUAT) @@ -562,43 +555,43 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr { td->flag |= TD_NOCENTER; } - + if (bone->flag & BONE_TRANSFORM_CHILD) { td->flag |= TD_NOCENTER; td->flag |= TD_NO_LOC; } - + td->protectflag= pchan->protectflag; - + td->loc = pchan->loc; VECCOPY(td->iloc, pchan->loc); - + td->ext->size= pchan->size; VECCOPY(td->ext->isize, pchan->size); - + if (pchan->rotmode) { td->ext->rot= pchan->eul; td->ext->quat= NULL; - + VECCOPY(td->ext->irot, pchan->eul); } else { td->ext->rot= NULL; td->ext->quat= pchan->quat; - + QUATCOPY(td->ext->iquat, pchan->quat); } /* proper way to get parent transform + own transform + constraints transform */ Mat3CpyMat4(omat, ob->obmat); - - if (pchan->parent) { - if(pchan->bone->flag & BONE_HINGE) - Mat3CpyMat4(pmat, pchan->parent->bone->arm_mat); - else + + if (pchan->parent) { + if(pchan->bone->flag & BONE_HINGE) + Mat3CpyMat4(pmat, pchan->parent->bone->arm_mat); + else Mat3CpyMat4(pmat, pchan->parent->pose_mat); - + if (constraints_list_needinv(t, &pchan->constraints)) { Mat3CpyMat4(tmat, pchan->constinv); Mat3Inv(cmat, tmat); @@ -613,20 +606,20 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr Mat3Inv(cmat, tmat); Mat3MulSerie(td->mtx, pchan->bone->bone_mat, omat, cmat, 0,0,0,0,0); // dang mulserie swaps args } - else - Mat3MulMat3(td->mtx, omat, pchan->bone->bone_mat); // Mat3MulMat3 has swapped args! + else + Mat3MulMat3(td->mtx, omat, pchan->bone->bone_mat); // Mat3MulMat3 has swapped args! } - + Mat3Inv(td->smtx, td->mtx); - + /* for axismat we use bone's own transform */ Mat3CpyMat4(pmat, pchan->pose_mat); Mat3MulMat3(td->axismtx, omat, pmat); Mat3Ortho(td->axismtx); - + if (t->mode==TFM_BONESIZE) { bArmature *arm= t->poseobj->data; - + if(arm->drawtype==ARM_ENVELOPE) { td->loc= NULL; td->val= &bone->dist; @@ -639,7 +632,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->val= NULL; } } - + /* in this case we can do target-less IK grabbing */ if (t->mode==TFM_TRANSLATION) { bKinematicConstraint *data= has_targetless_ik(pchan); @@ -653,27 +646,27 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->loc = data->grabtarget; VECCOPY(td->iloc, td->loc); data->flag |= CONSTRAINT_IK_AUTO; - + /* only object matrix correction */ Mat3CpyMat3 (td->mtx, omat); Mat3Inv (td->smtx, td->mtx); } } - + /* store reference to first constraint */ td->con= pchan->constraints.first; } -static void bone_children_clear_transflag(TransInfo *t, ListBase *lb) +static void bone_children_clear_transflag(int mode, short around, ListBase *lb) { Bone *bone= lb->first; - + for(;bone;bone= bone->next) { if((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED)) { bone->flag |= BONE_HINGE_CHILD_TRANSFORM; } - else if (bone->flag & BONE_TRANSFORM && (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) && t->around == V3D_LOCAL) + else if (bone->flag & BONE_TRANSFORM && (mode == TFM_ROTATION || mode == TFM_TRACKBALL) && around == V3D_LOCAL) { bone->flag |= BONE_TRANSFORM_CHILD; } @@ -682,69 +675,73 @@ static void bone_children_clear_transflag(TransInfo *t, ListBase *lb) bone->flag &= ~BONE_TRANSFORM; } - bone_children_clear_transflag(t, &bone->childbase); + bone_children_clear_transflag(mode, around, &bone->childbase); } } /* sets transform flags in the bones, returns total */ -static void set_pose_transflags(TransInfo *t, Object *ob) +int count_set_pose_transflags(int *out_mode, short around, Object *ob) { bArmature *arm= ob->data; bPoseChannel *pchan; Bone *bone; - int hastranslation; - - t->total= 0; - - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; + int mode = *out_mode; + int hastranslation = 0; + int total = 0; + + for(pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + bone = pchan->bone; if(bone->layer & arm->layer) { if(bone->flag & BONE_SELECTED) bone->flag |= BONE_TRANSFORM; else bone->flag &= ~BONE_TRANSFORM; - + bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM; bone->flag &= ~BONE_TRANSFORM_CHILD; } } - + /* make sure no bone can be transformed when a parent is transformed */ /* since pchans are depsgraph sorted, the parents are in beginning of list */ - if(t->mode!=TFM_BONESIZE) { - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; + if(mode != TFM_BONESIZE) { + for(pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + bone = pchan->bone; if(bone->flag & BONE_TRANSFORM) - bone_children_clear_transflag(t, &bone->childbase); + bone_children_clear_transflag(mode, around, &bone->childbase); } - } + } /* now count, and check if we have autoIK or have to switch from translate to rotate */ - hastranslation= 0; + hastranslation = 0; - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - bone= pchan->bone; + for(pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + bone = pchan->bone; if(bone->flag & BONE_TRANSFORM) { - t->total++; - - if(t->mode==TFM_TRANSLATION) { + total++; + + if(mode == TFM_TRANSLATION) { if( has_targetless_ik(pchan)==NULL ) { if(pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) { if(pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM) - hastranslation= 1; + hastranslation = 1; } else if((pchan->protectflag & OB_LOCK_LOC)!=OB_LOCK_LOC) - hastranslation= 1; + hastranslation = 1; } else - hastranslation= 1; + hastranslation = 1; } } } /* if there are no translatable bones, do rotation */ - if(t->mode==TFM_TRANSLATION && !hastranslation) - t->mode= TFM_ROTATION; + if(mode == TFM_TRANSLATION && !hastranslation) + { + *out_mode = TFM_ROTATION; + } + + return total; } @@ -754,16 +751,16 @@ static void set_pose_transflags(TransInfo *t, Object *ob) static void pchan_autoik_adjust (bPoseChannel *pchan, short chainlen) { bConstraint *con; - + /* don't bother to search if no valid constraints */ if ((pchan->constflag & (PCHAN_HAS_IK|PCHAN_HAS_TARGET))==0) return; - + /* check if pchan has ik-constraint */ for (con= pchan->constraints.first; con; con= con->next) { if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0)) { bKinematicConstraint *data= con->data; - + /* only accept if a temporary one (for auto-ik) */ if (data->flag & CONSTRAINT_IK_TEMP) { /* chainlen is new chainlen, but is limited by maximum chainlen */ @@ -779,9 +776,9 @@ static void pchan_autoik_adjust (bPoseChannel *pchan, short chainlen) /* change the chain-length of auto-ik */ void transform_autoik_update (TransInfo *t, short mode) { - short *chainlen= &t->scene->toolsettings->autoik_chainlen; + short *chainlen= &t->settings->autoik_chainlen; bPoseChannel *pchan; - + /* mode determines what change to apply to chainlen */ if (mode == 1) { /* mode=1 is from WHEELMOUSEDOWN... increases len */ @@ -791,15 +788,15 @@ void transform_autoik_update (TransInfo *t, short mode) /* mode==-1 is from WHEELMOUSEUP... decreases len */ if (*chainlen > 0) (*chainlen)--; } - + /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */ if (ELEM(NULL, t->poseobj, t->poseobj->pose)) return; - + /* apply to all pose-channels */ for (pchan=t->poseobj->pose->chanbase.first; pchan; pchan=pchan->next) { pchan_autoik_adjust(pchan, *chainlen); - } + } } /* frees temporal IKs */ @@ -808,11 +805,11 @@ static void pose_grab_with_ik_clear(Object *ob) bKinematicConstraint *data; bPoseChannel *pchan; bConstraint *con, *next; - + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { /* clear all temporary lock flags */ pchan->ikflag &= ~(BONE_IK_NO_XDOF_TEMP|BONE_IK_NO_YDOF_TEMP|BONE_IK_NO_ZDOF_TEMP); - + pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET); /* remove all temporary IK-constraints added */ for (con= pchan->constraints.first; con; con= next) { @@ -839,11 +836,11 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) bKinematicConstraint *data; bConstraint *con; bConstraint *targetless = 0; - + /* Sanity check */ - if (pchan == NULL) + if (pchan == NULL) return 0; - + /* Rule: not if there's already an IK on this channel */ for (con= pchan->constraints.first; con; con= con->next) { if (con->type==CONSTRAINT_TYPE_KINEMATIC) { @@ -860,7 +857,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) return 0; } } - + con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC); BLI_addtail(&pchan->constraints, con); pchan->constflag |= (PCHAN_HAS_IK|PCHAN_HAS_TARGET); /* for draw, but also for detecting while pose solving */ @@ -873,22 +870,22 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) data->flag |= CONSTRAINT_IK_TEMP|CONSTRAINT_IK_AUTO; VECCOPY(data->grabtarget, pchan->pose_tail); data->rootbone= 1; - + /* we include only a connected chain */ while ((pchan) && (pchan->bone->flag & BONE_CONNECTED)) { /* here, we set ik-settings for bone from pchan->protectflag */ if (pchan->protectflag & OB_LOCK_ROTX) pchan->ikflag |= BONE_IK_NO_XDOF_TEMP; if (pchan->protectflag & OB_LOCK_ROTY) pchan->ikflag |= BONE_IK_NO_YDOF_TEMP; if (pchan->protectflag & OB_LOCK_ROTZ) pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP; - + /* now we count this pchan as being included */ data->rootbone++; pchan= pchan->parent; } - + /* make a copy of maximum chain-length */ data->max_rootbone= data->rootbone; - + return 1; } @@ -910,7 +907,7 @@ static short pose_grab_with_ik_children(bPose *pose, Bone *bone) if (pchan) added+= pose_grab_with_ik_add(pchan); } - + return added; } @@ -921,12 +918,12 @@ static short pose_grab_with_ik(Object *ob) bPoseChannel *pchan, *parent; Bone *bonec; short tot_ik= 0; - + if ((ob==NULL) || (ob->pose==NULL) || (ob->flag & OB_POSEMODE)==0) return 0; - + arm = ob->data; - + /* Rule: allow multiple Bones (but they must be selected, and only one ik-solver per chain should get added) */ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if (pchan->bone->layer & arm->layer) { @@ -939,7 +936,7 @@ static short pose_grab_with_ik(Object *ob) } if ((pchan->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL)) continue; - + /* rule: if selected Bone is not a root bone, it gets a temporal IK */ if (pchan->parent) { /* only adds if there's no IK yet (and no parent bone was selected) */ @@ -957,9 +954,9 @@ static short pose_grab_with_ik(Object *ob) } } } - + return (tot_ik) ? 1 : 0; -} +} /* only called with pose mode active object now */ @@ -971,13 +968,13 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob) TransDataExtension *tdx; short ik_on= 0; int i; - + t->total= 0; - + /* check validity of state */ arm= get_armature(ob); if ((arm==NULL) || (ob->pose==NULL)) return; - + if (arm->flag & ARM_RESTPOS) { if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE)==0) { // XXX use transform operator reports @@ -991,15 +988,15 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob) ik_on= pose_grab_with_ik(ob); if (ik_on) t->flag |= T_AUTOIK; } - + /* set flags and count total (warning, can change transform to rotate) */ - set_pose_transflags(t, ob); - - if(t->total==0) return; + t->total = count_set_pose_transflags(&t->mode, t->around, ob); + + if(t->total == 0) return; t->flag |= T_POSE; t->poseobj= ob; /* we also allow non-active objects to be transformed, in weightpaint */ - + /* init trans data */ td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransPoseBone"); tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt"); @@ -1007,8 +1004,8 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob) td->ext= tdx; td->tdi = NULL; td->val = NULL; - } - + } + /* use pose channels to fill trans data */ td= t->data; for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { @@ -1017,12 +1014,12 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob) td++; } } - + if(td != (t->data+t->total)) { // XXX use transform operator reports // BKE_report(op->reports, RPT_DEBUG, "Bone selection count error."); } - + /* initialise initial auto=ik chainlen's? */ if (ik_on) transform_autoik_update(t, 0); } @@ -1063,16 +1060,16 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) } if (!t->total) return; - + Mat3CpyMat4(mtx, t->obedit->obmat); Mat3Inv(smtx, mtx); td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransEditBone"); - + for (ebo = edbo->first; ebo; ebo = ebo->next) { ebo->oldlength = ebo->length; // length==0.0 on extrude, used for scaling radius of bone points - + if(ebo->layer & arm->layer) { if (t->mode==TFM_BONE_ENVELOPE) { @@ -1080,17 +1077,17 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) { td->val= &ebo->rad_head; td->ival= *td->val; - + VECCOPY (td->center, ebo->head); td->flag= TD_SELECTED; - + Mat3CpyMat3(td->smtx, smtx); Mat3CpyMat3(td->mtx, mtx); - + td->loc = NULL; td->ext = NULL; td->tdi = NULL; - + td++; } if (ebo->flag & BONE_TIPSEL) @@ -1099,17 +1096,17 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->ival= *td->val; VECCOPY (td->center, ebo->tail); td->flag= TD_SELECTED; - + Mat3CpyMat3(td->smtx, smtx); Mat3CpyMat3(td->mtx, mtx); - + td->loc = NULL; td->ext = NULL; td->tdi = NULL; - + td++; } - + } else if (t->mode==TFM_BONESIZE) { @@ -1129,19 +1126,19 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) } VECCOPY (td->center, ebo->head); td->flag= TD_SELECTED; - + /* use local bone matrix */ - VecSubf(delta, ebo->tail, ebo->head); + VecSubf(delta, ebo->tail, ebo->head); vec_roll_to_mat3(delta, ebo->roll, bonemat); Mat3MulMat3(td->mtx, mtx, bonemat); Mat3Inv(td->smtx, td->mtx); - + Mat3CpyMat3(td->axismtx, td->mtx); Mat3Ortho(td->axismtx); td->ext = NULL; td->tdi = NULL; - + td++; } } @@ -1152,13 +1149,13 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->loc= NULL; td->val= &(ebo->roll); td->ival= ebo->roll; - + VECCOPY (td->center, ebo->head); td->flag= TD_SELECTED; td->ext = NULL; td->tdi = NULL; - + td++; } } @@ -1176,7 +1173,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) Mat3CpyMat3(td->smtx, smtx); Mat3CpyMat3(td->mtx, mtx); - VecSubf(delta, ebo->tail, ebo->head); + VecSubf(delta, ebo->tail, ebo->head); vec_roll_to_mat3(delta, ebo->roll, td->axismtx); if ((ebo->flag & BONE_ROOTSEL) == 0) @@ -1202,7 +1199,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) Mat3CpyMat3(td->smtx, smtx); Mat3CpyMat3(td->mtx, mtx); - VecSubf(delta, ebo->tail, ebo->head); + VecSubf(delta, ebo->tail, ebo->head); vec_roll_to_mat3(delta, ebo->roll, td->axismtx); td->extra = ebo; /* to fix roll */ @@ -1239,16 +1236,16 @@ static void createTransMBallVerts(bContext *C, TransInfo *t) /* note: in prop mode we need at least 1 selected */ if (countsel==0) return; - - if(propmode) t->total = count; + + if(propmode) t->total = count; else t->total = countsel; - + td = t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(MBall EditMode)"); tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "MetaElement_TransExtension"); Mat3CpyMat4(mtx, t->obedit->obmat); Mat3Inv(smtx, mtx); - + for(ml= editelems.first; ml; ml= ml->next) { if(propmode || (ml->flag & SELECT)) { td->loc= &ml->x; @@ -1366,7 +1363,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) /* to be sure */ if(cu->editnurb==NULL) return; - + /* count total of vertices, check identical as in 2nd loop for making transdata! */ for(nu= cu->editnurb->first; nu; nu= nu->next) { if((nu->type & 7)==CU_BEZIER) { @@ -1395,14 +1392,14 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) } /* note: in prop mode we need at least 1 selected */ if (countsel==0) return; - - if(propmode) t->total = count; + + if(propmode) t->total = count; else t->total = countsel; t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)"); Mat3CpyMat4(mtx, t->obedit->obmat); Mat3Inv(smtx, mtx); - + td = t->data; for(nu= cu->editnurb->first; nu; nu= nu->next) { if((nu->type & 7)==CU_BEZIER) { @@ -1411,7 +1408,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) { if(bezt->hide==0) { TransDataCurveHandleFlags *hdata = NULL; - + if( propmode || ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) || ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)==0) @@ -1429,7 +1426,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) td->ext = NULL; td->tdi = NULL; td->val = NULL; - + hdata = initTransDataCurveHandes(td, bezt); Mat3CpyMat3(td->smtx, smtx); @@ -1439,7 +1436,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) count++; tail++; } - + /* This is the Curve Point, the other two are handles */ if(propmode || (bezt->f2 & SELECT)) { VECCOPY(td->iloc, bezt->vec[1]); @@ -1449,7 +1446,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) else td->flag= 0; td->ext = NULL; td->tdi = NULL; - + if (t->mode==TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */ td->val = &(bezt->radius); td->ival = bezt->radius; @@ -1462,13 +1459,13 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) Mat3CpyMat3(td->smtx, smtx); Mat3CpyMat3(td->mtx, mtx); - + if ((bezt->f1&SELECT)==0 && (bezt->f3&SELECT)==0) /* If the middle is selected but the sides arnt, this is needed */ if (hdata==NULL) { /* if the handle was not saved by the previous handle */ hdata = initTransDataCurveHandes(td, bezt); } - + td++; count++; tail++; @@ -1494,7 +1491,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) if (hdata==NULL) { /* if the handle was not saved by the previous handle */ hdata = initTransDataCurveHandes(td, bezt); } - + Mat3CpyMat3(td->smtx, smtx); Mat3CpyMat3(td->mtx, mtx); @@ -1510,7 +1507,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) } if (propmode && head != tail) calc_distanceCurveVerts(head, tail-1); - + /* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandes * but for now just dont change handle types */ if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0) @@ -1529,7 +1526,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) else td->flag= 0; td->ext = NULL; td->tdi = NULL; - + if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) { td->val = &(bp->radius); td->ival = bp->radius; @@ -1578,14 +1575,14 @@ static void createTransLatticeVerts(bContext *C, TransInfo *t) } bp++; } - + /* note: in prop mode we need at least 1 selected */ if (countsel==0) return; - - if(propmode) t->total = count; + + if(propmode) t->total = count; else t->total = countsel; t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)"); - + Mat3CpyMat4(mtx, t->obedit->obmat); Mat3Inv(smtx, mtx); @@ -1633,7 +1630,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) int count = 0, hasselected = 0; int propmode = t->flag & T_PROP_EDIT; - if(psys==NULL || t->scene->selectmode==SCE_SELECT_PATH) return; + if(psys==NULL || t->settings->particle.selectmode==SCE_SELECT_PATH) return; psmd = psys_get_modifier(ob,psys); @@ -1663,10 +1660,10 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) pa->flag |= PARS_TRANSFORM; } } - + /* note: in prop mode we need at least 1 selected */ if (hasselected==0) return; - + t->total = count; td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Particle Mode)"); @@ -1804,13 +1801,13 @@ static void editmesh_set_connectivity_distance(EditMesh *em, int total, float *v /* Floodfill routine */ /* - At worst this is n*n of complexity where n is number of edges + At worst this is n*n of complexity where n is number of edges Best case would be n if the list is ordered perfectly. Estimate is n log n in average (so not too bad) */ while(done) { done= 0; - + for(eed= em->edges.first; eed; eed= eed->next) { if(eed->h==0) { EditVert *v1= eed->v1, *v2= eed->v2; @@ -1905,7 +1902,7 @@ static void editmesh_set_connectivity_distance(EditMesh *em, int total, float *v VECMUL(cent, 1.0f / (float)efa->len); } - + if (cent[0] == 0.0f && cent[1] == 0.0f && cent[2] == 0.0f) cent[2] = 1.0f; VECCOPY(centout, cent); } @@ -1919,7 +1916,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, BMesh *em, BMVert *eve // td->loc = key->co; //else td->loc = eve->co; - + VECCOPY(td->center, td->loc); if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE)) get_face_center(td->center, em, eve); @@ -1949,7 +1946,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, BMesh *em, BMVert *eve static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { float *vec = userData; - + vec+= 3*index; VECCOPY(vec, co); } @@ -1958,14 +1955,14 @@ static int modifiers_disable_subsurf_temporary(Object *ob) { ModifierData *md; int disabled = 0; - + for(md=ob->modifiers.first; md; md=md->next) if(md->type==eModifierType_Subsurf) if(md->mode & eModifierMode_OnCage) { md->mode ^= eModifierMode_DisableTemporary; disabled= 1; } - + return disabled; } @@ -1987,12 +1984,12 @@ static float *get_crazy_mapped_editverts(TransInfo *t) vertexcos= MEM_mallocN(3*sizeof(float)*me->edit_btmesh->bm->totvert, "vertexcos map"); dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos); - + dm->release(dm); - + /* set back the flag, no new cage needs to be built, transform does it */ modifiers_disable_subsurf_temporary(t->obedit); - + return vertexcos; } @@ -2001,15 +1998,15 @@ static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, { float vecu[3], vecv[3]; float q1[4], q2[4]; - + TAN_MAKE_VEC(vecu, v1, v2); TAN_MAKE_VEC(vecv, v1, v3); triatoquat(v1, vecu, vecv, q1); - + TAN_MAKE_VEC(vecu, def1, def2); TAN_MAKE_VEC(vecv, def1, def3); triatoquat(def1, vecu, vecv, q2); - + QuatSub(quat, q2, q1); } #undef TAN_MAKE_VEC @@ -2021,16 +2018,16 @@ static void set_crazyspace_quats(BMEditMesh *em, float *origcos, float *mappedco BMFace *efa; float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4; intptr_t index= 0; - + /* two abused locations in vertices */ for(eve= em->verts.first; eve; eve= eve->next, index++) { eve->tmp.p = NULL; eve->prev= (BMVert *)index; } - + /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ for(efa= em->faces.first; efa; efa= efa->next) { - + /* retrieve mapped coordinates */ v1= mappedcos + 3*(intptr_t)(efa->v1->prev); v2= mappedcos + 3*(intptr_t)(efa->v2->prev); @@ -2045,7 +2042,7 @@ static void set_crazyspace_quats(BMEditMesh *em, float *origcos, float *mappedco efa->v2->tmp.p= (void*)quats; quats+= 4; } - + if(efa->v4) { v4= mappedcos + 3*(intptr_t)(efa->v4->prev); co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co; @@ -2113,7 +2110,7 @@ void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) { static void createTransEditVerts(bContext *C, TransInfo *t) { - Scene *scene = CTX_data_scene(C); + ToolSettings *ts = CTX_data_tool_settings(C); TransData *tob = NULL; BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh; BMesh *bm = em->bm; @@ -2133,16 +2130,15 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } // transform now requires awareness for select mode, so we tag the f1 flags in verts - if(scene->selectmode & SCE_SELECT_VERTEX) { - eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); - for( ; eve; eve=BMIter_Step(&iter)) { + if(ts->selectmode & SCE_SELECT_VERTEX) { + BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) { if(!BM_TestHFlag(eve, BM_HIDDEN) && BM_TestHFlag(eve, BM_SELECT)) BMINDEX_SET(eve, SELECT); else BMINDEX_SET(eve, 0); } } - else if(scene->selectmode & SCE_SELECT_EDGE) { + else if(ts->selectmode & SCE_SELECT_EDGE) { BMEdge *eed; eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); @@ -2172,7 +2168,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } } } - + /* now we can count */ eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); for( ; eve; eve=BMIter_Step(&iter)) { @@ -2181,10 +2177,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t) if(propmode) count++; } } - + /* note: in prop mode we need at least 1 selected */ if (countsel==0) return; - + /* check active */ if (em->selected.last) { BMEditSelection *ese = em->selected.last; @@ -2193,22 +2189,22 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } } - + if(propmode) { - t->total = count; - + t->total = count; + /* allocating scratch arrays */ vectors = (float *)MEM_mallocN(t->total * 3 * sizeof(float), "scratch vectors"); nears = (BMVert**)MEM_mallocN(t->total * sizeof(BMVert*), "scratch nears"); } else t->total = countsel; tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)"); - + Mat3CpyMat4(mtx, t->obedit->obmat); Mat3Inv(smtx, mtx); //BMESH_TODO if(propmode) editmesh_set_connectivity_distance(em, t->total, vectors, nears); - + /* detect CrazySpace [tm] */ if(propmode==0) { if(modifiers_getCageIndex(t->obedit, NULL)>=0) { @@ -2233,7 +2229,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } } } - + /* find out which half we do */ if(mirror) { eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); @@ -2245,19 +2241,19 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } } } - + eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); for(a=0; eve; eve=BMIter_Step(&iter), a++) { if(!BM_TestHFlag(eve, BM_HIDDEN)) { if(propmode || BMINDEX_GET(eve)) { VertsToTransData(t, tob, bm, eve); - + /* selected */ if(BMINDEX_GET(eve)) tob->flag |= TD_SELECTED; - + /* active */ if(eve == eve_act) tob->flag |= TD_ACTIVE; - + if(propmode) { /*BMESH_TODO this has to do with edge connectivity @@ -2273,11 +2269,11 @@ static void createTransEditVerts(bContext *C, TransInfo *t) tob->dist = MAXFLOAT; //} } - + /* CrazySpace */ if(defmats) { // || (quats && eve->tmp.p)) { float mat[3][3], imat[3][3], qmat[3][3]; - + /* use both or either quat and defmat correction */ //BMESH_TODO, need to restore this quats thing /*if(quats && eve->tmp.f) { @@ -2293,7 +2289,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) Mat3MulMat3(mat, mtx, defmats[a]); Mat3Inv(imat, mat); - + Mat3CpyMat3(tob->smtx, imat); Mat3CpyMat3(tob->mtx, mat); } @@ -2301,7 +2297,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) Mat3CpyMat3(tob->smtx, smtx); Mat3CpyMat3(tob->mtx, mtx); } - + /* Mirror? */ //BMESH_TODO @@ -2311,7 +2307,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) //} tob++; } - } + } } if (propmode) { MEM_freeN(vectors); @@ -2329,7 +2325,7 @@ void flushTransNodes(TransInfo *t) { int a; TransData2D *td; - + /* flush to 2d vector from internally used 3d vector */ for(a=0, td= t->data2d; a<t->total; a++, td++) { td->loc2d[0]= td->loc[0]; @@ -2347,7 +2343,7 @@ void flushTransSeq(TransInfo *t) TransDataSeq *tdsq= NULL; Sequence *seq; - + /* prevent updating the same seq twice * if the transdata order is changed this will mess up @@ -2365,7 +2361,7 @@ void flushTransSeq(TransInfo *t) case SELECT: if (seq->type != SEQ_META && seq_tx_test(seq)) /* for meta's, their children move */ seq->start= new_frame - tdsq->start_offset; - + if (seq->depth==0) { seq->machine= (int)(td2d->loc[1] + 0.5f); CLAMP(seq->machine, 1, MAXSEQ); @@ -2389,7 +2385,7 @@ void flushTransSeq(TransInfo *t) * children are ALWAYS transformed first * so we dont need to do this in another loop. */ calc_sequence(seq); - + /* test overlap, displayes red outline */ seq->flag &= ~SEQ_OVERLAP; if( seq_test_overlap(seqbasep, seq) ) { @@ -2467,7 +2463,7 @@ static void createTransUVs(bContext *C, TransInfo *t) EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh; EditFace *efa; - + if(!ED_uvedit_test(t->obedit)) return; /* count */ @@ -2476,10 +2472,10 @@ static void createTransUVs(bContext *C, TransInfo *t) if(uvedit_face_visible(scene, ima, efa, tf)) { efa->tmp.p = tf; - - if (uvedit_uv_selected(scene, efa, tf, 0)) countsel++; - if (uvedit_uv_selected(scene, efa, tf, 1)) countsel++; - if (uvedit_uv_selected(scene, efa, tf, 2)) countsel++; + + if (uvedit_uv_selected(scene, efa, tf, 0)) countsel++; + if (uvedit_uv_selected(scene, efa, tf, 1)) countsel++; + if (uvedit_uv_selected(scene, efa, tf, 2)) countsel++; if (efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) countsel++; if(propmode) count += (efa->v4)? 4: 3; @@ -2487,10 +2483,10 @@ static void createTransUVs(bContext *C, TransInfo *t) efa->tmp.p = NULL; } } - + /* note: in prop mode we need at least 1 selected */ if (countsel==0) return; - + t->total= (propmode)? count: countsel; t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)"); /* for each 2d uv coord a 3d vector is allocated, so that they can be @@ -2502,7 +2498,7 @@ static void createTransUVs(bContext *C, TransInfo *t) td= t->data; td2d= t->data2d; - + for (efa= em->faces.first; efa; efa= efa->next) { if ((tf=(MTFace *)efa->tmp.p)) { if (propmode) { @@ -2519,7 +2515,7 @@ static void createTransUVs(bContext *C, TransInfo *t) } } } - + if (sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_begin(t->scene, t->obedit); #endif @@ -2541,7 +2537,7 @@ void flushTransUVs(TransInfo *t) for(a=0, td= t->data2d; a<t->total; a++, td++) { td->loc2d[0]= td->loc[0]*invx; td->loc2d[1]= td->loc[1]*invy; - + if((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) { td->loc2d[0]= (float)floor(width*td->loc2d[0] + 0.5f)/width; td->loc2d[1]= (float)floor(height*td->loc2d[1] + 0.5f)/height; @@ -2592,40 +2588,251 @@ int clipUVTransform(TransInfo *t, float *vec, int resize) vec[1] -= max[1]-aspy; else clipy= 0; - } + } return (clipx || clipy); } -/* ********************* ACTION/NLA EDITOR ****************** */ +/* ********************* ANIMATION EDITORS (GENERAL) ************************* */ + +/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */ +static short FrameOnMouseSide(char side, float frame, float cframe) +{ + /* both sides, so it doesn't matter */ + if (side == 'B') return 1; + + /* only on the named side */ + if (side == 'R') + return (frame >= cframe) ? 1 : 0; + else + return (frame <= cframe) ? 1 : 0; +} + +/* ********************* NLA EDITOR ************************* */ + +static void createTransNlaData(bContext *C, TransInfo *t) +{ + Scene *scene= CTX_data_scene(C); + TransData *td = NULL; + TransDataNla *tdn = NULL; + + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + int count=0; + char side; + + /* determine what type of data we are operating on */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return; + + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_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 + } + else { + /* normal transform - both sides of current frame are considered */ + side = 'B'; + } + + /* loop 1: count how many strips are selected (consider each strip as 2 points) */ + for (ale= anim_data.first; ale; ale= ale->next) { + 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... + /* transition strips can't get directly transformed */ + if (strip->type != NLASTRIP_TYPE_TRANSITION) { + if (strip->flag & NLASTRIP_FLAG_SELECT) { + if (FrameOnMouseSide(side, strip->start, (float)CFRA)) count++; + if (FrameOnMouseSide(side, strip->end, (float)CFRA)) count++; + } + } + } + } + + /* stop if trying to build list if nothing selected */ + if (count == 0) { + /* cleanup temp list */ + BLI_freelistN(&anim_data); + return; + } + + /* allocate memory for data */ + t->total= count; + + t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(NLA Editor)"); + td= t->data; + t->customData= MEM_callocN(t->total*sizeof(TransDataNla), "TransDataNla (NLA Editor)"); + tdn= t->customData; + + /* loop 2: build transdata array */ + for (ale= anim_data.first; ale; ale= ale->next) { + /* only if a real NLA-track */ + if (ale->type == ANIMTYPE_NLATRACK) { + NlaTrack *nlt= (NlaTrack *)ale->data; + NlaStrip *strip; + + /* only consider selected strips */ + for (strip= nlt->strips.first; strip; strip= strip->next) { + // TODO: we can make strips have handles later on... + /* transition strips can't get directly transformed */ + if (strip->type != NLASTRIP_TYPE_TRANSITION) { + if (strip->flag & NLASTRIP_FLAG_SELECT) { + /* our transform data is constructed as follows: + * - only the handles on the right side of the current-frame get included + * - td structs are transform-elements operated on by the transform system + * and represent a single handle. The storage/pointer used (val or loc) depends on + * whether we're scaling or transforming. Ultimately though, the handles + * the td writes to will simply be a dummy in tdn + * - for each strip being transformed, a single tdn struct is used, so in some + * 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); + } + else { + td->val= &tdn->h1[0]; + td->ival= tdn->h1[0]; + } + + td->extra= tdn; + td++; + } + if (FrameOnMouseSide(side, strip->end, (float)CFRA)) + { + /* 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); + } + else { + 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... + */ + if (tdn->handle == 2) + tdn += 2; + else + tdn++; + } + } + } + } + } + + /* cleanup temp list */ + BLI_freelistN(&anim_data); +} + +/* ********************* ACTION EDITOR ****************** */ /* Called by special_aftertrans_update to make sure selected gp-frames replace * any other gp-frames which may reside on that frame (that are not selected). * It also makes sure gp-frames are still stored in chronological order after * transform. */ +#if 0 static void posttrans_gpd_clean (bGPdata *gpd) { bGPDlayer *gpl; - + for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { ListBase sel_buffer = {NULL, NULL}; bGPDframe *gpf, *gpfn; bGPDframe *gfs, *gfsn; - - /* loop 1: loop through and isolate selected gp-frames to buffer + + /* loop 1: loop through and isolate selected gp-frames to buffer * (these need to be sorted as they are isolated) */ for (gpf= gpl->frames.first; gpf; gpf= gpfn) { short added= 0; gpfn= gpf->next; - + if (gpf->flag & GP_FRAME_SELECT) { BLI_remlink(&gpl->frames, gpf); - + /* find place to add them in buffer * - go backwards as most frames will still be in order, - * so doing it this way will be faster + * so doing it this way will be faster */ for (gfs= sel_buffer.last; gfs; gfs= gfs->prev) { /* if current (gpf) occurs after this one in buffer, add! */ @@ -2639,27 +2846,27 @@ static void posttrans_gpd_clean (bGPdata *gpd) BLI_addhead(&sel_buffer, gpf); } } - + /* error checking: it is unlikely, but may be possible to have none selected */ if (sel_buffer.first == NULL) continue; - + /* if all were selected (i.e. gpl->frames is empty), then just transfer sel-buf over */ if (gpl->frames.first == NULL) { gpl->frames.first= sel_buffer.first; gpl->frames.last= sel_buffer.last; - + continue; } - + /* loop 2: remove duplicates of frames in buffers */ for (gpf= gpl->frames.first; gpf && sel_buffer.first; gpf= gpfn) { gpfn= gpf->next; - + /* loop through sel_buffer, emptying stuff from front of buffer if ok */ for (gfs= sel_buffer.first; gfs && gpf; gfs= gfsn) { gfsn= gfs->next; - + /* if this buffer frame needs to go before current, add it! */ if (gfs->framenum < gpf->framenum) { /* transfer buffer frame to frames list (before current) */ @@ -2671,23 +2878,24 @@ static void posttrans_gpd_clean (bGPdata *gpd) /* transfer buffer frame to frames list (before current) */ BLI_remlink(&sel_buffer, gfs); BLI_insertlinkbefore(&gpl->frames, gpf, gfs); - + /* get rid of current frame */ // TRANSFORM_FIX_ME //gpencil_layer_delframe(gpl, gpf); } } } - + /* if anything is still in buffer, append to end */ for (gfs= sel_buffer.first; gfs; gfs= gfsn) { gfsn= gfs->next; - + BLI_remlink(&sel_buffer, gfs); BLI_addtail(&gpl->frames, gfs); } } } +#endif /* Called during special_aftertrans_update to make sure selected keyframes replace * any other keyframes which may reside on that frame (that is not selected). @@ -2696,36 +2904,36 @@ static void posttrans_fcurve_clean (FCurve *fcu) { float *selcache; /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */ int len, index, i; /* number of frames in cache, item index */ - + /* allocate memory for the cache */ // TODO: investigate using GHash for this instead? - if (fcu->totvert == 0) + if (fcu->totvert == 0) return; selcache= MEM_callocN(sizeof(float)*fcu->totvert, "FCurveSelFrameNums"); len= 0; index= 0; - - /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting - * as there is no guarantee what order the keyframes are exactly, even though + + /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting + * as there is no guarantee what order the keyframes are exactly, even though * they have been sorted by time. */ - + /* Loop 1: find selected keyframes */ for (i = 0; i < fcu->totvert; i++) { BezTriple *bezt= &fcu->bezt[i]; - + if (BEZSELECTED(bezt)) { selcache[index]= bezt->vec[1][0]; index++; len++; } } - + /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */ if (len) { for (i = 0; i < fcu->totvert; i++) { BezTriple *bezt= &fcu->bezt[i]; - + if (BEZSELECTED(bezt) == 0) { /* check beztriple should be removed according to cache */ for (index= 0; index < len; index++) { @@ -2738,97 +2946,86 @@ static void posttrans_fcurve_clean (FCurve *fcu) } } } - + testhandles_fcurve(fcu); } - + /* free cache */ MEM_freeN(selcache); } + /* Called by special_aftertrans_update to make sure selected keyframes replace * any other keyframes which may reside on that frame (that is not selected). - * remake_action_ipos should have already been called + * remake_action_ipos should have already been called */ static void posttrans_action_clean (bAnimContext *ac, bAction *act) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; - + /* filter data */ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); ANIM_animdata_filter(ac, &anim_data, filter, act, ANIMCONT_ACTION); - - /* loop through relevant data, removing keyframes from the ipo-blocks that were attached - * - all keyframes are converted in/out of global time + + /* loop through relevant data, removing keyframes from the ipo-blocks that were attached + * - all keyframes are converted in/out of global time */ for (ale= anim_data.first; ale; ale= ale->next) { - Object *nob= ANIM_nla_mapping_get(ac, ale); - - if (nob) { - //ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 0, 1); + AnimData *adt= ANIM_nla_mapping_get(ac, ale); + + if (adt) { + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); posttrans_fcurve_clean(ale->key_data); - //ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } - else + else posttrans_fcurve_clean(ale->key_data); } - + /* free temp data */ BLI_freelistN(&anim_data); } /* ----------------------------- */ -/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */ -static short FrameOnMouseSide(char side, float frame, float cframe) -{ - /* both sides, so it doesn't matter */ - if (side == 'B') return 1; - - /* only on the named side */ - if (side == 'R') - return (frame >= cframe) ? 1 : 0; - else - return (frame <= cframe) ? 1 : 0; -} - /* fully select selected beztriples, but only include if it's on the right side of cfra */ static int count_fcurve_keys(FCurve *fcu, char side, float cfra) { BezTriple *bezt; int i, count = 0; - + if (ELEM(NULL, fcu, fcu->bezt)) return count; - + /* only include points that occur on the right side of cfra */ for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) { if (bezt->f2 & SELECT) { /* fully select the other two keys */ bezt->f1 |= SELECT; bezt->f3 |= SELECT; - + /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) count += 3; } } - + return count; } /* fully select selected beztriples, but only include if it's on the right side of cfra */ +#if 0 static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra) { bGPDframe *gpf; int count = 0; - + if (gpl == NULL) return count; - + /* only include points that occur on the right side of cfra */ for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { if (gpf->flag & GP_FRAME_SELECT) { @@ -2836,22 +3033,22 @@ static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra) count++; } } - + return count; } +#endif /* This function assigns the information to transdata */ -static void TimeToTransData(TransData *td, float *time, Object *ob) +static void TimeToTransData(TransData *td, float *time, AnimData *adt) { /* memory is calloc'ed, so that should zero everything nicely for us */ td->val = time; td->ival = *(time); - - /* store the Object where this keyframe exists as a keyframe of the - * active action as td->ob. Usually, this member is only used for constraints - * drawing + + /* store the AnimData where this keyframe exists as a keyframe of the + * active action as td->extra. */ - td->ob= ob; + td->extra= adt; } /* This function advances the address to which td points to, so it must return @@ -2859,34 +3056,34 @@ static void TimeToTransData(TransData *td, float *time, Object *ob) * overwrite the existing ones... i.e. td = IcuToTransData(td, icu, ob, side, cfra); * * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data - * on the named side are used. + * on the named side are used. */ -static TransData *FCurveToTransData(TransData *td, FCurve *fcu, Object *ob, char side, float cfra) +static TransData *FCurveToTransData(TransData *td, FCurve *fcu, AnimData *adt, char side, float cfra) { BezTriple *bezt; int i; - + if (fcu == NULL) return td; - + for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) { /* only add selected keyframes (for now, proportional edit is not enabled) */ if (BEZSELECTED(bezt)) { /* only add if on the right 'side' of the current frame */ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) { /* each control point needs to be added separetely */ - TimeToTransData(td, bezt->vec[0], ob); + TimeToTransData(td, bezt->vec[0], adt); td++; - - TimeToTransData(td, bezt->vec[1], ob); + + TimeToTransData(td, bezt->vec[1], adt); td++; - - TimeToTransData(td, bezt->vec[2], ob); + + TimeToTransData(td, bezt->vec[2], adt); td++; } - } + } } - + return td; } @@ -2901,17 +3098,17 @@ void flushTransGPactionData (TransInfo *t) { tGPFtransdata *tfd; int i; - + /* find the first one to start from */ if (t->mode == TFM_TIME_SLIDE) tfd= (tGPFtransdata *)( (float *)(t->customData) + 2 ); else tfd= (tGPFtransdata *)(t->customData); - + /* flush data! */ for (i = 0; i < t->total; i++, tfd++) { *(tfd->sdata)= (int)floor(tfd->val + 0.5); - } + } } /* This function advances the address to which td points to, so it must return @@ -2919,13 +3116,14 @@ void flushTransGPactionData (TransInfo *t) * overwrite the existing ones... i.e. td = GPLayerToTransData(td, ipo, ob, side, cfra); * * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data - * on the named side are used. + * on the named side are used. */ +#if 0 static int GPLayerToTransData (TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl, char side, float cfra) { bGPDframe *gpf; int count= 0; - + /* check for select frames on right side of current frame */ for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { if (gpf->flag & GP_FRAME_SELECT) { @@ -2933,10 +3131,10 @@ static int GPLayerToTransData (TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl /* memory is calloc'ed, so that should zero everything nicely for us */ td->val= &tfd->val; td->ival= (float)gpf->framenum; - + tfd->val= (float)gpf->framenum; tfd->sdata= &gpf->framenum; - + /* advance td now */ td++; tfd++; @@ -2944,9 +3142,10 @@ static int GPLayerToTransData (TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl } } } - + return count; } +#endif static void createTransActionData(bContext *C, TransInfo *t) { @@ -2973,7 +3172,7 @@ static void createTransActionData(bContext *C, TransInfo *t) 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 */ @@ -2989,13 +3188,13 @@ static void createTransActionData(bContext *C, TransInfo *t) /* 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); + 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) + * higher scaling ratios, but is faster than converting all points) */ - if (nob) - cfra = get_action_frame(nob, (float)CFRA); + if (adt) + cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); else cfra = (float)CFRA; @@ -3036,24 +3235,24 @@ static void createTransActionData(bContext *C, TransInfo *t) //if (ale->type == ANIMTYPE_GPLAYER) { // bGPDlayer *gpl= (bGPDlayer *)ale->data; // int i; - // + // // i = GPLayerToTransData(td, tfd, gpl, side, cfra); // td += i; // tfd += i; //} //else { - Object *nob= ANIM_nla_mapping_get(&ac, ale); + 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) + * higher scaling ratios, but is faster than converting all points) */ - if (nob) - cfra = get_action_frame(nob, (float)CFRA); + if (adt) + cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); else cfra = (float)CFRA; - td= FCurveToTransData(td, fcu, nob, side, cfra); + td= FCurveToTransData(td, fcu, adt, side, cfra); //} } @@ -3068,42 +3267,40 @@ static void createTransActionData(bContext *C, TransInfo *t) if (max < *(td->val)) max= *(td->val); } - /* minx/maxx values used by TimeSlide are stored as a + /* 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). + * in postTrans (T_FREE_CUSTOMDATA). */ *((float *)(t->customData)) = min; *((float *)(t->customData) + 1) = max; } - + /* cleanup temp list */ BLI_freelistN(&anim_data); } /* ********************* GRAPH EDITOR ************************* */ - - /* Helper function for createTransGraphEditData, which is reponsible for associating * source data with transform data */ -static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, float *loc, float *cent, short selected, short ishandle, short intvals) +static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, float *loc, float *cent, short selected, short ishandle, short intvals) { /* 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]) * - * Due to NLA scaling, we apply NLA scaling to some of the verts here, - * and then that scaling will be undone after transform is done. + * 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 (nob) { - td2d->loc[0] = get_action_frame_inv(nob, loc[0]); + 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] = get_action_frame_inv(nob, cent[0]); + td->center[0] = BKE_nla_tweakedit_remap(adt, cent[0], NLATIME_CONVERT_UNMAP); td->center[1] = cent[1]; td->center[2] = 0.0f; @@ -3119,12 +3316,15 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, fl 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; @@ -3132,14 +3332,14 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, fl else td->dist= MAXFLOAT; - if (ishandle) + if (ishandle) td->flag |= TD_NOTIMESNAP; if (intvals) td->flag |= TD_INTVALUES; Mat3One(td->mtx); Mat3One(td->smtx); -} +} static void createTransGraphEditData(bContext *C, TransInfo *t) { @@ -3167,7 +3367,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) /* 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) { @@ -3184,14 +3384,14 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) /* 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... + 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) + * higher scaling ratios, but is faster than converting all points) */ - if (nob) - cfra = get_action_frame(nob, (float)CFRA); + if (adt) + cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); else cfra = (float)CFRA; @@ -3241,13 +3441,19 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) td2d= t->data2d; /* 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 + 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) + */ + if (adt) + 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; @@ -3261,7 +3467,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) 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, intvals); + bezt_to_transdata(td++, td2d++, adt, bezt->vec[0], bezt->vec[1], 1, 1, intvals); } else h1= 0; @@ -3270,7 +3476,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) 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, intvals); + bezt_to_transdata(td++, td2d++, adt, bezt->vec[2], bezt->vec[1], 1, 1, intvals); } else h2= 0; @@ -3286,12 +3492,12 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) hdata = initTransDataCurveHandes(td, bezt); } - bezt_to_transdata(td++, td2d++, nob, bezt->vec[1], bezt->vec[1], 1, 0, intvals); + 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. + /* 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)) { @@ -3305,7 +3511,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) } /* Sets handles based on the selection */ - testhandles_fcurve(fcu); + testhandles_fcurve(fcu); } /* cleanup temp list */ @@ -3350,7 +3556,7 @@ static BeztMap *bezt_to_beztmaps (BezTriple *bezts, int totvert) bezm->pipo= (prevbezt) ? prevbezt->ipo : bezt->ipo; bezm->cipo= bezt->ipo; } - + return bezms; } @@ -3383,7 +3589,7 @@ static void sort_time_beztmaps (BeztMap *bezms, int totvert) * optimisation: this only needs to be performed in the first loop */ if (bezm->swapHs == 0) { - if ( (bezm->bezt->vec[0][0] > bezm->bezt->vec[1][0]) && + if ( (bezm->bezt->vec[0][0] > bezm->bezt->vec[1][0]) && (bezm->bezt->vec[2][0] < bezm->bezt->vec[1][0]) ) { /* handles need to be swapped */ @@ -3396,7 +3602,7 @@ static void sort_time_beztmaps (BeztMap *bezms, int totvert) } bezm++; - } + } } } @@ -3409,7 +3615,7 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv int i, j; char *adjusted; - /* dynamically allocate an array of chars to mark whether an TransData's + /* 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 */ @@ -3418,7 +3624,7 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv /* for each beztmap item, find if it is used anywhere */ bezm= bezms; for (i= 0; i < totvert; i++, bezm++) { - /* loop through transdata, testing if we have a hit + /* loop through transdata, testing if we have a hit * for the handles (vec[0]/vec[2]), we must also check if they need to be swapped... */ td= t->data2d; @@ -3463,11 +3669,11 @@ static void beztmap_to_data (TransInfo *t, FCurve *fcu, BeztMap *bezms, int totv MEM_freeN(adjusted); } -/* This function is called by recalcData during the Transform loop to recalculate +/* 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 + * 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_graph_transdata (TransInfo *t, ListBase *anim_data) @@ -3499,37 +3705,44 @@ void remake_graph_transdata (TransInfo *t, ListBase *anim_data) } /* this function is called on recalcData to apply the transforms applied - * to the transdata on to the actual keyframe data + * to the transdata on to the actual keyframe data */ void flushTransGraphData(TransInfo *t) { SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; TransData *td; TransData2D *td2d; + 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++) { - /* handle snapping for time values - * - we should still be in NLA-mapping timespace + 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) */ 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) ); + case SACTSNAP_FRAME: /* snap to nearest frame (or second if drawing seconds) */ + if (sipo->flag & SIPO_DRAWTIME) + td2d->loc[0]= (float)( floor((td2d->loc[0]/secf) + 0.5f) * secf ); + else + 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]); + 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 */ - //if (NLA_IPO_SCALED) - // td2d->loc2d[0]= get_action_frame(OBACT, td2d->loc[0]); - //else + /* 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 */ @@ -3540,7 +3753,6 @@ void flushTransGraphData(TransInfo *t) } } - /* **************** IpoKey stuff, for Object TransData ********** */ /* while transforming */ @@ -3569,13 +3781,13 @@ static void ipokey_to_transdata(IpoKey *ik, TransData *td) TransDataIpokey *tdi= td->tdi; BezTriple *bezt; int a, delta= 0; - + td->val= NULL; // is read on ESC - + for(a=0; a<OB_TOTIPO; a++) { if(ik->data[a]) { bezt= ik->data[a]; - + switch( ob_ar[a] ) { case OB_LOC_X: case OB_DLOC_X: @@ -3586,7 +3798,7 @@ static void ipokey_to_transdata(IpoKey *ik, TransData *td) case OB_LOC_Z: case OB_DLOC_Z: tdi->locz= &(bezt->vec[1][1]); break; - + case OB_DROT_X: delta= 1; case OB_ROT_X: @@ -3599,7 +3811,7 @@ static void ipokey_to_transdata(IpoKey *ik, TransData *td) delta= 1; case OB_ROT_Z: tdi->rotz= &(bezt->vec[1][1]); break; - + case OB_SIZE_X: case OB_DSIZE_X: tdi->sizex= &(bezt->vec[1][1]); break; @@ -3608,26 +3820,26 @@ static void ipokey_to_transdata(IpoKey *ik, TransData *td) tdi->sizey= &(bezt->vec[1][1]); break; case OB_SIZE_Z: case OB_DSIZE_Z: - tdi->sizez= &(bezt->vec[1][1]); break; - } + tdi->sizez= &(bezt->vec[1][1]); break; + } } } - + /* oldvals for e.g. undo */ if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx); if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy); if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz); - + /* remember, for mapping curves ('1'=10 degrees) */ if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx); if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty); if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz); - + /* this is not allowed to be dsize! */ if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex); if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey); if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez); - + tdi->flag= TOB_IPO; if(delta) tdi->flag |= TOB_IPODROT; } @@ -3644,8 +3856,8 @@ static void ipokey_to_transdata(IpoKey *ik, TransData *td) static short constraints_list_needinv(TransInfo *t, ListBase *list) { bConstraint *con; - - /* loop through constraints, checking if there's one of the mentioned + + /* loop through constraints, checking if there's one of the mentioned * constraints needing special crazyspace corrections */ if (list) { @@ -3657,19 +3869,19 @@ static short constraints_list_needinv(TransInfo *t, ListBase *list) if (con->type == CONSTRAINT_TYPE_CHILDOF) return 1; if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) return 1; if (con->type == CONSTRAINT_TYPE_CLAMPTO) return 1; - + /* constraints that require this only under special conditions */ if (con->type == CONSTRAINT_TYPE_ROTLIKE) { /* CopyRot constraint only does this when rotating, and offset is on */ bRotateLikeConstraint *data = (bRotateLikeConstraint *)con->data; - + if ((data->flag & ROTLIKE_OFFSET) && (t->mode == TFM_ROTATION)) return 1; } } } } - + /* no appropriate candidates found */ return 0; } @@ -3701,13 +3913,13 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count *flag= 0; } else if (seq->type ==SEQ_META) { - + /* for meta's we only ever need to extend their children, no matter what depth * just check the meta's are in the bounds */ if (t->frame_side=='R' && right <= cfra) *recursive= 0; else if (t->frame_side=='L' && left >= cfra) *recursive= 0; else *recursive= 1; - + *count= 0; *flag= 0; } @@ -3831,15 +4043,15 @@ static TransData *SeqToTransData(TransInfo *t, TransData *td, TransData2D *td2d, td2d->loc[2] = 0.0f; td2d->loc2d = NULL; - + tdsq->seq= seq; /* Use instead of seq->flag for nested strips and other * cases where the selection may need to be modified */ tdsq->flag= flag; tdsq->sel_flag= sel_flag; - - + + td->extra= (void *)tdsq; /* allow us to update the strip from here */ td->flag = 0; @@ -3861,7 +4073,7 @@ static TransData *SeqToTransData(TransInfo *t, TransData *td, TransData2D *td2d, /* Time Transform (extend) */ td->val= td2d->loc; td->ival= td2d->loc[0]; - + return td; } @@ -3870,15 +4082,15 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData * Sequence *seq; int recursive, count, flag; int tot= 0; - + for (seq= seqbase->first; seq; seq= seq->next) { SeqTransInfo(t, seq, &recursive, &count, &flag); - + /* add children first so recalculating metastrips does nested strips first */ if (recursive) { int tot_children= SeqToTransData_Recursive(t, &seq->seqbase, td, td2d, tdsq); - + td= td + tot_children; td2d= td2d + tot_children; tdsq= tdsq + tot_children; @@ -3911,7 +4123,7 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData * static void createTransSeqData(bContext *C, TransInfo *t) { - + View2D *v2d= UI_view2d_fromcontext(C); Scene *scene= CTX_data_scene(C); Editing *ed= seq_give_editing(t->scene, FALSE); @@ -3949,12 +4161,12 @@ static void createTransSeqData(bContext *C, TransInfo *t) if (count == 0) { return; } - + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransSeq TransData"); td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransSeq TransData2D"); tdsq = t->customData= MEM_callocN(t->total*sizeof(TransDataSeq), "TransSeq TransDataSeq"); - + /* loop 2: build transdata array */ SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq); @@ -3962,7 +4174,7 @@ static void createTransSeqData(bContext *C, TransInfo *t) /* transcribe given object into TransData for Transforming */ -static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *ob) +static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object *ob) { Scene *scene = CTX_data_scene(C); Object *track; @@ -3976,35 +4188,35 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * Mat3Ortho(td->axismtx); td->con= ob->constraints.first; - - /* hack: tempolarily disable tracking and/or constraints when getting + + /* hack: tempolarily disable tracking and/or constraints when getting * object matrix, if tracking is on, or if constraints don't need * inverse correction to stop it from screwing up space conversion * matrix later */ constinv = constraints_list_needinv(t, &ob->constraints); - + /* disable constraints inversion for dummy pass */ if (t->mode == TFM_DUMMY) skip_invert = 1; - + if (skip_invert == 0 && (ob->track || constinv==0)) { track= ob->track; ob->track= NULL; - + if (constinv == 0) { fakecons.first = ob->constraints.first; fakecons.last = ob->constraints.last; ob->constraints.first = ob->constraints.last = NULL; } - + where_is_object(t->scene, ob); - + if (constinv == 0) { ob->constraints.first = fakecons.first; ob->constraints.last = fakecons.last; } - + ob->track= track; } else @@ -4014,23 +4226,23 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * td->loc = ob->loc; VECCOPY(td->iloc, td->loc); - + td->ext->rot = ob->rot; VECCOPY(td->ext->irot, ob->rot); VECCOPY(td->ext->drot, ob->drot); - + td->ext->size = ob->size; VECCOPY(td->ext->isize, ob->size); VECCOPY(td->ext->dsize, ob->dsize); VECCOPY(td->center, ob->obmat[3]); - + Mat4CpyMat4(td->ext->obmat, ob->obmat); /* is there a need to set the global<->data space conversion matrices? */ if (ob->parent || constinv) { float totmat[3][3], obinv[3][3]; - + /* Get the effect of parenting, and/or certain constraints. * NOTE: some Constraints, and also Tracking should never get this * done, as it doesn't work well. @@ -4046,7 +4258,7 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * Mat3One(td->smtx); Mat3One(td->mtx); } - + /* set active flag */ if (ob == OBACT) { @@ -4061,39 +4273,39 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t) { Scene *sce = CTX_data_scene(C); View3D *v3d = t->view; - + /* if Base selected and has parent selected: base->flag= BA_WAS_SEL */ Base *base; - + /* don't do it if we're not actually going to recalculate anything */ if(t->mode == TFM_DUMMY) return; /* makes sure base flags and object flags are identical */ copy_baseflags(t->scene); - + /* handle pending update events, otherwise they got copied below */ for (base= sce->base.first; base; base= base->next) { - if(base->object->recalc) + if(base->object->recalc) object_handle_update(t->scene, base->object); } - + for (base= sce->base.first; base; base= base->next) { base->flag &= ~BA_WAS_SEL; - + if(TESTBASELIB(v3d, base)) { Object *ob= base->object; Object *parsel= ob->parent; - + /* if parent selected, deselect */ while(parsel) { if(parsel->flag & SELECT) break; parsel= parsel->parent; } - + if(parsel) { if ((t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) && t->around == V3D_LOCAL) @@ -4113,7 +4325,7 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t) /* all recalc flags get flushed to all layers, so a layer flip later on works fine */ DAG_scene_flush_update(t->scene, -1, 0); - + /* and we store them temporal in base (only used for transform code) */ /* this because after doing updates, the object->recalc is cleared */ for (base= sce->base.first; base; base= base->next) { @@ -4128,7 +4340,7 @@ static void clear_trans_object_base_flags(TransInfo *t) { Scene *sce = t->scene; Base *base; - + for (base= sce->base.first; base; base = base->next) { if(base->flag & BA_WAS_SEL) @@ -4138,39 +4350,25 @@ static void clear_trans_object_base_flags(TransInfo *t) } } -/* auto-keyframing feature - checks for whether anything should be done for the current frame */ -// TODO: this should probably be done per channel instead... -short autokeyframe_cfra_can_key(Scene *scene, Object *ob) -{ - float cfra= (float)CFRA; // XXX for now, this will do - - /* only filter if auto-key mode requires this */ - if (IS_AUTOKEY_ON(scene) == 0) - return 0; - else if (IS_AUTOKEY_MODE(scene, NORMAL)) - return 1; - else - return id_frame_has_keyframe(&ob->id, cfra, ANIMFILTER_KEYS_LOCAL); -} - -/* auto-keyframing feature - for objects - * tmode: should be a transform mode +/* auto-keyframing feature - for objects + * tmode: should be a transform mode */ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) { ID *id= &ob->id; FCurve *fcu; - - if (autokeyframe_cfra_can_key(scene, ob)) { + + // TODO: this should probably be done per channel instead... + if (autokeyframe_cfra_can_key(scene, id)) { AnimData *adt= ob->adt; float cfra= (float)CFRA; // xxx this will do for now short flag = 0; - + if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED; if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX; - + if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { /* only key on available channels */ if (adt && adt->action) { @@ -4182,7 +4380,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) } else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) { short doLoc=0, doRot=0, doScale=0; - + /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */ if (tmode == TFM_TRANSLATION) { doLoc = 1; @@ -4193,9 +4391,9 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) doLoc = 1; } else if (v3d->around == V3D_CURSOR) - doLoc = 1; - - if ((v3d->flag & V3D_ALIGN)==0) + doLoc = 1; + + if ((v3d->flag & V3D_ALIGN)==0) doRot = 1; } else if (tmode == TFM_RESIZE) { @@ -4204,12 +4402,12 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) doLoc = 1; } else if (v3d->around == V3D_CURSOR) - doLoc = 1; - + doLoc = 1; + if ((v3d->flag & V3D_ALIGN)==0) doScale = 1; } - + // TODO: the group names here are temporary... // TODO: should this be made to use the builtin KeyingSets instead? if (doLoc) { @@ -4234,22 +4432,22 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag); - + insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag); - + insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag); insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag); } - + // XXX todo... find a way to send notifiers from here... } } -/* auto-keyframing feature - for poses/pose-channels - * tmode: should be a transform mode +/* auto-keyframing feature - for poses/pose-channels + * tmode: should be a transform mode * targetless_ik: has targetless ik been done on any channels? */ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, short targetless_ik) @@ -4261,13 +4459,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, bPose *pose= ob->pose; bPoseChannel *pchan; FCurve *fcu; - - if (autokeyframe_cfra_can_key(scene, ob)) { + + // TODO: this should probably be done per channel instead... + if (autokeyframe_cfra_can_key(scene, id)) { float cfra= (float)CFRA; short flag= 0; char buf[512]; - - /* flag is initialised from UserPref keyframing settings + + /* flag is initialised from UserPref keyframing settings * - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get * visual keyframes even if flag not set, as it's not that useful otherwise * (for quick animation recording) @@ -4276,12 +4475,12 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, flag |= INSERTKEY_MATRIX; if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED; - + for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) { if (pchan->bone->flag & BONE_TRANSFORM) { /* clear any 'unkeyed' flag it may have */ pchan->bone->flag &= ~BONE_UNKEYED; - + /* only insert into available channels? */ if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { if (act) { @@ -4292,29 +4491,29 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, /* only insert keyframe if needed? */ else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) { short doLoc=0, doRot=0, doScale=0; - + /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */ if (tmode == TFM_TRANSLATION) { - if (targetless_ik) + if (targetless_ik) doRot= 1; - else + else doLoc = 1; } else if (tmode == TFM_ROTATION) { if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE)) doLoc = 1; - - if ((v3d->flag & V3D_ALIGN)==0) + + if ((v3d->flag & V3D_ALIGN)==0) doRot = 1; } else if (tmode == TFM_RESIZE) { if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE)) doLoc = 1; - + if ((v3d->flag & V3D_ALIGN)==0) doScale = 1; } - + if (doLoc) { sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); @@ -4349,7 +4548,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - + if (pchan->rotmode == PCHAN_ROT_QUAT) { sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); @@ -4363,7 +4562,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); } - + sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name); insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag); insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); @@ -4371,15 +4570,15 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, } } } - + // XXX todo... figure out way to get appropriate notifiers sent - + /* do the bone paths */ #if 0 // TRANSFORM_FIX_ME if (arm->pathflag & ARM_PATH_ACFRA) { pose_clear_paths(ob); pose_recalculate_paths(ob); - } + } #endif } else { @@ -4403,7 +4602,7 @@ void special_aftertrans_update(TransInfo *t) // short redrawipo=0, resetslowpar=1; int cancelled= (t->state == TRANS_CANCEL); short duplicate= (t->undostr && strstr(t->undostr, "Duplicate")) ? 1 : 0; - + if (t->spacetype==SPACE_VIEW3D) { if (t->obedit) { if (cancelled==0) { @@ -4426,7 +4625,7 @@ void special_aftertrans_update(TransInfo *t) #if 0 // TRANSFORM_FIX_ME, Would prefer to use this since the array takes into // account what where transforming (with extend, locked strips etc) // But at the moment t->data is freed in postTrans so for now re-shuffeling selected strips works ok. - Campbell - + int a; TransData *td= t->data; @@ -4451,7 +4650,7 @@ void special_aftertrans_update(TransInfo *t) for(seq= seqbasep->first; seq; seq= seq->next) { max_machine = MAX2(max_machine, seq->machine); } - + for (machine = 0; machine <= max_machine; machine++) { for(seq= seqbasep->first; seq; seq= seq->next) { @@ -4461,7 +4660,7 @@ void special_aftertrans_update(TransInfo *t) } } #endif - + for(seq= seqbasep->first; seq; seq= seq->next) { /* We might want to build a list of effects that need to be updated during transform */ if(seq->type & SEQ_EFFECT) { @@ -4473,7 +4672,7 @@ void special_aftertrans_update(TransInfo *t) sort_seq(t->scene); } - + if (t->customData) MEM_freeN(t->customData); if (t->data) @@ -4483,47 +4682,47 @@ void special_aftertrans_update(TransInfo *t) SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; Scene *scene; bAnimContext ac; - + /* initialise relevant anim-context 'context' data from TransInfo data */ /* NOTE: sync this with the code in ANIM_animdata_get_context() */ memset(&ac, 0, sizeof(bAnimContext)); - + scene= ac.scene= t->scene; ob= ac.obact= OBACT; ac.sa= t->sa; ac.ar= t->ar; ac.spacetype= (t->sa)? t->sa->spacetype : 0; ac.regiontype= (t->ar)? t->ar->regiontype : 0; - + if (ANIM_animdata_context_getdata(&ac) == 0) return; - + if (ac.datatype == ANIMCONT_DOPESHEET) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); - + /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - + /* these should all be ipo-blocks */ for (ale= anim_data.first; ale; ale= ale->next) { - Object *nob= ANIM_nla_mapping_get(&ac, ale); + AnimData *adt= ANIM_nla_mapping_get(&ac, ale); FCurve *fcu= (FCurve *)ale->key_data; - - if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && + + if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { - if (nob) { - ANIM_nla_mapping_apply_fcurve(nob, fcu, 0, 1); + if (adt) { + ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1); posttrans_fcurve_clean(fcu); - ANIM_nla_mapping_apply_fcurve(nob, fcu, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1); } else posttrans_fcurve_clean(fcu); } } - + /* free temp memory */ BLI_freelistN(&anim_data); } @@ -4532,15 +4731,15 @@ void special_aftertrans_update(TransInfo *t) // fixme... some of this stuff is not good if (ob) { ob->ctime= -1234567.0f; - + if (ob->pose || ob_get_key(ob)) DAG_object_flush_update(scene, ob, OB_RECALC); else DAG_object_flush_update(scene, ob, OB_RECALC_OB); } - + /* Do curve cleanups? */ - if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && + if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { posttrans_action_clean(&ac, (bAction *)ac.data); @@ -4550,16 +4749,16 @@ void special_aftertrans_update(TransInfo *t) #if 0 // XXX old animation system /* fix up the Ipocurves and redraw stuff */ Key *key= (Key *)ac.data; - + if (key->ipo) { - if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && + if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { posttrans_ipo_clean(key->ipo); } } #endif // XXX old animation system - + DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); } #if 0 // XXX future of this is still not clear @@ -4569,23 +4768,23 @@ void special_aftertrans_update(TransInfo *t) { bScreen *sc= (bScreen *)ac.data; ScrArea *sa; - + /* BAD... we need to loop over all screen areas for current screen... - * - sync this with actdata_filter_gpencil() in editaction.c + * - sync this with actdata_filter_gpencil() in editaction.c */ for (sa= sc->areabase.first; sa; sa= sa->next) { bGPdata *gpd= gpencil_data_getactive(sa); - - if (gpd) + + if (gpd) posttrans_gpd_clean(gpd); } } } #endif // XXX future of this is still not clear - + /* make sure all F-Curves are set correctly */ ANIM_editkeyframes_refresh(&ac); - + /* clear flag that was set for time-slide drawing */ saction->flag &= ~SACTION_MOVING; } @@ -4593,60 +4792,105 @@ void special_aftertrans_update(TransInfo *t) SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; Scene *scene; bAnimContext ac; - + /* initialise relevant anim-context 'context' data from TransInfo data */ /* NOTE: sync this with the code in ANIM_animdata_get_context() */ memset(&ac, 0, sizeof(bAnimContext)); - + scene= ac.scene= t->scene; ob= ac.obact= OBACT; ac.sa= t->sa; ac.ar= t->ar; ac.spacetype= (t->sa)? t->sa->spacetype : 0; ac.regiontype= (t->ar)? t->ar->regiontype : 0; - + if (ANIM_animdata_context_getdata(&ac) == 0) return; - - if (ac.datatype) + + if (ac.datatype) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_CURVEVISIBLE); - + /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - + /* these should all be ipo-blocks */ for (ale= anim_data.first; ale; ale= ale->next) { - Object *nob= ANIM_nla_mapping_get(&ac, ale); + AnimData *adt= ANIM_nla_mapping_get(&ac, ale); FCurve *fcu= (FCurve *)ale->key_data; - - if ( (sipo->flag & SIPO_NOTRANSKEYCULL)==0 && + + if ( (sipo->flag & SIPO_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { - if (nob) { - ANIM_nla_mapping_apply_fcurve(nob, fcu, 0, 1); + if (adt) { + ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1); posttrans_fcurve_clean(fcu); - ANIM_nla_mapping_apply_fcurve(nob, fcu, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1); } else posttrans_fcurve_clean(fcu); } } - + /* free temp memory */ BLI_freelistN(&anim_data); } - + /* make sure all F-Curves are set correctly */ ANIM_editkeyframes_refresh(&ac); } + else if (t->spacetype == SPACE_NLA) { + Scene *scene; + bAnimContext ac; + + /* initialise relevant anim-context 'context' data from TransInfo data */ + /* NOTE: sync this with the code in ANIM_animdata_get_context() */ + memset(&ac, 0, sizeof(bAnimContext)); + + scene= ac.scene= t->scene; + ob= ac.obact= OBACT; + ac.sa= t->sa; + ac.ar= t->ar; + ac.spacetype= (t->sa)? t->sa->spacetype : 0; + ac.regiontype= (t->ar)? t->ar->regiontype : 0; + + if (ANIM_animdata_context_getdata(&ac) == 0) + return; + + if (ac.datatype) + { + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NLATRACKS); + + /* get channels to work on */ + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale= anim_data.first; ale; ale= ale->next) { + NlaTrack *nlt= (NlaTrack *)ale->data; + + /* make sure strips are in order again */ + BKE_nlatrack_sort_strips(nlt); + + /* remove the temp metas */ + BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); + } + + /* free temp memory */ + BLI_freelistN(&anim_data); + } + + // XXX check on the calls below... we need some of these sanity checks + //synchronize_action_strips(); + //ANIM_editkeyframes_refresh(&ac); + } else if (t->obedit) { // TRANSFORM_FIX_ME // if (t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE) // allqueue(REDRAWBUTSEDIT, 0); - + if (t->obedit->type == OB_MESH) { BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh; @@ -4659,11 +4903,11 @@ void special_aftertrans_update(TransInfo *t) bPose *pose; bPoseChannel *pchan; short targetless_ik= 0; - + ob= t->poseobj; arm= ob->data; pose= ob->pose; - + /* if target-less IK grabbing, we calculate the pchan transforms and clear flag */ if (!cancelled && t->mode==TFM_TRANSLATION) targetless_ik= apply_targetless_ik(ob); @@ -4674,10 +4918,10 @@ void special_aftertrans_update(TransInfo *t) if(data) data->flag &= ~CONSTRAINT_IK_AUTO; } } - + if (t->mode==TFM_TRANSLATION) pose_grab_with_ik_clear(ob); - + /* automatic inserting of keys and unkeyed tagging - only if transform wasn't cancelled (or TFM_DUMMY) */ if (!cancelled && (t->mode != TFM_DUMMY)) { autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); @@ -4688,56 +4932,44 @@ void special_aftertrans_update(TransInfo *t) DAG_object_flush_update(t->scene, ob, OB_RECALC_DATA); ob->recalc= 0; // is set on OK position already by recalcData() } - else + else DAG_object_flush_update(t->scene, ob, OB_RECALC_DATA); - + //if (t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE) // allqueue(REDRAWBUTSEDIT, 0); - + } else if(G.f & G_PARTICLEEDIT) { ; } - else { + else { /* Objects */ // XXX ideally, this would go through context iterators, but we don't have context iterator access here, // so we make do with old data + access styles... Scene *scene= t->scene; Base *base; - + for (base= FIRSTBASE; base; base= base->next) { ob= base->object; - + if (base->flag & SELECT && (t->mode != TFM_DUMMY)) { /* pointcache refresh */ - if (BKE_ptcache_object_reset(ob, PTCACHE_RESET_DEPSGRAPH)) + if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) ob->recalc |= OB_RECALC_DATA; - + + /* Needed for proper updating of "quick cached" dynamics. */ + /* Creates troubles for moving animated objects without */ + /* autokey though, probably needed is an anim sys override? */ + /* Please remove if some other solution is found. -jahka */ + DAG_object_flush_update(scene, ob, OB_RECALC_OB); + /* Set autokey if necessary */ if (!cancelled) autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode); } } } - -#if 0 // TRANSFORM_FIX_ME - else if (t->spacetype == SPACE_NLA) { - recalc_all_ipos(); // bad - synchronize_action_strips(); - - /* cleanup */ - for (base=t->scene->base.first; base; base=base->next) - base->flag &= ~(BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA); - - /* after transform, remove duplicate keyframes on a frame that resulted from transform */ - if ( (G.snla->flag & SNLA_NOTRANSKEYCULL)==0 && - ((cancelled == 0) || (duplicate)) ) - { - posttrans_nla_clean(t); - } - } -#endif - + clear_trans_object_base_flags(t); #if 0 // TRANSFORM_FIX_ME @@ -4746,10 +4978,10 @@ void special_aftertrans_update(TransInfo *t) allqueue(REDRAWACTION, 0); allqueue(REDRAWIPO, 0); } - + if(resetslowpar) reset_slowparents(); - + /* note; should actually only be done for all objects when a lamp is moved... (ton) */ if(t->spacetype==SPACE_VIEW3D && G.vd->drawtype == OB_SHADED) reshadeall_displist(); @@ -4762,10 +4994,10 @@ static void createTransObject(bContext *C, TransInfo *t) TransDataExtension *tx; // IpoKey *ik; // ListBase elems; - + set_trans_object_base_flags(C, t); - /* count */ + /* count */ CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { #if 0 // TRANSFORM_FIX_ME @@ -4773,12 +5005,12 @@ static void createTransObject(bContext *C, TransInfo *t) if ((ob->id.lib == 0) && (ob->ipo) && (ob->ipo->showkey) && (ob->ipoflag & OB_DRAWKEY)) { elems.first= elems.last= NULL; make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */ - + pushdata(&elems, sizeof(ListBase)); - + for(ik= elems.first; ik; ik= ik->next) t->total++; - + if(elems.first==NULL) t->total++; } @@ -4794,24 +5026,24 @@ static void createTransObject(bContext *C, TransInfo *t) clear_trans_object_base_flags(t); return; } - + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransOb"); tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransObExtension"); CTX_DATA_BEGIN(C, Base*, base, selected_bases) { Object *ob= base->object; - + td->flag = TD_SELECTED; td->protectflag= ob->protectflag; td->ext = tx; - + if (base->flag & BA_TRANSFORM_CHILD) { td->flag |= TD_NOCENTER; td->flag |= TD_NO_LOC; } - + /* select linked objects, but skip them later */ if (ob->id.lib != 0) { td->flag |= TD_SKIP; @@ -4821,55 +5053,55 @@ static void createTransObject(bContext *C, TransInfo *t) // TRANSFORM_FIX_ME #if 0 if((ob->id.lib == 0) && (ob->ipo) && (ob->ipo->showkey) && (ob->ipoflag & OB_DRAWKEY)) { - + popfirst(&elems); // bring back pushed listbase - + if(elems.first) { int cfraont; int ipoflag; - + base->flag |= BA_DO_IPO+BA_WAS_SEL; base->flag &= ~SELECT; - + cfraont= CFRA; set_no_parent_ipo(1); ipoflag= ob->ipoflag; ob->ipoflag &= ~OB_OFFS_OB; - + /* * This is really EVIL code that pushes down Object values * (loc, dloc, orig, size, dsize, rot, drot) * */ - + pushdata((void*)ob->loc, 7 * 3 * sizeof(float)); // tsk! tsk! - + for(ik= elems.first; ik; ik= ik->next) { - + /* weak... this doesn't correct for floating values, giving small errors */ CFRA= (int)(ik->val/t->scene->r.framelen); - + do_ob_ipo(ob); ObjectToTransData(C, t, td, ob); // does where_is_object() - + td->flag= TD_SELECTED; - + td->tdi= MEM_callocN(sizeof(TransDataIpokey), "TransDataIpokey"); /* also does tdi->flag and oldvals, needs to be after ob_to_transob()! */ ipokey_to_transdata(ik, td); - + td++; tx++; if(ik->next) td->ext= tx; // prevent corrupting mem! } free_ipokey(&elems); - + poplast(ob->loc); set_no_parent_ipo(0); - + CFRA= cfraont; ob->ipoflag= ipoflag; - - where_is_object(t->scene, ob); // restore + + where_is_object(t->scene, ob); // restore } else { ObjectToTransData(C, t, td, ob); @@ -4893,7 +5125,7 @@ static void createTransObject(bContext *C, TransInfo *t) /* transcribe given node into TransData2D for Transforming */ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) -// static void NodeToTransData(bContext *C, TransInfo *t, TransData2D *td, bNode *node) +// static void NodeToTransData(bContext *C, TransInfo *t, TransData2D *td, bNode *node) { td2d->loc[0] = node->locx; /* hold original location */ td2d->loc[1] = node->locy; @@ -4921,22 +5153,22 @@ void createTransNodeData(bContext *C, TransInfo *t) { TransData *td; TransData2D *td2d; - + t->total= CTX_DATA_COUNT(C, selected_nodes); - + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransNode TransData"); td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransNode TransData2D"); - + CTX_DATA_BEGIN(C, bNode *, selnode, selected_nodes) NodeToTransData(td++, td2d++, selnode); CTX_DATA_END } -void createTransData(bContext *C, TransInfo *t) +void createTransData(bContext *C, TransInfo *t) { Scene *scene = CTX_data_scene(C); Object *ob = OBACT; - + if (t->options == CTX_TEXTURE) { t->flag |= T_TEXTURE; createTransTexspace(C, t); @@ -4970,8 +5202,7 @@ void createTransData(bContext *C, TransInfo *t) } else if (t->spacetype == SPACE_NLA) { t->flag |= T_POINTS|T_2D_EDIT; - // TRANSFORM_FIX_ME - //createTransNlaData(C, t); + createTransNlaData(C, t); } else if (t->spacetype == SPACE_SEQ) { t->flag |= T_POINTS|T_2D_EDIT; @@ -4981,7 +5212,7 @@ void createTransData(bContext *C, TransInfo *t) else if (t->spacetype == SPACE_IPO) { t->flag |= T_POINTS|T_2D_EDIT; createTransGraphEditData(C, t); -#if 0 +#if 0 if (t->data && (t->flag & T_PROP_EDIT)) { sort_trans_data(t); // makes selected become first in array set_prop_dist(t, 1); @@ -5001,7 +5232,7 @@ void createTransData(bContext *C, TransInfo *t) else if (t->obedit) { t->ext = NULL; if (t->obedit->type == OB_MESH) { - createTransEditVerts(C, t); + createTransEditVerts(C, t); } else if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { createTransCurveVerts(C, t); @@ -5015,7 +5246,7 @@ void createTransData(bContext *C, TransInfo *t) else if (t->obedit->type==OB_ARMATURE) { t->flag &= ~T_PROP_EDIT; createTransArmatureVerts(C, t); - } + } else { printf("edit type not implemented!\n"); } @@ -5034,7 +5265,7 @@ void createTransData(bContext *C, TransInfo *t) } t->flag |= T_EDIT|T_POINTS; - + /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */ if(t->mode==TFM_BONESIZE) { t->flag &= ~(T_EDIT|T_POINTS); @@ -5043,7 +5274,7 @@ void createTransData(bContext *C, TransInfo *t) } } else if (ob && (ob->flag & OB_POSEMODE)) { - // XXX this is currently limited to active armature only... + // XXX this is currently limited to active armature only... // XXX active-layer checking isn't done as that should probably be checked through context instead createTransPose(C, t, ob); } @@ -5077,7 +5308,7 @@ void createTransData(bContext *C, TransInfo *t) t->flag &= ~T_PROP_EDIT; /* no proportional edit in object mode */ createTransObject(C, t); t->flag |= T_OBJECT; - + if (t->ar->regiontype == RGN_TYPE_WINDOW) { View3D *v3d = t->view; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index d79fe98b563..3fc9fe73a5b 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -59,13 +59,10 @@ //#include "BIF_screen.h" //#include "BIF_mywindow.h" #include "BIF_gl.h" -//#include "BIF_editaction.h" //#include "BIF_editmesh.h" -//#include "BIF_editnla.h" //#include "BIF_editsima.h" //#include "BIF_editparticle.h" //#include "BIF_meshtools.h" -#include "BIF_retopo.h" #include "BKE_action.h" #include "BKE_anim.h" @@ -82,6 +79,7 @@ #include "BKE_key.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_nla.h" #include "BKE_object.h" #include "BKE_utildefines.h" #include "BKE_context.h" @@ -91,7 +89,9 @@ #include "ED_armature.h" #include "ED_image.h" #include "ED_keyframing.h" +#include "ED_markers.h" #include "ED_mesh.h" +#include "ED_retopo.h" #include "ED_space_api.h" #include "ED_uvedit.h" #include "ED_view3d.h" @@ -103,6 +103,8 @@ #include "BLI_editVert.h" #include "BLI_rand.h" +#include "RNA_access.h" + #include "WM_types.h" #include "UI_resources.h" @@ -115,8 +117,6 @@ extern ListBase editelems; -extern TransInfo Trans; /* From transform.c */ - /* ************************** Functions *************************** */ void getViewVector(TransInfo *t, float coord[3], float vec[3]) @@ -155,8 +155,8 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) for (; md; md=md->next) { if (md->type==eModifierType_Mirror) { - MirrorModifierData *mmd = (MirrorModifierData*) md; - + MirrorModifierData *mmd = (MirrorModifierData*) md; + if(mmd->flag & MOD_MIR_CLIPPING) { axis = 0; if(mmd->flag & MOD_MIR_AXIS_X) { @@ -175,7 +175,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) float mtx[4][4], imtx[4][4]; int i; TransData *td = t->data; - + if (mmd->mirror_ob) { float obinv[4][4]; @@ -192,10 +192,10 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) break; if (td->loc==NULL) break; - + if (td->flag & TD_SKIP) continue; - + VecCopyf(loc, td->loc); VecCopyf(iloc, td->iloc); @@ -206,22 +206,22 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) clip = 0; if(axis & 1) { - if(fabs(iloc[0])<=tolerance[0] || + if(fabs(iloc[0])<=tolerance[0] || loc[0]*iloc[0]<0.0f) { loc[0]= 0.0f; clip = 1; } } - + if(axis & 2) { - if(fabs(iloc[1])<=tolerance[1] || + if(fabs(iloc[1])<=tolerance[1] || loc[1]*iloc[1]<0.0f) { loc[1]= 0.0f; clip = 1; } } if(axis & 4) { - if(fabs(iloc[2])<=tolerance[2] || + if(fabs(iloc[2])<=tolerance[2] || loc[2]*iloc[2]<0.0f) { loc[2]= 0.0f; clip = 1; @@ -248,7 +248,7 @@ static void editbmesh_apply_to_mirror(TransInfo *t) BMVert *eve; BMIter iter; int i; - + for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; @@ -256,108 +256,45 @@ static void editbmesh_apply_to_mirror(TransInfo *t) break; if (td->flag & TD_SKIP) continue; - + eve = td->extra; if(eve) { eve->co[0]= -td->loc[0]; eve->co[1]= td->loc[1]; eve->co[2]= td->loc[2]; - } - } + } + } } -/* called for updating while transform acts, once per redraw */ -void recalcData(TransInfo *t) +/* tags the given ID block for refreshes (if applicable) due to + * Animation Editor editing + */ +static void animedit_refresh_id_tags (ID *id) { - Scene *scene = t->scene; - Base *base; + AnimData *adt= BKE_animdata_from_id(id); -#if 0 // TRANSFORM_FIX_ME - if (t->spacetype == SPACE_ACTION) { - Object *ob= OBACT; - void *data; - short context; - - /* determine what type of data we are operating on */ - data = get_action_context(&context); - if (data == NULL) return; + /* tag AnimData for refresh so that other views will update in realtime with these changes */ + if (adt) + adt->recalc |= ADT_RECALC_ANIM; - /* always flush data if gpencil context */ - if (context == ACTCONT_GPENCIL) { - flushTransGPactionData(t); - } - - if (G.saction->lock) { - if (context == ACTCONT_ACTION) { - if(ob) { - ob->ctime= -1234567.0f; - if(ob->pose || ob_get_key(ob)) - DAG_object_flush_update(G.scene, ob, OB_RECALC); - else - DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); - } - } - else if (context == ACTCONT_SHAPEKEY) { - DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA); - } - } - } - else if (t->spacetype == SPACE_NLA) { - if (G.snla->lock) { - for (base=G.scene->base.first; base; base=base->next) { - if (base->flag & BA_HAS_RECALC_OB) - base->object->recalc |= OB_RECALC_OB; - if (base->flag & BA_HAS_RECALC_DATA) - base->object->recalc |= OB_RECALC_DATA; - - if (base->object->recalc) - base->object->ctime= -1234567.0f; // eveil! - - /* recalculate scale of selected nla-strips */ - if (base->object->nlastrips.first) { - Object *bob= base->object; - bActionStrip *strip; - - for (strip= bob->nlastrips.first; strip; strip= strip->next) { - if (strip->flag & ACTSTRIP_SELECT) { - float actlen= strip->actend - strip->actstart; - float len= strip->end - strip->start; - - strip->scale= len / (actlen * strip->repeat); - } - } - } - } - - DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0); - } - else { - for (base=G.scene->base.first; base; base=base->next) { - /* recalculate scale of selected nla-strips */ - if (base->object && base->object->nlastrips.first) { - Object *bob= base->object; - bActionStrip *strip; - - for (strip= bob->nlastrips.first; strip; strip= strip->next) { - if (strip->flag & ACTSTRIP_SELECT) { - float actlen= strip->actend - strip->actstart; - float len= strip->end - strip->start; - - /* prevent 'negative' scaling */ - if (len < 0) { - SWAP(float, strip->start, strip->end); - len= fabs(len); - } - - /* calculate new scale */ - strip->scale= len / (actlen * strip->repeat); - } - } - } - } + /* 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; } -#endif +} + +/* called for updating while transform acts, once per redraw */ +void recalcData(TransInfo *t) +{ + Scene *scene = t->scene; + Base *base; + if (t->obedit) { } else if(G.f & G_PARTICLEEDIT) { @@ -369,6 +306,41 @@ 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; @@ -404,33 +376,207 @@ void recalcData(TransInfo *t) /* 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); + } + else if (t->spacetype == SPACE_NLA) { + TransDataNla *tdn= (TransDataNla *)t->customData; + SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first; + Scene *scene= t->scene; + double secf= FPS; + int i; - /* update realtime - not working? */ - if (sipo->lock) { - + /* 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) + */ + for (i = 0; i < t->total; i++, tdn++) { + NlaStrip *strip= tdn->strip; + 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 + * + * this is done as a iterative procedure (done 5 times max for now) + */ + 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 + * - if there were no neighbours, clear the transforms (make it default to the strip's current values) + */ + if (strip->prev && strip->next) { + tdn->h1[0]= strip->prev->end; + tdn->h2[0]= strip->next->start; + } + else { + tdn->h1[0]= strip->start; + tdn->h2[0]= strip->end; + } + } + 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 */ + if (snla->flag & SNLA_DRAWTIME) { + tdn->h1[0]= (float)( floor((tdn->h1[0]/secf) + 0.5f) * secf ); + tdn->h2[0]= (float)( floor((tdn->h2[0]/secf) + 0.5f) * secf ); + } + else { + tdn->h1[0]= (float)( floor(tdn->h1[0]+0.5f) ); + 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 + */ + if (delta > 0) { + for (track=tdn->nlt->next, n=0; (track) && (n < delta); track=track->next, 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 */ + } + else /* can't move any further */ + break; + } + } + 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 */ + } + else /* can't move any further */ + break; + } + } + } } } else if (t->obedit) { if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { Curve *cu= t->obedit->data; Nurb *nu= cu->editnurb->first; - + DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ - + if (t->state == TRANS_CANCEL) { while(nu) { calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */ @@ -450,7 +596,7 @@ void recalcData(TransInfo *t) else if(t->obedit->type==OB_LATTICE) { Lattice *la= t->obedit->data; DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ - + if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt); } else if (t->obedit->type == OB_MESH) { @@ -460,7 +606,7 @@ void recalcData(TransInfo *t) flushTransUVs(t); if(sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_re_solve(); - + DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); } else { BMEditMesh *em = ((Mesh*)t->obedit->data)->edit_btmesh; @@ -475,11 +621,11 @@ void recalcData(TransInfo *t) } if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) editbmesh_apply_to_mirror(t); - + DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ - - BMEdit_RecalcTesselation(em); + EDBM_RecalcNormals(em); + BMEdit_RecalcTesselation(em); } } else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */ @@ -488,10 +634,10 @@ void recalcData(TransInfo *t) EditBone *ebo; TransData *td = t->data; int i; - + /* Ensure all bones are correctly adjusted */ for (ebo = edbo->first; ebo; ebo = ebo->next){ - + if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ /* If this bone has a parent tip that has been moved */ if (ebo->parent->flag & BONE_TIPSEL){ @@ -504,7 +650,7 @@ void recalcData(TransInfo *t) if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head; } } - + /* on extrude bones, oldlength==0.0f, so we scale radius of points */ ebo->length= VecLenf(ebo->head, ebo->tail); if(ebo->oldlength==0.0f) { @@ -524,8 +670,8 @@ void recalcData(TransInfo *t) ebo->oldlength= ebo->length; } } - - + + if (t->mode != TFM_BONE_ROLL) { /* fix roll */ @@ -535,10 +681,10 @@ void recalcData(TransInfo *t) { float vec[3], up_axis[3]; float qrot[4]; - + ebo = td->extra; VECCOPY(up_axis, td->axismtx[2]); - + if (t->mode != TFM_ROTATION) { VecSubf(vec, ebo->tail, ebo->head); @@ -550,15 +696,15 @@ void recalcData(TransInfo *t) { Mat3MulVecfl(t->mat, up_axis); } - + ebo->roll = ED_rollBoneToVector(ebo, up_axis); } } } - - if(arm->flag & ARM_MIRROR_EDIT) + + if(arm->flag & ARM_MIRROR_EDIT) transform_armature_mirror_update(t->obedit); - + } else DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */ @@ -566,7 +712,7 @@ void recalcData(TransInfo *t) else if( (t->flag & T_POSE) && t->poseobj) { Object *ob= t->poseobj; bArmature *arm= ob->data; - + /* if animtimer is running, and the object already has animation data, * check if the auto-record feature means that we should record 'samples' * (i.e. uneditable animation values) @@ -577,7 +723,7 @@ void recalcData(TransInfo *t) short targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet! autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); } - + /* old optimize trick... this enforces to bypass the depgraph */ if (!(arm->flag & ARM_DELAYDEFORM)) { DAG_object_flush_update(scene, ob, OB_RECALC_DATA); /* sets recalc flags */ @@ -588,13 +734,13 @@ void recalcData(TransInfo *t) else { for(base= FIRSTBASE; base; base= base->next) { Object *ob= base->object; - + /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */ if(base->flag & BA_HAS_RECALC_OB) ob->recalc |= OB_RECALC_OB; if(base->flag & BA_HAS_RECALC_DATA) ob->recalc |= OB_RECALC_DATA; - + /* if object/base is selected */ if ((base->flag & SELECT) || (ob->flag & SELECT)) { /* if animtimer is running, and the object already has animation data, @@ -607,13 +753,13 @@ void recalcData(TransInfo *t) autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode); } } - + /* proxy exception */ if(ob->proxy) ob->proxy->recalc |= ob->recalc; if(ob->proxy_group) group_tag_recalc(ob->proxy_group->dup_group); - } + } } /* update shaded drawmode while transform */ @@ -625,22 +771,22 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) { float v1[3], v2[3], v3[3]; char col[3], col2[3]; - + if (t->spacetype == SPACE_VIEW3D) { View3D *v3d = t->view; - + glPushMatrix(); - + //if(t->obedit) glLoadMatrixf(t->obedit->obmat); // sets opengl viewing - - + + VecCopyf(v3, dir); VecMulf(v3, v3d->far); - + VecSubf(v2, center, v3); VecAddf(v1, center, v3); - + if (options & DRAWLIGHT) { col[0] = col[1] = col[2] = 220; } @@ -649,13 +795,13 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) } UI_make_axis_color(col, col2, axis); glColor3ubv((GLubyte *)col2); - + setlinestyle(0); - glBegin(GL_LINE_STRIP); - glVertex3fv(v1); - glVertex3fv(v2); + glBegin(GL_LINE_STRIP); + glVertex3fv(v1); + glVertex3fv(v2); glEnd(); - + glPopMatrix(); } } @@ -668,20 +814,22 @@ void resetTransRestrictions(TransInfo *t) int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) { Scene *sce = CTX_data_scene(C); + ToolSettings *ts = CTX_data_tool_settings(C); ARegion *ar = CTX_wm_region(C); ScrArea *sa = CTX_wm_area(C); Object *obedit = CTX_data_edit_object(C); - + /* moving: is shown in drawobject() (transform color) */ -// TRANSFORM_FIX_ME +// TRANSFORM_FIX_ME // if(obedit || (t->flag & T_POSE) ) G.moving= G_TRANSFORM_EDIT; // else if(G.f & G_PARTICLEEDIT) G.moving= G_TRANSFORM_PARTICLE; // else G.moving= G_TRANSFORM_OBJ; - + t->scene = sce; t->sa = sa; t->ar = ar; t->obedit = obedit; + t->settings = ts; t->data = NULL; t->ext = NULL; @@ -689,14 +837,14 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->helpline = HLP_NONE; t->flag = 0; - + t->redraw = 1; /* redraw first time */ - + if (event) { t->imval[0] = event->x - t->ar->winrct.xmin; t->imval[1] = event->y - t->ar->winrct.ymin; - + t->event_type = event->type; } else @@ -704,7 +852,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->imval[0] = 0; t->imval[1] = 0; } - + t->con.imval[0] = t->imval[0]; t->con.imval[1] = t->imval[1]; @@ -721,27 +869,27 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->vec[0] = t->vec[1] = t->vec[2] = 0.0f; - + t->center[0] = t->center[1] = t->center[2] = 0.0f; - + Mat3One(t->mat); - + t->spacetype = sa->spacetype; if(t->spacetype == SPACE_VIEW3D) { View3D *v3d = sa->spacedata.first; - + t->view = v3d; t->animtimer= CTX_wm_screen(C)->animtimer; - + if(v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN; t->around = v3d->around; if (op && RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_orientation")) { - t->current_orientation = RNA_int_get(op->ptr, "constraint_orientation"); + t->current_orientation = RNA_enum_get(op->ptr, "constraint_orientation"); if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C) - 1) { @@ -755,15 +903,16 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } else if(t->spacetype==SPACE_IMAGE || t->spacetype==SPACE_NODE) { + SpaceImage *sima = sa->spacedata.first; // XXX for now, get View2D from the active region t->view = &ar->v2d; - t->around = ar->v2d.around; + t->around = sima->around; } else { // XXX for now, get View2D from the active region t->view = &ar->v2d; - + t->around = V3D_CENTER; } @@ -777,7 +926,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) // Need stuff to take it from edit mesh or whatnot here else { - if (t->obedit && t->obedit->type == OB_MESH && sce->toolsettings->editbutflag & B_MESH_X_MIRROR) + if (t->obedit && t->obedit->type == OB_MESH && ts->editbutflag & B_MESH_X_MIRROR) { t->flag |= T_MIRROR; } @@ -797,10 +946,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } else { - if ((t->options & CTX_NO_PET) == 0 && (sce->proportional)) { + if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) { t->flag |= T_PROP_EDIT; - - if(sce->proportional == 2) + + if(ts->proportional == 2) t->flag |= T_PROP_CONNECTED; // yes i know, has to become define } } @@ -811,16 +960,16 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } else { - t->prop_size = sce->toolsettings->proportional_size; + t->prop_size = ts->proportional_size; } - + if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff")) { t->prop_mode = RNA_enum_get(op->ptr, "proportional_editing_falloff"); } else { - t->prop_mode = sce->prop_mode; + t->prop_mode = ts->prop_mode; } /* TRANSFORM_FIX_ME rna restrictions */ @@ -832,12 +981,12 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) setTransformViewMatrices(t); initNumInput(&t->num); initNDofInput(&t->ndof); - + return 1; } /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */ -void postTrans (TransInfo *t) +void postTrans (TransInfo *t) { TransData *td; @@ -845,7 +994,7 @@ void postTrans (TransInfo *t) { ED_region_draw_cb_exit(t->ar->type, t->draw_handle); } - + /* postTrans can be called when nothing is selected, so data is NULL already */ if (t->data) { int a; @@ -853,7 +1002,7 @@ void postTrans (TransInfo *t) /* since ipokeys are optional on objects, we mallocced them per trans-data */ for(a=0, td= t->data; a<t->total; a++, td++) { if(td->tdi) MEM_freeN(td->tdi); - if (td->flag & TD_BEZTRIPLE) MEM_freeN(td->hdata); + if (td->flag & TD_BEZTRIPLE) MEM_freeN(td->hdata); } MEM_freeN(t->data); } @@ -869,21 +1018,15 @@ void postTrans (TransInfo *t) if(sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL); } - else if(t->spacetype==SPACE_ACTION) { + else if(ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { if (t->customData) MEM_freeN(t->customData); - } else if (t->spacetype==SPACE_VIEW3D) { - if (t->obedit) { - /*retesselate*/ - //EDBM_Tesselate(((Mesh*)t->obedit->data)->edit_mesh); - } - } -} + }} void applyTransObjects(TransInfo *t) { TransData *td; - + for (td = t->data; td < t->data + t->total; td++) { VECCOPY(td->iloc, td->loc); if (td->ext->rot) { @@ -892,9 +1035,9 @@ void applyTransObjects(TransInfo *t) if (td->ext->size) { VECCOPY(td->ext->isize, td->ext->size); } - } + } recalcData(t); -} +} /* helper for below */ static void restore_ipokey(float *poin, float *old) @@ -927,15 +1070,15 @@ static void restoreElement(TransData *td) { } } } - + if (td->flag & TD_BEZTRIPLE) { *(td->hdata->h1) = td->hdata->ih1; *(td->hdata->h2) = td->hdata->ih2; } - + if(td->tdi) { TransDataIpokey *tdi= td->tdi; - + restore_ipokey(tdi->locx, tdi->oldloc); restore_ipokey(tdi->locy, tdi->oldloc+1); restore_ipokey(tdi->locz, tdi->oldloc+2); @@ -943,7 +1086,7 @@ static void restoreElement(TransData *td) { restore_ipokey(tdi->rotx, tdi->oldrot); restore_ipokey(tdi->roty, tdi->oldrot+1); restore_ipokey(tdi->rotz, tdi->oldrot+2); - + restore_ipokey(tdi->sizex, tdi->oldsize); restore_ipokey(tdi->sizey, tdi->oldsize+1); restore_ipokey(tdi->sizez, tdi->oldsize+2); @@ -953,13 +1096,13 @@ static void restoreElement(TransData *td) { void restoreTransObjects(TransInfo *t) { TransData *td; - + for (td = t->data; td < t->data + t->total; td++) { restoreElement(td); } - + Mat3One(t->mat); - + recalcData(t); } @@ -968,7 +1111,7 @@ void calculateCenter2D(TransInfo *t) if (t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; float vec[3]; - + VECCOPY(vec, t->center); Mat4MulVecfl(ob->obmat, vec); projectIntView(t, vec, t->center2d); @@ -989,13 +1132,13 @@ void calculateCenterCursor(TransInfo *t) if (t->flag & (T_EDIT|T_POSE)) { Object *ob = t->obedit?t->obedit:t->poseobj; float mat[3][3], imat[3][3]; - + VecSubf(t->center, t->center, ob->obmat[3]); Mat3CpyMat4(mat, ob->obmat); Mat3Inv(imat, mat); Mat3MulVecfl(imat, t->center); } - + calculateCenter2D(t); } @@ -1003,13 +1146,13 @@ void calculateCenterCursor2D(TransInfo *t) { View2D *v2d= t->view; float aspx=1.0, aspy=1.0; - + if(t->spacetype==SPACE_IMAGE) /* only space supported right now but may change */ ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); if (v2d) { - t->center[0] = v2d->cursor[0] * aspx; - t->center[1] = v2d->cursor[1] * aspy; + t->center[0] = v2d->cursor[0] * aspx; + t->center[1] = v2d->cursor[1] * aspy; } calculateCenter2D(t); @@ -1020,7 +1163,7 @@ void calculateCenterMedian(TransInfo *t) float partial[3] = {0.0f, 0.0f, 0.0f}; int total = 0; int i; - + for(i = 0; i < t->total; i++) { if (t->data[i].flag & TD_SELECTED) { if (!(t->data[i].flag & TD_NOCENTER)) @@ -1030,8 +1173,8 @@ void calculateCenterMedian(TransInfo *t) } } else { - /* - All the selected elements are at the head of the array + /* + All the selected elements are at the head of the array which means we can stop when it finds unselected data */ break; @@ -1056,8 +1199,8 @@ void calculateCenterBound(TransInfo *t) MinMax3(min, max, t->data[i].center); } else { - /* - All the selected elements are at the head of the array + /* + All the selected elements are at the head of the array which means we can stop when it finds unselected data */ break; @@ -1074,7 +1217,7 @@ void calculateCenterBound(TransInfo *t) calculateCenter2D(t); } -void calculateCenter(TransInfo *t) +void calculateCenter(TransInfo *t) { switch(t->around) { case V3D_CENTER: @@ -1106,7 +1249,7 @@ void calculateCenter(TransInfo *t) break; } /* END EDIT MODE ACTIVE ELEMENT */ #endif - + calculateCenterMedian(t); if((t->flag & (T_EDIT|T_POSE))==0) { @@ -1118,7 +1261,7 @@ void calculateCenter(TransInfo *t) projectIntView(t, t->center, t->center2d); } } - + } } @@ -1138,21 +1281,21 @@ void calculateCenter(TransInfo *t) View3D *v3d = t->view; Scene *scene = t->scene; RegionView3D *rv3d = t->ar->regiondata; - + if(v3d->camera == OBACT && rv3d->persp==V3D_CAMOB) { float axis[3]; /* persinv is nasty, use viewinv instead, always right */ VECCOPY(axis, t->viewinv[2]); Normalize(axis); - + /* 6.0 = 6 grid units */ axis[0]= t->center[0]- 6.0f*axis[0]; axis[1]= t->center[1]- 6.0f*axis[1]; axis[2]= t->center[2]- 6.0f*axis[2]; - + projectIntView(t, axis, t->center2d); - + /* rotate only needs correct 2d center, grab needs initgrabz() value */ if(t->mode==TFM_TRANSLATION) { @@ -1161,7 +1304,7 @@ void calculateCenter(TransInfo *t) } } } - } + } if(t->spacetype==SPACE_VIEW3D) { @@ -1169,14 +1312,14 @@ void calculateCenter(TransInfo *t) if(t->flag & (T_EDIT|T_POSE)) { Object *ob= t->obedit?t->obedit:t->poseobj; float vec[3]; - + VECCOPY(vec, t->center); Mat4MulVecfl(ob->obmat, vec); initgrabz(t->ar->regiondata, vec[0], vec[1], vec[2]); } else { initgrabz(t->ar->regiondata, t->center[0], t->center[1], t->center[2]); - } + } } } @@ -1186,18 +1329,18 @@ void calculatePropRatio(TransInfo *t) int i; float dist; short connected = t->flag & T_PROP_CONNECTED; - + if (t->flag & T_PROP_EDIT) { for(i = 0 ; i < t->total; i++, td++) { if (td->flag & TD_SELECTED) { td->factor = 1.0f; } - else if ((connected && + else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) || (connected == 0 && td->rdist > t->prop_size)) { - /* + /* The elements are sorted according to their dist member in the array, that means we can stop when it finds one element outside of the propsize. */ @@ -1209,7 +1352,7 @@ void calculatePropRatio(TransInfo *t) /* Use rdist for falloff calculations, it is the real distance */ td->flag &= ~TD_NOACTION; dist= (t->prop_size-td->rdist)/t->prop_size; - + /* * Clamp to positive numbers. * Certain corner cases with connectivity and individual centers @@ -1217,7 +1360,7 @@ void calculatePropRatio(TransInfo *t) */ if (dist < 0.0f) dist = 0.0f; - + switch(t->prop_mode) { case PROP_SHARP: td->factor= dist*dist; @@ -1280,24 +1423,19 @@ void calculatePropRatio(TransInfo *t) } } -TransInfo *BIF_GetTransInfo() -{ - return NULL; -} - float get_drawsize(ARegion *ar, float *co) { RegionView3D *rv3d= ar->regiondata; float size, vec[3], len1, len2; - + /* size calculus, depending ortho/persp settings, like initgrabz() */ size= rv3d->persmat[0][3]*co[0]+ rv3d->persmat[1][3]*co[1]+ rv3d->persmat[2][3]*co[2]+ rv3d->persmat[3][3]; - + VECCOPY(vec, rv3d->persinv[0]); len1= Normalize(vec); VECCOPY(vec, rv3d->persinv[1]); len2= Normalize(vec); - + size*= 0.01f*(len1>len2?len1:len2); /* correct for window size to make widgets appear fixed size */ diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 4d721a83c78..ae8aacb3477 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -1,5 +1,5 @@ /** - * $Id: transform_input.c 18142 2008-12-29 07:19:16Z aligorith $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -26,6 +26,7 @@ #include <math.h> #include "DNA_screen_types.h" +#include "DNA_windowmanager_types.h" #include "BLI_arithb.h" @@ -34,7 +35,7 @@ #include "transform.h" - + /* ************************** INPUT FROM MOUSE *************************** */ void InputVector(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) @@ -52,7 +53,7 @@ void InputVector(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) { convertViewVec(t, output, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); } - + } void InputSpring(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) @@ -64,11 +65,11 @@ void InputSpring(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) dx = (float)(mi->center[0] - mi->precision_mval[0]); dy = (float)(mi->center[1] - mi->precision_mval[1]); ratio = (float)sqrt( dx*dx + dy*dy); - + dx= (float)(mi->center[0] - mval[0]); dy= (float)(mi->center[1] - mval[1]); precise_ratio = (float)sqrt( dx*dx + dy*dy); - + ratio = (ratio + (precise_ratio - ratio) / 10.0f) / mi->factor; } else @@ -77,16 +78,16 @@ void InputSpring(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) dy = (float)(mi->center[1] - mval[1]); ratio = (float)sqrt( dx*dx + dy*dy) / mi->factor; } - + output[0] = ratio; } void InputSpringFlip(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) { InputSpring(t, mi, mval, output); - + /* flip scale */ - if ((mi->center[0] - mval[0]) * (mi->center[0] - mi->imval[0]) + + if ((mi->center[0] - mval[0]) * (mi->center[0] - mi->imval[0]) + (mi->center[1] - mval[1]) * (mi->center[1] - mi->imval[1]) < 0) { output[0] *= -1.0f; @@ -95,7 +96,7 @@ void InputSpringFlip(TransInfo *t, MouseInput *mi, short mval[2], float output[3 void InputTrackBall(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) { - + if(mi->precision) { output[0] = ( mi->imval[1] - mi->precision_mval[1] ) + ( mi->precision_mval[1] - mval[1] ) * 0.1f; @@ -106,7 +107,7 @@ void InputTrackBall(TransInfo *t, MouseInput *mi, short mval[2], float output[3] output[0] = (float)( mi->imval[1] - mval[1] ); output[1] = (float)( mval[0] - mi->imval[0] ); } - + output[0] *= mi->factor; output[1] *= mi->factor; } @@ -124,7 +125,7 @@ void InputHorizontalRatio(TransInfo *t, MouseInput *mi, short mval[2], float out else { x = mval[0]; } - + output[0] = (x - pad) / (t->ar->winx - 2 * pad); } @@ -133,7 +134,7 @@ void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, short mval[2], float InputVector(t, mi, mval, vec); Projf(vec, vec, t->viewinv[0]); - + output[0] = Inpf(t->viewinv[0], vec) * 2.0f; } @@ -149,7 +150,7 @@ void InputVerticalRatio(TransInfo *t, MouseInput *mi, short mval[2], float outpu else { y = mval[0]; } - + output[0] = (y - pad) / (t->ar->winy - 2 * pad); } @@ -158,7 +159,7 @@ void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, short mval[2], float ou InputVector(t, mi, mval, vec); Projf(vec, vec, t->viewinv[1]); - + output[0] = Inpf(t->viewinv[1], vec) * 2.0f; } @@ -181,7 +182,7 @@ void InputAngle(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) /* (A*B?A*B:1.0f) this takes care of potential divide by zero errors */ float dphi; - + dphi = saacos((float)deler); if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi; @@ -189,33 +190,33 @@ void InputAngle(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) * approximate the angle with the oposite side of the normalized triangle * This is a good approximation here since the smallest acos value seems to be around * 0.02 degree and lower values don't even have a 0.01% error compared to the approximation - * */ + * */ if (dphi == 0) { double dx, dy; - + dx2 /= A; dy2 /= A; - + dx1 /= B; dy1 /= B; - + dx = dx1 - dx2; dy = dy1 - dy2; - + dphi = sqrt(dx*dx + dy*dy); if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi; } - + if(mi->precision) dphi = dphi/30.0f; - + /* if no delta angle, don't update initial position */ if (dphi != 0) { mi->imval[0] = mval[0]; mi->imval[1] = mval[1]; } - + output[0] += dphi; } @@ -226,7 +227,7 @@ void initMouseInput(TransInfo *t, MouseInput *mi, int center[2], short mval[2]) mi->center[0] = center[0]; mi->center[1] = center[1]; - + mi->imval[0] = mval[0]; mi->imval[1] = mval[1]; } @@ -246,7 +247,7 @@ static void calcSpringFactor(MouseInput *mi) void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode) { - + switch(mode) { case INPUT_VECTOR: @@ -269,7 +270,7 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode) break; case INPUT_TRACKBALL: /* factor has to become setting or so */ - mi->factor = 0.1f; + mi->factor = 0.01f; mi->apply = InputTrackBall; t->helpline = HLP_TRACKBALL; break; @@ -295,8 +296,8 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode) mi->apply = NULL; break; } - - /* bootstrap mouse input with initial values */ + + /* bootstrap mouse input with initial values */ applyMouseInput(t, mi, mi->imval, t->values); } @@ -311,7 +312,7 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, short mval[2], float output[3 int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event) { int redraw = 0; - + switch (event->type) { case LEFTSHIFTKEY: @@ -333,6 +334,6 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event) redraw = 1; break; } - + return redraw; } diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 99d7805b938..bf87319d05c 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -27,18 +27,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -// TRANSFORM_FIX_ME -// Disable everything here, don't need it for now -#if 0 - #include <stdlib.h> #include <string.h> #include <math.h> -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #ifndef WIN32 #include <unistd.h> #else @@ -61,31 +53,36 @@ #include "DNA_userdef_types.h" #include "DNA_view3d_types.h" +#include "RNA_access.h" + #include "BKE_armature.h" +#include "BKE_context.h" #include "BKE_global.h" #include "BKE_lattice.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_utildefines.h" +#include "BKE_tessmesh.h" #include "BLI_arithb.h" #include "BLI_editVert.h" -#include "BIF_editarmature.h" #include "BIF_gl.h" -#include "BIF_mywindow.h" -#include "BIF_resources.h" -#include "BIF_screen.h" -#include "BIF_space.h" -#include "BIF_transform.h" -#include "BIF_editmesh.h" -#include "BIF_editparticle.h" - -#include "BSE_edit.h" -#include "BSE_view.h" -#include "BDR_drawobject.h" - -#include "blendef.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_armature.h" +#include "ED_mesh.h" +#include "ED_particle.h" +#include "ED_space_api.h" +#include "ED_transform.h" +#include "ED_view3d.h" + +#include "UI_resources.h" + +/* local module include */ #include "transform.h" /* return codes for select, and drawing flags */ @@ -113,26 +110,23 @@ #define MAN_GHOST 1 #define MAN_MOVECOL 2 -/* GLOBAL VARIABLE THAT SHOULD MOVED TO SCREEN MEMBER OR SOMETHING */ -extern TransInfo Trans; - static int is_mat4_flipped(float mat[][4]) { float vec[3]; - + Crossf(vec, mat[0], mat[1]); if( Inpf(vec, mat[2]) < 0.0 ) return 1; return 0; -} +} /* transform widget center calc helper for below */ -static void calc_tw_center(float *co) +static void calc_tw_center(Scene *scene, float *co) { - float *twcent= G.scene->twcent; - float *min= G.scene->twmin; - float *max= G.scene->twmax; - + float *twcent= scene->twcent; + float *min= scene->twmin; + float *max= scene->twmax; + DO_MINMAX(co, min, max); VecAddf(twcent, twcent, co); } @@ -145,7 +139,7 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags) *drawflags &= ~MAN_TRANS_Y; if(protectflag & OB_LOCK_LOCZ) *drawflags &= ~MAN_TRANS_Z; - + if(protectflag & OB_LOCK_ROTX) *drawflags &= ~MAN_ROT_X; if(protectflag & OB_LOCK_ROTY) @@ -162,13 +156,13 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags) } /* for pose mode */ -static void stats_pose(View3D *v3d, bPoseChannel *pchan) +static void stats_pose(Scene *scene, View3D *v3d, bPoseChannel *pchan) { Bone *bone= pchan->bone; - + if(bone) { if (bone->flag & BONE_TRANSFORM) { - calc_tw_center(pchan->pose_head); + calc_tw_center(scene, pchan->pose_head); protectflag_to_drawflags(pchan->protectflag, &v3d->twdrawflag); } } @@ -181,91 +175,69 @@ static void stats_editbone(View3D *v3d, EditBone *ebo) protectflag_to_drawflags(OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE, &v3d->twdrawflag); } -/* only counts the parent selection, and tags transform flag */ -/* bad call... should re-use method from transform_conversion once */ -static void count_bone_select(TransInfo *t, bArmature *arm, ListBase *lb, int do_it) -{ - Bone *bone; - int do_next; - - for(bone= lb->first; bone; bone= bone->next) { - bone->flag &= ~BONE_TRANSFORM; - do_next= do_it; - if(do_it) { - if(bone->layer & arm->layer) { - if (bone->flag & BONE_SELECTED) { - /* We don't let connected children get "grabbed" */ - if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_CONNECTED)==0 ) { - bone->flag |= BONE_TRANSFORM; - t->total++; - do_next= 0; // no transform on children if one parent bone is selected - } - } - } - } - count_bone_select(t, arm, &bone->childbase, do_next); - } -} - /* centroid, boundbox, of selection */ /* returns total items selected */ -int calc_manipulator_stats(ScrArea *sa) +int calc_manipulator_stats(const bContext *C) { - TransInfo *t; + ScrArea *sa= CTX_wm_area(C); + ARegion *ar= CTX_wm_region(C); + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); View3D *v3d= sa->spacedata.first; + RegionView3D *rv3d= ar->regiondata; Base *base; Object *ob= OBACT; float normal[3]={0.0, 0.0, 0.0}; float plane[3]={0.0, 0.0, 0.0}; - int a, totsel=0; + int a, totsel= 0; -//XXX t = BIF_GetTransInfo(); - /* transform widget matrix */ - Mat4One(v3d->twmat); - + Mat4One(rv3d->twmat); + v3d->twdrawflag= 0xFFFF; - + /* transform widget centroid/center */ - G.scene->twcent[0]= G.scene->twcent[1]= G.scene->twcent[2]= 0.0f; - INIT_MINMAX(G.scene->twmin, G.scene->twmax); - - if(t->obedit) { - ob= t->obedit; - if((ob->lay & G.vd->lay)==0) return 0; - - if(t->obedit->type==OB_MESH) { - EditMesh *em = NULL; // TRANSFORM_FIX_ME - EditVert *eve; - EditSelection ese; + scene->twcent[0]= scene->twcent[1]= scene->twcent[2]= 0.0f; + INIT_MINMAX(scene->twmin, scene->twmax); + + if(obedit) { + ob= obedit; + if((ob->lay & v3d->lay)==0) return 0; + + if(obedit->type==OB_MESH) { + BMEditMesh *em = ((Mesh*)obedit->data)->edit_btmesh; + BMesh *bm = em->bm; + BMVert *eve; + BMEditSelection ese; + BMIter iter; float vec[3]= {0,0,0}; - + /* USE LAST SELECTE WITH ACTIVE */ - if (G.vd->around==V3D_ACTIVE && EM_get_actSelection(&ese)) { - EM_editselection_center(vec, &ese); - calc_tw_center(vec); + if (v3d->around==V3D_ACTIVE && EDBM_get_actSelection(em, &ese)) { + EDBM_editselection_center(em, vec, &ese); + calc_tw_center(scene, vec); totsel= 1; } else { /* do vertices for center, and if still no normal found, use vertex normals */ - for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->f & SELECT) { + BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) { + if(BM_TestHFlag(eve, BM_SELECT)) { totsel++; - calc_tw_center(eve->co); + calc_tw_center(scene, eve->co); } } } } /* end editmesh */ - else if (t->obedit->type==OB_ARMATURE){ - bArmature *arm= t->obedit->data; + else if (obedit->type==OB_ARMATURE){ + bArmature *arm= obedit->data; EditBone *ebo; - for (ebo=G.edbo.first;ebo;ebo=ebo->next){ + for (ebo= arm->edbo->first; ebo; ebo=ebo->next){ if(ebo->layer & arm->layer) { if (ebo->flag & BONE_TIPSEL) { - calc_tw_center(ebo->tail); + calc_tw_center(scene, ebo->tail); totsel++; } if (ebo->flag & BONE_ROOTSEL) { - calc_tw_center(ebo->head); + calc_tw_center(scene, ebo->head); totsel++; } if (ebo->flag & BONE_SELECTED) { @@ -274,12 +246,12 @@ int calc_manipulator_stats(ScrArea *sa) } } } - else if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { - Curve *cu= t->obedit->data; + else if ELEM(obedit->type, OB_CURVE, OB_SURF) { + Curve *cu= obedit->data; Nurb *nu; BezTriple *bezt; BPoint *bp; - + nu= cu->editnurb->first; while(nu) { if((nu->type & 7)==CU_BEZIER) { @@ -292,25 +264,25 @@ int calc_manipulator_stats(ScrArea *sa) */ if (G.f & G_HIDDENHANDLES) { if (bezt->f2 & SELECT) { - calc_tw_center(bezt->vec[1]); + calc_tw_center(scene, bezt->vec[1]); totsel++; } } else if ( (bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT ) { - calc_tw_center(bezt->vec[1]); + calc_tw_center(scene, bezt->vec[1]); totsel++; } else { if(bezt->f1) { - calc_tw_center(bezt->vec[0]); + calc_tw_center(scene, bezt->vec[0]); totsel++; } if(bezt->f2) { - calc_tw_center(bezt->vec[1]); + calc_tw_center(scene, bezt->vec[1]); totsel++; } if(bezt->f3) { - calc_tw_center(bezt->vec[2]); + calc_tw_center(scene, bezt->vec[2]); totsel++; } } @@ -322,7 +294,7 @@ int calc_manipulator_stats(ScrArea *sa) a= nu->pntsu*nu->pntsv; while(a--) { if(bp->f1 & SELECT) { - calc_tw_center(bp->vec); + calc_tw_center(scene, bp->vec); totsel++; } bp++; @@ -331,76 +303,71 @@ int calc_manipulator_stats(ScrArea *sa) nu= nu->next; } } - else if(t->obedit->type==OB_MBALL) { + else if(obedit->type==OB_MBALL) { /* editmball.c */ - extern ListBase editelems; /* go away ! */ + ListBase editelems= {NULL, NULL}; /* XXX */ MetaElem *ml, *ml_sel=NULL; - + ml= editelems.first; while(ml) { if(ml->flag & SELECT) { - calc_tw_center(&ml->x); + calc_tw_center(scene, &ml->x); ml_sel = ml; totsel++; } ml= ml->next; } } - else if(t->obedit->type==OB_LATTICE) { + else if(obedit->type==OB_LATTICE) { BPoint *bp; - bp= editLatt->def; - - a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + Lattice *lt= obedit->data; + + bp= lt->editlatt->def; + + a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw; while(a--) { if(bp->f1 & SELECT) { - calc_tw_center(bp->vec); + calc_tw_center(scene, bp->vec); totsel++; } bp++; } } - + /* selection center */ if(totsel) { - VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid! - Mat4MulVecfl(t->obedit->obmat, G.scene->twcent); - Mat4MulVecfl(t->obedit->obmat, G.scene->twmin); - Mat4MulVecfl(t->obedit->obmat, G.scene->twmax); + VecMulf(scene->twcent, 1.0f/(float)totsel); // centroid! + Mat4MulVecfl(obedit->obmat, scene->twcent); + Mat4MulVecfl(obedit->obmat, scene->twmin); + Mat4MulVecfl(obedit->obmat, scene->twmax); } } else if(ob && (ob->flag & OB_POSEMODE)) { bArmature *arm = ob->data; bPoseChannel *pchan; - int mode; - - if((ob->lay & G.vd->lay)==0) return 0; - - mode = Trans.mode; - Trans.mode = TFM_ROTATION; // mislead counting bones... bah - - /* count total, we use same method as transform will do */ - Trans.total= 0; - count_bone_select(&Trans, arm, &arm->bonebase, 1); - totsel = Trans.total; + int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed + + if((ob->lay & v3d->lay)==0) return 0; + + totsel = count_set_pose_transflags(&mode, 0, ob); + if(totsel) { /* use channels to get stats */ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - stats_pose(v3d, pchan); + stats_pose(scene, v3d, pchan); } - - VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid! - Mat4MulVecfl(ob->obmat, G.scene->twcent); - Mat4MulVecfl(ob->obmat, G.scene->twmin); - Mat4MulVecfl(ob->obmat, G.scene->twmax); + + VecMulf(scene->twcent, 1.0f/(float)totsel); // centroid! + Mat4MulVecfl(ob->obmat, scene->twcent); + Mat4MulVecfl(ob->obmat, scene->twmin); + Mat4MulVecfl(ob->obmat, scene->twmax); } - /* restore, mode can be TFM_INIT */ - Trans.mode = mode; } else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) { ; } else if(G.f & G_PARTICLEEDIT) { - ParticleSystem *psys=PE_get_current(OBACT); + ParticleSystem *psys= PE_get_current(scene, ob); ParticleData *pa = psys->particles; ParticleEditKey *ek; int k; @@ -411,7 +378,7 @@ int calc_manipulator_stats(ScrArea *sa) for(k=0, ek=psys->edit->keys[a]; k<pa->totkey; k++, ek++) { if(ek->flag & PEK_SELECT) { - calc_tw_center(ek->world_co); + calc_tw_center(scene, ek->world_co); totsel++; } } @@ -419,48 +386,43 @@ int calc_manipulator_stats(ScrArea *sa) /* selection center */ if(totsel) - VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid! + VecMulf(scene->twcent, 1.0f/(float)totsel); // centroid! } } else { - + /* we need the one selected object, if its not active */ ob= OBACT; if(ob && !(ob->flag & SELECT)) ob= NULL; - - for(base= G.scene->base.first; base; base= base->next) { - if TESTBASELIB(base) { - if(ob==NULL) + + for(base= scene->base.first; base; base= base->next) { + if TESTBASELIB(scene, base) { + if(ob==NULL) ob= base->object; - calc_tw_center(base->object->obmat[3]); + calc_tw_center(scene, base->object->obmat[3]); protectflag_to_drawflags(base->object->protectflag, &v3d->twdrawflag); totsel++; } } - + /* selection center */ if(totsel) { - VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid! + VecMulf(scene->twcent, 1.0f/(float)totsel); // centroid! } } - + /* global, local or normal orientation? */ if(ob && totsel) { - + switch(v3d->twmode) { - case V3D_MANIP_GLOBAL: - strcpy(t->spacename, "global"); - break; - + case V3D_MANIP_NORMAL: - if(t->obedit || ob->flag & OB_POSEMODE) { + if(obedit || ob->flag & OB_POSEMODE) { float mat[3][3]; int type; - - strcpy(t->spacename, "normal"); - - type = getTransformOrientation(normal, plane, (G.vd->around == V3D_ACTIVE)); - + + type = getTransformOrientation(C, normal, plane, (v3d->around == V3D_ACTIVE)); + switch (type) { case ORIENTATION_NORMAL: @@ -488,57 +450,55 @@ int calc_manipulator_stats(ScrArea *sa) } break; } - + if (type == ORIENTATION_NONE) { - Mat4One(v3d->twmat); + Mat4One(rv3d->twmat); } else { - Mat4CpyMat3(v3d->twmat, mat); + Mat4CpyMat3(rv3d->twmat, mat); } break; } /* no break we define 'normal' as 'local' in Object mode */ case V3D_MANIP_LOCAL: - strcpy(t->spacename, "local"); - Mat4CpyMat4(v3d->twmat, ob->obmat); - Mat4Ortho(v3d->twmat); + Mat4CpyMat4(rv3d->twmat, ob->obmat); + Mat4Ortho(rv3d->twmat); break; - + case V3D_MANIP_VIEW: { float mat[3][3]; - strcpy(t->spacename, "view"); - Mat3CpyMat4(mat, v3d->viewinv); + Mat3CpyMat4(mat, rv3d->viewinv); Mat3Ortho(mat); - Mat4CpyMat3(v3d->twmat, mat); + Mat4CpyMat3(rv3d->twmat, mat); } break; default: /* V3D_MANIP_CUSTOM */ - applyTransformOrientation(); + // XXX applyTransformOrientation(C, t); break; } - + } - + return totsel; } /* ******************** DRAWING STUFFIES *********** */ -static float screen_aligned(float mat[][4]) +static float screen_aligned(RegionView3D *rv3d, float mat[][4]) { float vec[3], size; - + VECCOPY(vec, mat[0]); size= Normalize(vec); - + glTranslatef(mat[3][0], mat[3][1], mat[3][2]); - + /* sets view screen aligned */ - glRotatef( -360.0f*saacos(G.vd->viewquat[0])/(float)M_PI, G.vd->viewquat[1], G.vd->viewquat[2], G.vd->viewquat[3]); - + glRotatef( -360.0f*saacos(rv3d->viewquat[0])/(float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]); + return size; } @@ -557,32 +517,32 @@ static void partial_donut(float radring, float radhole, int start, int end, int float cos_theta1, sin_theta1; float ring_delta, side_delta; int i, j, docaps= 1; - + if(start==0 && end==nrings) docaps= 0; - + ring_delta= 2.0f*(float)M_PI/(float)nrings; side_delta= 2.0f*(float)M_PI/(float)nsides; - + theta= (float)M_PI+0.5f*ring_delta; cos_theta= (float)cos(theta); sin_theta= (float)sin(theta); - + for(i= nrings - 1; i >= 0; i--) { theta1= theta + ring_delta; cos_theta1= (float)cos(theta1); sin_theta1= (float)sin(theta1); - + if(docaps && i==start) { // cap glBegin(GL_POLYGON); phi= 0.0; for(j= nsides; j >= 0; j--) { float cos_phi, sin_phi, dist; - + phi += side_delta; cos_phi= (float)cos(phi); sin_phi= (float)sin(phi); dist= radhole + radring * cos_phi; - + glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi); } glEnd(); @@ -592,35 +552,35 @@ static void partial_donut(float radring, float radhole, int start, int end, int phi= 0.0; for(j= nsides; j >= 0; j--) { float cos_phi, sin_phi, dist; - + phi += side_delta; cos_phi= (float)cos(phi); sin_phi= (float)sin(phi); dist= radhole + radring * cos_phi; - + glVertex3f(cos_theta1 * dist, -sin_theta1 * dist, radring * sin_phi); glVertex3f(cos_theta * dist, -sin_theta * dist, radring * sin_phi); } glEnd(); } - + if(docaps && i==end) { // cap glBegin(GL_POLYGON); phi= 0.0; for(j= nsides; j >= 0; j--) { float cos_phi, sin_phi, dist; - + phi -= side_delta; cos_phi= (float)cos(phi); sin_phi= (float)sin(phi); dist= radhole + radring * cos_phi; - + glVertex3f(cos_theta * dist, -sin_theta * dist, radring * sin_phi); } glEnd(); } - - + + theta= theta1; cos_theta= cos_theta1; sin_theta= sin_theta1; @@ -632,30 +592,30 @@ static void partial_donut(float radring, float radhole, int start, int end, int moving: in transform theme color else the red/green/blue */ -static void manipulator_setcolor(char axis, int colcode) +static void manipulator_setcolor(View3D *v3d, char axis, int colcode) { float vec[4]; char col[4]; - + vec[3]= 0.7f; // alpha set on 0.5, can be glEnabled or not - + if(colcode==MAN_GHOST) { glColor4ub(0, 0, 0, 70); } else if(colcode==MAN_MOVECOL) { - BIF_GetThemeColor3ubv(TH_TRANSFORM, col); + UI_GetThemeColor3ubv(TH_TRANSFORM, col); glColor4ub(col[0], col[1], col[2], 128); } else { switch(axis) { case 'c': - BIF_GetThemeColor3ubv(TH_TRANSFORM, col); - if(G.vd->twmode == V3D_MANIP_LOCAL) { + UI_GetThemeColor3ubv(TH_TRANSFORM, col); + if(v3d->twmode == V3D_MANIP_LOCAL) { col[0]= col[0]>200?255:col[0]+55; col[1]= col[1]>200?255:col[1]+55; col[2]= col[2]>200?255:col[2]+55; } - else if(G.vd->twmode == V3D_MANIP_NORMAL) { + else if(v3d->twmode == V3D_MANIP_NORMAL) { col[0]= col[0]<55?0:col[0]-55; col[1]= col[1]<55?0:col[1]-55; col[2]= col[2]<55?0:col[2]-55; @@ -676,32 +636,32 @@ static void manipulator_setcolor(char axis, int colcode) } /* viewmatrix should have been set OK, also no shademode! */ -static void draw_manipulator_axes(int colcode, int flagx, int flagy, int flagz) +static void draw_manipulator_axes(View3D *v3d, int colcode, int flagx, int flagy, int flagz) { - + /* axes */ if(flagx) { - manipulator_setcolor('x', colcode); + manipulator_setcolor(v3d, 'x', colcode); if(flagx & MAN_SCALE_X) glLoadName(MAN_SCALE_X); else if(flagx & MAN_TRANS_X) glLoadName(MAN_TRANS_X); glBegin(GL_LINES); glVertex3f(0.2f, 0.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f); glEnd(); - } + } if(flagy) { if(flagy & MAN_SCALE_Y) glLoadName(MAN_SCALE_Y); else if(flagy & MAN_TRANS_Y) glLoadName(MAN_TRANS_Y); - manipulator_setcolor('y', colcode); + manipulator_setcolor(v3d, 'y', colcode); glBegin(GL_LINES); glVertex3f(0.0f, 0.2f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); glEnd(); - } + } if(flagz) { if(flagz & MAN_SCALE_Z) glLoadName(MAN_SCALE_Z); else if(flagz & MAN_TRANS_Z) glLoadName(MAN_TRANS_Z); - manipulator_setcolor('z', colcode); + manipulator_setcolor(v3d, 'z', colcode); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.2f); glVertex3f(0.0f, 0.0f, 1.0f); @@ -710,68 +670,68 @@ static void draw_manipulator_axes(int colcode, int flagx, int flagy, int flagz) } /* only called while G.moving */ -static void draw_manipulator_rotate_ghost(float mat[][4], int drawflags) +static void draw_manipulator_rotate_ghost(View3D *v3d, RegionView3D *rv3d, int drawflags) { GLUquadricObj *qobj; float size, phi, startphi, vec[3], svec[3], matt[4][4], cross[3], tmat[3][3]; int arcs= (G.rt!=2); - + glDisable(GL_DEPTH_TEST); - qobj= gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - + qobj= gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + glColor4ub(0,0,0,64); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); - - /* we need both [4][4] transforms, Trans.mat seems to be premul, not post for mat[][4] */ - Mat4CpyMat4(matt, mat); // to copy the parts outside of [3][3] - Mat4MulMat34(matt, Trans.mat, mat); + + /* we need both [4][4] transforms, t->mat seems to be premul, not post for mat[][4] */ + Mat4CpyMat4(matt, rv3d->twmat); // to copy the parts outside of [3][3] +// XXX Mat4MulMat34(matt, t->mat, rv3d->twmat); /* Screen aligned view rot circle */ if(drawflags & MAN_ROT_V) { - + /* prepare for screen aligned draw */ glPushMatrix(); - size= screen_aligned(mat); - - vec[0]= (float)(Trans.con.imval[0] - Trans.center2d[0]); - vec[1]= (float)(Trans.con.imval[1] - Trans.center2d[1]); + size= screen_aligned(rv3d, rv3d->twmat); + + vec[0]= 0; // XXX (float)(t->con.imval[0] - t->center2d[0]); + vec[1]= 0; // XXX (float)(t->con.imval[1] - t->center2d[1]); vec[2]= 0.0f; Normalize(vec); - + startphi= saacos( vec[1] ); if(vec[0]<0.0) startphi= -startphi; - - phi= (float)fmod(180.0*Trans.val/M_PI, 360.0); + + phi= 0; // XXX (float)fmod(180.0*t->val/M_PI, 360.0); if(phi > 180.0) phi-= 360.0; else if(phi<-180.0) phi+= 360.0; - + gluPartialDisk(qobj, 0.0, size, 32, 1, 180.0*startphi/M_PI, phi); - + glPopMatrix(); } else if(arcs) { float imat[3][3], ivmat[3][3]; /* try to get the start rotation */ - - svec[0]= (float)(Trans.con.imval[0] - Trans.center2d[0]); - svec[1]= (float)(Trans.con.imval[1] - Trans.center2d[1]); + + svec[0]= 0; // XXX (float)(t->con.imval[0] - t->center2d[0]); + svec[1]= 0; // XXX (float)(t->con.imval[1] - t->center2d[1]); svec[2]= 0.0f; - + /* screen aligned vec transform back to manipulator space */ - Mat3CpyMat4(ivmat, G.vd->viewinv); - Mat3CpyMat4(tmat, mat); + Mat3CpyMat4(ivmat, rv3d->viewinv); + Mat3CpyMat4(tmat, rv3d->twmat); Mat3Inv(imat, tmat); Mat3MulMat3(tmat, imat, ivmat); - + Mat3MulVecfl(tmat, svec); // tmat is used further on Normalize(svec); - } - - mymultmatrix(mat); // aligns with original widget - + } + + wmMultMatrix(rv3d->twmat); // aligns with original widget + /* Z disk */ if(drawflags & MAN_ROT_Z) { if(arcs) { @@ -779,18 +739,18 @@ static void draw_manipulator_rotate_ghost(float mat[][4], int drawflags) svec[0]+= tmat[2][0]; svec[1]+= tmat[2][1]; Normalize(svec); - + startphi= (float)atan2(svec[0], svec[1]); } else startphi= 0.5f*(float)M_PI; - - VECCOPY(vec, mat[0]); // use x axis to detect rotation + + VECCOPY(vec, rv3d->twmat[0]); // use x axis to detect rotation Normalize(vec); Normalize(matt[0]); phi= saacos( Inpf(vec, matt[0]) ); if(phi!=0.0) { Crossf(cross, vec, matt[0]); // results in z vector - if(Inpf(cross, mat[2]) > 0.0) phi= -phi; + if(Inpf(cross, rv3d->twmat[2]) > 0.0) phi= -phi; gluPartialDisk(qobj, 0.0, 1.0, 32, 1, 180.0*startphi/M_PI, 180.0*(phi)/M_PI); } } @@ -801,23 +761,23 @@ static void draw_manipulator_rotate_ghost(float mat[][4], int drawflags) svec[1]+= tmat[2][1]; svec[2]+= tmat[2][2]; Normalize(svec); - + startphi= (float)(M_PI + atan2(svec[2], -svec[1])); } else startphi= 0.0f; - - VECCOPY(vec, mat[1]); // use y axis to detect rotation + + VECCOPY(vec, rv3d->twmat[1]); // use y axis to detect rotation Normalize(vec); Normalize(matt[1]); phi= saacos( Inpf(vec, matt[1]) ); if(phi!=0.0) { Crossf(cross, vec, matt[1]); // results in x vector - if(Inpf(cross, mat[0]) > 0.0) phi= -phi; + if(Inpf(cross, rv3d->twmat[0]) > 0.0) phi= -phi; glRotatef(90.0, 0.0, 1.0, 0.0); gluPartialDisk(qobj, 0.0, 1.0, 32, 1, 180.0*startphi/M_PI, 180.0*phi/M_PI); glRotatef(-90.0, 0.0, 1.0, 0.0); } - } + } /* Y circle */ if(drawflags & MAN_ROT_Y) { if(arcs) { @@ -825,83 +785,83 @@ static void draw_manipulator_rotate_ghost(float mat[][4], int drawflags) svec[0]+= tmat[2][0]; svec[2]+= tmat[2][2]; Normalize(svec); - + startphi= (float)(M_PI + atan2(-svec[0], svec[2])); } else startphi= (float)M_PI; - - VECCOPY(vec, mat[2]); // use z axis to detect rotation + + VECCOPY(vec, rv3d->twmat[2]); // use z axis to detect rotation Normalize(vec); Normalize(matt[2]); phi= saacos( Inpf(vec, matt[2]) ); if(phi!=0.0) { Crossf(cross, vec, matt[2]); // results in y vector - if(Inpf(cross, mat[1]) > 0.0) phi= -phi; + if(Inpf(cross, rv3d->twmat[1]) > 0.0) phi= -phi; glRotatef(-90.0, 1.0, 0.0, 0.0); gluPartialDisk(qobj, 0.0, 1.0, 32, 1, 180.0*startphi/M_PI, 180.0*phi/M_PI); glRotatef(90.0, 1.0, 0.0, 0.0); } } - + glDisable(GL_BLEND); - myloadmatrix(G.vd->viewmat); + wmLoadMatrix(rv3d->viewmat); } -static void draw_manipulator_rotate(float mat[][4], int moving, int drawflags, int combo) +static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, int drawflags, int combo) { - GLUquadricObj *qobj; + GLUquadricObj *qobj; double plane[4]; float size, vec[3], unitmat[4][4]; - float cywid= 0.33f*0.01f*(float)U.tw_handlesize; + float cywid= 0.33f*0.01f*(float)U.tw_handlesize; float cusize= cywid*0.65f; int arcs= (G.rt!=2); int colcode; - + if(moving) colcode= MAN_MOVECOL; else colcode= MAN_RGB; - + /* when called while moving in mixed mode, do not draw when... */ if((drawflags & MAN_ROT_C)==0) return; - + /* Init stuff */ glDisable(GL_DEPTH_TEST); Mat4One(unitmat); qobj= gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - + gluQuadricDrawStyle(qobj, GLU_FILL); + /* prepare for screen aligned draw */ - VECCOPY(vec, mat[0]); + VECCOPY(vec, rv3d->twmat[0]); size= Normalize(vec); glPushMatrix(); - glTranslatef(mat[3][0], mat[3][1], mat[3][2]); - + glTranslatef(rv3d->twmat[3][0], rv3d->twmat[3][1], rv3d->twmat[3][2]); + if(arcs) { /* clipplane makes nice handles, calc here because of multmatrix but with translate! */ - VECCOPY(plane, G.vd->viewinv[2]); + VECCOPY(plane, rv3d->viewinv[2]); plane[3]= -0.02*size; // clip just a bit more glClipPlane(GL_CLIP_PLANE0, plane); } /* sets view screen aligned */ - glRotatef( -360.0f*saacos(G.vd->viewquat[0])/(float)M_PI, G.vd->viewquat[1], G.vd->viewquat[2], G.vd->viewquat[3]); - + glRotatef( -360.0f*saacos(rv3d->viewquat[0])/(float)M_PI, rv3d->viewquat[1], rv3d->viewquat[2], rv3d->viewquat[3]); + /* Screen aligned help circle */ if(arcs) { if((G.f & G_PICKSEL)==0) { - BIF_ThemeColorShade(TH_BACK, -30); + UI_ThemeColorShade(TH_BACK, -30); drawcircball(GL_LINE_LOOP, unitmat[3], size, unitmat); } } /* Screen aligned view rot circle */ if(drawflags & MAN_ROT_V) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_V); - BIF_ThemeColor(TH_TRANSFORM); + UI_ThemeColor(TH_TRANSFORM); drawcircball(GL_LINE_LOOP, unitmat[3], 1.2f*size, unitmat); - - if(moving) { + + if(moving) { float vec[3]; - vec[0]= (float)(Trans.imval[0] - Trans.center2d[0]); - vec[1]= (float)(Trans.imval[1] - Trans.center2d[1]); + vec[0]= 0; // XXX (float)(t->imval[0] - t->center2d[0]); + vec[1]= 0; // XXX (float)(t->imval[1] - t->center2d[1]); vec[2]= 0.0f; Normalize(vec); VecMulf(vec, 1.2f*size); @@ -912,20 +872,20 @@ static void draw_manipulator_rotate(float mat[][4], int moving, int drawflags, i } } glPopMatrix(); - + /* apply the transform delta */ if(moving) { float matt[4][4]; - Mat4CpyMat4(matt, mat); // to copy the parts outside of [3][3] - Mat4MulMat34(matt, Trans.mat, mat); - mymultmatrix(matt); + Mat4CpyMat4(matt, rv3d->twmat); // to copy the parts outside of [3][3] + // XXX Mat4MulMat34(matt, t->mat, rv3d->twmat); + wmMultMatrix(matt); glFrontFace( is_mat4_flipped(matt)?GL_CW:GL_CCW); } else { - glFrontFace( is_mat4_flipped(mat)?GL_CW:GL_CCW); - mymultmatrix(mat); + glFrontFace( is_mat4_flipped(rv3d->twmat)?GL_CW:GL_CCW); + wmMultMatrix(rv3d->twmat); } - + /* axes */ if(arcs==0) { if(!(G.f & G_PICKSEL)) { @@ -933,17 +893,17 @@ static void draw_manipulator_rotate(float mat[][4], int moving, int drawflags, i /* axis */ glBegin(GL_LINES); if( (drawflags & MAN_ROT_X) || (moving && (drawflags & MAN_ROT_Z)) ) { - manipulator_setcolor('x', colcode); + manipulator_setcolor(v3d, 'x', colcode); glVertex3f(0.2f, 0.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f); - } + } if( (drawflags & MAN_ROT_Y) || (moving && (drawflags & MAN_ROT_X)) ) { - manipulator_setcolor('y', colcode); + manipulator_setcolor(v3d, 'y', colcode); glVertex3f(0.0f, 0.2f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); - } + } if( (drawflags & MAN_ROT_Z) || (moving && (drawflags & MAN_ROT_Y)) ) { - manipulator_setcolor('z', colcode); + manipulator_setcolor(v3d, 'z', colcode); glVertex3f(0.0f, 0.0f, 0.2f); glVertex3f(0.0f, 0.0f, 1.0f); } @@ -951,183 +911,248 @@ static void draw_manipulator_rotate(float mat[][4], int moving, int drawflags, i } } } - + if(arcs==0 && moving) { - + /* Z circle */ if(drawflags & MAN_ROT_Z) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); - manipulator_setcolor('z', colcode); + manipulator_setcolor(v3d, 'z', colcode); drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat); } /* X circle */ if(drawflags & MAN_ROT_X) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_X); glRotatef(90.0, 0.0, 1.0, 0.0); - manipulator_setcolor('x', colcode); + manipulator_setcolor(v3d, 'x', colcode); drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat); glRotatef(-90.0, 0.0, 1.0, 0.0); - } + } /* Y circle */ if(drawflags & MAN_ROT_Y) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); glRotatef(-90.0, 1.0, 0.0, 0.0); - manipulator_setcolor('y', colcode); + manipulator_setcolor(v3d, 'y', colcode); drawcircball(GL_LINE_LOOP, unitmat[3], 1.0, unitmat); glRotatef(90.0, 1.0, 0.0, 0.0); } - + if(arcs) glDisable(GL_CLIP_PLANE0); } // donut arcs if(arcs) { glEnable(GL_CLIP_PLANE0); - + /* Z circle */ if(drawflags & MAN_ROT_Z) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); - manipulator_setcolor('z', colcode); + manipulator_setcolor(v3d, 'z', colcode); partial_donut(cusize/4.0f, 1.0f, 0, 48, 8, 48); } /* X circle */ if(drawflags & MAN_ROT_X) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_X); glRotatef(90.0, 0.0, 1.0, 0.0); - manipulator_setcolor('x', colcode); + manipulator_setcolor(v3d, 'x', colcode); partial_donut(cusize/4.0f, 1.0f, 0, 48, 8, 48); glRotatef(-90.0, 0.0, 1.0, 0.0); - } + } /* Y circle */ if(drawflags & MAN_ROT_Y) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); glRotatef(-90.0, 1.0, 0.0, 0.0); - manipulator_setcolor('y', colcode); + manipulator_setcolor(v3d, 'y', colcode); partial_donut(cusize/4.0f, 1.0f, 0, 48, 8, 48); glRotatef(90.0, 1.0, 0.0, 0.0); } - + glDisable(GL_CLIP_PLANE0); } - + if(arcs==0) { - + /* Z handle on X axis */ if(drawflags & MAN_ROT_Z) { glPushMatrix(); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); - manipulator_setcolor('z', colcode); + manipulator_setcolor(v3d, 'z', colcode); partial_donut(0.7f*cusize, 1.0f, 31, 33, 8, 64); glPopMatrix(); - } + } /* Y handle on X axis */ if(drawflags & MAN_ROT_Y) { glPushMatrix(); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); - manipulator_setcolor('y', colcode); - + manipulator_setcolor(v3d, 'y', colcode); + glRotatef(90.0, 1.0, 0.0, 0.0); glRotatef(90.0, 0.0, 0.0, 1.0); partial_donut(0.7f*cusize, 1.0f, 31, 33, 8, 64); - + glPopMatrix(); } - + /* X handle on Z axis */ if(drawflags & MAN_ROT_X) { glPushMatrix(); if(G.f & G_PICKSEL) glLoadName(MAN_ROT_X); - manipulator_setcolor('x', colcode); - + manipulator_setcolor(v3d, 'x', colcode); + glRotatef(-90.0, 0.0, 1.0, 0.0); glRotatef(90.0, 0.0, 0.0, 1.0); partial_donut(0.7f*cusize, 1.0f, 31, 33, 8, 64); glPopMatrix(); } - + } - + /* restore */ - myloadmatrix(G.vd->viewmat); + wmLoadMatrix(rv3d->viewmat); gluDeleteQuadric(qobj); - if(G.vd->zbuf) glEnable(GL_DEPTH_TEST); - + if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + +} + +static void drawsolidcube(float size) +{ + static float cube[8][3] = { + {-1.0, -1.0, -1.0}, + {-1.0, -1.0, 1.0}, + {-1.0, 1.0, 1.0}, + {-1.0, 1.0, -1.0}, + { 1.0, -1.0, -1.0}, + { 1.0, -1.0, 1.0}, + { 1.0, 1.0, 1.0}, + { 1.0, 1.0, -1.0}, }; + float n[3]; + + glPushMatrix(); + glScalef(size, size, size); + + n[0]=0; n[1]=0; n[2]=0; + glBegin(GL_QUADS); + n[0]= -1.0; + glNormal3fv(n); + glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]); + n[0]=0; + glEnd(); + + glBegin(GL_QUADS); + n[1]= -1.0; + glNormal3fv(n); + glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]); + n[1]=0; + glEnd(); + + glBegin(GL_QUADS); + n[0]= 1.0; + glNormal3fv(n); + glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]); + n[0]=0; + glEnd(); + + glBegin(GL_QUADS); + n[1]= 1.0; + glNormal3fv(n); + glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]); + n[1]=0; + glEnd(); + + glBegin(GL_QUADS); + n[2]= 1.0; + glNormal3fv(n); + glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]); + n[2]=0; + glEnd(); + + glBegin(GL_QUADS); + n[2]= -1.0; + glNormal3fv(n); + glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]); + glEnd(); + + glPopMatrix(); } -static void draw_manipulator_scale(float mat[][4], int moving, int drawflags, int combo, int colcode) + +static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving, int drawflags, int combo, int colcode) { - float cywid= 0.25f*0.01f*(float)U.tw_handlesize; + float cywid= 0.25f*0.01f*(float)U.tw_handlesize; float cusize= cywid*0.75f, dz; - + /* when called while moving in mixed mode, do not draw when... */ if((drawflags & MAN_SCALE_C)==0) return; - + glDisable(GL_DEPTH_TEST); - + /* not in combo mode */ if( (combo & (V3D_MANIP_TRANSLATE|V3D_MANIP_ROTATE))==0) { float size, unitmat[4][4]; - + int shift= 0; // XXX + /* center circle, do not add to selection when shift is pressed (planar constraint) */ - if( (G.f & G_PICKSEL) && (G.qual & LR_SHIFTKEY)==0) glLoadName(MAN_SCALE_C); - - manipulator_setcolor('c', colcode); + if( (G.f & G_PICKSEL) && shift==0) glLoadName(MAN_SCALE_C); + + manipulator_setcolor(v3d, 'c', colcode); glPushMatrix(); - size= screen_aligned(mat); + size= screen_aligned(rv3d, rv3d->twmat); Mat4One(unitmat); drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f*size, unitmat); glPopMatrix(); - + dz= 1.0; } else dz= 1.0f-4.0f*cusize; - + if(moving) { float matt[4][4]; - - Mat4CpyMat4(matt, mat); // to copy the parts outside of [3][3] - Mat4MulMat34(matt, Trans.mat, mat); - mymultmatrix(matt); + + Mat4CpyMat4(matt, rv3d->twmat); // to copy the parts outside of [3][3] + // XXX Mat4MulMat34(matt, t->mat, rv3d->twmat); + wmMultMatrix(matt); glFrontFace( is_mat4_flipped(matt)?GL_CW:GL_CCW); } else { - mymultmatrix(mat); - glFrontFace( is_mat4_flipped(mat)?GL_CW:GL_CCW); + wmMultMatrix(rv3d->twmat); + glFrontFace( is_mat4_flipped(rv3d->twmat)?GL_CW:GL_CCW); } - + /* axis */ - + /* in combo mode, this is always drawn as first type */ - draw_manipulator_axes(colcode, drawflags & MAN_SCALE_X, drawflags & MAN_SCALE_Y, drawflags & MAN_SCALE_Z); - + draw_manipulator_axes(v3d, colcode, drawflags & MAN_SCALE_X, drawflags & MAN_SCALE_Y, drawflags & MAN_SCALE_Z); + /* Z cube */ glTranslatef(0.0, 0.0, dz); if(drawflags & MAN_SCALE_Z) { if(G.f & G_PICKSEL) glLoadName(MAN_SCALE_Z); - manipulator_setcolor('z', colcode); + manipulator_setcolor(v3d, 'z', colcode); drawsolidcube(cusize); - } + } /* X cube */ glTranslatef(dz, 0.0, -dz); if(drawflags & MAN_SCALE_X) { if(G.f & G_PICKSEL) glLoadName(MAN_SCALE_X); - manipulator_setcolor('x', colcode); + manipulator_setcolor(v3d, 'x', colcode); drawsolidcube(cusize); - } + } /* Y cube */ glTranslatef(-dz, dz, 0.0); if(drawflags & MAN_SCALE_Y) { if(G.f & G_PICKSEL) glLoadName(MAN_SCALE_Y); - manipulator_setcolor('y', colcode); + manipulator_setcolor(v3d, 'y', colcode); drawsolidcube(cusize); } - + /* if shiftkey, center point as last, for selectbuffer order */ if(G.f & G_PICKSEL) { - if(G.qual & LR_SHIFTKEY) { + int shift= 0; // XXX + + if(shift) { glTranslatef(0.0, -dz, 0.0); glLoadName(MAN_SCALE_C); glBegin(GL_POINTS); @@ -1135,11 +1160,11 @@ static void draw_manipulator_scale(float mat[][4], int moving, int drawflags, in glEnd(); } } - + /* restore */ - myloadmatrix(G.vd->viewmat); - - if(G.vd->zbuf) glEnable(GL_DEPTH_TEST); + wmLoadMatrix(rv3d->viewmat); + + if(v3d->zbuf) glEnable(GL_DEPTH_TEST); glFrontFace(GL_CCW); } @@ -1149,132 +1174,133 @@ static void draw_cone(GLUquadricObj *qobj, float len, float width) glTranslatef(0.0, 0.0, -0.5f*len); gluCylinder(qobj, width, 0.0, len, 8, 1); gluQuadricOrientation(qobj, GLU_INSIDE); - gluDisk(qobj, 0.0, width, 8, 1); + gluDisk(qobj, 0.0, width, 8, 1); gluQuadricOrientation(qobj, GLU_OUTSIDE); glTranslatef(0.0, 0.0, 0.5f*len); } static void draw_cylinder(GLUquadricObj *qobj, float len, float width) { - + width*= 0.8f; // just for beauty - + glTranslatef(0.0, 0.0, -0.5f*len); gluCylinder(qobj, width, width, len, 8, 1); gluQuadricOrientation(qobj, GLU_INSIDE); - gluDisk(qobj, 0.0, width, 8, 1); + gluDisk(qobj, 0.0, width, 8, 1); gluQuadricOrientation(qobj, GLU_OUTSIDE); glTranslatef(0.0, 0.0, len); - gluDisk(qobj, 0.0, width, 8, 1); + gluDisk(qobj, 0.0, width, 8, 1); glTranslatef(0.0, 0.0, -0.5f*len); } -static void draw_manipulator_translate(float mat[][4], int moving, int drawflags, int combo, int colcode) +static void draw_manipulator_translate(View3D *v3d, RegionView3D *rv3d, int moving, int drawflags, int combo, int colcode) { - GLUquadricObj *qobj; + GLUquadricObj *qobj; float cylen= 0.01f*(float)U.tw_handlesize; float cywid= 0.25f*cylen, dz, size; float unitmat[4][4]; - + int shift= 0; // XXX + /* when called while moving in mixed mode, do not draw when... */ if((drawflags & MAN_TRANS_C)==0) return; - - if(moving) glTranslatef(Trans.vec[0], Trans.vec[1], Trans.vec[2]); + + // XXX if(moving) glTranslatef(t->vec[0], t->vec[1], t->vec[2]); glDisable(GL_DEPTH_TEST); qobj= gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - + gluQuadricDrawStyle(qobj, GLU_FILL); + /* center circle, do not add to selection when shift is pressed (planar constraint) */ - if( (G.f & G_PICKSEL) && (G.qual & LR_SHIFTKEY)==0) glLoadName(MAN_TRANS_C); - - manipulator_setcolor('c', colcode); + if( (G.f & G_PICKSEL) && shift==0) glLoadName(MAN_TRANS_C); + + manipulator_setcolor(v3d, 'c', colcode); glPushMatrix(); - size= screen_aligned(mat); + size= screen_aligned(rv3d, rv3d->twmat); Mat4One(unitmat); drawcircball(GL_LINE_LOOP, unitmat[3], 0.2f*size, unitmat); glPopMatrix(); - + /* and now apply matrix, we move to local matrix drawing */ - mymultmatrix(mat); - + wmMultMatrix(rv3d->twmat); + /* axis */ glLoadName(-1); - + // translate drawn as last, only axis when no combo with scale, or for ghosting if((combo & V3D_MANIP_SCALE)==0 || colcode==MAN_GHOST) - draw_manipulator_axes(colcode, drawflags & MAN_TRANS_X, drawflags & MAN_TRANS_Y, drawflags & MAN_TRANS_Z); + draw_manipulator_axes(v3d, colcode, drawflags & MAN_TRANS_X, drawflags & MAN_TRANS_Y, drawflags & MAN_TRANS_Z); + - /* offset in combo mode, for rotate a bit more */ if(combo & (V3D_MANIP_ROTATE)) dz= 1.0f+2.0f*cylen; else if(combo & (V3D_MANIP_SCALE)) dz= 1.0f+0.5f*cylen; else dz= 1.0f; - + /* Z Cone */ glTranslatef(0.0, 0.0, dz); if(drawflags & MAN_TRANS_Z) { if(G.f & G_PICKSEL) glLoadName(MAN_TRANS_Z); - manipulator_setcolor('z', colcode); + manipulator_setcolor(v3d, 'z', colcode); draw_cone(qobj, cylen, cywid); - } + } /* X Cone */ glTranslatef(dz, 0.0, -dz); if(drawflags & MAN_TRANS_X) { if(G.f & G_PICKSEL) glLoadName(MAN_TRANS_X); glRotatef(90.0, 0.0, 1.0, 0.0); - manipulator_setcolor('x', colcode); + manipulator_setcolor(v3d, 'x', colcode); draw_cone(qobj, cylen, cywid); glRotatef(-90.0, 0.0, 1.0, 0.0); - } + } /* Y Cone */ glTranslatef(-dz, dz, 0.0); if(drawflags & MAN_TRANS_Y) { if(G.f & G_PICKSEL) glLoadName(MAN_TRANS_Y); glRotatef(-90.0, 1.0, 0.0, 0.0); - manipulator_setcolor('y', colcode); + manipulator_setcolor(v3d, 'y', colcode); draw_cone(qobj, cylen, cywid); } gluDeleteQuadric(qobj); - myloadmatrix(G.vd->viewmat); - - if(G.vd->zbuf) glEnable(GL_DEPTH_TEST); - + wmLoadMatrix(rv3d->viewmat); + + if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + } -static void draw_manipulator_rotate_cyl(float mat[][4], int moving, int drawflags, int combo, int colcode) +static void draw_manipulator_rotate_cyl(View3D *v3d, RegionView3D *rv3d, int moving, int drawflags, int combo, int colcode) { GLUquadricObj *qobj; float size; float cylen= 0.01f*(float)U.tw_handlesize; float cywid= 0.25f*cylen; - + /* when called while moving in mixed mode, do not draw when... */ if((drawflags & MAN_ROT_C)==0) return; /* prepare for screen aligned draw */ glPushMatrix(); - size= screen_aligned(mat); - + size= screen_aligned(rv3d, rv3d->twmat); + glDisable(GL_DEPTH_TEST); - qobj= gluNewQuadric(); - + qobj= gluNewQuadric(); + /* Screen aligned view rot circle */ if(drawflags & MAN_ROT_V) { float unitmat[4][4]; Mat4One(unitmat); - + if(G.f & G_PICKSEL) glLoadName(MAN_ROT_V); - BIF_ThemeColor(TH_TRANSFORM); + UI_ThemeColor(TH_TRANSFORM); drawcircball(GL_LINE_LOOP, unitmat[3], 1.2f*size, unitmat); - + if(moving) { float vec[3]; - vec[0]= (float)(Trans.imval[0] - Trans.center2d[0]); - vec[1]= (float)(Trans.imval[1] - Trans.center2d[1]); + vec[0]= 0; // XXX (float)(t->imval[0] - t->center2d[0]); + vec[1]= 0; // XXX (float)(t->imval[1] - t->center2d[1]); vec[2]= 0.0f; Normalize(vec); VecMulf(vec, 1.2f*size); @@ -1285,65 +1311,65 @@ static void draw_manipulator_rotate_cyl(float mat[][4], int moving, int drawflag } } glPopMatrix(); - + /* apply the transform delta */ if(moving) { float matt[4][4]; - Mat4CpyMat4(matt, mat); // to copy the parts outside of [3][3] - if (Trans.flag & T_USES_MANIPULATOR) { - Mat4MulMat34(matt, Trans.mat, mat); - } - mymultmatrix(matt); + Mat4CpyMat4(matt, rv3d->twmat); // to copy the parts outside of [3][3] + // XXX if (t->flag & T_USES_MANIPULATOR) { + // XXX Mat4MulMat34(matt, t->mat, rv3d->twmat); + // XXX } + wmMultMatrix(matt); } else { - mymultmatrix(mat); + wmMultMatrix(rv3d->twmat); } - - glFrontFace( is_mat4_flipped(mat)?GL_CW:GL_CCW); - + + glFrontFace( is_mat4_flipped(rv3d->twmat)?GL_CW:GL_CCW); + /* axis */ if( (G.f & G_PICKSEL)==0 ) { - + // only draw axis when combo didn't draw scale axes if((combo & V3D_MANIP_SCALE)==0) - draw_manipulator_axes(colcode, drawflags & MAN_ROT_X, drawflags & MAN_ROT_Y, drawflags & MAN_ROT_Z); - + draw_manipulator_axes(v3d, colcode, drawflags & MAN_ROT_X, drawflags & MAN_ROT_Y, drawflags & MAN_ROT_Z); + /* only has to be set when not in picking */ - gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricDrawStyle(qobj, GLU_FILL); } - + /* Z cyl */ glTranslatef(0.0, 0.0, 1.0); if(drawflags & MAN_ROT_Z) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Z); - manipulator_setcolor('z', colcode); + manipulator_setcolor(v3d, 'z', colcode); draw_cylinder(qobj, cylen, cywid); - } + } /* X cyl */ glTranslatef(1.0, 0.0, -1.0); if(drawflags & MAN_ROT_X) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_X); glRotatef(90.0, 0.0, 1.0, 0.0); - manipulator_setcolor('x', colcode); + manipulator_setcolor(v3d, 'x', colcode); draw_cylinder(qobj, cylen, cywid); glRotatef(-90.0, 0.0, 1.0, 0.0); - } + } /* Y cylinder */ glTranslatef(-1.0, 1.0, 0.0); if(drawflags & MAN_ROT_Y) { if(G.f & G_PICKSEL) glLoadName(MAN_ROT_Y); glRotatef(-90.0, 1.0, 0.0, 0.0); - manipulator_setcolor('y', colcode); + manipulator_setcolor(v3d, 'y', colcode); draw_cylinder(qobj, cylen, cywid); } - + /* restore */ - + gluDeleteQuadric(qobj); - myloadmatrix(G.vd->viewmat); - - if(G.vd->zbuf) glEnable(GL_DEPTH_TEST); - + wmLoadMatrix(rv3d->viewmat); + + if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + } @@ -1353,78 +1379,33 @@ static float get_manipulator_drawsize(ARegion *ar) { RegionView3D *rv3d= ar->regiondata; float size = get_drawsize(ar, rv3d->twmat[3]); - + size*= (float)U.tw_size; return size; } -/* exported to transform_constraints.c */ -/* mat, vec = default orientation and location */ -/* type = transform type */ -/* axis = x, y, z, c */ -/* col: 0 = colored, 1 = moving, 2 = ghost */ -void draw_manipulator_ext(ScrArea *sa, int type, char axis, int col, float vec[3], float mat[][3]) -{ - int drawflags= 0; - float mat4[4][4]; - int colcode; - - Mat4CpyMat3(mat4, mat); - VECCOPY(mat4[3], vec); - - Mat4MulFloat3((float *)mat4, get_manipulator_drawsize(sa)); - - glEnable(GL_BLEND); // let's do it transparent by default - if(col==0) colcode= MAN_RGB; - else if(col==1) colcode= MAN_MOVECOL; - else colcode= MAN_GHOST; - - - if(type==TFM_ROTATION) { - if(axis=='x') drawflags= MAN_ROT_X; - else if(axis=='y') drawflags= MAN_ROT_Y; - else if(axis=='z') drawflags= MAN_ROT_Z; - else drawflags= MAN_ROT_C; - - draw_manipulator_rotate_cyl(mat4, col, drawflags, V3D_MANIP_ROTATE, colcode); - } - else if(type==TFM_RESIZE) { - if(axis=='x') drawflags= MAN_SCALE_X; - else if(axis=='y') drawflags= MAN_SCALE_Y; - else if(axis=='z') drawflags= MAN_SCALE_Z; - else drawflags= MAN_SCALE_C; - - draw_manipulator_scale(mat4, col, drawflags, V3D_MANIP_SCALE, colcode); - } - else { - if(axis=='x') drawflags= MAN_TRANS_X; - else if(axis=='y') drawflags= MAN_TRANS_Y; - else if(axis=='z') drawflags= MAN_TRANS_Z; - else drawflags= MAN_TRANS_C; - - draw_manipulator_translate(mat4, 0, drawflags, V3D_MANIP_TRANSLATE, colcode); - } - - - glDisable(GL_BLEND); -} /* main call, does calc centers & orientation too */ /* uses global G.moving */ static int drawflags= 0xFFFF; // only for the calls below, belongs in scene...? -void BIF_draw_manipulator(ScrArea *sa) + +void BIF_draw_manipulator(const bContext *C) { + ScrArea *sa= CTX_wm_area(C); + ARegion *ar= CTX_wm_region(C); + Scene *scene= CTX_data_scene(C); View3D *v3d= sa->spacedata.first; + RegionView3D *rv3d= ar->regiondata; int totsel; - + if(!(v3d->twflag & V3D_USE_MANIPULATOR)) return; if(G.moving && (G.moving & G_TRANSFORM_MANIP)==0) return; - + if(G.moving==0) { v3d->twflag &= ~V3D_DRAW_MANIPULATOR; - - totsel= calc_manipulator_stats(sa); + + totsel= calc_manipulator_stats(C); if(totsel==0) return; drawflags= v3d->twdrawflag; /* set in calc_manipulator_stats */ @@ -1434,123 +1415,119 @@ void BIF_draw_manipulator(ScrArea *sa) switch(v3d->around) { case V3D_CENTER: case V3D_ACTIVE: - v3d->twmat[3][0]= (G.scene->twmin[0] + G.scene->twmax[0])/2.0f; - v3d->twmat[3][1]= (G.scene->twmin[1] + G.scene->twmax[1])/2.0f; - v3d->twmat[3][2]= (G.scene->twmin[2] + G.scene->twmax[2])/2.0f; - if(v3d->around==V3D_ACTIVE && t->obedit==NULL) { + rv3d->twmat[3][0]= (scene->twmin[0] + scene->twmax[0])/2.0f; + rv3d->twmat[3][1]= (scene->twmin[1] + scene->twmax[1])/2.0f; + rv3d->twmat[3][2]= (scene->twmin[2] + scene->twmax[2])/2.0f; + if(v3d->around==V3D_ACTIVE && scene->obedit==NULL) { Object *ob= OBACT; - if(ob && !(ob->flag & OB_POSEMODE)) - VECCOPY(v3d->twmat[3], ob->obmat[3]); + if(ob && !(ob->flag & OB_POSEMODE)) + VECCOPY(rv3d->twmat[3], ob->obmat[3]); } break; case V3D_LOCAL: case V3D_CENTROID: - VECCOPY(v3d->twmat[3], G.scene->twcent); + VECCOPY(rv3d->twmat[3], scene->twcent); break; case V3D_CURSOR: - VECCOPY(v3d->twmat[3], give_cursor()); + VECCOPY(rv3d->twmat[3], give_cursor(scene, v3d)); break; } - - Mat4MulFloat3((float *)v3d->twmat, get_manipulator_drawsize(sa)); + + Mat4MulFloat3((float *)rv3d->twmat, get_manipulator_drawsize(ar)); } - + if(v3d->twflag & V3D_DRAW_MANIPULATOR) { - + if(v3d->twtype & V3D_MANIP_ROTATE) { - + /* rotate has special ghosting draw, for pie chart */ - if(G.moving) draw_manipulator_rotate_ghost(v3d->twmat, drawflags); - + if(G.moving) draw_manipulator_rotate_ghost(v3d, rv3d, drawflags); + if(G.moving) glEnable(GL_BLEND); - + if(G.rt==3) { - if(G.moving) draw_manipulator_rotate_cyl(v3d->twmat, 1, drawflags, v3d->twtype, MAN_MOVECOL); - else draw_manipulator_rotate_cyl(v3d->twmat, 0, drawflags, v3d->twtype, MAN_RGB); + if(G.moving) draw_manipulator_rotate_cyl(v3d, rv3d, 1, drawflags, v3d->twtype, MAN_MOVECOL); + else draw_manipulator_rotate_cyl(v3d, rv3d, 0, drawflags, v3d->twtype, MAN_RGB); } else - draw_manipulator_rotate(v3d->twmat, G.moving, drawflags, v3d->twtype); - + draw_manipulator_rotate(v3d, rv3d, G.moving, drawflags, v3d->twtype); + glDisable(GL_BLEND); } if(v3d->twtype & V3D_MANIP_SCALE) { if(G.moving) { glEnable(GL_BLEND); - draw_manipulator_scale(v3d->twmat, 0, drawflags, v3d->twtype, MAN_GHOST); - draw_manipulator_scale(v3d->twmat, 1, drawflags, v3d->twtype, MAN_MOVECOL); + draw_manipulator_scale(v3d, rv3d, 0, drawflags, v3d->twtype, MAN_GHOST); + draw_manipulator_scale(v3d, rv3d, 1, drawflags, v3d->twtype, MAN_MOVECOL); glDisable(GL_BLEND); } - else draw_manipulator_scale(v3d->twmat, 0, drawflags, v3d->twtype, MAN_RGB); + else draw_manipulator_scale(v3d, rv3d, 0, drawflags, v3d->twtype, MAN_RGB); } if(v3d->twtype & V3D_MANIP_TRANSLATE) { if(G.moving) { glEnable(GL_BLEND); - draw_manipulator_translate(v3d->twmat, 0, drawflags, v3d->twtype, MAN_GHOST); - draw_manipulator_translate(v3d->twmat, 1, drawflags, v3d->twtype, MAN_MOVECOL); + draw_manipulator_translate(v3d, rv3d, 0, drawflags, v3d->twtype, MAN_GHOST); + draw_manipulator_translate(v3d, rv3d, 1, drawflags, v3d->twtype, MAN_MOVECOL); glDisable(GL_BLEND); } - else draw_manipulator_translate(v3d->twmat, 0, drawflags, v3d->twtype, MAN_RGB); + else draw_manipulator_translate(v3d, rv3d, 0, drawflags, v3d->twtype, MAN_RGB); } } } -static int manipulator_selectbuf(ScrArea *sa, float hotspot) +static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, short *mval, float hotspot) { View3D *v3d= sa->spacedata.first; + RegionView3D *rv3d= ar->regiondata; rctf rect; GLuint buffer[64]; // max 4 items per select, so large enuf - short hits, mval[2]; - + short hits; + extern void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); // XXX check a bit later on this... (ton) + G.f |= G_PICKSEL; - - getmouseco_areawin(mval); + rect.xmin= mval[0]-hotspot; rect.xmax= mval[0]+hotspot; rect.ymin= mval[1]-hotspot; rect.ymax= mval[1]+hotspot; - - /* get rid of overlay button matrix */ - persp(PERSP_VIEW); - - setwinmatrixview3d(sa->winx, sa->winy, &rect); - Mat4MulMat4(v3d->persmat, v3d->viewmat, sa->winmat); - + + setwinmatrixview3d(ar, v3d, &rect); + Mat4MulMat4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); + glSelectBuffer( 64, buffer); glRenderMode(GL_SELECT); glInitNames(); /* these two calls whatfor? It doesnt work otherwise */ glPushName(-2); - + /* do the drawing */ if(v3d->twtype & V3D_MANIP_ROTATE) { - if(G.rt==3) draw_manipulator_rotate_cyl(v3d->twmat, 0, MAN_ROT_C & v3d->twdrawflag, v3d->twtype, MAN_RGB); - else draw_manipulator_rotate(v3d->twmat, 0, MAN_ROT_C & v3d->twdrawflag, v3d->twtype); + if(G.rt==3) draw_manipulator_rotate_cyl(v3d, rv3d, 0, MAN_ROT_C & v3d->twdrawflag, v3d->twtype, MAN_RGB); + else draw_manipulator_rotate(v3d, rv3d, 0, MAN_ROT_C & v3d->twdrawflag, v3d->twtype); } if(v3d->twtype & V3D_MANIP_SCALE) - draw_manipulator_scale(v3d->twmat, 0, MAN_SCALE_C & v3d->twdrawflag, v3d->twtype, MAN_RGB); + draw_manipulator_scale(v3d, rv3d, 0, MAN_SCALE_C & v3d->twdrawflag, v3d->twtype, MAN_RGB); if(v3d->twtype & V3D_MANIP_TRANSLATE) - draw_manipulator_translate(v3d->twmat, 0, MAN_TRANS_C & v3d->twdrawflag, v3d->twtype, MAN_RGB); - + draw_manipulator_translate(v3d, rv3d, 0, MAN_TRANS_C & v3d->twdrawflag, v3d->twtype, MAN_RGB); + glPopName(); hits= glRenderMode(GL_RENDER); - + G.f &= ~G_PICKSEL; - setwinmatrixview3d(sa->winx, sa->winy, NULL); - Mat4MulMat4(v3d->persmat, v3d->viewmat, sa->winmat); - - persp(PERSP_WIN); - + setwinmatrixview3d(ar, v3d, NULL); + Mat4MulMat4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); + if(hits==1) return buffer[3]; else if(hits>1) { GLuint val, dep, mindep=0, mindeprot=0, minval=0, minvalrot=0; int a; - + /* we compare the hits in buffer, but value centers highest */ /* we also store the rotation hits separate (because of arcs) and return hits on other widgets if there are */ for(a=0; a<hits; a++) { dep= buffer[4*a + 1]; val= buffer[4*a + 3]; - + if(val==MAN_TRANS_C) return MAN_TRANS_C; else if(val==MAN_SCALE_C) return MAN_SCALE_C; else { @@ -1568,7 +1545,7 @@ static int manipulator_selectbuf(ScrArea *sa, float hotspot) } } } - + if(minval) return minval; else @@ -1578,108 +1555,110 @@ static int manipulator_selectbuf(ScrArea *sa, float hotspot) } /* return 0; nothing happened */ -int BIF_do_manipulator(ScrArea *sa) +int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op) { + ScrArea *sa= CTX_wm_area(C); View3D *v3d= sa->spacedata.first; + ARegion *ar= CTX_wm_region(C); + int constraint_axis[3] = {0, 0, 0}; int val; - + int shift = event->shift; + if(!(v3d->twflag & V3D_USE_MANIPULATOR)) return 0; if(!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return 0; - + // find the hotspots first test narrow hotspot - val= manipulator_selectbuf(sa, 0.5f*(float)U.tw_hotspot); + val= manipulator_selectbuf(sa, ar, event->mval, 0.5f*(float)U.tw_hotspot); if(val) { - checkFirstTime(); // TEMPORARY, check this before doing any transform call. + // drawflags still global, for drawing call above - drawflags= manipulator_selectbuf(sa, 0.2f*(float)U.tw_hotspot); + drawflags= manipulator_selectbuf(sa, ar, event->mval, 0.2f*(float)U.tw_hotspot); if(drawflags==0) drawflags= val; if (drawflags & MAN_TRANS_C) { - initManipulator(TFM_TRANSLATION); switch(drawflags) { case MAN_TRANS_C: break; case MAN_TRANS_X: - if(G.qual & LR_SHIFTKEY) { - drawflags= MAN_TRANS_Y|MAN_TRANS_Z; - BIF_setDualAxisConstraint(v3d->twmat[1], v3d->twmat[2], " Y+Z"); + if(shift) { + constraint_axis[1] = 1; + constraint_axis[2] = 1; } else - BIF_setSingleAxisConstraint(v3d->twmat[0], " X"); + constraint_axis[0] = 1; break; case MAN_TRANS_Y: - if(G.qual & LR_SHIFTKEY) { - drawflags= MAN_TRANS_X|MAN_TRANS_Z; - BIF_setDualAxisConstraint(v3d->twmat[0], v3d->twmat[2], " X+Z"); + if(shift) { + constraint_axis[0] = 1; + constraint_axis[2] = 1; } else - BIF_setSingleAxisConstraint(v3d->twmat[1], " Y"); + constraint_axis[1] = 1; break; case MAN_TRANS_Z: - if(G.qual & LR_SHIFTKEY) { - drawflags= MAN_TRANS_X|MAN_TRANS_Y; - BIF_setDualAxisConstraint(v3d->twmat[0], v3d->twmat[1], " X+Y"); + if(shift) { + constraint_axis[0] = 1; + constraint_axis[1] = 1; } else - BIF_setSingleAxisConstraint(v3d->twmat[2], " Z"); + constraint_axis[2] = 1; break; } - ManipulatorTransform(); + RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); + WM_operator_name_call(C, "TFM_OT_translation", WM_OP_INVOKE_REGION_WIN, op->ptr); } else if (drawflags & MAN_SCALE_C) { - initManipulator(TFM_RESIZE); switch(drawflags) { case MAN_SCALE_X: - if(G.qual & LR_SHIFTKEY) { - drawflags= MAN_SCALE_Y|MAN_SCALE_Z; - BIF_setDualAxisConstraint(v3d->twmat[1], v3d->twmat[2], " Y+Z"); + if(shift) { + constraint_axis[1] = 1; + constraint_axis[2] = 1; } else - BIF_setSingleAxisConstraint(v3d->twmat[0], " X"); + constraint_axis[0] = 1; break; case MAN_SCALE_Y: - if(G.qual & LR_SHIFTKEY) { - drawflags= MAN_SCALE_X|MAN_SCALE_Z; - BIF_setDualAxisConstraint(v3d->twmat[0], v3d->twmat[2], " X+Z"); + if(shift) { + constraint_axis[0] = 1; + constraint_axis[2] = 1; } else - BIF_setSingleAxisConstraint(v3d->twmat[1], " Y"); + constraint_axis[1] = 1; break; case MAN_SCALE_Z: - if(G.qual & LR_SHIFTKEY) { - drawflags= MAN_SCALE_X|MAN_SCALE_Y; - BIF_setDualAxisConstraint(v3d->twmat[0], v3d->twmat[1], " X+Y"); + if(shift) { + constraint_axis[0] = 1; + constraint_axis[1] = 1; } else - BIF_setSingleAxisConstraint(v3d->twmat[2], " Z"); + constraint_axis[2] = 1; break; } - ManipulatorTransform(); + RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); + WM_operator_name_call(C, "TFM_OT_resize", WM_OP_INVOKE_REGION_WIN, op->ptr); } - else if (drawflags == MAN_ROT_T) { /* trackbal need special case, init is different */ - initManipulator(TFM_TRACKBALL); - ManipulatorTransform(); + else if (drawflags == MAN_ROT_T) { /* trackball need special case, init is different */ + WM_operator_name_call(C, "TFM_OT_trackball", WM_OP_INVOKE_REGION_WIN, op->ptr); } else if (drawflags & MAN_ROT_C) { - initManipulator(TFM_ROTATION); switch(drawflags) { case MAN_ROT_X: - BIF_setSingleAxisConstraint(v3d->twmat[0], " X"); + constraint_axis[0] = 1; break; case MAN_ROT_Y: - BIF_setSingleAxisConstraint(v3d->twmat[1], " Y"); + constraint_axis[1] = 1; break; case MAN_ROT_Z: - BIF_setSingleAxisConstraint(v3d->twmat[2], " Z"); + constraint_axis[2] = 1; break; } - ManipulatorTransform(); + RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); + WM_operator_name_call(C, "TFM_OT_rotation", WM_OP_INVOKE_REGION_WIN, op->ptr); } } /* after transform, restore drawflags */ drawflags= 0xFFFF; - + return val; } -#endif diff --git a/source/blender/editors/transform/transform_ndofinput.c b/source/blender/editors/transform/transform_ndofinput.c index c52492ebd6b..f8567023e5f 100644 --- a/source/blender/editors/transform/transform_ndofinput.c +++ b/source/blender/editors/transform/transform_ndofinput.c @@ -31,12 +31,15 @@ #include "BKE_utildefines.h" /* ABS */ #include "DNA_view3d_types.h" /* for G.vd (view3d) */ +#include "DNA_windowmanager_types.h" /* for G.vd (view3d) */ #include "WM_types.h" #include "transform.h" +#if 0 static int updateNDofMotion(NDofInput *n); // return 0 when motion is null +#endif static void resetNDofInput(NDofInput *n); void initNDofInput(NDofInput *n) @@ -120,6 +123,8 @@ void applyNDofInput(NDofInput *n, float *vec) } } +// TRANSFORM_FIX_ME +#if 0 static int updateNDofMotion(NDofInput *n) { @@ -127,14 +132,11 @@ static int updateNDofMotion(NDofInput *n) int i; int retval = 0; -// TRANSFORM_FIX_ME -#if 0 getndof(fval); if (G.vd->ndoffilter) filterNDOFvalues(fval); -#endif - + for(i = 0; i < 6; i++) { if (!retval && fval[i] != 0.0f) @@ -149,6 +151,7 @@ static int updateNDofMotion(NDofInput *n) return retval; } +#endif diff --git a/source/blender/editors/transform/transform_numinput.c b/source/blender/editors/transform/transform_numinput.c index 34976105db3..f5f1d5fac9e 100644 --- a/source/blender/editors/transform/transform_numinput.c +++ b/source/blender/editors/transform/transform_numinput.c @@ -34,6 +34,7 @@ #include "BKE_utildefines.h" /* ABS */ #include "WM_types.h" +#include "DNA_windowmanager_types.h" #include "transform.h" diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 769001b30a8..2fc3d2f1e53 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -1,5 +1,5 @@ /** - * $Id: transform_ops.c 17542 2008-11-23 15:27:53Z theeth $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -56,31 +56,38 @@ static float VecOne[3] = {1, 1, 1}; /* need constants for this */ EnumPropertyItem proportional_mode_types[] = { - {0, "OFF", "Off", ""}, - {1, "ON", "On", ""}, - {2, "CONNECTED", "Connected", ""}, - {0, NULL, NULL, NULL} + {0, "OFF", 0, "Off", ""}, + {1, "ON", 0, "On", ""}, + {2, "CONNECTED", 0, "Connected", ""}, + {0, NULL, 0, NULL, NULL} }; EnumPropertyItem snap_mode_types[] = { - {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", "Closest", ""}, - {SCE_SNAP_TARGET_CENTER, "CENTER", "Center", ""}, - {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", "Median", ""}, - {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", "Active", ""}, - {0, NULL, NULL, NULL} + {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", ""}, + {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", ""}, + {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", ""}, + {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", ""}, + {0, NULL, 0, NULL, NULL} }; EnumPropertyItem proportional_falloff_types[] = { - {PROP_SMOOTH, "SMOOTH", "Smooth", ""}, - {PROP_SPHERE, "SPHERE", "Sphere", ""}, - {PROP_ROOT, "ROOT", "Root", ""}, - {PROP_SHARP, "SHARP", "Sharp", ""}, - {PROP_LIN, "LINEAR", "Linear", ""}, - {PROP_CONST, "CONSTANT", "Constant", ""}, - {PROP_RANDOM, "RANDOM", "Random", ""}, - {0, NULL, NULL, NULL} + {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""}, + {PROP_SPHERE, "SPHERE", 0, "Sphere", ""}, + {PROP_ROOT, "ROOT", 0, "Root", ""}, + {PROP_SHARP, "SHARP", 0, "Sharp", ""}, + {PROP_LIN, "LINEAR", 0, "Linear", ""}, + {PROP_CONST, "CONSTANT", 0, "Constant", ""}, + {PROP_RANDOM, "RANDOM", 0, "Random", ""}, + {0, NULL, 0, NULL, NULL} }; +EnumPropertyItem orientation_items[]= { + {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}, + {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""}, + {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""}, + {V3D_MANIP_VIEW, "VIEW", 0, "View", ""}, + {0, NULL, 0, NULL, NULL}}; + char OP_TRANSLATION[] = "TFM_OT_translation"; char OP_ROTATION[] = "TFM_OT_rotation"; char OP_TOSPHERE[] = "TFM_OT_tosphere"; @@ -89,6 +96,7 @@ char OP_SHEAR[] = "TFM_OT_shear"; char OP_WARP[] = "TFM_OT_warp"; char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten"; char OP_TILT[] = "TFM_OT_tilt"; +char OP_TRACKBALL[] = "TFM_OT_trackball"; TransformModeItem transform_modes[] = @@ -101,17 +109,14 @@ TransformModeItem transform_modes[] = {OP_WARP, TFM_WARP}, {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN}, {OP_TILT, TFM_TILT}, + {OP_TRACKBALL, TFM_TRACKBALL}, {NULL, 0} }; static int select_orientation_exec(bContext *C, wmOperator *op) { int orientation = RNA_enum_get(op->ptr, "orientation"); - int custom_index= RNA_int_get(op->ptr, "custom_index");; - if(orientation == V3D_MANIP_CUSTOM) - orientation += custom_index; - BIF_selectTransformOrientationValue(C, orientation); return OPERATOR_FINISHED; @@ -121,24 +126,24 @@ static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event { uiPopupMenu *pup; uiLayout *layout; - + pup= uiPupMenuBegin(C, "Orientation", 0); layout= uiPupMenuLayout(pup); - BIF_menuTransformOrientation(C, layout, NULL); + uiItemsEnumO(layout, "TFM_OT_select_orientation", "orientation"); uiPupMenuEnd(C, pup); - + return OPERATOR_CANCELLED; } - + +static EnumPropertyItem *select_orientation_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + *free= 1; + return BIF_enumTransformOrientation(C); +} + void TFM_OT_select_orientation(struct wmOperatorType *ot) { - static EnumPropertyItem orientation_items[]= { - {V3D_MANIP_GLOBAL, "GLOBAL", "Global", ""}, - {V3D_MANIP_NORMAL, "NORMAL", "Normal", ""}, - {V3D_MANIP_LOCAL, "LOCAL", "Local", ""}, - {V3D_MANIP_VIEW, "VIEW", "View", ""}, - {V3D_MANIP_CUSTOM, "CUSTOM", "Custom", ""}, - {0, NULL, NULL, NULL}}; + PropertyRNA *prop; /* identifiers */ ot->name = "Select Orientation"; @@ -149,8 +154,8 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot) ot->exec = select_orientation_exec; ot->poll = ED_operator_areaactive; - RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_CUSTOM, "Orientation", "DOC_BROKEN"); - RNA_def_int(ot->srna, "custom_index", 0, 0, INT_MAX, "Custom Index", "", 0, INT_MAX); + prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); + RNA_def_enum_funcs(prop, select_orientation_itemf); } static void transformops_exit(bContext *C, wmOperator *op) @@ -183,27 +188,27 @@ static int transformops_data(bContext *C, wmOperator *op, wmEvent *event) } retval = initTransform(C, t, op, event, mode); - + /* store data */ op->customdata = t; } - + return retval; /* return 0 on error */ } static int transform_modal(bContext *C, wmOperator *op, wmEvent *event) { int exit_code; - + TransInfo *t = op->customdata; - + transformEvent(t, event); - + transformApply(C, t); - - + + exit_code = transformEnd(C, t); - + if (exit_code != OPERATOR_RUNNING_MODAL) { transformops_exit(C, op); @@ -215,11 +220,11 @@ static int transform_modal(bContext *C, wmOperator *op, wmEvent *event) static int transform_cancel(bContext *C, wmOperator *op) { TransInfo *t = op->customdata; - + t->state = TRANS_CANCEL; transformEnd(C, t); transformops_exit(C, op); - + return OPERATOR_CANCELLED; } @@ -237,11 +242,11 @@ static int transform_exec(bContext *C, wmOperator *op) t->options |= CTX_AUTOCONFIRM; transformApply(C, t); - + transformEnd(C, t); transformops_exit(C, op); - + return OPERATOR_FINISHED; } @@ -279,7 +284,7 @@ void Properties_Snapping(struct wmOperatorType *ot, short align) RNA_def_boolean(ot->srna, "snap", 0, "Snap to Point", ""); RNA_def_enum(ot->srna, "snap_mode", snap_mode_types, 0, "Mode", ""); RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX); - + if (align) { RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", ""); @@ -289,8 +294,11 @@ void Properties_Snapping(struct wmOperatorType *ot, short align) void Properties_Constraints(struct wmOperatorType *ot) { + PropertyRNA *prop; + RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", ""); - RNA_def_int(ot->srna, "constraint_orientation", 0, 0, INT_MAX, "Constraint Orientation", "", 0, INT_MAX); + prop= RNA_def_enum(ot->srna, "constraint_orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); + RNA_def_enum_funcs(prop, select_orientation_itemf); } void TFM_OT_translation(struct wmOperatorType *ot) @@ -298,7 +306,7 @@ void TFM_OT_translation(struct wmOperatorType *ot) /* identifiers */ ot->name = "Translation"; ot->idname = OP_TRANSLATION; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -314,7 +322,7 @@ void TFM_OT_translation(struct wmOperatorType *ot) RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); Properties_Constraints(ot); - + Properties_Snapping(ot, 1); } @@ -323,7 +331,7 @@ void TFM_OT_resize(struct wmOperatorType *ot) /* identifiers */ ot->name = "Resize"; ot->idname = OP_RESIZE; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -339,16 +347,38 @@ void TFM_OT_resize(struct wmOperatorType *ot) RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); Properties_Constraints(ot); - + Properties_Snapping(ot, 0); } + +void TFM_OT_trackball(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Trackball"; + ot->idname = OP_TRACKBALL; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + + /* api callbacks */ + ot->invoke = transform_invoke; + ot->exec = transform_exec; + ot->modal = transform_modal; + ot->cancel = transform_cancel; + ot->poll = ED_operator_areaactive; + + RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "angle", "", -FLT_MAX, FLT_MAX); + + Properties_Proportional(ot); + + RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); +} + void TFM_OT_rotation(struct wmOperatorType *ot) { /* identifiers */ ot->name = "Rotation"; ot->idname = OP_ROTATION; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -364,7 +394,7 @@ void TFM_OT_rotation(struct wmOperatorType *ot) RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); Properties_Constraints(ot); - + Properties_Snapping(ot, 0); } @@ -373,7 +403,7 @@ void TFM_OT_tilt(struct wmOperatorType *ot) /* identifiers */ ot->name = "Tilt"; ot->idname = OP_TILT; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -396,7 +426,7 @@ void TFM_OT_warp(struct wmOperatorType *ot) /* identifiers */ ot->name = "Warp"; ot->idname = OP_WARP; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -420,7 +450,7 @@ void TFM_OT_shear(struct wmOperatorType *ot) /* identifiers */ ot->name = "Shear"; ot->idname = OP_SHEAR; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -444,7 +474,7 @@ void TFM_OT_shrink_fatten(struct wmOperatorType *ot) /* identifiers */ ot->name = "Shrink/Fatten"; ot->idname = OP_SHRINK_FATTEN; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -465,7 +495,7 @@ void TFM_OT_tosphere(struct wmOperatorType *ot) /* identifiers */ ot->name = "To Sphere"; ot->idname = OP_TOSPHERE; - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -484,39 +514,39 @@ void TFM_OT_tosphere(struct wmOperatorType *ot) void TFM_OT_transform(struct wmOperatorType *ot) { static EnumPropertyItem transform_mode_types[] = { - {TFM_INIT, "INIT", "Init", ""}, - {TFM_DUMMY, "DUMMY", "Dummy", ""}, - {TFM_TRANSLATION, "TRANSLATION", "Translation", ""}, - {TFM_ROTATION, "ROTATION", "Rotation", ""}, - {TFM_RESIZE, "RESIZE", "Resize", ""}, - {TFM_TOSPHERE, "TOSPHERE", "Tosphere", ""}, - {TFM_SHEAR, "SHEAR", "Shear", ""}, - {TFM_WARP, "WARP", "Warp", ""}, - {TFM_SHRINKFATTEN, "SHRINKFATTEN", "Shrinkfatten", ""}, - {TFM_TILT, "TILT", "Tilt", ""}, - {TFM_TRACKBALL, "TRACKBALL", "Trackball", ""}, - {TFM_PUSHPULL, "PUSHPULL", "Pushpull", ""}, - {TFM_CREASE, "CREASE", "Crease", ""}, - {TFM_MIRROR, "MIRROR", "Mirror", ""}, - {TFM_BONESIZE, "BONESIZE", "Bonesize", ""}, - {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", "Bone_Envelope", ""}, - {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", "Curve_Shrinkfatten", ""}, - {TFM_BONE_ROLL, "BONE_ROLL", "Bone_Roll", ""}, - {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", "Time_Translate", ""}, - {TFM_TIME_SLIDE, "TIME_SLIDE", "Time_Slide", ""}, - {TFM_TIME_SCALE, "TIME_SCALE", "Time_Scale", ""}, - {TFM_TIME_EXTEND, "TIME_EXTEND", "Time_Extend", ""}, - {TFM_BAKE_TIME, "BAKE_TIME", "Bake_Time", ""}, - {TFM_BEVEL, "BEVEL", "Bevel", ""}, - {TFM_BWEIGHT, "BWEIGHT", "Bweight", ""}, - {TFM_ALIGN, "ALIGN", "Align", ""}, - {0, NULL, NULL, NULL} + {TFM_INIT, "INIT", 0, "Init", ""}, + {TFM_DUMMY, "DUMMY", 0, "Dummy", ""}, + {TFM_TRANSLATION, "TRANSLATION", 0, "Translation", ""}, + {TFM_ROTATION, "ROTATION", 0, "Rotation", ""}, + {TFM_RESIZE, "RESIZE", 0, "Resize", ""}, + {TFM_TOSPHERE, "TOSPHERE", 0, "Tosphere", ""}, + {TFM_SHEAR, "SHEAR", 0, "Shear", ""}, + {TFM_WARP, "WARP", 0, "Warp", ""}, + {TFM_SHRINKFATTEN, "SHRINKFATTEN", 0, "Shrinkfatten", ""}, + {TFM_TILT, "TILT", 0, "Tilt", ""}, + {TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""}, + {TFM_PUSHPULL, "PUSHPULL", 0, "Pushpull", ""}, + {TFM_CREASE, "CREASE", 0, "Crease", ""}, + {TFM_MIRROR, "MIRROR", 0, "Mirror", ""}, + {TFM_BONESIZE, "BONESIZE", 0, "Bonesize", ""}, + {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""}, + {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""}, + {TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""}, + {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""}, + {TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""}, + {TFM_TIME_SCALE, "TIME_SCALE", 0, "Time_Scale", ""}, + {TFM_TIME_EXTEND, "TIME_EXTEND", 0, "Time_Extend", ""}, + {TFM_BAKE_TIME, "BAKE_TIME", 0, "Bake_Time", ""}, + {TFM_BEVEL, "BEVEL", 0, "Bevel", ""}, + {TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""}, + {TFM_ALIGN, "ALIGN", 0, "Align", ""}, + {0, NULL, 0, NULL, NULL} }; /* identifiers */ ot->name = "Transform"; ot->idname = "TFM_OT_transform"; - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; /* api callbacks */ ot->invoke = transform_invoke; @@ -531,9 +561,8 @@ void TFM_OT_transform(struct wmOperatorType *ot) Properties_Proportional(ot); RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); - - RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", ""); - RNA_def_int(ot->srna, "constraint_orientation", 0, 0, INT_MAX, "Constraint Orientation", "", 0, INT_MAX); + + Properties_Constraints(ot); } void transform_operatortypes(void) @@ -547,10 +576,11 @@ void transform_operatortypes(void) WM_operatortype_append(TFM_OT_warp); WM_operatortype_append(TFM_OT_shrink_fatten); WM_operatortype_append(TFM_OT_tilt); + WM_operatortype_append(TFM_OT_trackball); WM_operatortype_append(TFM_OT_select_orientation); } - + void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid) { wmKeymapItem *km; @@ -558,9 +588,9 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key { case SPACE_VIEW3D: km = WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0); - + km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0); - + km = WM_keymap_add_item(keymap, "TFM_OT_rotation", RKEY, KM_PRESS, 0, 0); km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0); @@ -568,9 +598,9 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key km = WM_keymap_add_item(keymap, "TFM_OT_warp", WKEY, KM_PRESS, KM_SHIFT, 0); km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); - + km = WM_keymap_add_item(keymap, "TFM_OT_shear", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0); - + km = WM_keymap_add_item(keymap, "TFM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0); km = WM_keymap_add_item(keymap, "TFM_OT_tilt", TKEY, KM_PRESS, 0, 0); @@ -581,55 +611,68 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key case SPACE_ACTION: km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0); RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE); - + km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0); RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE); - + km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0); RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND); - + km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0); RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE); - + km= WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, 0, 0); RNA_int_set(km->ptr, "mode", TFM_TIME_SLIDE); break; case SPACE_IPO: km= WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0); - + km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0); - + // 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_rotation", RKEY, KM_PRESS, 0, 0); - + km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0); break; + case SPACE_NLA: + km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0); + RNA_int_set(km->ptr, "mode", TFM_TRANSLATION); + + km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0); + RNA_int_set(km->ptr, "mode", TFM_TRANSLATION); + + km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0); + RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND); + + km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0); + RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE); + break; case SPACE_NODE: km= WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0); - + km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_A, KM_ANY, 0, 0); km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0); - + km = WM_keymap_add_item(keymap, "TFM_OT_rotation", RKEY, KM_PRESS, 0, 0); - + km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0); break; case SPACE_SEQ: km= WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0); - + km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0); - + km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0); RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND); break; case SPACE_IMAGE: km = WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0); - + km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0); - + km = WM_keymap_add_item(keymap, "TFM_OT_rotation", RKEY, KM_PRESS, 0, 0); km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 332a1e5a324..6cda535516e 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -60,6 +60,8 @@ #include "UI_interface.h" +#include "RNA_define.h" + #include "transform.h" /* *********************** TransSpace ************************** */ @@ -355,19 +357,48 @@ void BIF_selectTransformOrientationValue(bContext *C, int orientation) { v3d->twmode = orientation; } -void BIF_menuTransformOrientation(bContext *C, uiLayout *layout, void *arg) +EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) { - ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - TransformOrientation *ts; - int i= V3D_MANIP_CUSTOM; + Scene *scene; + ListBase *transform_spaces; + TransformOrientation *ts= NULL; + + EnumPropertyItem global = {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}; + EnumPropertyItem normal = {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""}; + EnumPropertyItem local = {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""}; + EnumPropertyItem view = {V3D_MANIP_VIEW, "VIEW", 0, "View", ""}; + EnumPropertyItem sepr = {0, "", 0, NULL, NULL}; + EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem *item= NULL; + int i = V3D_MANIP_CUSTOM, totitem= 0; + + RNA_enum_item_add(&item, &totitem, &global); + RNA_enum_item_add(&item, &totitem, &normal); + RNA_enum_item_add(&item, &totitem, &local); + RNA_enum_item_add(&item, &totitem, &view); + + if(C) { + scene= CTX_data_scene(C); + + if(scene) { + transform_spaces = &scene->transform_spaces; + ts = transform_spaces->first; + } + } + + if(ts) + RNA_enum_item_add(&item, &totitem, &sepr); + + for(; ts; ts = ts->next) { + tmp.identifier = "CUSTOM"; + tmp.name= ts->name; + tmp.value = i++; + RNA_enum_item_add(&item, &totitem, &tmp); + } - uiItemEnumO(layout, NULL, 0, "TFM_OT_select_orientation", "orientation", V3D_MANIP_GLOBAL); - uiItemEnumO(layout, NULL, 0, "TFM_OT_select_orientation", "orientation", V3D_MANIP_LOCAL); - uiItemEnumO(layout, NULL, 0, "TFM_OT_select_orientation", "orientation", V3D_MANIP_NORMAL); - uiItemEnumO(layout, NULL, 0, "TFM_OT_select_orientation", "orientation", V3D_MANIP_VIEW); + RNA_enum_item_end(&item, &totitem); - for(ts = transform_spaces->first; ts; ts = ts->next) - uiItemIntO(layout, ts->name, 0, "TFM_OT_select_orientation", "custom_index", i++); + return item; } char * BIF_menustringTransformOrientation(const bContext *C, char *title) { @@ -403,7 +434,7 @@ int BIF_countTransformOrientation(const bContext *C) { return count; } -void applyTransformOrientation(bContext *C, TransInfo *t) { +void applyTransformOrientation(const bContext *C, TransInfo *t) { TransformOrientation *ts; View3D *v3d = CTX_wm_view3d(C); int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); @@ -533,7 +564,7 @@ void initTransformOrientation(bContext *C, TransInfo *t) } } -int getTransformOrientation(bContext *C, float normal[3], float plane[3], int activeOnly) +int getTransformOrientation(const bContext *C, float normal[3], float plane[3], int activeOnly) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -591,14 +622,11 @@ int getTransformOrientation(bContext *C, float normal[3], float plane[3], int ac BMFace *efa; BMIter iter; - efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL); - for( ; efa; efa=BMIter_Step(&iter)) - { - if(BM_TestHFlag(efa, BM_SELECT)) - { + BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { + if(BM_TestHFlag(efa, BM_SELECT)) { VECADD(normal, normal, efa->no); VecSubf(vec, efa->loopbase->v->co, - ((BMLoop*)efa->loopbase->head.next)->v->co); + ((BMLoop*)efa->loopbase->head.next)->v->co); VECADD(plane, plane, vec); } } @@ -610,11 +638,9 @@ int getTransformOrientation(bContext *C, float normal[3], float plane[3], int ac BMVert *v1 = NULL, *v2 = NULL, *v3 = NULL; BMIter iter; float cotangent[3]; - - eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL); - for( ; eve; eve=BMIter_Step(&iter)) - { - if ( BM_TestHFlag(eve, BM_SELECT) ) { + + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (BM_TestHFlag(eve, BM_SELECT)) { if (v1 == NULL) { v1 = eve; } @@ -637,9 +663,8 @@ int getTransformOrientation(bContext *C, float normal[3], float plane[3], int ac { BMEdge *eed = NULL; BMIter iter; - - eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL); - for( ; eed; eed=BMIter_Step(&iter)) { + + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { if(BM_TestHFlag(eed, BM_SELECT)) { VecSubf(plane, eed->v2->co, eed->v1->co); break; @@ -653,9 +678,8 @@ int getTransformOrientation(bContext *C, float normal[3], float plane[3], int ac { BMEdge *eed = NULL; BMIter iter; - - eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL); - for( ; eed; eed=BMIter_Step(&iter)) { + + BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) { if(BM_TestHFlag(eed, BM_SELECT)) { /* use average vert normals as plane and edge vector as normal */ VECCOPY(plane, eed->v1->no); @@ -668,13 +692,11 @@ int getTransformOrientation(bContext *C, float normal[3], float plane[3], int ac } else if (em->bm->totvertsel == 2) { - BMVert *v1=NULL, *v2=NULL; + BMVert *v1 = NULL, *v2 = NULL; BMIter iter; - eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL); - for( ; eve; eve=BMIter_Step(&iter)) - { - if ( BM_TestHFlag(eve, BM_SELECT) ) { + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (BM_TestHFlag(eve, BM_SELECT)) { if (v1 == NULL) { v1 = eve; } @@ -694,10 +716,8 @@ int getTransformOrientation(bContext *C, float normal[3], float plane[3], int ac { BMIter iter; - eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL); - for( ; eve; eve=BMIter_Step(&iter)) - { - if ( BM_TestHFlag(eve, BM_SELECT) ) { + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (BM_TestHFlag(eve, BM_SELECT)) { VECCOPY(normal, eve->no); break; } @@ -707,14 +727,10 @@ int getTransformOrientation(bContext *C, float normal[3], float plane[3], int ac else if (em->bm->totvertsel > 3) { BMIter iter; - - eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL); - normal[0] = normal[1] = normal[2] = 0; - - for( ; eve; eve=BMIter_Step(&iter)) - { - if ( BM_TestHFlag(eve, BM_SELECT) ) { + + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (BM_TestHFlag(eve, BM_SELECT)) { VecAddf(normal, normal, eve->no); } } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index ad8ef95a870..575e8f2150a 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -63,8 +63,6 @@ //#include "BIF_drawimage.h" //#include "BIF_editmesh.h" -#include "BIF_transform.h" - #include "BKE_global.h" #include "BKE_utildefines.h" #include "BKE_DerivedMesh.h" @@ -77,6 +75,7 @@ #include "ED_armature.h" #include "ED_image.h" #include "ED_mesh.h" +#include "ED_transform.h" #include "ED_uvedit.h" #include "ED_view3d.h" @@ -212,7 +211,7 @@ int handleSnapping(TransInfo *t, wmEvent *event) if (BIF_snappingSupported(t->obedit) && event->type == TABKEY && event->shift) { /* toggle snap and reinit */ - t->scene->snap_flag ^= SCE_SNAP; + t->settings->snap_flag ^= SCE_SNAP; initSnapping(t, NULL); status = 1; } @@ -284,10 +283,10 @@ int validSnappingNormal(TransInfo *t) void initSnapping(TransInfo *t, wmOperator *op) { - Scene *scene = t->scene; + ToolSettings *ts = t->settings; Object *obedit = t->obedit; int snapping = 0; - short snap_mode = t->scene->snap_target; + short snap_mode = t->settings->snap_target; resetSnapping(t); @@ -312,8 +311,8 @@ void initSnapping(TransInfo *t, wmOperator *op) } else { - snapping = ((scene->snap_flag & SCE_SNAP) == SCE_SNAP); - t->tsnap.align = ((t->scene->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE); + snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP); + t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE); } if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV @@ -544,7 +543,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec) int dist = SNAP_MIN_DISTANCE; // Use a user defined value here SnapMode mode; - if (t->scene->snap_mode == SCE_SNAP_MODE_VOLUME) + if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME) { ListBase depth_peels; DepthPeel *p1, *p2; @@ -577,7 +576,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec) p1->flag = 1; /* if peeling objects, take the first and last from each object */ - if (t->scene->snap_flag & SCE_SNAP_PEEL_OBJECT) + if (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) { DepthPeel *peel; for (peel = p1->next; peel; peel = peel->next) @@ -1361,6 +1360,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, B int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) { + ToolSettings *ts= scene->toolsettings; int retval = 0; if (ob->type == OB_MESH) { @@ -1378,13 +1378,13 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); } - retval = snapDerivedMesh(scene->snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth); + retval = snapDerivedMesh(ts->snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth); dm->release(dm); } else if (ob->type == OB_ARMATURE) { - retval = snapArmature(scene->snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth); + retval = snapArmature(ts->snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth); } return retval; |