[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [50287] trunk/blender/source/blender/ editors/transform: Fix #32450: edge slide with multiple loops selected could move some loops

Brecht Van Lommel brechtvanlommel at pandora.be
Fri Aug 31 14:08:05 CEST 2012


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 {




More information about the Bf-blender-cvs mailing list