diff options
Diffstat (limited to 'source/blender/editors/transform/transform.c')
-rw-r--r-- | source/blender/editors/transform/transform.c | 405 |
1 files changed, 256 insertions, 149 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 0acbe608f41..394dd433060 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -89,11 +89,11 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_utildefines.h" #include "BLI_editVert.h" #include "BLI_ghash.h" #include "BLI_linklist.h" - #include "UI_resources.h" //#include "blendef.h" @@ -103,6 +103,7 @@ #include "transform.h" void drawTransformApply(const struct bContext *C, struct ARegion *ar, void *arg); +int doEdgeSlide(TransInfo *t, float perc); /* ************************** SPACE DEPENDANT CODE **************************** */ @@ -337,7 +338,7 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) } } -static void viewRedrawPost(TransInfo *t) +static void viewRedrawPost(bContext *C, TransInfo *t) { ED_area_headerprint(t->sa, NULL); @@ -345,6 +346,10 @@ static void viewRedrawPost(TransInfo *t) /* if autokeying is enabled, send notifiers that keyframes were added */ if (IS_AUTOKEY_ON(t->scene)) WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL); + + /* XXX temp, first hack to get auto-render in compositor work (ton) */ + WM_event_add_notifier(C, NC_SCENE|ND_TRANSFORM_DONE, CTX_data_scene(C)); + } #if 0 // TRANSFORM_FIX_ME @@ -384,7 +389,7 @@ void BIF_selectOrientation() { #endif } -static void view_editmove(unsigned short event) +static void view_editmove(unsigned short UNUSED(event)) { #if 0 // TRANSFORM_FIX_ME int refresh = 0; @@ -481,6 +486,8 @@ static void view_editmove(unsigned short event) * */ #define TFM_MODAL_PROPSIZE_UP 20 #define TFM_MODAL_PROPSIZE_DOWN 21 +#define TFM_MODAL_AUTOIK_LEN_INC 22 +#define TFM_MODAL_AUTOIK_LEN_DEC 23 /* called in transform_ops.c, on each regeneration of keymaps */ wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf) @@ -507,6 +514,8 @@ wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf) {NUM_MODAL_INCREMENT_DOWN, "INCREMENT_DOWN", 0, "Numinput Increment Down", ""}, {TFM_MODAL_PROPSIZE_UP, "PROPORTIONAL_SIZE_UP", 0, "Increase Proportional Influence", ""}, {TFM_MODAL_PROPSIZE_DOWN, "PROPORTIONAL_SIZE_DOWN", 0, "Decrease Poportional Influence", ""}, + {TFM_MODAL_AUTOIK_LEN_INC, "AUTOIK_CHAIN_LEN_UP", 0, "Increase Max AutoIK Chain Length", ""}, + {TFM_MODAL_AUTOIK_LEN_DEC, "AUTOIK_CHAIN_LEN_DOWN", 0, "Decrease Max AutoIK Chain Length", ""}, {0, NULL, 0, NULL, NULL}}; wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Transform Modal Map"); @@ -530,6 +539,9 @@ wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_INV_ON); WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, TFM_MODAL_SNAP_INV_OFF); + + WM_modalkeymap_add_item(keymap, RIGHTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_INV_ON); + WM_modalkeymap_add_item(keymap, RIGHTCTRLKEY, KM_RELEASE, KM_ANY, 0, TFM_MODAL_SNAP_INV_OFF); WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, TFM_MODAL_ADD_SNAP); WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, KM_ALT, 0, TFM_MODAL_REMOVE_SNAP); @@ -541,14 +553,19 @@ wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, PAGEDOWNKEY, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_DOWN); WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_UP); WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_DOWN); - + + WM_modalkeymap_add_item(keymap, PAGEUPKEY, KM_PRESS, KM_SHIFT, 0, TFM_MODAL_AUTOIK_LEN_INC); + WM_modalkeymap_add_item(keymap, PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0, TFM_MODAL_AUTOIK_LEN_DEC); + WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT, 0, TFM_MODAL_AUTOIK_LEN_INC); + WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_SHIFT, 0, TFM_MODAL_AUTOIK_LEN_DEC); + return keymap; } int 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}}; + float mati[3][3]= MAT3_UNITY; char cmode = constraintModeToChar(t); int handled = 1; @@ -562,7 +579,9 @@ int transformEvent(TransInfo *t, wmEvent *event) t->mval[0] = event->x - t->ar->winrct.xmin; t->mval[1] = event->y - t->ar->winrct.ymin; - t->redraw |= TREDRAW_SOFT; + // t->redraw |= TREDRAW_SOFT; /* Use this for soft redraw. Might cause flicker in object mode */ + t->redraw |= TREDRAW_HARD; + if (t->state == TRANS_STARTING) { t->state = TRANS_RUNNING; @@ -592,20 +611,22 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case TFM_MODAL_ROTATE: /* only switch when... */ - if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { - - resetTransRestrictions(t); - - if (t->mode == TFM_ROTATION) { - restoreTransObjects(t); - initTrackball(t); - } - else { - restoreTransObjects(t); - initRotation(t); + if(!(t->options & CTX_TEXTURE)) { + if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { + + resetTransRestrictions(t); + + if (t->mode == TFM_ROTATION) { + restoreTransObjects(t); + initTrackball(t); + } + else { + restoreTransObjects(t); + initRotation(t); + } + initSnapping(t, NULL); // need to reinit after mode change + t->redraw |= TREDRAW_HARD; } - initSnapping(t, NULL); // need to reinit after mode change - t->redraw |= TREDRAW_HARD; } break; case TFM_MODAL_RESIZE: @@ -724,6 +745,8 @@ int transformEvent(TransInfo *t, wmEvent *event) case TFM_MODAL_PROPSIZE_UP: if(t->flag & T_PROP_EDIT) { t->prop_size*= 1.1f; + if(t->spacetype==SPACE_VIEW3D && t->persp != RV3D_ORTHO) + t->prop_size= MIN2(t->prop_size, ((View3D *)t->view)->far); calculatePropRatio(t); } t->redraw |= TREDRAW_HARD; @@ -735,6 +758,16 @@ int transformEvent(TransInfo *t, wmEvent *event) } t->redraw |= TREDRAW_HARD; break; + case TFM_MODAL_AUTOIK_LEN_INC: + if (t->flag & T_AUTOIK) + transform_autoik_update(t, 1); + t->redraw |= TREDRAW_HARD; + break; + case TFM_MODAL_AUTOIK_LEN_DEC: + if (t->flag & T_AUTOIK) + transform_autoik_update(t, -1); + t->redraw |= TREDRAW_HARD; + break; default: handled = 0; break; @@ -833,20 +866,22 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case RKEY: /* only switch when... */ - if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { + if(!(t->options & CTX_TEXTURE)) { + 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); - } - else { - restoreTransObjects(t); - initRotation(t); + if (t->mode == TFM_ROTATION) { + restoreTransObjects(t); + initTrackball(t); + } + else { + restoreTransObjects(t); + initRotation(t); + } + initSnapping(t, NULL); // need to reinit after mode change + t->redraw |= TREDRAW_HARD; } - initSnapping(t, NULL); // need to reinit after mode change - t->redraw |= TREDRAW_HARD; } break; case CKEY: @@ -950,6 +985,8 @@ int transformEvent(TransInfo *t, wmEvent *event) case PADPLUSKEY: if(event->alt && t->flag & T_PROP_EDIT) { t->prop_size *= 1.1f; + if(t->spacetype==SPACE_VIEW3D && t->persp != RV3D_ORTHO) + t->prop_size= MIN2(t->prop_size, ((View3D *)t->view)->far); calculatePropRatio(t); } t->redraw= 1; @@ -1201,14 +1238,17 @@ static void drawArc(float size, float angle_start, float angle_end, int segments glEnd(); } -static void drawHelpline(bContext *C, int x, int y, void *customdata) +static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) { TransInfo *t = (TransInfo*)customdata; if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR)) { float vecrot[3], cent[2]; - int mval[2] = {x, y}; + int mval[2]; + + mval[0]= x; + mval[1]= y; VECCOPY(vecrot, t->center); if(t->flag & T_EDIT) { @@ -1306,20 +1346,20 @@ static void drawHelpline(bContext *C, int x, int y, void *customdata) } case HLP_TRACKBALL: { - char col[3], col2[3]; + unsigned char col[3], col2[3]; UI_GetThemeColor3ubv(TH_GRID, col); glTranslatef(mval[0], mval[1], 0); glLineWidth(3.0); - UI_make_axis_color(col, col2, 'x'); + 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'); + UI_make_axis_color(col, col2, 'Y'); glColor3ubv((GLubyte *)col2); drawArrow(UP, 5, 10, 5); @@ -1333,16 +1373,16 @@ static void drawHelpline(bContext *C, int x, int y, void *customdata) } } -void drawTransformView(const struct bContext *C, struct ARegion *ar, void *arg) +void drawTransformView(const struct bContext *C, struct ARegion *UNUSED(ar), void *arg) { TransInfo *t = arg; - drawConstraint(C, t); + drawConstraint(t); drawPropCircle(C, t); drawSnapping(C, t); } -void drawTransformPixel(const struct bContext *C, struct ARegion *ar, void *arg) +void drawTransformPixel(const struct bContext *UNUSED(C), struct ARegion *UNUSED(ar), void *UNUSED(arg)) { // TransInfo *t = arg; // @@ -1465,10 +1505,16 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int { int options = 0; + t->context = C; + /* added initialize, for external calls to set stuff in TransInfo, like undo string */ t->state = TRANS_STARTING; + if(RNA_struct_find_property(op->ptr, "texture_space")) + if(RNA_boolean_get(op->ptr, "texture_space")) + options |= CTX_TEXTURE; + t->options = options; t->mode = mode; @@ -1534,7 +1580,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int if ((ELEM(kmi->type, LEFTCTRLKEY, RIGHTCTRLKEY) && event->ctrl) || (ELEM(kmi->type, LEFTSHIFTKEY, RIGHTSHIFTKEY) && event->shift) || (ELEM(kmi->type, LEFTALTKEY, RIGHTALTKEY) && event->alt) || - (kmi->type == COMMANDKEY && event->oskey)) { + (kmi->type == OSKEY && event->oskey)) { t->modifiers |= MOD_SNAP_INVERT; } break; @@ -1606,6 +1652,11 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int break; case TFM_EDGE_SLIDE: initEdgeSlide(t); + if(t->state == TRANS_CANCEL) + { + postTrans(C, t); + return 0; + } break; case TFM_BONE_ROLL: initBoneRoll(t); @@ -1653,7 +1704,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int /* overwrite initial values if operator supplied a non-null vector */ if (RNA_property_is_set(op->ptr, "value")) { - float values[4]; + float values[4]= {0}; /* incase value isn't length 4, avoid uninitialized memory */ RNA_float_get_array(op->ptr, "value", values); QUATCOPY(t->values, values); QUATCOPY(t->auto_values, values); @@ -1665,6 +1716,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int { RNA_float_get_array(op->ptr, "axis", t->axis); normalize_v3(t->axis); + copy_v3_v3(t->axis_orig, t->axis); } /* Constraint init from operator */ @@ -1692,11 +1744,15 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int } } + t->context = NULL; + return 1; } -void transformApply(const bContext *C, TransInfo *t) +void transformApply(bContext *C, TransInfo *t) { + t->context = C; + if ((t->redraw & TREDRAW_HARD) || (t->draw_handle_apply == NULL && (t->redraw & TREDRAW_SOFT))) { selectConstraint(t); @@ -1721,15 +1777,17 @@ void transformApply(const bContext *C, TransInfo *t) //do_screenhandlers(G.curscreen); t->redraw |= TREDRAW_HARD; } + + t->context = NULL; } -void drawTransformApply(const struct bContext *C, struct ARegion *ar, void *arg) +void drawTransformApply(const bContext *C, struct ARegion *UNUSED(ar), void *arg) { TransInfo *t = arg; if (t->redraw & TREDRAW_SOFT) { t->redraw |= TREDRAW_HARD; - transformApply(C, t); + transformApply((bContext *)C, t); } } @@ -1737,11 +1795,17 @@ int transformEnd(bContext *C, TransInfo *t) { int exit_code = OPERATOR_RUNNING_MODAL; + t->context = C; + if (t->state != TRANS_STARTING && t->state != TRANS_RUNNING) { /* handle restoring objects */ if(t->state == TRANS_CANCEL) { + /* exception, edge slide transformed UVs too */ + if(t->mode==TFM_EDGE_SLIDE) + doEdgeSlide(t, 0.0f); + exit_code = OPERATOR_CANCELLED; restoreTransObjects(t); // calls recalcData() } @@ -1757,7 +1821,7 @@ int transformEnd(bContext *C, TransInfo *t) postTrans(C, t); /* send events out for redraws */ - viewRedrawPost(t); + viewRedrawPost(C, t); /* Undo as last, certainly after special_trans_update! */ @@ -1773,6 +1837,8 @@ int transformEnd(bContext *C, TransInfo *t) viewRedrawForce(C, t); } + t->context = NULL; + return exit_code; } @@ -1872,23 +1938,29 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu } else { /* quaternions get limited with euler... (compatability mode) */ - float eul[3], oldeul[3], quat1[4]; - - QUATCOPY(quat1, quat); - quat_to_eul( eul,quat); - quat_to_eul( oldeul,oldquat); - + float eul[3], oldeul[3], nquat[4], noldquat[4]; + float qlen; + + qlen= normalize_qt_qt(nquat, quat); + normalize_qt_qt(noldquat, oldquat); + + quat_to_eul(eul, nquat); + quat_to_eul(oldeul, noldquat); + 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]; - + eul_to_quat( quat,eul); + + /* restore original quat size */ + mul_qt_fl(quat, qlen); /* 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) ) { + if ( (nquat[0]<0.0f && quat[0]>0.0f) || (nquat[0]>0.0f && quat[0]<0.0f) ) { mul_qt_fl(quat, -1.0f); } } @@ -1896,18 +1968,17 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu /* ******************* TRANSFORM LIMITS ********************** */ -static void constraintTransLim(TransInfo *t, TransData *td) +static void constraintTransLim(TransInfo *UNUSED(t), TransData *td) { if (td->con) { bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT); - bConstraintOb cob; + bConstraintOb cob= {0}; bConstraint *con; /* Make a temporary bConstraintOb for using these limit constraints * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ - memset(&cob, 0, sizeof(bConstraintOb)); unit_m4(cob.matrix); VECCOPY(cob.matrix[3], td->loc); @@ -1961,37 +2032,29 @@ static void constraintob_from_transdata(bConstraintOb *cob, TransData *td) * - current space should be local */ memset(cob, 0, sizeof(bConstraintOb)); - if (td->rotOrder == ROT_MODE_QUAT) { - /* quats */ - if (td->ext) { + if (td->ext) + { + if (td->ext->rotOrder == ROT_MODE_QUAT) { + /* quats */ /* objects and bones do normalization first too, otherwise we don't necessarily end up with a rotation matrix, and then conversion back to quat gives a different result */ float quat[4]; - copy_qt_qt(quat, td->ext->quat); - normalize_qt(quat); + normalize_qt_qt(quat, td->ext->quat); quat_to_mat4(cob->matrix, quat); } - else - return; - } - else if (td->rotOrder == ROT_MODE_AXISANGLE) { - /* axis angle */ - if (td->ext) + else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) { + /* axis angle */ axis_angle_to_mat4(cob->matrix, &td->ext->quat[1], td->ext->quat[0]); - else - return; - } - else { - /* eulers */ - if (td->ext) - eulO_to_mat4(cob->matrix, td->ext->rot, td->rotOrder); - else - return; + } + else { + /* eulers */ + eulO_to_mat4(cob->matrix, td->ext->rot, td->ext->rotOrder); + } } } -static void constraintRotLim(TransInfo *t, TransData *td) +static void constraintRotLim(TransInfo *UNUSED(t), TransData *td) { if (td->con) { bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT); @@ -2045,17 +2108,17 @@ static void constraintRotLim(TransInfo *t, TransData *td) if(dolimit) { /* copy results from cob->matrix */ - if (td->rotOrder == ROT_MODE_QUAT) { + if (td->ext->rotOrder == ROT_MODE_QUAT) { /* quats */ mat4_to_quat( td->ext->quat,cob.matrix); } - else if (td->rotOrder == ROT_MODE_AXISANGLE) { + else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) { /* axis angle */ mat4_to_axis_angle( &td->ext->quat[1], &td->ext->quat[0],cob.matrix); } else { /* eulers */ - mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix); + mat4_to_eulO( td->ext->rot, td->ext->rotOrder,cob.matrix); } } } @@ -2065,14 +2128,13 @@ static void constraintSizeLim(TransInfo *t, TransData *td) { if (td->con && td->ext) { bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_SIZELIMIT); - bConstraintOb cob; + bConstraintOb cob= {0}; bConstraint *con; /* Make a temporary bConstraintOb for using these limit constraints * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ - memset(&cob, 0, sizeof(bConstraintOb)); if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { /* scale val and reset size */ return; // TODO: fix this case @@ -2180,7 +2242,7 @@ void initWarp(TransInfo *t) mul_m4_v3(t->viewmat, center); sub_v3_v3(center, t->viewmat[3]); if (i) - minmax_v3_v3v3(min, max, center); + minmax_v3v3_v3(min, max, center); else { copy_v3_v3(max, center); copy_v3_v3(min, center); @@ -2211,7 +2273,7 @@ int handleEventWarp(TransInfo *t, wmEvent *event) return status; } -int Warp(TransInfo *t, short mval[2]) +int Warp(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3]; @@ -2309,7 +2371,7 @@ int Warp(TransInfo *t, short mval[2]) /* ************************** SHEAR *************************** */ -void postInputShear(TransInfo *t, float values[3]) +void postInputShear(TransInfo *UNUSED(t), float values[3]) { mul_v3_fl(values, 0.05f); } @@ -2359,7 +2421,7 @@ int handleEventShear(TransInfo *t, wmEvent *event) } -int Shear(TransInfo *t, short mval[2]) +int Shear(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; float vec[3]; @@ -2490,6 +2552,9 @@ static void headerResize(TransInfo *t, float vec[3], char *str) { else sprintf(str, "Scale X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); } + + if (t->flag & (T_PROP_EDIT|T_PROP_CONNECTED)) + sprintf(str, "%s Proportional size: %.2f", str, t->prop_size); } #define SIGN(a) (a<-FLT_EPSILON?1:a>FLT_EPSILON?2:3) @@ -2723,7 +2788,7 @@ void initToSphere(TransInfo *t) t->val /= (float)t->total; } -int ToSphere(TransInfo *t, short mval[2]) +int ToSphere(TransInfo *t, short UNUSED(mval[2])) { float vec[3]; float ratio, radius; @@ -2820,6 +2885,8 @@ void initRotation(TransInfo *t) negate_v3_v3(t->axis, t->viewinv[2]); normalize_v3(t->axis); + + copy_v3_v3(t->axis_orig, t->axis); } static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around) { @@ -2897,9 +2964,19 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short sub_v3_v3v3(vec, vec, td->center); // Translation needed from the initial location - mul_m3_v3(pmtx, vec); // To Global space - mul_m3_v3(td->smtx, vec);// To Pose space - + /* special exception, see TD_PBONE_LOCAL_MTX definition comments */ + if(td->flag & TD_PBONE_LOCAL_MTX_P) { + /* do nothing */ + } + else if (td->flag & TD_PBONE_LOCAL_MTX_C) { + mul_m3_v3(pmtx, vec); // To Global space + mul_m3_v3(td->ext->l_smtx, vec);// To Pose space (Local Location) + } + else { + mul_m3_v3(pmtx, vec); // To Global space + mul_m3_v3(td->smtx, vec);// To Pose space + } + protectedTransBits(td->protectflag, vec); add_v3_v3v3(td->loc, td->iloc, vec); @@ -2910,7 +2987,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* rotation */ if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself /* euler or quaternion/axis-angle? */ - if (td->rotOrder == ROT_MODE_QUAT) { + if (td->ext->rotOrder == ROT_MODE_QUAT) { mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); mat3_to_quat( quat,fmat); // Actual transform @@ -2920,7 +2997,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } - else if (td->rotOrder == ROT_MODE_AXISANGLE) { + else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) { /* calculate effect based on quats */ float iquat[4], tquat[4]; @@ -2943,12 +3020,12 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* calculate the total rotatation in eulers */ VECCOPY(eul, td->ext->irot); - eulO_to_mat3( eulmat,eul, td->rotOrder); + eulO_to_mat3( eulmat,eul, td->ext->rotOrder); /* mat = transform, obmat = bone rotation */ mul_m3_m3m3(fmat, smat, eulmat); - mat3_to_compatible_eulO( eul, td->ext->rot, td->rotOrder,fmat); + mat3_to_compatible_eulO( eul, td->ext->rot, td->ext->rotOrder,fmat); /* and apply (to end result only) */ protectedRotateBits(td->protectflag, eul, td->ext->irot); @@ -2980,7 +3057,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* rotation */ if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself /* euler or quaternion? */ - if ((td->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) { + if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) { mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); mat3_to_quat( quat,fmat); // Actual transform @@ -2988,7 +3065,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* this function works on end result */ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat); } - else if (td->rotOrder == ROT_MODE_AXISANGLE) { + else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) { /* calculate effect based on quats */ float iquat[4], tquat[4]; @@ -2998,7 +3075,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short mat3_to_quat( quat,fmat); // Actual transform mul_qt_qtqt(tquat, quat, iquat); - quat_to_axis_angle( td->ext->rotAxis, td->ext->rotAngle,quat); + quat_to_axis_angle( td->ext->rotAxis, td->ext->rotAngle,tquat); /* this function works on end result */ protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle); @@ -3011,11 +3088,11 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short /* calculate the total rotatation in eulers */ add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */ - eulO_to_mat3( obmat,eul, td->rotOrder); + eulO_to_mat3( obmat,eul, td->ext->rotOrder); /* mat = transform, obmat = object rotation */ mul_m3_m3m3(fmat, smat, obmat); - mat3_to_compatible_eulO( eul, td->ext->rot, td->rotOrder,fmat); + mat3_to_compatible_eulO( eul, td->ext->rot, td->ext->rotOrder,fmat); /* correct back for delta rot */ sub_v3_v3v3(eul, eul, td->ext->drot); @@ -3058,14 +3135,12 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) } } -int Rotation(TransInfo *t, short mval[2]) +int Rotation(TransInfo *t, short UNUSED(mval[2])) { char str[64]; float final; - - float mat[3][3]; - + final = t->values[0]; applyNDofInput(&t->ndof, &final); @@ -3076,8 +3151,7 @@ int Rotation(TransInfo *t, short mval[2]) t->con.applyRot(t, NULL, t->axis, NULL); } else { /* reset axis if constraint is not set */ - negate_v3_v3(t->axis, t->viewinv[2]); - normalize_v3(t->axis); + copy_v3_v3(t->axis, t->axis_orig); } applySnapping(t, &final); @@ -3104,9 +3178,10 @@ int Rotation(TransInfo *t, short mval[2]) sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext); } + if (t->flag & (T_PROP_EDIT|T_PROP_CONNECTED)) + sprintf(str, "%s Proportional size: %.2f", str, t->prop_size); + t->values[0] = final; - - vec_rot_to_mat3( mat, t->axis, final); applyRotation(t, final, t->axis); @@ -3172,7 +3247,7 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a } } -int Trackball(TransInfo *t, short mval[2]) +int Trackball(TransInfo *t, short UNUSED(mval[2])) { char str[128]; float axis1[3], axis2[3]; @@ -3278,7 +3353,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) { applyAspectRatio(t, dvec); dist = len_v3(vec); - if(t->scene->unit.system) { + if(!(t->flag & T_2D_EDIT) && t->scene->unit.system) { int i, do_split= t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1:0; for(i=0; i<3; i++) @@ -3291,7 +3366,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) { } } - if(t->scene->unit.system) + if(!(t->flag & T_2D_EDIT) && t->scene->unit.system) bUnit_AsString(distvec, sizeof(distvec), dist*t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, 0); else if( dist > 1e10 || dist < -1e10 ) /* prevent string buffer overflow */ sprintf(distvec, "%.4e", dist); @@ -3327,6 +3402,9 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) { else sprintf(str, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]); } + + if (t->flag & (T_PROP_EDIT|T_PROP_CONNECTED)) + sprintf(str, "%s Proportional size: %.2f", str, t->prop_size); } static void applyTranslation(TransInfo *t, float vec[3]) { @@ -3391,13 +3469,16 @@ static void applyTranslation(TransInfo *t, float vec[3]) { } /* uses t->vec to store actual translation in */ -int Translation(TransInfo *t, short mval[2]) +int Translation(TransInfo *t, short UNUSED(mval[2])) { char str[250]; if (t->con.mode & CON_APPLY) { float pvec[3] = {0.0f, 0.0f, 0.0f}; float tvec[3]; + if (hasNumInput(&t->num)) { + removeAspectRatio(t, t->values); + } applySnapping(t, t->values); t->con.applyVec(t, NULL, t->values, tvec, pvec); VECCOPY(t->values, tvec); @@ -3407,11 +3488,9 @@ int Translation(TransInfo *t, short mval[2]) applyNDofInput(&t->ndof, t->values); snapGrid(t, t->values); applyNumInput(&t->num, t->values); - if (hasNumInput(&t->num)) - { + if (hasNumInput(&t->num)) { removeAspectRatio(t, t->values); } - applySnapping(t, t->values); headerTranslation(t, t->values, str); } @@ -3457,7 +3536,7 @@ void initShrinkFatten(TransInfo *t) -int ShrinkFatten(TransInfo *t, short mval[2]) +int ShrinkFatten(TransInfo *t, short UNUSED(mval[2])) { float vec[3]; float distance; @@ -3532,7 +3611,7 @@ void initTilt(TransInfo *t) -int Tilt(TransInfo *t, short mval[2]) +int Tilt(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; int i; @@ -3604,7 +3683,7 @@ void initCurveShrinkFatten(TransInfo *t) t->flag |= T_NO_CONSTRAINT; } -int CurveShrinkFatten(TransInfo *t, short mval[2]) +int CurveShrinkFatten(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; float ratio; @@ -3672,7 +3751,7 @@ void initPushPull(TransInfo *t) } -int PushPull(TransInfo *t, short mval[2]) +int PushPull(TransInfo *t, short UNUSED(mval[2])) { float vec[3], axis[3]; float distance; @@ -3805,12 +3884,12 @@ int handleEventBevel(TransInfo *t, wmEvent *event) return 0; } -int Bevel(TransInfo *t, short mval[2]) +int Bevel(TransInfo *t, short UNUSED(mval[2])) { float distance,d; int i; char str[128]; - char *mode; + const char *mode; TransData *td = t->data; mode = (G.editBMesh->options & BME_BEVEL_VERT) ? "verts only" : "normal"; @@ -3873,7 +3952,7 @@ void initBevelWeight(TransInfo *t) t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; } -int BevelWeight(TransInfo *t, short mval[2]) +int BevelWeight(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; float weight; @@ -3946,7 +4025,7 @@ void initCrease(TransInfo *t) t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; } -int Crease(TransInfo *t, short mval[2]) +int Crease(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; float crease; @@ -4140,7 +4219,7 @@ void initBoneEnvelope(TransInfo *t) t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; } -int BoneEnvelope(TransInfo *t, short mval[2]) +int BoneEnvelope(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; float ratio; @@ -4242,6 +4321,7 @@ static int createSlideVerts(TransInfo *t) efa->e1->f1++; if(efa->e1->f1 > 2) { //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + MEM_freeN(sld); return 0; } } @@ -4250,6 +4330,7 @@ static int createSlideVerts(TransInfo *t) efa->e2->f1++; if(efa->e2->f1 > 2) { //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + MEM_freeN(sld); return 0; } } @@ -4258,6 +4339,7 @@ static int createSlideVerts(TransInfo *t) efa->e3->f1++; if(efa->e3->f1 > 2) { //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + MEM_freeN(sld); return 0; } } @@ -4266,13 +4348,15 @@ static int createSlideVerts(TransInfo *t) efa->e4->f1++; if(efa->e4->f1 > 2) { //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + MEM_freeN(sld); return 0; } } // Make sure loop is not 2 edges of same face if(ct > 1) { //BKE_report(op->reports, RPT_ERROR, "Loop crosses itself"); - return 0; + MEM_freeN(sld); + return 0; } } @@ -4284,6 +4368,7 @@ static int createSlideVerts(TransInfo *t) // Test for multiple segments if(vertsel > numsel+1) { //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop"); + MEM_freeN(sld); return 0; } @@ -4320,6 +4405,7 @@ static int createSlideVerts(TransInfo *t) if(timesthrough >= numsel*2) { BLI_linklist_free(edgelist,NULL); //BKE_report(op->reports, RPT_ERROR, "Could not order loop"); + MEM_freeN(sld); return 0; } } @@ -4452,7 +4538,7 @@ static int createSlideVerts(TransInfo *t) look = look->next; } - // make sure the UPs nad DOWNs are 'faceloops' + // make sure the UPs and DOWNs are 'faceloops' // Also find the nearest slidevert to the cursor look = vertlist; @@ -4469,7 +4555,7 @@ static int createSlideVerts(TransInfo *t) return 0; } - if(me->drawflag & ME_DRAW_EDGELEN) { + if(me->drawflag & ME_DRAWEXTRA_EDGELEN) { if(!(tempsv->up->f & SELECT)) { tempsv->up->f |= SELECT; tempsv->up->f2 |= 16; @@ -4491,7 +4577,7 @@ static int createSlideVerts(TransInfo *t) sv = BLI_ghash_lookup(vertgh, ev); if(sv) { - float co[3], co2[3], vec[3]; + float co[3], co2[3], tvec[3]; ev = (EditVert*)look->link; @@ -4508,12 +4594,12 @@ static int createSlideVerts(TransInfo *t) } if (ev == tempsv->up->v1) { - sub_v3_v3v3(vec, co, co2); + sub_v3_v3v3(tvec, co, co2); } else { - sub_v3_v3v3(vec, co2, co); + sub_v3_v3v3(tvec, co2, co); } - add_v3_v3(start, vec); + add_v3_v3(start, tvec); if (v3d) { view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat); @@ -4521,12 +4607,12 @@ static int createSlideVerts(TransInfo *t) } if (ev == tempsv->down->v1) { - sub_v3_v3v3(vec, co2, co); + sub_v3_v3v3(tvec, co2, co); } else { - sub_v3_v3v3(vec, co, co2); + sub_v3_v3v3(tvec, co, co2); } - add_v3_v3(end, vec); + add_v3_v3(end, tvec); totvec += 1.0f; nearest = (EditVert*)look->link; @@ -4544,7 +4630,26 @@ static int createSlideVerts(TransInfo *t) start[0] = t->mval[0]; start[1] = t->mval[1]; add_v3_v3v3(end, start, vec); - + + + /* Ensure minimum screen distance, when looking top down on edge loops */ +#define EDGE_SLIDE_MIN 30 + if (len_squared_v2v2(start, end) < (EDGE_SLIDE_MIN * EDGE_SLIDE_MIN)) { + if(ABS(start[0]-end[0]) + ABS(start[1]-end[1]) < 4.0f) { + /* even more exceptional case, points are ontop of eachother */ + end[0]= start[0]; + end[1]= start[1] + EDGE_SLIDE_MIN; + } + else { + sub_v2_v2(end, start); + normalize_v2(end); + mul_v2_fl(end, EDGE_SLIDE_MIN); + add_v2_v2(end, start); + } + } +#undef EDGE_SLIDE_MIN + + sld->start[0] = (short) start[0]; sld->start[1] = (short) start[1]; sld->end[0] = (short) end[0]; @@ -4589,7 +4694,7 @@ static int createSlideVerts(TransInfo *t) uv_new = tf->uv[k]; if (ev->tmp.l) { - if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001 || fabs(suv->origuv[1]-uv_new[1])) { + if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001f || fabs(suv->origuv[1]-uv_new[1]) > 0.0001f) { ev->tmp.l = -1; /* Tag as invalid */ BLI_linklist_free(suv->fuv_list,NULL); suv->fuv_list = NULL; @@ -4664,7 +4769,7 @@ void freeSlideVerts(TransInfo *t) Mesh *me = t->obedit->data; int uvlay_idx; - if(me->drawflag & ME_DRAW_EDGELEN) { + if(me->drawflag & ME_DRAWEXTRA_EDGELEN) { TransDataSlideVert *tempsv; LinkNode *look = sld->vertlist; GHash *vertgh = sld->vhash; @@ -4711,7 +4816,11 @@ void initEdgeSlide(TransInfo *t) t->mode = TFM_EDGE_SLIDE; t->transform = EdgeSlide; - createSlideVerts(t); + if(!createSlideVerts(t)) { + t->state= TRANS_CANCEL; + return; + } + sld = t->customData; if (!sld) @@ -4744,18 +4853,16 @@ int doEdgeSlide(TransInfo *t, float perc) LinkNode *vertlist=sld->vertlist, *look; GHash *vertgh = sld->vhash; TransDataSlideVert *tempsv; - float len = 0.0f; + float len; int prop=1, flip=0; /* UV correction vars */ GHash **uvarray= sld->uvhash; int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE); int uvlay_idx; - TransDataSlideUv *suv=sld->slideuv; + TransDataSlideUv *suv; float uv_tmp[2]; LinkNode *fuv_link; - len = 0.0f; - tempsv = BLI_ghash_lookup(vertgh,nearest); centerVert = editedge_getSharedVert(tempsv->up, tempsv->down); @@ -4846,7 +4953,7 @@ int doEdgeSlide(TransInfo *t, float perc) return 1; } -int EdgeSlide(TransInfo *t, short mval[2]) +int EdgeSlide(TransInfo *t, short UNUSED(mval[2])) { char str[50]; float final; @@ -4905,7 +5012,7 @@ void initBoneRoll(TransInfo *t) t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; } -int BoneRoll(TransInfo *t, short mval[2]) +int BoneRoll(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; int i; @@ -5041,7 +5148,7 @@ void initMirror(TransInfo *t) } } -int Mirror(TransInfo *t, short mval[2]) +int Mirror(TransInfo *t, short UNUSED(mval[2])) { TransData *td; float size[3], mat[3][3]; @@ -5118,7 +5225,7 @@ void initAlign(TransInfo *t) initMouseInputMode(t, &t->mouse, INPUT_NONE); } -int Align(TransInfo *t, short mval[2]) +int Align(TransInfo *t, short UNUSED(mval[2])) { TransData *td = t->data; float center[3]; @@ -5221,7 +5328,7 @@ static void applySeqSlide(TransInfo *t, float val[2]) { } } -int SeqSlide(TransInfo *t, short mval[2]) +int SeqSlide(TransInfo *t, short UNUSED(mval[2])) { char str[200]; @@ -5449,7 +5556,7 @@ static void headerTimeTranslate(TransInfo *t, char *str) sprintf(str, "DeltaX: %s", &tvec[0]); } -static void applyTimeTranslate(TransInfo *t, float sval) +static void applyTimeTranslate(TransInfo *t, float UNUSED(sval)) { TransData *td = t->data; TransData2D *td2d = t->data2d; @@ -5751,7 +5858,7 @@ static void applyTimeScale(TransInfo *t) { } } -int TimeScale(TransInfo *t, short mval[2]) +int TimeScale(TransInfo *t, short UNUSED(mval[2])) { char str[200]; @@ -5772,14 +5879,14 @@ int TimeScale(TransInfo *t, short mval[2]) /* ************************************ */ -void BIF_TransformSetUndo(char *str) +void BIF_TransformSetUndo(char *UNUSED(str)) { // TRANSFORM_FIX_ME //Trans.undostr= str; } -void NDofTransform() +void NDofTransform(void) { #if 0 // TRANSFORM_FIX_ME float fval[7]; |