Fix T40422: EdgeSlide works incorrectly with boundry edges
authorCampbell Barton <ideasman42@gmail.com>
Thu, 29 May 2014 15:49:36 +0000 (01:49 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 29 May 2014 15:53:47 +0000 (01:53 +1000)
source/blender/editors/transform/transform.c

index cf9f89e333c09d67c7c5c2506538b814d64902bb..eae02c920c90dfdc1d4bf5c81cb68e2bd155f5d7 100644 (file)
@@ -5426,6 +5426,16 @@ static bool createEdgeSlideVerts(TransInfo *t)
                BMLoop *l_a, *l_b;
                BMVert *v_first;
 
+               /* If this succeeds call get_next_loop()
+                * which calculates the direction to slide based on clever checks.
+                *
+                * otherwise we simply use 'e_dir' as an edge-rail.
+                * (which is better when the attached edge is a boundary, see: T40422)
+                */
+#define EDGESLIDE_VERT_IS_INNER(v, e_dir) \
+               ((BM_edge_is_boundary(e_dir) == false) && \
+                (BM_vert_edge_count_nonwire(v) == 2))
+
                v = NULL;
                BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
                        if (BM_elem_flag_test(v, BM_ELEM_TAG))
@@ -5474,10 +5484,12 @@ static bool createEdgeSlideVerts(TransInfo *t)
                        }
                        else {
                                BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v);
-                               if (BM_vert_edge_count_nonwire(v) == 2)
+                               if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
                                        get_next_loop(v, l_a, e, l_tmp->e, vec_a);
-                               else
+                               }
+                               else {
                                        sub_v3_v3v3(vec_a, BM_edge_other_vert(l_tmp->e, v)->co, v->co);
+                               }
                        }
                }
 
@@ -5489,11 +5501,12 @@ static bool createEdgeSlideVerts(TransInfo *t)
                        }
                        else {
                                BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v);
-                               if (BM_vert_edge_count_nonwire(v) == 2)
+                               if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
                                        get_next_loop(v, l_b, e, l_tmp->e, vec_b);
-                               else
+                               }
+                               else {
                                        sub_v3_v3v3(vec_b, BM_edge_other_vert(l_tmp->e, v)->co, v->co);
-
+                               }
                        }
                }
                else {
@@ -5546,7 +5559,7 @@ static bool createEdgeSlideVerts(TransInfo *t)
                                if (l_a) {
                                        BMLoop *l_tmp = BM_loop_other_edge_loop(l_a, v);
                                        sv->v_a = BM_edge_other_vert(l_tmp->e, v);
-                                       if (BM_vert_edge_count_nonwire(v) == 2) {
+                                       if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
                                                get_next_loop(v, l_a, e_prev, l_tmp->e, sv->dir_a);
                                        }
                                        else {
@@ -5557,7 +5570,7 @@ static bool createEdgeSlideVerts(TransInfo *t)
                                if (l_b) {
                                        BMLoop *l_tmp = BM_loop_other_edge_loop(l_b, v);
                                        sv->v_b = BM_edge_other_vert(l_tmp->e, v);
-                                       if (BM_vert_edge_count_nonwire(v) == 2) {
+                                       if (EDGESLIDE_VERT_IS_INNER(v, l_tmp->e)) {
                                                get_next_loop(v, l_b, e_prev, l_tmp->e, sv->dir_b);
                                        }
                                        else {
@@ -5603,6 +5616,8 @@ static bool createEdgeSlideVerts(TransInfo *t)
                } while ((e != v_first->e) && (l_a || l_b));
 
                loop_nr++;
+
+#undef EDGESLIDE_VERT_IS_INNER
        }
 
        /* use for visibility checks */