diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-07-26 15:15:22 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-07-26 15:15:22 +0400 |
commit | 5dc3cfc983da11ead73c079096cd21e9592ce612 (patch) | |
tree | 8201441aef3795df1ed756aa69eec5f3b2ea8708 /source/blender | |
parent | 7c58ec9337761291f9489996f2e9d630b0f6ad4e (diff) |
fix [#36282] Spin error with non uniform scale
add support for passing object matrix to bmesh transform operators.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenlib/BLI_math_matrix.h | 17 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_matrix.c | 28 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 5 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_dupe.c | 12 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_utils.c | 14 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_extrude.c | 33 |
6 files changed, 63 insertions, 46 deletions
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 1d877be67bd..a4b0f449dc3 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -133,12 +133,12 @@ void normalize_m4_m4(float R[4][4], float A[4][4]); void orthogonalize_m3(float R[3][3], int axis); void orthogonalize_m4(float R[4][4], int axis); -int is_orthogonal_m3(float mat[3][3]); -int is_orthogonal_m4(float mat[4][4]); -int is_orthonormal_m3(float mat[3][3]); -int is_orthonormal_m4(float mat[4][4]); +bool is_orthogonal_m3(float mat[3][3]); +bool is_orthogonal_m4(float mat[4][4]); +bool is_orthonormal_m3(float mat[3][3]); +bool is_orthonormal_m4(float mat[4][4]); -int is_uniform_scaled_m3(float mat[3][3]); +bool is_uniform_scaled_m3(float mat[3][3]); void adjoint_m2_m2(float R[2][2], float A[2][2]); void adjoint_m3_m3(float R[3][3], float A[3][3]); @@ -194,8 +194,11 @@ void loc_axisangle_size_to_mat4(float R[4][4], void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t); void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t); -int is_negative_m3(float mat[3][3]); -int is_negative_m4(float mat[4][4]); +bool is_negative_m3(float mat[3][3]); +bool is_negative_m4(float mat[4][4]); + +bool is_zero_m3(float mat[3][3]); +bool is_zero_m4(float mat[4][4]); /*********************************** Other ***********************************/ diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 3f635f97ec0..8565698110e 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -930,7 +930,7 @@ void orthogonalize_m4(float mat[4][4], int axis) mul_v3_fl(mat[2], size[2]); } -int is_orthogonal_m3(float m[3][3]) +bool is_orthogonal_m3(float m[3][3]) { int i, j; @@ -944,7 +944,7 @@ int is_orthogonal_m3(float m[3][3]) return 1; } -int is_orthogonal_m4(float m[4][4]) +bool is_orthogonal_m4(float m[4][4]) { int i, j; @@ -959,7 +959,7 @@ int is_orthogonal_m4(float m[4][4]) return 1; } -int is_orthonormal_m3(float m[3][3]) +bool is_orthonormal_m3(float m[3][3]) { if (is_orthogonal_m3(m)) { int i; @@ -974,7 +974,7 @@ int is_orthonormal_m3(float m[3][3]) return 0; } -int is_orthonormal_m4(float m[4][4]) +bool is_orthonormal_m4(float m[4][4]) { if (is_orthogonal_m4(m)) { int i; @@ -989,7 +989,7 @@ int is_orthonormal_m4(float m[4][4]) return 0; } -int is_uniform_scaled_m3(float m[3][3]) +bool is_uniform_scaled_m3(float m[3][3]) { const float eps = 1e-7; float t[3][3]; @@ -1434,20 +1434,34 @@ void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const floa loc_quat_size_to_mat4(out, floc, fquat, fsize); } -int is_negative_m3(float mat[3][3]) +bool is_negative_m3(float mat[3][3]) { float vec[3]; cross_v3_v3v3(vec, mat[0], mat[1]); return (dot_v3v3(vec, mat[2]) < 0.0f); } -int is_negative_m4(float mat[4][4]) +bool is_negative_m4(float mat[4][4]) { float vec[3]; cross_v3_v3v3(vec, mat[0], mat[1]); return (dot_v3v3(vec, mat[2]) < 0.0f); } +bool is_zero_m3(float mat[3][3]) +{ + return (is_zero_v3(mat[0]) && + is_zero_v3(mat[1]) && + is_zero_v3(mat[2])); +} +bool is_zero_m4(float mat[4][4]) +{ + return (is_zero_v4(mat[0]) && + is_zero_v4(mat[1]) && + is_zero_v4(mat[2]) && + is_zero_v4(mat[3])); +} + /* make a 4x4 matrix out of 3 transform components */ /* matrices are made in the order: scale * rot * loc */ /* TODO: need to have a version that allows for rotation order... */ diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 451d4a37a00..b56ed15b901 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -663,6 +663,7 @@ static BMOpDefine bmo_rotate_def = { {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */ {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining rotation */ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -679,6 +680,7 @@ static BMOpDefine bmo_translate_def = { "translate", /* slots_in */ {{"vec", BMO_OP_SLOT_VEC}, /* translation offset */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, @@ -696,6 +698,7 @@ static BMOpDefine bmo_scale_def = { "scale", /* slots_in */ {{"vec", BMO_OP_SLOT_VEC}, /* scale factor */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, @@ -715,6 +718,7 @@ static BMOpDefine bmo_transform_def = { "transform", /* slots_in */ {{"matrix", BMO_OP_SLOT_MAT}, /* transform matrix */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, @@ -1159,6 +1163,7 @@ static BMOpDefine bmo_spin_def = { {"axis", BMO_OP_SLOT_VEC}, /* rotation axis */ {"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */ {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */ + {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"steps", BMO_OP_SLOT_INT}, /* number of steps */ {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */ {{'\0'}}, diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index 48103969474..59e018eccf1 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -489,8 +489,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) BMO_op_initf(bm, &dupop, op->flag, "duplicate geom=%S", op, "geom_last.out"); BMO_op_exec(bm, &dupop); BMO_op_callf(bm, op->flag, - "rotate cent=%v matrix=%m3 verts=%S", - cent, rmat, &dupop, "geom.out"); + "rotate cent=%v matrix=%m3 space=%s verts=%S", + cent, rmat, op, "space", &dupop, "geom.out"); BMO_slot_copy(&dupop, slots_out, "geom.out", op, slots_out, "geom_last.out"); BMO_op_finish(bm, &dupop); @@ -500,8 +500,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) op, "geom_last.out"); BMO_op_exec(bm, &extop); BMO_op_callf(bm, op->flag, - "rotate cent=%v matrix=%m3 verts=%S", - cent, rmat, &extop, "geom.out"); + "rotate cent=%v matrix=%m3 space=%s verts=%S", + cent, rmat, op, "space", &extop, "geom.out"); BMO_slot_copy(&extop, slots_out, "geom.out", op, slots_out, "geom_last.out"); BMO_op_finish(bm, &extop); @@ -510,8 +510,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) if (usedvec) { mul_m3_v3(rmat, dvec); BMO_op_callf(bm, op->flag, - "translate vec=%v verts=%S", - dvec, op, "geom_last.out"); + "translate vec=%v space=%s verts=%S", + dvec, op, "space", op, "geom_last.out"); } } } diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 053e4da6e02..85bd8a85376 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -55,9 +55,15 @@ void bmo_transform_exec(BMesh *UNUSED(bm), BMOperator *op) { BMOIter iter; BMVert *v; - float mat[4][4]; + float mat[4][4], mat_space[4][4], imat_space[4][4]; BMO_slot_mat4_get(op->slots_in, "matrix", mat); + BMO_slot_mat4_get(op->slots_in, "space", mat_space); + + if (!is_zero_m4(mat_space)) { + invert_m4_m4(imat_space, mat_space); + mul_serie_m4(mat, imat_space, mat, mat_space, NULL, NULL, NULL, NULL, NULL); + } BMO_ITER (v, &iter, op->slots_in, "verts", BM_VERT) { mul_m4_v3(mat, v->co); @@ -73,7 +79,7 @@ void bmo_translate_exec(BMesh *bm, BMOperator *op) unit_m4(mat); copy_v3_v3(mat[3], vec); - BMO_op_callf(bm, op->flag, "transform matrix=%m4 verts=%s", mat, op, "verts"); + BMO_op_callf(bm, op->flag, "transform matrix=%m4 space=%s verts=%s", mat, op, "space", op, "verts"); } void bmo_scale_exec(BMesh *bm, BMOperator *op) @@ -87,7 +93,7 @@ void bmo_scale_exec(BMesh *bm, BMOperator *op) mat[1][1] = vec[1]; mat[2][2] = vec[2]; - BMO_op_callf(bm, op->flag, "transform matrix=%m3 verts=%s", mat, op, "verts"); + BMO_op_callf(bm, op->flag, "transform matrix=%m3 space=%s verts=%s", mat, op, "space", op, "verts"); } void bmo_rotate_exec(BMesh *bm, BMOperator *op) @@ -99,7 +105,7 @@ void bmo_rotate_exec(BMesh *bm, BMOperator *op) BMO_slot_mat4_get(op->slots_in, "matrix", mat); pivot_m4(mat, center); - BMO_op_callf(bm, op->flag, "transform matrix=%m4 verts=%s", mat, op, "verts"); + BMO_op_callf(bm, op->flag, "transform matrix=%m4 space=%s verts=%s", mat, op, "space", op, "verts"); } void bmo_reverse_faces_exec(BMesh *bm, BMOperator *op) diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index 65c528dbe03..b38f09b1dec 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -713,7 +713,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; BMOperator spinop; - float cent[3], axis[3], imat[3][3]; + float cent[3], axis[3]; float d[3] = {0.0f, 0.0f, 0.0f}; int steps, dupli; float angle; @@ -726,15 +726,10 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) angle = -angle; dupli = RNA_boolean_get(op->ptr, "dupli"); - /* undo object transformation */ - copy_m3_m4(imat, obedit->imat); - sub_v3_v3(cent, obedit->obmat[3]); - mul_m3_v3(imat, cent); - mul_m3_v3(imat, axis); - + /* keep the values in worldspace since we're passing the obmat */ if (!EDBM_op_init(em, &spinop, op, - "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, d, steps, angle, dupli)) + "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b", + BM_ELEM_SELECT, cent, axis, d, steps, angle, obedit->obmat, dupli)) { return OPERATOR_CANCELLED; } @@ -800,8 +795,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) BMVert *eve, *v1, *v2; BMIter iter, eiter; BMOperator spinop; - float dvec[3], nor[3], cent[3], axis[3]; - float imat[3][3]; + float dvec[3], nor[3], cent[3], axis[3], v1_co_global[3], v2_co_global[3]; int steps, turns; int valence; @@ -811,13 +805,6 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "center", cent); RNA_float_get_array(op->ptr, "axis", axis); - /* undo object transformation */ - copy_m3_m4(imat, obedit->imat); - sub_v3_v3(cent, obedit->obmat[3]); - mul_m3_v3(imat, cent); - mul_m3_v3(imat, axis); - - /* find two vertices with valence count == 1, more or less is wrong */ v1 = NULL; v2 = NULL; @@ -850,15 +837,17 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) } /* calculate dvec */ - sub_v3_v3v3(dvec, v1->co, v2->co); + mul_v3_m4v3(v1_co_global, obedit->obmat, v1->co); + mul_v3_m4v3(v2_co_global, obedit->obmat, v2->co); + sub_v3_v3v3(dvec, v1_co_global, v2_co_global); mul_v3_fl(dvec, 1.0f / steps); - if (dot_v3v3(nor, dvec) > 0.000f) + if (dot_v3v3(nor, dvec) > 0.0f) negate_v3(dvec); if (!EDBM_op_init(em, &spinop, op, - "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), false)) + "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b", + BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), obedit->obmat, false)) { return OPERATOR_CANCELLED; } |