Revision: 50287
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50287
Author:   blendix
Date:     2012-08-31 12:08:04 +0000 (Fri, 31 Aug 2012)
Log Message:
-----------
Fix #32450: edge slide with multiple loops selected could move some loops
in the wrong direction.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/transform/transform.c
    trunk/blender/source/blender/editors/transform/transform.h

Modified: trunk/blender/source/blender/editors/transform/transform.c
===================================================================
--- trunk/blender/source/blender/editors/transform/transform.c  2012-08-31 
00:21:56 UTC (rev 50286)
+++ trunk/blender/source/blender/editors/transform/transform.c  2012-08-31 
12:08:04 UTC (rev 50287)
@@ -4759,7 +4759,7 @@
        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 @@
        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 @@
        }
 
        sv_array = MEM_callocN(sizeof(TransDataSlideVert) * j, "sv_array");
+       loop_nr = 0;
 
        j = 0;
        while (1) {
@@ -4910,6 +4912,8 @@
 
                        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 @@
                                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 @@
                        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 @@
        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 @@
                                                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 @@
                }
 
                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 @@
        
        /*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 @@
        
        BLI_smallhash_release(&table);
        BMBVH_FreeBVH(btree);
+       MEM_freeN(loop_dir);
+       MEM_freeN(loop_maxdist);
        
        return 1;
 }

Modified: trunk/blender/source/blender/editors/transform/transform.h
===================================================================
--- trunk/blender/source/blender/editors/transform/transform.h  2012-08-31 
00:21:56 UTC (rev 50286)
+++ trunk/blender/source/blender/editors/transform/transform.h  2012-08-31 
12:08:04 UTC (rev 50287)
@@ -198,6 +198,8 @@
        float edge_len;
 
        float upvec[3], downvec[3];
+
+       int loop_nr;
 } TransDataSlideVert;
 
 typedef struct SlideData {

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to