Fix #32450: edge slide with multiple loops selected could move some loops
in the wrong direction.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -198,6 +198,8 @@ typedef struct TransDataSlideVert {
|
||||
float edge_len;
|
||||
|
||||
float upvec[3], downvec[3];
|
||||
|
||||
int loop_nr;
|
||||
} TransDataSlideVert;
|
||||
|
||||
typedef struct SlideData {
|
||||
|
Reference in New Issue
Block a user