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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-08-31 16:08:04 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-08-31 16:08:04 +0400
commit0b4dfa1fcb2e4b43923c219ed59aaf31bbf0fed9 (patch)
treeae6ad1fc9a91cb35d6bf5552b57a02f408742d90 /source/blender/editors/transform
parente5f23b4aced872f666987bf26c689abf1787bbd4 (diff)
Fix #32450: edge slide with multiple loops selected could move some loops
in the wrong direction.
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform.c60
-rw-r--r--source/blender/editors/transform/transform.h2
2 files changed, 45 insertions, 17 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index b3f012efb59..685141810fd 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4759,7 +4759,7 @@ static int createSlideVerts(TransInfo *t)
BMEditMesh *em = me->edit_btmesh;
BMesh *bm = em->bm;
BMIter iter, iter2;
- BMEdge *e, *e1 /*, *ee, *le */ /* UNUSED */;
+ BMEdge *e, *e1;
BMVert *v, *v2, *first;
BMLoop *l, *l1, *l2;
TransDataSlideVert *sv_array;
@@ -4771,9 +4771,10 @@ static int createSlideVerts(TransInfo *t)
ARegion *ar = t->ar;
float projectMat[4][4];
float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
- float start[3] = {0.0f, 0.0f, 0.0f}, dir[3], end[3] = {0.0f, 0.0f, 0.0f};
+ float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
float vec[3], vec2[3] /*, lastvec[3], size, dis=0.0, z */ /* UNUSED */;
- int numsel, i, j;
+ float dir[3], maxdist, (*loop_dir)[3], *loop_maxdist;
+ int numsel, i, j, loop_nr, l_nr;
if (t->spacetype == SPACE_VIEW3D) {
/* background mode support */
@@ -4848,6 +4849,7 @@ static int createSlideVerts(TransInfo *t)
}
sv_array = MEM_callocN(sizeof(TransDataSlideVert) * j, "sv_array");
+ loop_nr = 0;
j = 0;
while (1) {
@@ -4910,6 +4912,8 @@ static int createSlideVerts(TransInfo *t)
sv->v = v;
sv->origvert = *v;
+ sv->loop_nr = loop_nr;
+
copy_v3_v3(sv->upvec, vec);
if (l2)
copy_v3_v3(sv->downvec, vec2);
@@ -4932,6 +4936,7 @@ static int createSlideVerts(TransInfo *t)
sv = sv_array + j + 1;
sv->v = v;
sv->origvert = *v;
+ sv->loop_nr = loop_nr;
l = BM_face_other_edge_loop(l1->f, l1->e, v);
sv->up = BM_edge_other_vert(l->e, v);
@@ -4958,6 +4963,8 @@ static int createSlideVerts(TransInfo *t)
BM_elem_flag_disable(v, BM_ELEM_TAG);
BM_elem_flag_disable(v2, BM_ELEM_TAG);
} while (e != first->e && l1);
+
+ loop_nr++;
}
/* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
@@ -4965,21 +4972,24 @@ static int createSlideVerts(TransInfo *t)
sld->sv = sv_array;
sld->totsv = j;
- /*find mouse vector*/
- /* dis = z = -1.0f; */ /* UNUSED */
- /* size = 50.0; */ /* UNUSED */
- /* zero_v3(lastvec); */ /* UNUSED */
+ /* find mouse vectors, the global one, and one per loop in case we have
+ * multiple loops selected, in case they are oriented different */
zero_v3(dir);
- /* ee = le = NULL; */ /* UNUSED */
+ maxdist = -1.0f;
+
+ loop_dir = MEM_callocN(sizeof(float)*3*loop_nr, "sv loop_dir");
+ loop_maxdist = MEM_callocN(sizeof(float)*loop_nr, "sv loop_maxdist");
+ for (j = 0; j < loop_nr; j++)
+ loop_maxdist[j] = -1.0f;
+
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
BMIter iter2;
BMEdge *e2;
- float vec1[3], dis2, mval[2] = {t->mval[0], t->mval[1]}, d;
+ float vec1[3], mval[2] = {t->mval[0], t->mval[1]}, d;
/* search cross edges for visible edge to the mouse cursor,
* then use the shared vertex to calculate screen vector*/
- dis2 = -1.0f;
for (i = 0; i < 2; i++) {
v = i ? e->v1 : e->v2;
BM_ITER_ELEM (e2, &iter2, v, BM_EDGES_OF_VERT) {
@@ -5007,17 +5017,23 @@ static int createSlideVerts(TransInfo *t)
ED_view3d_project_float_v3(ar, sv_array[j].up->co, vec2, projectMat);
}
else {
- add_v3_v3v3(vec1, v->co, sv_array[j].upvec);
+ add_v3_v3v3(vec2, v->co, sv_array[j].upvec);
ED_view3d_project_float_v3(ar, vec2, vec2, projectMat);
}
-
+
+ /* global direction */
d = dist_to_line_segment_v2(mval, vec1, vec2);
- if (dis2 == -1.0f || d < dis2) {
- dis2 = d;
- /* ee = e2; */ /* UNUSED */
- /* size = len_v3v3(vec1, vec2); */ /* UNUSED */
+ if (maxdist == -1.0f || d < maxdist) {
+ maxdist = d;
sub_v3_v3v3(dir, vec1, vec2);
}
+
+ /* per loop direction */
+ l_nr = sv_array[j].loop_nr;
+ if (loop_maxdist[l_nr] == -1.0f || d < loop_maxdist[l_nr]) {
+ loop_maxdist[l_nr] = d;
+ sub_v3_v3v3(loop_dir[l_nr], vec1, vec2);
+ }
}
}
}
@@ -5051,6 +5067,14 @@ static int createSlideVerts(TransInfo *t)
}
BLI_smallhash_insert(&sld->vhash, (uintptr_t)sv_array->v, sv_array);
+
+ /* switch up/down if loop direction is different from global direction */
+ l_nr = sv_array->loop_nr;
+ if (dot_v3v3(loop_dir[l_nr], dir) < 0.0f) {
+ swap_v3_v3(sv_array->upvec, sv_array->downvec);
+ SWAP(BMVert, sv_array->vup, sv_array->vdown);
+ SWAP(BMVert*, sv_array->up, sv_array->down);
+ }
}
if (rv3d)
@@ -5061,7 +5085,7 @@ static int createSlideVerts(TransInfo *t)
/*zero out start*/
zero_v3(start);
-
+
/*dir holds a vector along edge loop*/
copy_v3_v3(end, dir);
mul_v3_fl(end, 0.5f);
@@ -5078,6 +5102,8 @@ static int createSlideVerts(TransInfo *t)
BLI_smallhash_release(&table);
BMBVH_FreeBVH(btree);
+ MEM_freeN(loop_dir);
+ MEM_freeN(loop_maxdist);
return 1;
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 8a7148aad95..e645cb2fed6 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -198,6 +198,8 @@ typedef struct TransDataSlideVert {
float edge_len;
float upvec[3], downvec[3];
+
+ int loop_nr;
} TransDataSlideVert;
typedef struct SlideData {