Fix EdgeSlide behavior with boundry edges
authorCampbell Barton <ideasman42@gmail.com>
Sat, 31 May 2014 03:56:54 +0000 (13:56 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 31 May 2014 05:41:20 +0000 (15:41 +1000)
- would flip in opposite directions sometimes on the same loop
- some vertices would get directions from adjacent vertices

source/blender/editors/transform/transform.c

index eae02c920c90dfdc1d4bf5c81cb68e2bd155f5d7..34e76ce5ece6888766e462f43e936543a71631ac 100644 (file)
@@ -5424,8 +5424,8 @@ static bool createEdgeSlideVerts(TransInfo *t)
        while (1) {
                float vec_a[3], vec_b[3];
                BMLoop *l_a, *l_b;
+               BMLoop *l_a_prev, *l_b_prev;
                BMVert *v_first;
-
                /* If this succeeds call get_next_loop()
                 * which calculates the direction to slide based on clever checks.
                 *
@@ -5455,7 +5455,6 @@ static bool createEdgeSlideVerts(TransInfo *t)
                e = v->e;
 
                /*first, rewind*/
-               numsel = 0;
                do {
                        e = get_other_edge(v, e);
                        if (!e) {
@@ -5463,8 +5462,6 @@ static bool createEdgeSlideVerts(TransInfo *t)
                                break;
                        }
 
-                       numsel += 1;
-
                        if (!BM_elem_flag_test(BM_edge_other_vert(e, v), BM_ELEM_TAG))
                                break;
 
@@ -5513,6 +5510,9 @@ static bool createEdgeSlideVerts(TransInfo *t)
                        l_b = NULL;
                }
 
+               l_a_prev = NULL;
+               l_b_prev = NULL;
+
                /*iterate over the loop*/
                v_first = v;
                do {
@@ -5530,14 +5530,14 @@ static bool createEdgeSlideVerts(TransInfo *t)
                        copy_v3_v3(sv->v_co_orig, v->co);
                        sv->loop_nr = loop_nr;
 
-                       if (l_a) {
-                               BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v);
+                       if (l_a || l_a_prev) {
+                               BMLoop *l_tmp = BM_loop_other_edge_loop(l_a ? l_a : l_a_prev, v);
                                sv->v_a = BM_edge_other_vert(l_tmp->e, v);
                                copy_v3_v3(sv->dir_a, vec_a);
                        }
 
-                       if (l_b) {
-                               BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v);
+                       if (l_b || l_b_prev) {
+                               BMLoop *l_tmp = BM_loop_other_edge_loop(l_b ? l_b : l_b_prev, v);
                                sv->v_b = BM_edge_other_vert(l_tmp->e, v);
                                copy_v3_v3(sv->dir_b, vec_b);
                        }
@@ -5586,29 +5586,54 @@ static bool createEdgeSlideVerts(TransInfo *t)
                        l_a_ok_prev = (l_a != NULL);
                        l_b_ok_prev = (l_b != NULL);
 
-                       l_a = l_a ? get_next_loop(v, l_a, e_prev, e, vec_a) : NULL;
-                       l_b = l_b ? get_next_loop(v, l_b, e_prev, e, vec_b) : NULL;
-
-                       /* find the opposite loop if it was missing previously */
-                       if      (l_a == NULL && l_b && (l_b->radial_next != l_b)) l_a = l_b->radial_next;
-                       else if (l_b == NULL && l_a && (l_a->radial_next != l_a)) l_b = l_a->radial_next;
-
-                       /* if there are non-contiguous faces, we can still recover the loops of the new edges faces */
-                       /* note!, the behavior in this case means edges may move in opposite directions,
-                        * this could be made to work more usefully. */
-                       if (!(l_a && l_b) && (e->l != NULL)) {
-                               if (l_a_ok_prev) {
-                                       l_a = e->l;
-                                       if (l_a->radial_next != l_a) {
-                                               l_b = l_a->radial_next;
-                                       }
+                       l_a_prev = l_a;
+                       l_b_prev = l_b;
+
+                       if (l_a) {
+                               l_a = get_next_loop(v, l_a, e_prev, e, vec_a);
+                       }
+                       else {
+                               zero_v3(vec_a);
+                       }
+
+                       if (l_b) {
+                               l_b = get_next_loop(v, l_b, e_prev, e, vec_b);
+                       }
+                       else {
+                               zero_v3(vec_b);
+                       }
+
+
+                       if (l_a && l_b) {
+                               /* pass */
+                       }
+                       else {
+                               if (l_a || l_b) {
+                                       /* find the opposite loop if it was missing previously */
+                                       if      (l_a == NULL && l_b && (l_b->radial_next != l_b)) l_a = l_b->radial_next;
+                                       else if (l_b == NULL && l_a && (l_a->radial_next != l_a)) l_b = l_a->radial_next;
                                }
-                               else if (l_b_ok_prev) {
-                                       l_b = e->l;
-                                       if (l_b->radial_next != l_b) {
-                                               l_a = l_b->radial_next;
+                               else if (e->l != NULL) {
+                                       /* if there are non-contiguous faces, we can still recover the loops of the new edges faces */
+                                       /* note!, the behavior in this case means edges may move in opposite directions,
+                                        * this could be made to work more usefully. */
+
+                                       if (l_a_ok_prev) {
+                                               l_a = e->l;
+                                               l_b = (l_a->radial_next != l_a) ? l_a->radial_next : NULL;
+                                       }
+                                       else if (l_b_ok_prev) {
+                                               l_b = e->l;
+                                               l_a = (l_b->radial_next != l_b) ? l_b->radial_next : NULL;
                                        }
                                }
+
+                               if (!l_a_ok_prev && l_a) {
+                                       get_next_loop(v, l_a, e, e_prev, vec_a);
+                               }
+                               if (!l_b_ok_prev && l_b) {
+                                       get_next_loop(v, l_b, e, e_prev, vec_b);
+                               }
                        }
 
                        BM_elem_flag_disable(v, BM_ELEM_TAG);