diff options
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/transform.c | 1463 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 79 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_constraints.c | 5 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 447 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 170 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_input.c | 48 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_manipulator.c | 19 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_ops.c | 191 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_orientations.c | 273 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 127 |
10 files changed, 1751 insertions, 1071 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index e877f1fecae..7128bd9c6a9 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -100,6 +100,7 @@ #include "ED_markers.h" #include "ED_util.h" #include "ED_view3d.h" +#include "ED_mesh.h" #include "UI_view2d.h" #include "WM_types.h" @@ -108,6 +109,8 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" #include "BLI_editVert.h" +#include "BLI_ghash.h" +#include "BLI_linklist.h" #include "PIL_time.h" /* sleep */ @@ -319,7 +322,7 @@ static void viewRedrawForce(bContext *C, TransInfo *t) else if(t->spacetype == SPACE_NODE) { //ED_area_tag_redraw(t->sa); - WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_NODE, NULL); } else if(t->spacetype == SPACE_SEQ) { @@ -512,7 +515,7 @@ static char *transform_to_undostr(TransInfo *t) #define TFM_MODAL_SNAP_GEARS_OFF 7 /* called in transform_ops.c, on each regeneration of keymaps */ -void transform_modal_keymap(wmWindowManager *wm) +void transform_modal_keymap(wmKeyConfig *keyconf) { static EnumPropertyItem modal_items[] = { {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, @@ -524,12 +527,12 @@ void transform_modal_keymap(wmWindowManager *wm) {TFM_MODAL_SNAP_GEARS_OFF, "SNAP_GEARS_OFF", 0, "Snap Off", ""}, {0, NULL, 0, NULL, NULL}}; - wmKeyMap *keymap= WM_modalkeymap_get(wm, "Transform Modal Map"); + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Transform Modal Map"); /* this function is called for each spacetype, only needs to add map once */ if(keymap) return; - keymap= WM_modalkeymap_add(wm, "Transform Modal Map", modal_items); + keymap= WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items); /* items for modal map */ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CANCEL); @@ -770,10 +773,11 @@ void transformEvent(TransInfo *t, wmEvent *event) stopConstraint(t); } else { + short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, (CON_AXIS0), "along %s X"); + setUserConstraint(t, orientation, (CON_AXIS0), "along %s X"); else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, (CON_AXIS1|CON_AXIS2), "locking %s X"); + setUserConstraint(t, orientation, (CON_AXIS1|CON_AXIS2), "locking %s X"); } } } @@ -802,10 +806,11 @@ void transformEvent(TransInfo *t, wmEvent *event) stopConstraint(t); } else { + short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, (CON_AXIS1), "along %s Y"); + setUserConstraint(t, orientation, (CON_AXIS1), "along %s Y"); else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, (CON_AXIS0|CON_AXIS2), "locking %s Y"); + setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS2), "locking %s Y"); } } } @@ -830,10 +835,11 @@ void transformEvent(TransInfo *t, wmEvent *event) stopConstraint(t); } else { + short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, (CON_AXIS2), "along %s Z"); + setUserConstraint(t, orientation, (CON_AXIS2), "along %s Z"); else if ((t->modifiers & MOD_CONSTRAINT_PLANE) && ((t->flag & T_2D_EDIT)==0)) - setUserConstraint(t, (CON_AXIS0|CON_AXIS1), "locking %s Z"); + setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS1), "locking %s Z"); } } else if ((t->flag & T_2D_EDIT)==0) { @@ -1282,6 +1288,36 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) proportional = 0; } + // If modal, save settings back in scene if not set as operator argument + if (t->flag & T_MODAL) + { + /* save settings if not set in operator */ + if (RNA_struct_find_property(op->ptr, "proportional") && !RNA_property_is_set(op->ptr, "proportional")) + { + ts->proportional = proportional; + } + + if (RNA_struct_find_property(op->ptr, "proportional_size") && !RNA_property_is_set(op->ptr, "proportional_size")) + { + ts->proportional_size = t->prop_size; + } + + if (RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && !RNA_property_is_set(op->ptr, "proportional_editing_falloff")) + { + ts->prop_mode = t->prop_mode; + } + + if(t->spacetype == SPACE_VIEW3D) + { + if (RNA_struct_find_property(op->ptr, "constraint_orientation") && !RNA_property_is_set(op->ptr, "constraint_orientation")) + { + View3D *v3d = t->view; + + v3d->twmode = t->current_orientation; + } + } + } + if (RNA_struct_find_property(op->ptr, "proportional")) { RNA_enum_set(op->ptr, "proportional", proportional); @@ -1313,20 +1349,6 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); } - - // XXX If modal, save settings back in scene - if (t->flag & T_MODAL) - { - ts->prop_mode = t->prop_mode; - ts->proportional = proportional; - - if(t->spacetype == SPACE_VIEW3D) - { - View3D *v3d = t->view; - - v3d->twmode = t->current_orientation; - } - } } int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int mode) @@ -1428,6 +1450,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int case TFM_BONE_ENVELOPE: initBoneEnvelope(t); break; + case TFM_EDGE_SLIDE: + initEdgeSlide(t); + break; case TFM_BONE_ROLL: initBoneRoll(t); break; @@ -1499,7 +1524,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->con.mode |= CON_AXIS2; } - setUserConstraint(t, t->con.mode, "%s"); + setUserConstraint(t, t->current_orientation, t->con.mode, "%s"); } } @@ -1705,38 +1730,30 @@ 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 * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ memset(&cob, 0, sizeof(bConstraintOb)); Mat4One(cob.matrix); - if (td->tdi) { - TransDataIpokey *tdi= td->tdi; - cob.matrix[3][0]= tdi->locx[0]; - cob.matrix[3][1]= tdi->locy[0]; - cob.matrix[3][2]= tdi->locz[0]; - } - else { - VECCOPY(cob.matrix[3], td->loc); - } - + 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) continue; - + /* do space conversions */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1747,10 +1764,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) */ @@ -1759,17 +1776,9 @@ static void constraintTransLim(TransInfo *t, TransData *td) } } } - + /* copy results from cob->matrix */ - if (td->tdi) { - TransDataIpokey *tdi= td->tdi; - tdi->locx[0]= cob.matrix[3][0]; - tdi->locy[0]= cob.matrix[3][1]; - tdi->locz[0]= cob.matrix[3][2]; - } - else { - VECCOPY(td->loc, cob.matrix[3]); - } + VECCOPY(td->loc, cob.matrix[3]); } } @@ -1785,25 +1794,14 @@ static void constraintRotLim(TransInfo *t, TransData *td) * - current space should be local */ memset(&cob, 0, sizeof(bConstraintOb)); - if (td->flag & TD_USEQUAT) { + if (td->rotOrder == ROT_MODE_QUAT) { /* quats */ if (td->ext) QuatToMat4(td->ext->quat, cob.matrix); else return; } - else if (td->tdi) { // XXX depreceated - /* 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]; - - EulOToMat4(eul, td->rotOrder, cob.matrix); - } - else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + else if (td->rotOrder == ROT_MODE_AXISANGLE) { /* axis angle */ if (td->ext) AxisAngleToMat4(&td->ext->quat[1], td->ext->quat[0], cob.matrix); @@ -1857,22 +1855,11 @@ static void constraintRotLim(TransInfo *t, TransData *td) } /* copy results from cob->matrix */ - if (td->flag & TD_USEQUAT) { + if (td->rotOrder == ROT_MODE_QUAT) { /* quats */ Mat4ToQuat(cob.matrix, td->ext->quat); } - else if (td->tdi) { - /* ipo-keys eulers */ - TransDataIpokey *tdi= td->tdi; - float eul[3]; - - Mat4ToEulO(cob.matrix, eul, td->rotOrder); - - tdi->rotx[0]= eul[0]; - tdi->roty[0]= eul[1]; - tdi->rotz[0]= eul[2]; - } - else if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + else if (td->rotOrder == ROT_MODE_AXISANGLE) { /* axis angle */ Mat4ToAxisAngle(cob.matrix, &td->ext->quat[1], &td->ext->quat[0]); } @@ -1889,22 +1876,13 @@ 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 * - they only care that cob->matrix is correctly set ;-) * - current space should be local */ memset(&cob, 0, sizeof(bConstraintOb)); - 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)) { + if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { /* scale val and reset size */ return; // TODO: fix this case } @@ -1912,25 +1890,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) continue; - + /* do space conversions */ if (con->ownspace == CONSTRAINT_SPACE_WORLD) { /* just multiply by td->mtx (this should be ok) */ @@ -1941,10 +1919,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) */ @@ -1953,19 +1931,9 @@ 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)) { + if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) { /* scale val and reset size */ return; // TODO: fix this case } @@ -1973,7 +1941,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); } } @@ -1985,21 +1953,21 @@ 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; t->num.idx_max = 0; 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]; @@ -2014,7 +1982,7 @@ 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; @@ -2026,7 +1994,7 @@ void initWarp(TransInfo *t) int handleEventWarp(TransInfo *t, wmEvent *event) { int status = 0; - + if (event->type == MIDDLEMOUSE && event->val==KM_PRESS) { // Use customData pointer to signal warp direction @@ -2034,10 +2002,10 @@ int handleEventWarp(TransInfo *t, wmEvent *event) t->customData = (void*)1; else t->customData = 0; - + status = 1; } - + return status; } @@ -2047,7 +2015,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. @@ -2068,73 +2036,73 @@ int Warp(TransInfo *t, short mval[2]) } Mat4MulVecfl(t->viewmat, cursor); VecSubf(cursor, cursor, t->viewmat[3]); - + /* amount of degrees for warp */ circumfac = 360.0f * t->values[0]; - + if (t->customData) /* non-null value indicates reversed input */ { circumfac *= -1; } - + 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) break; - + 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); - + 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; } @@ -2145,22 +2113,22 @@ 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==KM_PRESS) { // Use customData pointer to signal Shear direction @@ -2174,10 +2142,10 @@ int handleEventShear(TransInfo *t, wmEvent *event) initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); t->customData = 0; } - + status = 1; } - + return status; } @@ -2190,47 +2158,47 @@ int Shear(TransInfo *t, short mval[2]) float value; int i; char str[50]; - + Mat3CpyMat4(persmat, t->viewmat); Mat3Inv(persinv, persmat); - + value = 0.05f * t->values[0]; - + snapGrid(t, &value); - + applyNumInput(&t->num, &value); - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); - + sprintf(str, "Shear: %s %s", c, t->proptext); } else { /* 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; - + if (td->flag & TD_SKIP) continue; - + if (t->obedit) { float mat3[3][3]; Mat3MulMat3(mat3, totmat, td->mtx); @@ -2240,19 +2208,19 @@ int Shear(TransInfo *t, short mval[2]) Mat3CpyMat3(tmat, totmat); } VecSubf(vec, td->center, t->center); - + Mat3MulVecfl(tmat, vec); - + VecAddf(vec, vec, t->center); VecSubf(vec, vec, td->center); - + VecMulf(vec, td->factor); - + VecAddf(td->loc, td->iloc, vec); } - + recalcData(t); - + ED_area_headerprint(t->sa, str); return 1; @@ -2264,9 +2232,9 @@ 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; @@ -2274,7 +2242,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; @@ -2292,7 +2260,7 @@ static void headerResize(TransInfo *t, float vec[3], char *str) { sprintf(&tvec[20], "%.4f", vec[1]); sprintf(&tvec[40], "%.4f", vec[2]); } - + if (t->con.mode & CON_APPLY) { switch(t->num.idx_max) { case 0: @@ -2320,14 +2288,14 @@ 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]; @@ -2338,7 +2306,7 @@ static void TransMat3ToSize( float mat[][3], float smat[][3], float *size) static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { float tmat[3][3], smat[3][3], center[3]; float vec[3]; - + if (t->flag & T_EDIT) { Mat3MulMat3(smat, mat, td->mtx); Mat3MulMat3(tmat, td->smtx, smat); @@ -2346,18 +2314,18 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { else { Mat3CpyMat3(tmat, mat); } - + if (t->con.applySize) { t->con.applySize(t, td, tmat); } - + /* local constraint shouldn't alter center */ if (t->around == V3D_LOCAL) { if (t->flag & T_OBJECT) { VECCOPY(center, td->center); } else if (t->flag & T_EDIT) { - + if(t->around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) { VECCOPY(center, td->center); } @@ -2372,14 +2340,14 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { else { VECCOPY(center, t->center); } - + 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. - Mat3MulMat3(obsizemat, tmat, td->axismtx); + Mat3MulMat3(obsizemat, td->axismtx, tmat); //printmatrix3("obsizemat", obsizemat); TransMat3ToSize(obsizemat, td->axismtx, fsize); //printvecf("fsize", fsize); @@ -2387,28 +2355,14 @@ 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)){ + 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]; @@ -2417,46 +2371,39 @@ 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); else VecSubf(vec, td->center, center); - + Mat3MulVecfl(tmat, vec); - + VecAddf(vec, vec, center); if (t->flag & T_POINTS) VecSubf(vec, vec, td->iloc); else VecSubf(vec, vec, td->center); - + VecMulf(vec, td->factor); - + if (t->flag & (T_OBJECT|T_POSE)) { Mat3MulVecfl(td->smtx, vec); } - + protectedTransBits(td->protectflag, vec); - - if(td->tdi) { - TransDataIpokey *tdi= td->tdi; - add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]); - add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]); - add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]); - } - else VecAddf(td->loc, td->iloc, vec); - + VecAddf(td->loc, td->iloc, vec); + constraintTransLim(t, td); } @@ -2467,7 +2414,7 @@ int Resize(TransInfo *t, short mval[2]) float ratio; int i; char str[200]; - + /* for manipulator, center handle, the scaling can't be done relative to center */ if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) { @@ -2477,60 +2424,60 @@ int Resize(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); } - + applySnapping(t, size); - + if (t->flag & T_AUTOVALUES) { VECCOPY(size, t->auto_values); } - + VECCOPY(t->values, size); - + SizeToMat3(size, mat); - + if (t->con.applySize) { t->con.applySize(t, NULL, mat); } - + Mat3CpyMat3(t->mat, mat); // used in manipulator - + headerResize(t, size, str); - + 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); } - + /* evil hack - redo resize if cliping needed */ if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) { SizeToMat3(size, mat); - + if (t->con.applySize) t->con.applySize(t, NULL, mat); - + for(i = 0, td=t->data; i < t->total; i++, td++) ElementResize(t, td, mat); } - + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -2540,26 +2487,26 @@ 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; t->num.idx_max = 0; 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); } - + t->val /= (float)t->total; } @@ -2570,56 +2517,56 @@ int ToSphere(TransInfo *t, short mval[2]) int i; char str[64]; TransData *td = t->data; - + ratio = t->values[0]; - + snapGrid(t, &ratio); - + applyNumInput(&t->num, &ratio); - + if (ratio < 0) ratio = 0.0f; else if (ratio > 1) ratio = 1.0f; - + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[20]; - + outputNumInput(&(t->num), c); - + sprintf(str, "To Sphere: %s %s", c, t->proptext); } else { /* 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) break; - + if (td->flag & TD_SKIP) continue; - + VecSubf(vec, td->iloc, t->center); - + radius = Normalize(vec); - + tratio = ratio * td->factor; - + VecMulf(vec, radius * (1.0f - tratio) + t->val * tratio); - + VecAddf(td->loc, t->center, vec); } - - + + recalcData(t); - + ED_area_headerprint(t->sa, str); - + return 1; } @@ -2630,19 +2577,19 @@ 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; } @@ -2651,40 +2598,40 @@ 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)) { center = td->center; } else { - /* !TODO! Make this if not rely on G */ 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); protectedTransBits(td->protectflag, vec); VecAddf(td->loc, td->iloc, vec); - + + 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); } @@ -2704,48 +2651,48 @@ 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 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/axis-angle? */ - if (td->flag & TD_USEQUAT) { + if (td->rotOrder == ROT_MODE_QUAT) { 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 if (td->rotOrder == PCHAN_ROT_AXISANGLE) { + else if (td->rotOrder == ROT_MODE_AXISANGLE) { /* calculate effect based on quats */ float iquat[4]; @@ -2797,93 +2744,67 @@ 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]); - add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]); - add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]); - } - else VecAddf(td->loc, td->iloc, 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) { + if ((td->rotOrder == ROT_MODE_QUAT) || (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 if (td->rotOrder == ROT_MODE_AXISANGLE) { + /* calculate effect based on quats */ + float iquat[4]; + + /* td->ext->(i)quat is in axis-angle form, not quats! */ + AxisAngleToQuat(iquat, &td->ext->iquat[1], td->ext->iquat[0]); + + Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); + Mat3ToQuat(fmat, quat); // Actual transform + + QuatMul(td->ext->quat, quat, iquat); + + /* make temp copy (since stored in same place) */ + QUATCOPY(quat, td->ext->quat); // this is just a 4d vector copying macro + QuatToAxisAngle(quat, &td->ext->quat[1], &td->ext->quat[0]); + + /* this function works on end result */ + protectedAxisAngleBits(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); - } - 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]); - } - 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); - } + + 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 */ + EulOToMat3(eul, td->rotOrder, obmat); + /* mat = transform, obmat = object rotation */ + Mat3MulMat3(fmat, smat, obmat); + + Mat3ToCompatibleEulO(fmat, eul, td->ext->rot, td->rotOrder); + + /* 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); } } @@ -2894,17 +2815,17 @@ 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) break; - + if (td->flag & TD_SKIP) continue; - + if (t->con.applyRot) { t->con.applyRot(t, td, axis, NULL); VecRotToMat3(axis, angle * td->factor, mat); @@ -2912,7 +2833,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) else if (t->flag & T_PROP_EDIT) { VecRotToMat3(axis, angle * td->factor, mat); } - + ElementRotation(t, td, mat, t->around); } } @@ -2920,62 +2841,62 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) int Rotation(TransInfo *t, short mval[2]) { char str[64]; - + float final; - + float axis[3]; float mat[3][3]; - + VECCOPY(axis, t->viewinv[2]); VecMulf(axis, -1.0f); Normalize(axis); - + 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)) { char c[20]; - + applyNumInput(&t->num, &final); - + outputNumInput(&(t->num), c); - + sprintf(str, "Rot: %s %s %s", &c[0], t->con.text, t->proptext); - + /* Clamp between -180 and 180 */ while (final >= 180.0) final -= 360.0; - + while (final <= -180.0) final += 360.0; - + final *= (float)(M_PI / 180.0); } else { sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext); } - + VecRotToMat3(axis, final, mat); - + // 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); - + return 1; } @@ -3193,10 +3114,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)) { @@ -3207,26 +3128,26 @@ 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); } } - + if (t->con.applyVec) { float pvec[3]; t->con.applyVec(t, td, vec, tvec, pvec); @@ -3234,21 +3155,14 @@ 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; - add_tdi_poin(tdi->locx, tdi->oldloc, tvec[0]); - add_tdi_poin(tdi->locy, tdi->oldloc+1, tvec[1]); - add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]); - } - else VecAddf(td->loc, td->iloc, tvec); - + + VecAddf(td->loc, td->iloc, tvec); + constraintTransLim(t, td); } } @@ -3915,7 +3829,7 @@ int BoneSize(TransInfo *t, short mval[2]) 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) @@ -3926,40 +3840,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; } @@ -3970,15 +3884,15 @@ 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; t->snap[1] = 0.1f; t->snap[2] = t->snap[1] * 0.1f; - + t->flag |= T_NO_CONSTRAINT; } @@ -3988,31 +3902,31 @@ int BoneEnvelope(TransInfo *t, short mval[2]) 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) @@ -4021,6 +3935,698 @@ int BoneEnvelope(TransInfo *t, short mval[2]) *td->val= ratio; } } + + recalcData(t); + + ED_area_headerprint(t->sa, str); + + return 1; +} + +/* ******************** Edge Slide *************** */ + +static int createSlideVerts(TransInfo *t) +{ +#if 0 + Mesh *me = t->obedit->data; + BMEditMesh *em = me->edit_btmesh; + EditFace *efa; + EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL; + EditVert *ev, *nearest = NULL; + LinkNode *edgelist = NULL, *vertlist=NULL, *look; + GHash *vertgh; + TransDataSlideVert *tempsv; + float perc = 0, percp = 0,vertdist; // XXX, projectMat[4][4]; + float shiftlabda= 0.0f,len = 0.0f; + int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0; + int wasshift = 0; + /* UV correction vars */ + GHash **uvarray= NULL; + SlideData *sld = MEM_callocN(sizeof(*sld), "sld"); + int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE); + int uvlay_idx; + TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL; + RegionView3D *v3d = t->ar->regiondata; + float projectMat[4][4]; + float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f}; + float vec[3]; + //short mval[2], mvalo[2]; + float labda = 0.0f, totvec=0.0; + + if (!v3d) { + /*ok, let's try to survive this*/ + Mat4One(projectMat); + } else { + view3d_get_object_project_mat(v3d, t->obedit, projectMat); + } + + //mvalo[0] = -1; mvalo[1] = -1; + numsel =0; + + // Get number of selected edges and clear some flags + for(eed=em->edges.first;eed;eed=eed->next) { + eed->f1 = 0; + eed->f2 = 0; + if(eed->f & SELECT) numsel++; + } + + for(ev=em->verts.first;ev;ev=ev->next) { + ev->f1 = 0; + } + + //Make sure each edge only has 2 faces + // make sure loop doesn't cross face + for(efa=em->faces.first;efa;efa=efa->next) { + int ct = 0; + if(efa->e1->f & SELECT) { + ct++; + efa->e1->f1++; + if(efa->e1->f1 > 2) { + //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + return 0; + } + } + if(efa->e2->f & SELECT) { + ct++; + efa->e2->f1++; + if(efa->e2->f1 > 2) { + //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + return 0; + } + } + if(efa->e3->f & SELECT) { + ct++; + efa->e3->f1++; + if(efa->e3->f1 > 2) { + //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + return 0; + } + } + if(efa->e4 && efa->e4->f & SELECT) { + ct++; + efa->e4->f1++; + if(efa->e4->f1 > 2) { + //BKE_report(op->reports, RPT_ERROR, "3+ face edge"); + 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; + } + } + + // Get # of selected verts + for(ev=em->verts.first;ev;ev=ev->next) { + if(ev->f & SELECT) vertsel++; + } + + // Test for multiple segments + if(vertsel > numsel+1) { + //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop"); + return 0; + } + + // Get the edgeloop in order - mark f1 with SELECT once added + for(eed=em->edges.first;eed;eed=eed->next) { + if((eed->f & SELECT) && !(eed->f1 & SELECT)) { + // If this is the first edge added, just put it in + if(!edgelist) { + BLI_linklist_prepend(&edgelist,eed); + numadded++; + first = eed; + last = eed; + eed->f1 = SELECT; + } else { + if(editedge_getSharedVert(eed, last)) { + BLI_linklist_append(&edgelist,eed); + eed->f1 = SELECT; + numadded++; + last = eed; + } else if(editedge_getSharedVert(eed, first)) { + BLI_linklist_prepend(&edgelist,eed); + eed->f1 = SELECT; + numadded++; + first = eed; + } + } + } + if(eed->next == NULL && numadded != numsel) { + eed=em->edges.first; + timesthrough++; + } + + // It looks like there was an unexpected case - Hopefully should not happen + if(timesthrough >= numsel*2) { + BLI_linklist_free(edgelist,NULL); + //BKE_report(op->reports, RPT_ERROR, "Could not order loop"); + return 0; + } + } + + // Put the verts in order in a linklist + look = edgelist; + while(look) { + eed = look->link; + if(!vertlist) { + if(look->next) { + temp = look->next->link; + + //This is the first entry takes care of extra vert + if(eed->v1 != temp->v1 && eed->v1 != temp->v2) { + BLI_linklist_append(&vertlist,eed->v1); + eed->v1->f1 = 1; + } else { + BLI_linklist_append(&vertlist,eed->v2); + eed->v2->f1 = 1; + } + } else { + //This is the case that we only have 1 edge + BLI_linklist_append(&vertlist,eed->v1); + eed->v1->f1 = 1; + } + } + // for all the entries + if(eed->v1->f1 != 1) { + BLI_linklist_append(&vertlist,eed->v1); + eed->v1->f1 = 1; + } else if(eed->v2->f1 != 1) { + BLI_linklist_append(&vertlist,eed->v2); + eed->v2->f1 = 1; + } + look = look->next; + } + + // populate the SlideVerts + + vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + look = vertlist; + while(look) { + i=0; + j=0; + ev = look->link; + tempsv = (struct TransDataSlideVert*)MEM_mallocN(sizeof(struct TransDataSlideVert),"SlideVert"); + tempsv->up = NULL; + tempsv->down = NULL; + tempsv->origvert.co[0] = ev->co[0]; + tempsv->origvert.co[1] = ev->co[1]; + tempsv->origvert.co[2] = ev->co[2]; + tempsv->origvert.no[0] = ev->no[0]; + tempsv->origvert.no[1] = ev->no[1]; + tempsv->origvert.no[2] = ev->no[2]; + // i is total edges that vert is on + // j is total selected edges that vert is on + + for(eed=em->edges.first;eed;eed=eed->next) { + if(eed->v1 == ev || eed->v2 == ev) { + i++; + if(eed->f & SELECT) { + j++; + } + } + } + // If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges + if(i == 4 && j == 2) { + for(eed=em->edges.first;eed;eed=eed->next) { + if(editedge_containsVert(eed, ev)) { + if(!(eed->f & SELECT)) { + if(!tempsv->up) { + tempsv->up = eed; + } else if (!(tempsv->down)) { + tempsv->down = eed; + } + } + } + } + } + // If it is on the end of the loop, it touches 1 selected and as least 2 more unselected + if(i >= 3 && j == 1) { + for(eed=em->edges.first;eed;eed=eed->next) { + if(editedge_containsVert(eed, ev) && eed->f & SELECT) { + for(efa = em->faces.first;efa;efa=efa->next) { + if(editface_containsEdge(efa, eed)) { + if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) { + if(!tempsv->up) { + tempsv->up = efa->e1; + } else if (!(tempsv->down)) { + tempsv->down = efa->e1; + } + } + if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) { + if(!tempsv->up) { + tempsv->up = efa->e2; + } else if (!(tempsv->down)) { + tempsv->down = efa->e2; + } + } + if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) { + if(!tempsv->up) { + tempsv->up = efa->e3; + } else if (!(tempsv->down)) { + tempsv->down = efa->e3; + } + } + if(efa->e4) { + if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) { + if(!tempsv->up) { + tempsv->up = efa->e4; + } else if (!(tempsv->down)) { + tempsv->down = efa->e4; + } + } + } + + } + } + } + } + } + if(i > 4 && j == 2) { + BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); + BLI_linklist_free(vertlist,NULL); + BLI_linklist_free(edgelist,NULL); + return 0; + } + BLI_ghash_insert(vertgh,ev,tempsv); + + look = look->next; + } + + // make sure the UPs nad DOWNs are 'faceloops' + // Also find the nearest slidevert to the cursor + + look = vertlist; + nearest = NULL; + vertdist = -1; + while(look) { + tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); + + if(!tempsv->up || !tempsv->down) { + //BKE_report(op->reports, RPT_ERROR, "Missing rails"); + BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN); + BLI_linklist_free(vertlist,NULL); + BLI_linklist_free(edgelist,NULL); + return 0; + } + + if(me->drawflag & ME_DRAW_EDGELEN) { + if(!(tempsv->up->f & SELECT)) { + tempsv->up->f |= SELECT; + tempsv->up->f2 |= 16; + } else { + tempsv->up->f2 |= ~16; + } + if(!(tempsv->down->f & SELECT)) { + tempsv->down->f |= SELECT; + tempsv->down->f2 |= 16; + } else { + tempsv->down->f2 |= ~16; + } + } + + if(look->next != NULL) { + TransDataSlideVert *sv; + + ev = (EditVert*)look->next->link; + sv = BLI_ghash_lookup(vertgh, ev); + + if(sv) { + float co[3], co2[3], vec[3]; + + ev = (EditVert*)look->link; + + if(!sharesFace(em, tempsv->up,sv->up)) { + EditEdge *swap; + swap = sv->up; + sv->up = sv->down; + sv->down = swap; + } + + if (v3d) { + view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat); + view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat); + } + + if (ev == tempsv->up->v1) { + VecSubf(vec, co, co2); + } else { + VecSubf(vec, co2, co); + } + + VecAddf(start, start, vec); + + if (v3d) { + view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat); + view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat); + } + + if (ev == tempsv->down->v1) { + VecSubf(vec, co2, co); + } else { + VecSubf(vec, co, co2); + } + + VecAddf(end, end, vec); + + totvec += 1.0f; + nearest = (EditVert*)look->link; + } + } + + + + look = look->next; + } + + VecAddf(start, start, end); + VecMulf(start, 0.5*(1.0/totvec)); + VECCOPY(vec, start); + start[0] = t->mval[0]; + start[1] = t->mval[1]; + VecAddf(end, start, vec); + + sld->start[0] = (short) start[0]; + sld->start[1] = (short) start[1]; + sld->end[0] = (short) end[0]; + sld->end[1] = (short) end[1]; + + if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) { + int maxnum = 0; + + uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array"); + sld->totuv = uvlay_tot; + suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(TransDataSlideUv), "SlideUVs"); /* uvLayers * verts */ + suv = NULL; + + for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { + + uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + + for(ev=em->verts.first;ev;ev=ev->next) { + ev->tmp.l = 0; + } + look = vertlist; + while(look) { + float *uv_new; + tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); + + ev = look->link; + suv = NULL; + for(efa = em->faces.first;efa;efa=efa->next) { + if (ev->tmp.l != -1) { /* test for self, in this case its invalid */ + int k=-1; /* face corner */ + + /* Is this vert in the faces corner? */ + if (efa->v1==ev) k=0; + else if (efa->v2==ev) k=1; + else if (efa->v3==ev) k=2; + else if (efa->v4 && efa->v4==ev) k=3; + + if (k != -1) { + MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx); + EditVert *ev_up, *ev_down; + + 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])) { + ev->tmp.l = -1; /* Tag as invalid */ + BLI_linklist_free(suv->fuv_list,NULL); + suv->fuv_list = NULL; + BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL); + suv = NULL; + break; + } + } else { + ev->tmp.l = 1; + suv = suv_last; + + suv->fuv_list = NULL; + suv->uv_up = suv->uv_down = NULL; + suv->origuv[0] = uv_new[0]; + suv->origuv[1] = uv_new[1]; + + BLI_linklist_prepend(&suv->fuv_list, uv_new); + BLI_ghash_insert(uvarray[uvlay_idx],ev,suv); + + suv_last++; /* advance to next slide UV */ + maxnum++; + } + + /* Now get the uvs along the up or down edge if we can */ + if (suv) { + if (!suv->uv_up) { + ev_up = editedge_getOtherVert(tempsv->up,ev); + if (efa->v1==ev_up) suv->uv_up = tf->uv[0]; + else if (efa->v2==ev_up) suv->uv_up = tf->uv[1]; + else if (efa->v3==ev_up) suv->uv_up = tf->uv[2]; + else if (efa->v4 && efa->v4==ev_up) suv->uv_up = tf->uv[3]; + } + if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */ + ev_down = editedge_getOtherVert(tempsv->down,ev); + if (efa->v1==ev_down) suv->uv_down = tf->uv[0]; + else if (efa->v2==ev_down) suv->uv_down = tf->uv[1]; + else if (efa->v3==ev_down) suv->uv_down = tf->uv[2]; + else if (efa->v4 && efa->v4==ev_down) suv->uv_down = tf->uv[3]; + } + + /* Copy the pointers to the face UV's */ + BLI_linklist_prepend(&suv->fuv_list, uv_new); + } + } + } + } + look = look->next; + } + } /* end uv layer loop */ + } /* end uvlay_tot */ + + sld->uvhash = uvarray; + sld->slideuv = slideuvs; + sld->vhash = vertgh; + sld->nearest = nearest; + sld->vertlist = vertlist; + sld->edgelist = edgelist; + sld->suv_last = suv_last; + sld->uvlay_tot = uvlay_tot; + + // we should have enough info now to slide + + t->customData = sld; + + return 1; +#endif +} + +void freeSlideVerts(TransInfo *t) +{ +#if 0 + TransDataSlideUv *suv; + SlideData *sld = t->customData; + int uvlay_idx; + + //BLI_ghash_free(edgesgh, freeGHash, NULL); + BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN); + BLI_linklist_free(sld->vertlist, NULL); + BLI_linklist_free(sld->edgelist, NULL); + + if (sld->uvlay_tot) { + for (uvlay_idx=0; uvlay_idx<sld->uvlay_tot; uvlay_idx++) { + BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL); + } + + suv = sld->suv_last-1; + while (suv >= sld->slideuv) { + if (suv->fuv_list) { + BLI_linklist_free(suv->fuv_list,NULL); + } + suv--; + } + + MEM_freeN(sld->slideuv); + MEM_freeN(sld->uvhash); + } + + MEM_freeN(sld); + t->customData = NULL; +#endif +} + +void initEdgeSlide(TransInfo *t) +{ + SlideData *sld; + + t->mode = TFM_EDGE_SLIDE; + t->transform = EdgeSlide; + + createSlideVerts(t); + sld = t->customData; + + if (!sld) + return; + + t->customFree = freeSlideVerts; + + initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO); + setCustomPoints(t, &t->mouse, sld->end, sld->start); + + 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; + + t->flag |= T_NO_CONSTRAINT; +} + +int doEdgeSlide(TransInfo *t, float perc) +{ +#if 0 + Mesh *me= t->obedit->data; + EditMesh *em = me->edit_mesh; + SlideData *sld = t->customData; + EditEdge *first=NULL,*last=NULL, *temp = NULL; + EditVert *ev, *nearest = sld->nearest; + EditVert *centerVert, *upVert, *downVert; + LinkNode *edgelist = sld->edgelist, *vertlist=sld->vertlist, *look; + GHash *vertgh = sld->vhash; + TransDataSlideVert *tempsv; + float shiftlabda= 0.0f,len = 0.0f; + int i = 0, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0; + int wasshift = 0; + /* UV correction vars */ + GHash **uvarray= sld->uvhash; + int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE); + int uvlay_idx; + TransDataSlideUv *slideuvs=sld->slideuv, *suv=sld->slideuv, *suv_last=NULL; + float uv_tmp[2]; + LinkNode *fuv_link; + float labda = 0.0f; + + len = 0.0f; + + tempsv = BLI_ghash_lookup(vertgh,nearest); + + centerVert = editedge_getSharedVert(tempsv->up, tempsv->down); + upVert = editedge_getOtherVert(tempsv->up, centerVert); + downVert = editedge_getOtherVert(tempsv->down, centerVert); + + len = MIN2(perc, VecLenf(upVert->co,downVert->co)); + len = MAX2(len, 0); + + //Adjust Edgeloop + if(prop) { + look = vertlist; + while(look) { + EditVert *tempev; + ev = look->link; + tempsv = BLI_ghash_lookup(vertgh,ev); + + tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev); + VecLerpf(ev->co, tempsv->origvert.co, tempev->co, fabs(perc)); + + if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { + for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { + suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev ); + if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) { + Vec2Lerpf(uv_tmp, suv->origuv, (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc)); + fuv_link = suv->fuv_list; + while (fuv_link) { + VECCOPY2D(((float *)fuv_link->link), uv_tmp); + fuv_link = fuv_link->next; + } + } + } + } + + look = look->next; + } + } + else { + //Non prop code + look = vertlist; + while(look) { + float newlen; + ev = look->link; + tempsv = BLI_ghash_lookup(vertgh,ev); + newlen = (len / VecLenf(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co)); + if(newlen > 1.0) {newlen = 1.0;} + if(newlen < 0.0) {newlen = 0.0;} + if(flip == 0) { + VecLerpf(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen)); + if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { + /* dont do anything if no UVs */ + for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { + suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev ); + if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) { + Vec2Lerpf(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen)); + fuv_link = suv->fuv_list; + while (fuv_link) { + VECCOPY2D(((float *)fuv_link->link), uv_tmp); + fuv_link = fuv_link->next; + } + } + } + } + } else{ + VecLerpf(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen)); + + if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) { + /* dont do anything if no UVs */ + for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) { + suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev ); + if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) { + Vec2Lerpf(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen)); + fuv_link = suv->fuv_list; + while (fuv_link) { + VECCOPY2D(((float *)fuv_link->link), uv_tmp); + fuv_link = fuv_link->next; + } + } + } + } + } + look = look->next; + } + + } +#endif + return 1; +} + +int EdgeSlide(TransInfo *t, short mval[2]) +{ + TransData *td = t->data; + char str[50]; + float final; + + final = t->values[0]; + + snapGrid(t, &final); + + if (hasNumInput(&t->num)) { + char c[20]; + + applyNumInput(&t->num, &final); + + outputNumInput(&(t->num), c); + + sprintf(str, "Edge Slide Percent: %s", &c[0]); + } + else { + sprintf(str, "Edge Slide Percent: %.2f", final); + } + + CLAMP(final, -1.0f, 1.0f); + + /*do stuff here*/ + if (t->customData) + doEdgeSlide(t, final); + else { + strcpy(str, "Invalid Edge Selection"); + t->state = TRANS_CANCEL; + } recalcData(t); @@ -4029,7 +4635,6 @@ int BoneEnvelope(TransInfo *t, short mval[2]) return 1; } - /* ******************** EditBone roll *************** */ void initBoneRoll(TransInfo *t) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index e5bd405c0cd..fc31fad622a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -32,10 +32,13 @@ #include "ED_transform.h" +#include "BLI_editVert.h" + /* ************************** Types ***************************** */ struct TransInfo; struct TransData; +struct TransformOrientation; struct TransSnap; struct NumInput; struct Object; @@ -52,6 +55,7 @@ struct bContext; struct wmEvent; struct wmTimer; struct ARegion; +struct ReportList; typedef struct NDofInput { int flag; @@ -83,6 +87,7 @@ typedef struct TransSnap { short modeTarget; short mode; short align; + short project; short status; float snapPoint[3]; /* snapping from this point */ float snapTarget[3]; /* to this point */ @@ -118,20 +123,9 @@ typedef struct TransCon { /* Apply function pointer for rotation transformation */ } TransCon; -typedef struct TransDataIpokey { - int flag; /* which keys */ - float *locx, *locy, *locz; /* channel pointers */ - float *rotx, *roty, *rotz; - float *quatx, *quaty, *quatz, *quatw; - float *sizex, *sizey, *sizez; - float oldloc[9]; /* storage old values */ - float oldrot[9]; - float oldsize[9]; - float oldquat[12]; -} TransDataIpokey; - typedef struct TransDataExtension { float drot[3]; /* Initial object drot */ + float dquat[4]; /* Initial object dquat */ float dsize[3]; /* Initial object dsize */ float *rot; /* Rotation of the data to transform (Faculative) */ float irot[3]; /* Initial rotation */ @@ -179,6 +173,31 @@ typedef struct TransDataNla { int handle; /* handle-index: 0 for dummy entry, -1 for start, 1 for end, 2 for both ends */ } TransDataNla; +struct LinkNode; +struct EditEdge; +struct EditVert; +struct GHash; +typedef struct TransDataSlideUv { + float origuv[2]; + float *uv_up, *uv_down; + //float *fuv[4]; + struct LinkNode *fuv_list; +} TransDataSlideUv; + +typedef struct TransDataSlideVert { + struct EditEdge *up, *down; + struct EditVert origvert; +} TransDataSlideVert; + +typedef struct SlideData { + TransDataSlideUv *slideuv, *suv_last; + int totuv, uvlay_tot; + struct GHash *vhash, **uvhash; + struct EditVert *nearest; + struct LinkNode *edgelist, *vertlist; + short start[2], end[2]; +} SlideData; + typedef struct TransData { float dist; /* Distance needed to affect element (for Proportionnal Editing) */ float rdist; /* Distance to the nearest element (for Proportionnal Editing) */ @@ -194,12 +213,11 @@ typedef struct TransData { struct Object *ob; struct bConstraint *con; /* for objects/bones, the first constraint in its constraint stack */ TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */ - TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */ TransDataCurveHandleFlags *hdata; /* for curves, stores handle flags for modification/cancel */ void *extra; /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */ - short flag; /* Various flags */ + int flag; /* Various flags */ short protectflag; /* If set, copy of Object or PoseChannel protection */ - int rotOrder; /* rotation order (for eulers), as defined in BLI_arithb.h */ + int rotOrder; /* rotation mode, as defined in eRotationModes (DNA_action_types.h) */ } TransData; typedef struct MouseInput { @@ -210,6 +228,7 @@ typedef struct MouseInput { short precision_mval[2]; /* mouse position when precision key was pressed */ int center[2]; float factor; + void *data; /* additional data, if needed by the particular function */ } MouseInput; typedef struct TransInfo { @@ -263,12 +282,15 @@ typedef struct TransInfo { struct Object *poseobj; /* if t->flag & T_POSE, this denotes pose object */ void *customData; /* Per Transform custom data */ + void (*customFree)(struct TransInfo *); /* if a special free function is needed */ /*************** NEW STUFF *********************/ short current_orientation; short prop_mode; + + short mirror; float values[4]; float auto_values[4]; @@ -378,6 +400,7 @@ typedef struct TransInfo { #define TD_NO_LOC (1 << 13) /* when this is set, don't apply translation changes to this element */ #define TD_NOTIMESNAP (1 << 14) /* for Graph Editor autosnap, indicates that point should not undergo autosnapping */ #define TD_INTVALUES (1 << 15) /* for Graph Editor - curves that can only have int-values need their keyframes tagged with this */ +#define TD_MIRROR_EDGE (1 << 16) /* For editmode mirror, clamp to x = 0 */ /* transsnap->status */ #define SNAP_ON 1 @@ -466,6 +489,9 @@ int BoneEnvelope(TransInfo *t, short mval[2]); void initBoneRoll(TransInfo *t); int BoneRoll(TransInfo *t, short mval[2]); +void initEdgeSlide(TransInfo *t); +int EdgeSlide(TransInfo *t, short mval[2]); + void initTimeTranslate(TransInfo *t); int TimeTranslate(TransInfo *t, short mval[2]); @@ -486,7 +512,7 @@ int Align(TransInfo *t, short mval[2]); void drawPropCircle(const struct bContext *C, TransInfo *t); -void transform_modal_keymap(struct wmWindowManager *wm); +void transform_modal_keymap(struct wmKeyConfig *keyconf); /*********************** transform_conversions.c ********** */ @@ -526,7 +552,7 @@ void drawConstraint(const struct bContext *C, TransInfo *t); void getConstraintMatrix(TransInfo *t); void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]); void setLocalConstraint(TransInfo *t, int mode, const char text[]); -void setUserConstraint(TransInfo *t, int mode, const char text[]); +void setUserConstraint(TransInfo *t, short orientation, int mode, const char text[]); void constraintNumInput(TransInfo *t, float vec[3]); @@ -556,6 +582,7 @@ void snapGrid(TransInfo *t, float *val); void snapGridAction(TransInfo *t, float *val, GearsType action); void initSnapping(struct TransInfo *t, struct wmOperator *op); +void applyProject(TransInfo *t); void applySnapping(TransInfo *t, float *vec); void resetSnapping(TransInfo *t); int handleSnapping(TransInfo *t, struct wmEvent *event); @@ -575,7 +602,8 @@ typedef enum { INPUT_HORIZONTAL_RATIO, INPUT_HORIZONTAL_ABSOLUTE, INPUT_VERTICAL_RATIO, - INPUT_VERTICAL_ABSOLUTE + INPUT_VERTICAL_ABSOLUTE, + INPUT_CUSTOM_RATIO } MouseInputMode; void initMouseInput(TransInfo *t, MouseInput *mi, int center[2], short mval[2]); @@ -583,6 +611,8 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode); int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, struct wmEvent *event); void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, short mval[2], float output[3]); +void setCustomPoints(TransInfo *t, MouseInput *mi, short start[2], short end[2]); + /*********************** Generics ********************************/ int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, struct wmEvent *event); @@ -640,18 +670,17 @@ int handleNDofInput(NDofInput *n, struct wmEvent *event); void initTransformOrientation(struct bContext *C, TransInfo *t); -int manageObjectSpace(struct bContext *C, int confirm, int set); -int manageMeshSpace(struct bContext *C, int confirm, int set); -int manageBoneSpace(struct bContext *C, int confirm, int set); +struct TransformOrientation *createObjectSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite); +struct TransformOrientation *createMeshSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite); +struct TransformOrientation *createBoneSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite); /* Those two fill in mat and return non-zero on success */ int createSpaceNormal(float mat[3][3], float normal[3]); int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]); -int addMatrixSpace(struct bContext *C, float mat[3][3], char name[]); +struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], char name[], int overwrite); int addObjectSpace(struct bContext *C, struct Object *ob); -void applyTransformOrientation(const struct bContext *C, TransInfo *t); - +void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *name); #define ORIENTATION_NONE 0 #define ORIENTATION_NORMAL 1 @@ -663,6 +692,8 @@ int getTransformOrientation(const struct bContext *C, float normal[3], float pla int createSpaceNormal(float mat[3][3], float normal[3]); int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]); +void freeSlideVerts(TransInfo *t); + #endif diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 158ea98c090..1143203217b 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -551,11 +551,10 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) { ftext is a format string passed to sprintf. It will add the name of the orientation where %s is (logically). */ -void setUserConstraint(TransInfo *t, int mode, const char ftext[]) { +void setUserConstraint(TransInfo *t, short orientation, int mode, const char ftext[]) { char text[40]; - //short twmode= (t->spacetype==SPACE_VIEW3D)? ((View3D*)t->view)->twmode: V3D_MANIP_GLOBAL; - switch(t->current_orientation) { + switch(orientation) { case V3D_MANIP_GLOBAL: { float mtx[3][3]; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 4267bd39d5e..764256c476d 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -126,7 +126,6 @@ #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" @@ -296,7 +295,7 @@ static void createTransTexspace(bContext *C, TransInfo *t) TransData *td; Object *ob; ID *id; - int *texflag; + short *texflag; ob = OBACT; @@ -382,7 +381,6 @@ static void createTransEdge(bContext *C, TransInfo *t) { Mat3CpyMat3(td->mtx, mtx); td->ext = NULL; - td->tdi = NULL; if (t->mode == TFM_BWEIGHT) { td->val = &(eed->bweight); td->ival = eed->bweight; @@ -512,8 +510,8 @@ static short apply_targetless_ik(Object *ob) /* rotation */ if (parchan->rotmode > 0) Mat3ToEulO(rmat3, parchan->eul, parchan->rotmode); - else if (parchan->rotmode == PCHAN_ROT_AXISANGLE) - Mat3ToAxisAngle(rmat3, &parchan->quat[1], &parchan->quat[0]); + else if (parchan->rotmode == ROT_MODE_AXISANGLE) + Mat3ToAxisAngle(rmat3, parchan->rotAxis, &pchan->rotAngle); else Mat3ToQuat(rmat3, parchan->quat); @@ -522,8 +520,8 @@ static short apply_targetless_ik(Object *ob) if (data->flag & CONSTRAINT_IK_STRETCH) { if (parchan->rotmode > 0) EulOToMat3(parchan->eul, parchan->rotmode, qrmat); - else if (parchan->rotmode == PCHAN_ROT_AXISANGLE) - AxisAngleToMat3(&parchan->quat[1], parchan->quat[0], qrmat); + else if (parchan->rotmode == ROT_MODE_AXISANGLE) + AxisAngleToMat3(parchan->rotAxis, parchan->rotAngle, qrmat); else QuatToMat3(parchan->quat, qrmat); @@ -559,10 +557,6 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ob = ob; td->flag = TD_SELECTED; - if (pchan->rotmode == PCHAN_ROT_QUAT) - { - td->flag |= TD_USEQUAT; - } if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) { td->flag |= TD_NOCENTER; @@ -587,15 +581,14 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ext->quat= NULL; VECCOPY(td->ext->irot, pchan->eul); - td->rotOrder= pchan->rotmode; } else { td->ext->rot= NULL; td->ext->quat= pchan->quat; QUATCOPY(td->ext->iquat, pchan->quat); - td->rotOrder= pchan->rotmode; } + td->rotOrder= pchan->rotmode; /* proper way to get parent transform + own transform + constraints transform */ @@ -1019,7 +1012,6 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob) tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt"); for(i=0; i<t->total; i++, td++, tdx++) { td->ext= tdx; - td->tdi = NULL; td->val = NULL; } @@ -1103,7 +1095,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->loc = NULL; td->ext = NULL; - td->tdi = NULL; td++; } @@ -1119,7 +1110,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->loc = NULL; td->ext = NULL; - td->tdi = NULL; td++; } @@ -1154,7 +1144,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) Mat3Ortho(td->axismtx); td->ext = NULL; - td->tdi = NULL; td++; } @@ -1171,7 +1160,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->flag= TD_SELECTED; td->ext = NULL; - td->tdi = NULL; td++; } @@ -1199,7 +1187,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) } td->ext = NULL; - td->tdi = NULL; td->val = NULL; td++; @@ -1222,7 +1209,6 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t) td->extra = ebo; /* to fix roll */ td->ext = NULL; - td->tdi = NULL; td->val = NULL; td++; @@ -1275,7 +1261,6 @@ static void createTransMBallVerts(bContext *C, TransInfo *t) Mat3CpyMat3(td->mtx, mtx); td->ext = tx; - td->tdi = NULL; /* Radius of MetaElem (mass of MetaElem influence) */ if(ml->flag & MB_SCALE_RAD){ @@ -1440,7 +1425,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) else td->flag= 0; } td->ext = NULL; - td->tdi = NULL; td->val = NULL; hdata = initTransDataCurveHandes(td, bezt); @@ -1461,7 +1445,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) if(bezt->f2 & SELECT) td->flag= TD_SELECTED; 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); @@ -1501,7 +1484,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) else td->flag= 0; } td->ext = NULL; - td->tdi = NULL; td->val = NULL; if (hdata==NULL) { /* if the handle was not saved by the previous handle */ @@ -1541,7 +1523,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) if(bp->f1 & SELECT) td->flag= TD_SELECTED; else td->flag= 0; td->ext = NULL; - td->tdi = NULL; if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) { td->val = &(bp->radius); @@ -1617,7 +1598,6 @@ static void createTransLatticeVerts(bContext *C, TransInfo *t) Mat3CpyMat3(td->mtx, mtx); td->ext = NULL; - td->tdi = NULL; td->val = NULL; td++; @@ -1728,7 +1708,6 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) td->ob = ob; td->ext = tx; - td->tdi = NULL; if(t->mode == TFM_BAKE_TIME) { td->val = key->time; td->ival = *(key->time); @@ -1951,7 +1930,6 @@ static void editmesh_set_connectivity_distance(EditMesh *em, int total, float *v td->axismtx[1][1] =\ td->axismtx[1][2] = 0.0f;\ td->ext = NULL;\ - td->tdi = NULL;\ td->val = NULL;\ td->extra = NULL;\ if (t->mode == TFM_BWEIGHT) {\ @@ -1985,7 +1963,6 @@ inline void VertsToTransData(TransInfo *t, TransData *td, BMesh *em, BMVert *eve td->axismtx[1][2] = 0.0f; td->ext = NULL; - td->tdi = NULL; td->val = NULL; td->extra = NULL; if (t->mode == TFM_BWEIGHT) { @@ -2298,7 +2275,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t) for(a=0; eve; eve=BMIter_Step(&iter), a++) { if(!BM_TestHFlag(eve, BM_HIDDEN) && selstate[a] && eve->co[0]!=0.0f) { if(eve->co[0]<0.0f) + { + t->mirror = -1; mirror = -1; + } break; } } @@ -2374,6 +2354,19 @@ static void createTransEditVerts(bContext *C, TransInfo *t) } } } + + if (mirror != 0) + { + tob = t->data; + for( a = 0; a < t->total; a++, tob++ ) + { + if (ABS(tob->loc[0]) <= 0.00001f) + { + tob->flag |= TD_MIRROR_EDGE; + } + } + } + if (propmode) { MEM_freeN(vectors); MEM_freeN(nears); @@ -2504,7 +2497,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; if(selected) { td->flag |= TD_SELECTED; @@ -2804,7 +2797,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; td->flag |= TD_SELECTED; td->dist= 0.0f; @@ -2835,7 +2828,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; td->flag |= TD_SELECTED; td->dist= 0.0f; @@ -2987,7 +2980,7 @@ static void posttrans_fcurve_clean (FCurve *fcu) /* 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++; @@ -2995,16 +2988,18 @@ static void posttrans_fcurve_clean (FCurve *fcu) } } - /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */ - if (len) { + /* Loop 2: delete unselected keyframes on the same frames + * (if any keyframes were found, or the whole curve wasn't affected) + */ + if ((len) && (len != fcu->totvert)) { 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++) { if (IS_EQ(bezt->vec[1][0], selcache[index])) { - //delete_icu_key(icu, i, 0); + delete_fcurve_key(fcu, i, 0); break; } else if (bezt->vec[1][0] > selcache[index]) @@ -3012,7 +3007,7 @@ static void posttrans_fcurve_clean (FCurve *fcu) } } } - + testhandles_fcurve(fcu); } @@ -3386,7 +3381,7 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; /* store AnimData info in td->extra, for applying mapping when flushing */ td->extra= adt; @@ -3819,98 +3814,6 @@ void flushTransGraphData(TransInfo *t) } } -/* **************** IpoKey stuff, for Object TransData ********** */ - -/* while transforming */ -void add_tdi_poin(float *poin, float *old, float delta) -{ - if(poin) { - poin[0]= old[0]+delta; - poin[-3]= old[3]+delta; - poin[3]= old[6]+delta; - } -} - -#if 0 // TRANSFORM_FIX_ME -/* storage of bezier triple. thats why -3 and +3! */ -static void set_tdi_old(float *old, float *poin) -{ - old[0]= *(poin); - old[3]= *(poin-3); - old[6]= *(poin+3); -} - -/* fill ipokey transdata with old vals and pointers */ -static void ipokey_to_transdata(IpoKey *ik, TransData *td) -{ - extern int ob_ar[]; // blenkernel ipo.c - 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: - tdi->locx= &(bezt->vec[1][1]); break; - case OB_LOC_Y: - case OB_DLOC_Y: - tdi->locy= &(bezt->vec[1][1]); break; - 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: - tdi->rotx= &(bezt->vec[1][1]); break; - case OB_DROT_Y: - delta= 1; - case OB_ROT_Y: - tdi->roty= &(bezt->vec[1][1]); break; - case OB_DROT_Z: - 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; - case OB_SIZE_Y: - case OB_DSIZE_Y: - tdi->sizey= &(bezt->vec[1][1]); break; - case OB_SIZE_Z: - case OB_DSIZE_Z: - 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; -} -#endif - /* *************************** Object Transform data ******************* */ /* Little helper function for ObjectToTransData used to give certain @@ -4128,7 +4031,7 @@ static TransData *SeqToTransData(TransInfo *t, TransData *td, TransData2D *td2d, memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; td->flag |= TD_SELECTED; td->dist= 0.0; @@ -4269,20 +4172,20 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * 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 @@ -4296,6 +4199,10 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * td->ext->rot = ob->rot; VECCOPY(td->ext->irot, ob->rot); VECCOPY(td->ext->drot, ob->drot); + + td->ext->quat = ob->quat; + QUATCOPY(td->ext->iquat, ob->quat); + QUATCOPY(td->ext->dquat, ob->dquat); td->ext->size = ob->size; VECCOPY(td->ext->isize, ob->size); @@ -4337,7 +4244,7 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * /* it deselects Bases, so we have to call the clear function always after */ static void set_trans_object_base_flags(bContext *C, TransInfo *t) { - Scene *sce = CTX_data_scene(C); + Scene *scene = CTX_data_scene(C); View3D *v3d = t->view; /* @@ -4354,15 +4261,15 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t) copy_baseflags(t->scene); /* handle pending update events, otherwise they got copied below */ - for (base= sce->base.first; base; base= base->next) { + for (base= scene->base.first; base; base= base->next) { if(base->object->recalc) object_handle_update(t->scene, base->object); } - for (base= sce->base.first; base; base= base->next) { + for (base= scene->base.first; base; base= base->next) { base->flag &= ~BA_WAS_SEL; - if(TESTBASELIB(v3d, base)) { + if(TESTBASELIB_BGMODE(v3d, base)) { Object *ob= base->object; Object *parsel= ob->parent; @@ -4394,7 +4301,7 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t) /* 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) { + for (base= scene->base.first; base; base= base->next) { if(base->object->recalc & OB_RECALC_OB) base->flag |= BA_HAS_RECALC_OB; if(base->object->recalc & OB_RECALC_DATA) @@ -4426,10 +4333,16 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) // TODO: this should probably be done per channel instead... if (autokeyframe_cfra_can_key(scene, id)) { - AnimData *adt= ob->adt; + KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene); + bCommonKeySrc cks; + ListBase dsources = {&cks, &cks}; float cfra= (float)CFRA; // xxx this will do for now short flag = 0; + /* init common-key-source for use by KeyingSets */ + memset(&cks, 0, sizeof(bCommonKeySrc)); + cks.id= &ob->id; + if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED; if (IS_AUTOKEY_FLAG(AUTOMATKEY)) @@ -4437,7 +4350,14 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE; - if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { + + if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) { + /* only insert into active keyingset */ + modify_keyframes(scene, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra); + } + else if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { + AnimData *adt= ob->adt; + /* only key on available channels */ if (adt && adt->action) { for (fcu= adt->action->curves.first; fcu; fcu= fcu->next) { @@ -4476,41 +4396,25 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode) doScale = 1; } - // TODO: the group names here are temporary... - // TODO: should this be made to use the builtin KeyingSets instead? + /* insert keyframes for the affected sets of channels using the builtin KeyingSets found */ if (doLoc) { - 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); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location"); + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (doRot) { - 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); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (doScale) { - 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); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scale"); + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } } + /* insert keyframe in all (transform) channels */ else { - // TODO: the group names here are temporary... - // TODO: should this be made to use the builtin KeyingSets instead? - 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); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } - - // XXX todo... find a way to send notifiers from here... } } @@ -4530,9 +4434,15 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, // TODO: this should probably be done per channel instead... if (autokeyframe_cfra_can_key(scene, id)) { + KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene); + bCommonKeySrc cks; + ListBase dsources = {&cks, &cks}; float cfra= (float)CFRA; short flag= 0; - char buf[512]; + + /* init common-key-source for use by KeyingSets */ + memset(&cks, 0, sizeof(bCommonKeySrc)); + cks.id= &ob->id; /* flag is initialised from UserPref keyframing settings * - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get @@ -4551,8 +4461,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, /* clear any 'unkeyed' flag it may have */ pchan->bone->flag &= ~BONE_UNKEYED; + /* only insert into active keyingset? */ + if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) { + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra); + } /* only insert into available channels? */ - if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { + else if (IS_AUTOKEY_FLAG(INSERTAVAIL)) { if (act) { for (fcu= act->curves.first; fcu; fcu= fcu->next) insert_keyframe(id, act, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag); @@ -4585,58 +4501,34 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode, } if (doLoc) { - sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name); - 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); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location"); + + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (doRot) { - 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); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag); - } - else { - sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name); - 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); - } + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation"); + + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } if (doScale) { - 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); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scale"); + + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } } - /* insert keyframe in any channel that's appropriate */ + /* insert keyframe in all (transform) channels */ else { - sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name); - 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); - insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); - insert_keyframe(id, NULL, pchan->name, buf, 3, cfra, flag); - } - else { - sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name); - 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); - } + KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale"); - 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); - insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag); + /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */ + cks.pchan= pchan; + modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } } } @@ -4676,13 +4568,7 @@ void special_aftertrans_update(TransInfo *t) if (t->spacetype==SPACE_VIEW3D) { if (t->obedit) { if (cancelled==0) { -#if 0 // TRANSFORM_FIX_ME - EM_automerge(1); - /* when snapping, delay retopo until after automerge */ - if (G.qual & LR_CTRLKEY) { - retopo_do_all(); - } -#endif + EM_automerge(t->scene, t->obedit, 1); } } } @@ -5007,7 +4893,7 @@ void special_aftertrans_update(TransInfo *t) // allqueue(REDRAWBUTSEDIT, 0); } - else if(t->scene->basact && (ob = t->scene->basact->object) && ob->mode & OB_MODE_PARTICLE_EDIT) { + else if(t->scene->basact && (ob = t->scene->basact->object) && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, ob)) { ; } else { @@ -5030,6 +4916,7 @@ void special_aftertrans_update(TransInfo *t) if(pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; } + BLI_freelistN(&pidlist); /* pointcache refresh */ if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED)) @@ -5076,30 +4963,7 @@ static void createTransObject(bContext *C, TransInfo *t) set_trans_object_base_flags(C, t); /* count */ -#if 0 // TRANSFORM_FIX_ME - CTX_DATA_BEGIN(C, Object*, ob, selected_objects) - { - /* store ipo keys? */ - 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++; - } -// else { - t->total++; -// } - } - CTX_DATA_END; -#else t->total= CTX_DATA_COUNT(C, selected_objects); -#endif if(!t->total) { /* clear here, main transform function escapes too */ @@ -5113,92 +4977,27 @@ static void createTransObject(bContext *C, TransInfo *t) CTX_DATA_BEGIN(C, Base*, base, selected_bases) { Object *ob= base->object; - + td->flag = TD_SELECTED; td->protectflag= ob->protectflag; td->ext = tx; - + td->rotOrder= ob->rotmode; + 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; } - - /* store ipo keys? */ - // 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 - } - else { - ObjectToTransData(C, t, td, ob); - td->tdi = NULL; - td->val = NULL; - td++; - tx++; - } - } -#endif -// else { - ObjectToTransData(C, t, td, ob); - td->tdi = NULL; - td->val = NULL; - td++; - tx++; -// } + + ObjectToTransData(C, t, td, ob); + td->val = NULL; + td++; + tx++; } CTX_DATA_END; } @@ -5220,7 +5019,7 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; - td->ext= NULL; td->tdi= NULL; td->val= NULL; + td->ext= NULL; td->val= NULL; td->flag |= TD_SELECTED; td->dist= 0.0; @@ -5364,7 +5163,7 @@ void createTransData(bContext *C, TransInfo *t) { if(ob_armature->type==OB_ARMATURE) { - if(ob_armature->mode & OB_MODE_POSE) + if((ob_armature->mode & OB_MODE_POSE) && ob_armature == modifiers_isDeformedByArmature(ob)) { createTransPose(C, t, ob_armature); break; @@ -5387,6 +5186,8 @@ void createTransData(bContext *C, TransInfo *t) } else { t->flag &= ~T_PROP_EDIT; /* no proportional edit in object mode */ + t->options |= CTX_NO_PET; + createTransObject(C, t); t->flag |= T_OBJECT; @@ -5394,7 +5195,7 @@ void createTransData(bContext *C, TransInfo *t) { View3D *v3d = t->view; RegionView3D *rv3d = CTX_wm_region_view3d(C); - if((t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB) + if(rv3d && (t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB) { t->flag |= T_CAMERA; } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 36ee9b81623..66b46ab5b96 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -59,6 +59,7 @@ //#include "BIF_screen.h" //#include "BIF_mywindow.h" #include "BIF_gl.h" +#include "BIF_glutil.h" //#include "BIF_editmesh.h" //#include "BIF_editsima.h" //#include "BIF_editparticle.h" @@ -92,7 +93,7 @@ #include "ED_keyframing.h" #include "ED_markers.h" #include "ED_mesh.h" -#include "ED_retopo.h" +#include "ED_particle.h" #include "ED_screen_types.h" #include "ED_space_api.h" #include "ED_uvedit.h" @@ -265,8 +266,13 @@ static void editbmesh_apply_to_mirror(TransInfo *t) eve->co[1]= td->loc[1]; eve->co[2]= td->loc[2]; } + + if (td->flag & TD_MIRROR_EDGE) + { + td->loc[0] = 0; } } +} /* tags the given ID block for refreshes (if applicable) due to * Animation Editor editing @@ -348,7 +354,7 @@ void recalcData(TransInfo *t) if (t->obedit) { } - else if(base && base->object->mode & OB_MODE_PARTICLE_EDIT) { + else if(base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(scene, base->object)) { flushTransParticles(t); } if (t->spacetype==SPACE_NODE) { @@ -618,13 +624,31 @@ void recalcData(TransInfo *t) } } } - else if (t->obedit) { + else if (t->spacetype == SPACE_IMAGE) { + if (t->obedit && t->obedit->type == OB_MESH) { + SpaceImage *sima= t->sa->spacedata.first; + + flushTransUVs(t); + if(sima->flag & SI_LIVE_UNWRAP) + ED_uvedit_live_unwrap_re_solve(); + + DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); + } + } + else if (t->spacetype == SPACE_VIEW3D) { + + /* project */ + if(t->state != TRANS_CANCEL) { + applyProject(t); + } + + if (t->obedit) { if ELEM(t->obedit->type, OB_CURVE, OB_SURF) { Curve *cu= t->obedit->data; Nurb *nu= cu->editnurb->first; - + DAG_id_flush_update(t->obedit->data, 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 */ @@ -637,8 +661,6 @@ void recalcData(TransInfo *t) calchandlesNurb(nu); nu= nu->next; } - /* TRANSFORM_FIX_ME */ - // retopo_do_all(); } } else if(t->obedit->type==OB_LATTICE) { @@ -648,23 +670,9 @@ void recalcData(TransInfo *t) if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt); } else if (t->obedit->type == OB_MESH) { - if(t->spacetype==SPACE_IMAGE) { - SpaceImage *sima= t->sa->spacedata.first; - - flushTransUVs(t); - if(sima->flag & SI_LIVE_UNWRAP) - ED_uvedit_live_unwrap_re_solve(); - - DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); - } else { BMEditMesh *em = ((Mesh*)t->obedit->data)->edit_btmesh; /* mirror modifier clipping? */ if(t->state != TRANS_CANCEL) { - /* TRANSFORM_FIX_ME */ -// if ((G.qual & LR_CTRLKEY)==0) { -// /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */ -// retopo_do_all(); -// } clipMirrorModifier(t, t->obedit); } if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR)) @@ -675,17 +683,16 @@ void recalcData(TransInfo *t) EDBM_RecalcNormals(em); BMEdit_RecalcTesselation(em); } - } else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */ bArmature *arm= t->obedit->data; ListBase *edbo = arm->edbo; 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){ @@ -698,7 +705,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) { @@ -718,8 +725,8 @@ void recalcData(TransInfo *t) ebo->oldlength= ebo->length; } } - - + + if (t->mode != TFM_BONE_ROLL) { /* fix roll */ @@ -729,10 +736,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); @@ -744,15 +751,15 @@ void recalcData(TransInfo *t) { Mat3MulVecfl(t->mat, up_axis); } - + ebo->roll = ED_rollBoneToVector(ebo, up_axis); } } } - + if(arm->flag & ARM_MIRROR_EDIT) transform_armature_mirror_update(t->obedit); - + } else DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA); /* sets recalc flags */ @@ -760,7 +767,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) @@ -772,7 +779,7 @@ void recalcData(TransInfo *t) animrecord_check_state(t->scene, &ob->id, t->animtimer); 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_id_flush_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */ @@ -783,13 +790,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, @@ -802,7 +809,7 @@ 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; @@ -810,11 +817,11 @@ void recalcData(TransInfo *t) group_tag_recalc(ob->proxy_group->dup_group); } } - - /* update shaded drawmode while transform */ - if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED) + + if(((View3D*)t->view)->drawtype == OB_SHADED) reshadeall_displist(t->scene); } +} void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) { @@ -936,7 +943,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) 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")) + if (op && RNA_struct_find_property(op->ptr, "constraint_orientation") && RNA_property_is_set(op->ptr, "constraint_orientation")) { t->current_orientation = RNA_enum_get(op->ptr, "constraint_orientation"); @@ -970,20 +977,24 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) if (RNA_boolean_get(op->ptr, "mirror")) { t->flag |= T_MIRROR; + t->mirror = 1; } } // Need stuff to take it from edit mesh or whatnot here else { - if (t->obedit && t->obedit->type == OB_MESH && ts->editbutflag & B_MESH_X_MIRROR) + if (t->obedit && t->obedit->type == OB_MESH && (((Mesh *)t->obedit->data)->editflag & ME_EDIT_MIRROR_X)) { t->flag |= T_MIRROR; + t->mirror = 1; } } - /* setting PET flag */ - if (op && RNA_struct_find_property(op->ptr, "proportional") && RNA_property_is_set(op->ptr, "proportional")) + /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */ + if (op && RNA_struct_find_property(op->ptr, "proportional")) { + if (RNA_property_is_set(op->ptr, "proportional")) + { switch(RNA_enum_get(op->ptr, "proportional")) { case 2: /* XXX connected constant */ @@ -995,10 +1006,10 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) } else { - if ((t->options & CTX_NO_PET) == 0 && (ts->proportional)) { + if ((t->options & CTX_NO_PET) == 0 && (ts->proportional != PROP_EDIT_OFF)) { t->flag |= T_PROP_EDIT; - if(ts->proportional == 2) + if(ts->proportional == PROP_EDIT_CONNECTED) t->flag |= T_PROP_CONNECTED; // yes i know, has to become define } } @@ -1012,6 +1023,13 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->prop_size = ts->proportional_size; } + + /* TRANSFORM_FIX_ME rna restrictions */ + if (t->prop_size <= 0) + { + t->prop_size = 1.0f; + } + 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"); @@ -1020,13 +1038,13 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) { t->prop_mode = ts->prop_mode; } - - /* TRANSFORM_FIX_ME rna restrictions */ - if (t->prop_size <= 0) + } + else /* add not pet option to context when not available */ { - t->prop_size = 1.0f; + t->options |= CTX_NO_PET; } + setTransformViewMatrices(t); initNumInput(&t->num); initNDofInput(&t->ndof); @@ -1050,8 +1068,8 @@ 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); } @@ -1067,8 +1085,16 @@ void postTrans (TransInfo *t) if(sima->flag & SI_LIVE_UNWRAP) ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL); } - else if(ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { - if (t->customData) + + if (t->mouse.data) + { + MEM_freeN(t->mouse.data); + } + + if (t->customFree) { + t->customFree(t); + } + else if (t->customData) { MEM_freeN(t->customData); }} @@ -1088,16 +1114,6 @@ void applyTransObjects(TransInfo *t) recalcData(t); } -/* helper for below */ -static void restore_ipokey(float *poin, float *old) -{ - if(poin) { - poin[0]= old[0]; - poin[-3]= old[3]; - poin[3]= old[6]; - } -} - static void restoreElement(TransData *td) { /* TransData for crease has no loc */ if (td->loc) { @@ -1113,34 +1129,16 @@ static void restoreElement(TransData *td) { if (td->ext->size) { VECCOPY(td->ext->size, td->ext->isize); } - if(td->flag & TD_USEQUAT) { if (td->ext->quat) { QUATCOPY(td->ext->quat, td->ext->iquat); } } - } 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); - - 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); } -} void restoreTransObjects(TransInfo *t) { @@ -1322,7 +1320,7 @@ void calculateCenter(TransInfo *t) Mat4MulVecfl(ob->obmat, t->con.center); } - /* voor panning from cameraview */ + /* for panning from cameraview */ if(t->flag & T_OBJECT) { if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW) @@ -1384,6 +1382,12 @@ void calculatePropRatio(TransInfo *t) if (td->flag & TD_SELECTED) { td->factor = 1.0f; } + else if (t->flag & T_MIRROR && td->loc[0] * t->mirror < -0.00001f) + { + td->flag |= TD_SKIP; + td->factor = 0.0f; + restoreElement(td); + } else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) || diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 6bd0a8c8d42..83d4a314057 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -34,7 +34,7 @@ #include "transform.h" - +#include "MEM_guardedalloc.h" /* ************************** INPUT FROM MOUSE *************************** */ @@ -163,6 +163,47 @@ void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, short mval[2], float ou output[0] = Inpf(t->viewinv[1], vec) * 2.0f; } +void setCustomPoints(TransInfo *t, MouseInput *mi, short start[2], short end[2]) +{ + short *data = mi->data; + + data[0] = start[0]; + data[1] = start[1]; + data[2] = end[0]; + data[3] = end[1]; +} + +void InputCustomRatio(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) +{ + float length; + float distance; + short *data = mi->data; + short dx, dy; + + dx = data[2] - data[0]; + dy = data[3] - data[1]; + + length = (float)sqrtf(dx*dx + dy*dy); + + if (mi->precision) { + /* deal with Shift key by adding motion / 10 to motion before shift press */ + short mdx, mdy; + mdx = (mi->precision_mval[0] + (float)(mval[0] - mi->precision_mval[0]) / 10.0f) - data[2]; + mdy = (mi->precision_mval[1] + (float)(mval[1] - mi->precision_mval[1]) / 10.0f) - data[3]; + + distance = (mdx*dx + mdy*dy) / length; + } + else { + short mdx, mdy; + mdx = mval[0] - data[2]; + mdy = mval[1] - data[3]; + + distance = (mdx*dx + mdy*dy) / length; + } + + output[0] = distance / length; +} + void InputAngle(TransInfo *t, MouseInput *mi, short mval[2], float output[3]) { double dx2 = mval[0] - mi->center[0]; @@ -291,6 +332,11 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode) mi->apply = InputVerticalAbsolute; t->helpline = HLP_VARROW; break; + case INPUT_CUSTOM_RATIO: + mi->apply = InputCustomRatio; + t->helpline = HLP_NONE; + mi->data = MEM_callocN(sizeof(short) * 4, "custom points"); + break; case INPUT_NONE: default: mi->apply = NULL; diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 664627f1e15..19881c7bc5b 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -415,6 +415,9 @@ int calc_manipulator_stats(const bContext *C) if(ob && totsel) { switch(v3d->twmode) { + + case V3D_MANIP_GLOBAL: + break; /* nothing to do */ case V3D_MANIP_NORMAL: if(obedit || ob->mode & OB_MODE_POSE) { @@ -476,8 +479,12 @@ int calc_manipulator_stats(const bContext *C) } break; default: /* V3D_MANIP_CUSTOM */ - // XXX applyTransformOrientation(C, t); - break; + { + float mat[3][3]; + applyTransformOrientation(C, mat, NULL); + Mat4CpyMat3(rv3d->twmat, mat); + break; + } } } @@ -1605,7 +1612,7 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op) break; } RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); - WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr); + WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_DEFAULT, op->ptr); } else if (drawflags & MAN_SCALE_C) { switch(drawflags) { @@ -1635,10 +1642,10 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op) break; } 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); + WM_operator_name_call(C, "TFM_OT_resize", WM_OP_INVOKE_DEFAULT, op->ptr); } 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); + WM_operator_name_call(C, "TFM_OT_trackball", WM_OP_INVOKE_DEFAULT, op->ptr); } else if (drawflags & MAN_ROT_C) { switch(drawflags) { @@ -1653,7 +1660,7 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op) break; } RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis); - WM_operator_name_call(C, "TFM_OT_rotate", WM_OP_INVOKE_REGION_WIN, op->ptr); + WM_operator_name_call(C, "TFM_OT_rotate", WM_OP_INVOKE_DEFAULT, op->ptr); } } /* after transform, restore drawflags */ diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 758b89d2e92..fe8e5b34b54 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -55,40 +55,6 @@ typedef struct TransformModeItem static float VecOne[3] = {1, 1, 1}; -/* need constants for this */ -EnumPropertyItem proportional_mode_types[] = { - {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", 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", 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_translate"; char OP_ROTATION[] = "TFM_OT_rotate"; char OP_TOSPHERE[] = "TFM_OT_tosphere"; @@ -99,6 +65,7 @@ char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten"; char OP_TILT[] = "TFM_OT_tilt"; char OP_TRACKBALL[] = "TFM_OT_trackball"; char OP_MIRROR[] = "TFM_OT_mirror"; +char OP_EDGE_SLIDE[] = "TFM_OT_edge_slide"; TransformModeItem transform_modes[] = @@ -113,6 +80,7 @@ TransformModeItem transform_modes[] = {OP_TILT, TFM_TILT}, {OP_TRACKBALL, TFM_TRACKBALL}, {OP_MIRROR, TFM_MIRROR}, + {OP_EDGE_SLIDE, TFM_EDGE_SLIDE}, {NULL, 0} }; @@ -121,6 +89,8 @@ static int select_orientation_exec(bContext *C, wmOperator *op) int orientation = RNA_enum_get(op->ptr, "orientation"); BIF_selectTransformOrientationValue(C, orientation); + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); return OPERATOR_FINISHED; } @@ -138,28 +108,111 @@ static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event 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) { PropertyRNA *prop; /* identifiers */ ot->name = "Select Orientation"; - ot->description= "Select orientation type."; + ot->description= "Select transformation orientation."; ot->idname = "TFM_OT_select_orientation"; + ot->flag = OPTYPE_UNDO; /* api callbacks */ ot->invoke = select_orientation_invoke; ot->exec = select_orientation_exec; ot->poll = ED_operator_areaactive; - prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); - RNA_def_enum_funcs(prop, select_orientation_itemf); + prop= RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE); + RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation."); + RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf); +} + + +static int delete_orientation_exec(bContext *C, wmOperator *op) +{ + View3D *v3d = CTX_wm_view3d(C); + int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + + BIF_removeTransformOrientationIndex(C, selected_index); + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + + return OPERATOR_FINISHED; +} + +static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return delete_orientation_exec(C, op); +} + +static int delete_orientation_poll(bContext *C) +{ + int selected_index = -1; + View3D *v3d = CTX_wm_view3d(C); + + if (ED_operator_areaactive(C) == 0) + return 0; + + + if(v3d) { + selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + } + + return selected_index >= 0; +} + +void TFM_OT_delete_orientation(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Delete Orientation"; + ot->description= "Delete transformation orientation."; + ot->idname = "TFM_OT_delete_orientation"; + ot->flag = OPTYPE_UNDO; + + /* api callbacks */ + ot->invoke = delete_orientation_invoke; + ot->exec = delete_orientation_exec; + ot->poll = delete_orientation_poll; +} + +static int create_orientation_exec(bContext *C, wmOperator *op) +{ + char name[36]; + int use = RNA_boolean_get(op->ptr, "use"); + int overwrite = RNA_boolean_get(op->ptr, "overwrite"); + + RNA_string_get(op->ptr, "name", name); + + BIF_createTransformOrientation(C, op->reports, name, use, overwrite); + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + + return OPERATOR_FINISHED; +} + +static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return create_orientation_exec(C, op); +} + +void TFM_OT_create_orientation(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Create Orientation"; + ot->description= "Create transformation orientation from selection."; + ot->idname = "TFM_OT_create_orientation"; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->invoke = create_orientation_invoke; + ot->exec = create_orientation_exec; + ot->poll = ED_operator_areaactive; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_string(ot->srna, "name", "", 35, "Name", "Text to insert at the cursor position."); + RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation"); + RNA_def_boolean(ot->srna, "overwrite", 0, "Overwrite previous", "Overwrite previously created orientation with same name"); } static void transformops_exit(bContext *C, wmOperator *op) @@ -270,7 +323,7 @@ static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event) TransInfo *t = op->customdata; /* add temp handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); t->flag |= T_MODAL; // XXX meh maybe somewhere else @@ -280,15 +333,15 @@ static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event) void Properties_Proportional(struct wmOperatorType *ot) { - RNA_def_enum(ot->srna, "proportional", proportional_mode_types, 0, "Proportional Editing", ""); - RNA_def_enum(ot->srna, "proportional_editing_falloff", prop_mode_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode."); + RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", ""); + RNA_def_enum(ot->srna, "proportional_editing_falloff", proportional_falloff_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode."); RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100); } 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_enum(ot->srna, "snap_mode", snap_mode_items, 0, "Mode", ""); RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX); if (align) @@ -303,8 +356,9 @@ void Properties_Constraints(struct wmOperatorType *ot) PropertyRNA *prop; RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", ""); - prop= RNA_def_enum(ot->srna, "constraint_orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); - RNA_def_enum_funcs(prop, select_orientation_itemf); + prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE); + RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation."); + RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf); } void TFM_OT_translate(struct wmOperatorType *ot) @@ -523,7 +577,7 @@ void TFM_OT_tosphere(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_areaactive; - RNA_def_float_percentage(ot->srna, "value", 0, 0, 1, "Percentage", "", 0, 1); + RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1); Properties_Proportional(ot); @@ -549,6 +603,26 @@ void TFM_OT_mirror(struct wmOperatorType *ot) Properties_Constraints(ot); } +void TFM_OT_edge_slide(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Edge Slide"; + ot->description= "Slide an edge loop along a mesh."; + ot->idname = OP_EDGE_SLIDE; + 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_editmesh; + + RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f); + + RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); +} + void TFM_OT_transform(struct wmOperatorType *ot) { static EnumPropertyItem transform_mode_types[] = { @@ -578,6 +652,7 @@ void TFM_OT_transform(struct wmOperatorType *ot) {TFM_BEVEL, "BEVEL", 0, "Bevel", ""}, {TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""}, {TFM_ALIGN, "ALIGN", 0, "Align", ""}, + {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""}, {0, NULL, 0, NULL, NULL} }; @@ -617,16 +692,19 @@ void transform_operatortypes(void) WM_operatortype_append(TFM_OT_tilt); WM_operatortype_append(TFM_OT_trackball); WM_operatortype_append(TFM_OT_mirror); + WM_operatortype_append(TFM_OT_edge_slide); WM_operatortype_append(TFM_OT_select_orientation); + WM_operatortype_append(TFM_OT_create_orientation); + WM_operatortype_append(TFM_OT_delete_orientation); } -void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid) +void transform_keymap_for_space(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int spaceid) { - wmKeymapItem *km; + wmKeyMapItem *km; /* transform.c, only adds modal map once, checks if it's there */ - transform_modal_keymap(wm); + transform_modal_keymap(keyconf); switch(spaceid) { @@ -651,6 +729,11 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key km = WM_keymap_add_item(keymap, "TFM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0); + km = WM_keymap_add_item(keymap, "TFM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); + RNA_boolean_set(km->ptr, "use", 1); + + km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0); + break; case SPACE_ACTION: km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0); @@ -721,7 +804,7 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0); - km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, 0, 0); + km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0); break; default: break; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index e73afa919b3..bad744d101b 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -23,6 +23,7 @@ */ #include <string.h> +#include <ctype.h> #include "MEM_guardedalloc.h" @@ -44,6 +45,7 @@ #include "BKE_armature.h" #include "BKE_context.h" #include "BKE_tessmesh.h" +#include "BKE_report.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -68,108 +70,131 @@ void BIF_clearTransformOrientation(bContext *C) { + View3D *v3d = CTX_wm_view3d(C); + ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; BLI_freelistN(transform_spaces); - // TRANSFORM_FIX_ME // Need to loop over all view3d -// if (G.vd->twmode >= V3D_MANIP_CUSTOM) -// G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + if(v3d && v3d->twmode >= V3D_MANIP_CUSTOM) { + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ +} } -void BIF_manageTransformOrientation(bContext *C, int confirm, int set) { +TransformOrientation* findOrientationName(bContext *C, char *name) +{ + ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; + TransformOrientation *ts= NULL; + + for (ts = transform_spaces->first; ts; ts = ts->next) { + if (strncmp(ts->name, name, 35) == 0) { + return ts; + } + } + + return NULL; +} + +void uniqueOrientationName(bContext *C, char *name) +{ + if (findOrientationName(C, name) != NULL) + { + char tempname[64]; + int number; + char *dot; + + + number = strlen(name); + + if (number && isdigit(name[number-1])) + { + dot = strrchr(name, '.'); // last occurrence + if (dot) + *dot=0; + } + + for (number = 1; number <= 999; number++) + { + sprintf(tempname, "%s.%03d", name, number); + if (findOrientationName(C, tempname) == NULL) + { + BLI_strncpy(name, tempname, 32); + break; + } + } + } +} + +void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name, int use, int overwrite) +{ Object *obedit = CTX_data_edit_object(C); Object *ob = CTX_data_active_object(C); - int index = -1; + TransformOrientation *ts = NULL; if (obedit) { if (obedit->type == OB_MESH) - index = manageMeshSpace(C, confirm, set); + ts = createMeshSpace(C, reports, name, overwrite); else if (obedit->type == OB_ARMATURE) - index = manageBoneSpace(C, confirm, set); + ts = createBoneSpace(C, reports, name, overwrite); } else if (ob && (ob->mode & OB_MODE_POSE)) { - index = manageBoneSpace(C, confirm, set); + ts = createBoneSpace(C, reports, name, overwrite); } else { - index = manageObjectSpace(C, confirm, set); + ts = createObjectSpace(C, reports, name, overwrite); } - if (set && index != -1) + if (use && ts != NULL) { - BIF_selectTransformOrientationValue(C, V3D_MANIP_CUSTOM + index); + BIF_selectTransformOrientation(C, ts); } } -int manageObjectSpace(bContext *C, int confirm, int set) { +TransformOrientation *createObjectSpace(bContext *C, ReportList *reports, char *name, int overwrite) { Base *base = CTX_data_active_base(C); + Object *ob; + float mat[3][3]; if (base == NULL) - return -1; - -//XXX if (confirm == 0) { -// if (set && pupmenu("Custom Orientation %t|Add and Use Active Object%x1") != 1) { -// return -1; -// } -// else if (set == 0 && pupmenu("Custom Orientation %t|Add Active Object%x1") != 1) { -// return -1; -// } -// } - - return addObjectSpace(C, base->object); -} + return NULL; + + + ob = base->object; + + Mat3CpyMat4(mat, ob->obmat); + Mat3Ortho(mat); -/* return 1 on confirm */ -int confirmSpace(int set, char text[]) + /* use object name if no name is given */ + if (name[0] == 0) { - char menu[64]; - - if (set) { - sprintf(menu, "Custom Orientation %%t|Add and Use %s%%x1", text); - } - else { - sprintf(menu, "Custom Orientation %%t|Add %s%%x1", text); + strncpy(name, ob->id.name+2, 35); } -//XXX if (pupmenu(menu) == 1) { - return 1; -// } -// else { -// return 0; -// } + return addMatrixSpace(C, mat, name, overwrite); } -int manageBoneSpace(bContext *C, int confirm, int set) { +TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) { float mat[3][3]; float normal[3], plane[3]; - char name[36] = ""; - int index; getTransformOrientation(C, normal, plane, 0); - if (confirm == 0 && confirmSpace(set, "Bone") == 0) { - return -1; - } - if (createSpaceNormalTangent(mat, normal, plane) == 0) { -//XXX error("Cannot use zero-length bone"); - return -1; + BKE_reports_prepend(reports, "Cannot use zero-length bone"); + return NULL; } + if (name[0] == 0) + { strcpy(name, "Bone"); + } - /* Input name */ -//XXX sbutton(name, 1, 35, "name: "); - - index = addMatrixSpace(C, mat, name); - return index; + return addMatrixSpace(C, mat, name, overwrite); } -int manageMeshSpace(bContext *C, int confirm, int set) { +TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) { float mat[3][3]; float normal[3], plane[3]; - char name[36] = ""; - int index; int type; type = getTransformOrientation(C, normal, plane, 0); @@ -177,51 +202,44 @@ int manageMeshSpace(bContext *C, int confirm, int set) { switch (type) { case ORIENTATION_VERT: - if (confirm == 0 && confirmSpace(set, "vertex") == 0) { - return -1; - } - if (createSpaceNormal(mat, normal) == 0) { -// XXX error("Cannot use vertex with zero-length normal"); - return -1; + BKE_reports_prepend(reports, "Cannot use vertex with zero-length normal"); + return NULL; } + if (name[0] == 0) + { strcpy(name, "Vertex"); + } break; case ORIENTATION_EDGE: - if (confirm == 0 && confirmSpace(set, "Edge") == 0) { - return -1; - } - if (createSpaceNormalTangent(mat, normal, plane) == 0) { -// XXX error("Cannot use zero-length edge"); - return -1; + BKE_reports_prepend(reports, "Cannot use zero-length edge"); + return NULL; } + if (name[0] == 0) + { strcpy(name, "Edge"); + } break; case ORIENTATION_FACE: - if (confirm == 0 && confirmSpace(set, "Face") == 0) { - return -1; - } - if (createSpaceNormalTangent(mat, normal, plane) == 0) { -// XXX error("Cannot use zero-area face"); - return -1; + BKE_reports_prepend(reports, "Cannot use zero-area face"); + return NULL; } + if (name[0] == 0) + { strcpy(name, "Face"); + } break; default: - return -1; + return NULL; break; } - /* Input name */ -//XXX sbutton(name, 1, 35, "name: "); - - index = addMatrixSpace(C, mat, name); - return index; + return addMatrixSpace(C, mat, name, overwrite); } int createSpaceNormal(float mat[3][3], float normal[3]) @@ -272,32 +290,17 @@ int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) return 1; } - -int addObjectSpace(bContext *C, Object *ob) { - float mat[3][3]; - char name[36] = ""; - - Mat3CpyMat4(mat, ob->obmat); - Mat3Ortho(mat); - - strncpy(name, ob->id.name+2, 35); - - /* Input name */ -//XXX sbutton(name, 1, 35, "name: "); - - return addMatrixSpace(C, mat, name); -} - -int addMatrixSpace(bContext *C, float mat[3][3], char name[]) { +TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - TransformOrientation *ts; - int index = 0; + TransformOrientation *ts = NULL; - /* if name is found in list, reuse that transform space */ - for (index = 0, ts = transform_spaces->first; ts; ts = ts->next, index++) { - if (strncmp(ts->name, name, 35) == 0) { - break; + if (overwrite) + { + ts = findOrientationName(C, name); } + else + { + uniqueOrientationName(C, name); } /* if not, create a new one */ @@ -311,31 +314,61 @@ int addMatrixSpace(bContext *C, float mat[3][3], char name[]) { /* copy matrix into transform space */ Mat3CpyMat3(ts->mat, mat); - ED_undo_push(C, "Add/Update Transform Orientation"); - - return index; + return ts; } void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts = transform_spaces->first; - //int selected_index = (G.vd->twmode - V3D_MANIP_CUSTOM); int i; for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) { if (ts == target) { + View3D *v3d = CTX_wm_view3d(C); + if(v3d) { + int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D -// if (selected_index == i) { -// G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ -// } -// else if (selected_index > i) -// G.vd->twmode--; + if (selected_index == i) { + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + } + else if (selected_index > i) { + v3d->twmode--; + } + + } + + BLI_freelinkN(transform_spaces, ts); + break; + } + } +} + +void BIF_removeTransformOrientationIndex(bContext *C, int index) { + ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; + TransformOrientation *ts = transform_spaces->first; + int i; + + for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) { + if (i == index) { + View3D *v3d = CTX_wm_view3d(C); + if(v3d) { + int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + + // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D + if (selected_index == i) { + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + } + else if (selected_index > i) { + v3d->twmode--; + } + + } BLI_freelinkN(transform_spaces, ts); break; } } - ED_undo_push(C, "Remove Transform Orientation"); } void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) { @@ -354,6 +387,7 @@ void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) { void BIF_selectTransformOrientationValue(bContext *C, int orientation) { View3D *v3d = CTX_wm_view3d(C); + if(v3d) /* currently using generic poll */ v3d->twmode = orientation; } @@ -433,7 +467,7 @@ int BIF_countTransformOrientation(const bContext *C) { return count; } -void applyTransformOrientation(const bContext *C, TransInfo *t) { +void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) { TransformOrientation *ts; View3D *v3d = CTX_wm_view3d(C); int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); @@ -442,8 +476,11 @@ void applyTransformOrientation(const bContext *C, TransInfo *t) { if (selected_index >= 0) { for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) { if (selected_index == i) { - strcpy(t->spacename, ts->name); - Mat3CpyMat3(t->spacemtx, ts->mat); + + if (name) + strcpy(name, ts->name); + + Mat3CpyMat3(mat, ts->mat); break; } } @@ -558,7 +595,7 @@ void initTransformOrientation(bContext *C, TransInfo *t) } break; default: /* V3D_MANIP_CUSTOM */ - applyTransformOrientation(C, t); + applyTransformOrientation(C, t->spacemtx, t->spacename); break; } } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 575e8f2150a..a2a7577c8d6 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -117,7 +117,7 @@ int BIF_snappingSupported(Object *obedit) { int status = 0; - if (obedit == NULL || ELEM(obedit->type, OB_MESH, OB_ARMATURE)) /* only support object mesh or armature */ + if (obedit == NULL || ELEM3(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE)) /* only support object mesh, armature, curves */ { status = 1; } @@ -219,8 +219,69 @@ int handleSnapping(TransInfo *t, wmEvent *event) return status; } +void applyProject(TransInfo *t) +{ + /* XXX FLICKER IN OBJECT MODE */ + if ((t->tsnap.project) && (t->tsnap.status & SNAP_ON) && (t->modifiers & MOD_SNAP_GEARS)) + { + TransData *td = t->data; + float tvec[3]; + float imat[4][4]; + int i; + + if(t->flag & (T_EDIT|T_POSE)) { + Object *ob = t->obedit?t->obedit:t->poseobj; + Mat4Invert(imat, ob->obmat); + } + + for(i = 0 ; i < t->total; i++, td++) { + float iloc[3], loc[3], no[3]; + float mval[2]; + int dist = 1000; + + if (td->flag & TD_NOACTION) + break; + + if (td->flag & TD_SKIP) + continue; + + VECCOPY(iloc, td->loc); + if (t->flag & (T_EDIT|T_POSE)) + { + Object *ob = t->obedit?t->obedit:t->poseobj; + Mat4MulVecfl(ob->obmat, iloc); + } + else if (t->flag & T_OBJECT) + { + VECCOPY(iloc, td->ob->obmat[3]); + } + + project_float(t->ar, iloc, mval); + + if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode)) + { +// if(t->flag & (T_EDIT|T_POSE)) { +// Mat4MulVecfl(imat, loc); +// } +// + VecSubf(tvec, loc, iloc); + + Mat3MulVecfl(td->smtx, tvec); + + VecAddf(td->loc, td->loc, tvec); + } + + //XXX constraintTransLim(t, td); + } + } +} + void applySnapping(TransInfo *t, float *vec) { + /* project is not applied this way */ + if (t->tsnap.project) + return; + if (t->tsnap.status & SNAP_FORCED) { t->tsnap.targetSnap(t); @@ -307,12 +368,24 @@ void initSnapping(TransInfo *t, wmOperator *op) RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal); Normalize(t->tsnap.snapNormal); } + + if (RNA_struct_find_property(op->ptr, "snap_project")) + { + t->tsnap.project = RNA_boolean_get(op->ptr, "snap_project"); } } + } else { snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP); t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE); + t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT); + } + + /* force project off when not supported */ + if (ts->snap_mode != SCE_SNAP_MODE_FACE) + { + t->tsnap.project = 0; } if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV @@ -322,7 +395,7 @@ void initSnapping(TransInfo *t, wmOperator *op) /* Edit mode */ if (t->tsnap.applySnap != NULL && // A snapping function actually exist (snapping) && // Only if the snap flag is on - (obedit != NULL && ELEM(obedit->type, OB_MESH, OB_ARMATURE)) ) // Temporary limited to edit mode meshes or armature + (obedit != NULL && ELEM3(obedit->type, OB_MESH, OB_ARMATURE, OB_CURVE)) ) // Temporary limited to edit mode meshes, armature, curves { t->tsnap.status |= SNAP_ON; t->tsnap.modePoint = SNAP_GEO; @@ -539,9 +612,12 @@ void CalcSnapGeometry(TransInfo *t, float *vec) { float loc[3]; float no[3]; + float mval[2]; int found = 0; int dist = SNAP_MIN_DISTANCE; // Use a user defined value here - SnapMode mode; + + mval[0] = t->mval[0]; + mval[1] = t->mval[1]; if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME) { @@ -553,7 +629,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec) depth_peels.first = depth_peels.last = NULL; - peelObjectsTransForm(t, &depth_peels, t->mval); + peelObjectsTransForm(t, &depth_peels, mval); // if (LAST_SNAP_POINT_VALID) // { @@ -636,18 +712,9 @@ void CalcSnapGeometry(TransInfo *t, float *vec) } else { - if (t->obedit == NULL) - { - mode = SNAP_NOT_SELECTED; - } - else - { - mode = SNAP_NOT_OBEDIT; + found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode); } - found = snapObjectsTransform(t, t->mval, &dist, loc, no, mode); - } - if (found == 1) { float tangent[3]; @@ -866,7 +933,7 @@ void TargetSnapClosest(TransInfo *t) } /*================================================================*/ -int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) { float lambda; int result; @@ -897,7 +964,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4 new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); if (new_dist <= *dist && new_depth < *depth) { @@ -917,7 +984,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4 return retval; } -int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) { float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3]; int result; @@ -965,7 +1032,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); /* 10% threshold if edge is closer but a bit further * this takes care of series of connected edges a bit slanted w.r.t the viewport @@ -1002,7 +1069,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n return retval; } -int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) +int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth) { int retval = 0; float dvec[3]; @@ -1023,7 +1090,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray new_depth = VecLenf(location, ray_start); project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]); + new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); if (new_dist <= *dist && new_depth < *depth) { @@ -1046,7 +1113,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray return retval; } -int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth) +int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth) { float imat[4][4]; float ray_start_local[3], ray_normal_local[3]; @@ -1358,7 +1425,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, B return retval; } -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) +int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth) { ToolSettings *ts= scene->toolsettings; int retval = 0; @@ -1390,7 +1457,7 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma return retval; } -int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mval[2], int *dist, float *loc, float *no, SnapMode mode) { +int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { Base *base; float depth = FLT_MAX; int retval = 0; @@ -1407,7 +1474,7 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv base= FIRSTBASE; for ( base = FIRSTBASE; base != NULL; base = base->next ) { - if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (mode == SNAP_NOT_OBEDIT && base != BASACT)) ) { + if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != BASACT)) ) { Object *ob = base->object; if (ob->transflag & OB_DUPLI) @@ -1432,12 +1499,12 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv return retval; } -int snapObjectsTransform(TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode) +int snapObjectsTransform(TransInfo *t, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { return snapObjects(t->scene, t->view, t->ar, t->obedit, mval, dist, loc, no, mode); } -int snapObjectsContext(bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode) +int snapObjectsContext(bContext *C, float mval[2], int *dist, float *loc, float *no, SnapMode mode) { ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; @@ -1502,7 +1569,7 @@ void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], O peel->flag = 0; } -int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], ListBase *depth_peels) +int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], ListBase *depth_peels) { int retval = 0; int totvert = dm->getNumVerts(dm); @@ -1610,7 +1677,7 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta return retval; } -int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, short mval[2]) +int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, float mval[2]) { Base *base; int retval = 0; @@ -1693,12 +1760,12 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase return retval; } -int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, short mval[2]) +int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, float mval[2]) { return peelObjects(t->scene, t->view, t->ar, t->obedit, depth_peels, mval); } -int peelObjectsContext(bContext *C, ListBase *depth_peels, short mval[2]) +int peelObjectsContext(bContext *C, ListBase *depth_peels, float mval[2]) { ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; |