[Bf-blender-cvs] [9cb397238d1] blender2.8: Fix crash selecting edit-mesh

Campbell Barton noreply at git.blender.org
Fri May 4 19:05:00 CEST 2018


Commit: 9cb397238d13e1362f0d94fd2b4e84a1fd1eb1b0
Author: Campbell Barton
Date:   Fri May 4 19:01:53 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB9cb397238d13e1362f0d94fd2b4e84a1fd1eb1b0

Fix crash selecting edit-mesh

The base and the vert/edge/face could be out of sync.

===================================================================

M	source/blender/editors/mesh/editmesh_select.c

===================================================================

diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index ac5999c97c4..b96fcd3b277 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -921,7 +921,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
  * selected vertices and edges get disadvantage
  * return 1 if found one
  */
-static int unified_findnearest(
+static bool unified_findnearest(
         ViewContext *vc,
         Base **r_base, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
 {
@@ -933,12 +933,21 @@ static int unified_findnearest(
 	/* since edges select lines, we give dots advantage of ~20 pix */
 	const float dist_margin = (dist_init / 2);
 	float dist = dist_init;
-	BMFace *efa_zbuf = NULL;
-	BMEdge *eed_zbuf = NULL;
 
-	BMVert *eve = NULL;
-	BMEdge *eed = NULL;
-	BMFace *efa = NULL;
+	struct {
+		struct {
+			BMVert *ele;
+			Base *base;
+		} v;
+		struct {
+			BMEdge *ele;
+			Base *base;
+		} e, e_zbuf;
+		struct {
+			BMFace *ele;
+			Base *base;
+		} f, f_zbuf;
+	} hit = {{NULL}};
 
 	/* TODO(campbell): perform selection as one pass
 	 * instead of many smaller passes (which doesn't work for zbuf occlusion). */
@@ -956,14 +965,18 @@ static int unified_findnearest(
 			Object *obedit = base_iter->object;
 			ED_view3d_viewcontext_init_object(vc, obedit);
 			ED_view3d_backbuf_validate(vc);
-
+			BMFace *efa_zbuf = NULL;
 			BMFace *efa_test = EDBM_face_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf);
-			if (efa && dist_center_p) {
+			if (hit.f.ele && dist_center_p) {
 				dist = min_ff(dist_margin, dist_center);
 			}
 			if (efa_test) {
-				*r_base = base_iter;
-				efa = efa_test;
+				hit.f.base = base_iter;
+				hit.f.ele  = efa_test;
+			}
+			if (efa_zbuf) {
+				hit.f_zbuf.base = base_iter;
+				hit.f_zbuf.ele  = efa_zbuf;
 			}
 		} /* bases */
 	}
@@ -977,13 +990,18 @@ static int unified_findnearest(
 			Object *obedit = base_iter->object;
 			ED_view3d_viewcontext_init_object(vc, obedit);
 			ED_view3d_backbuf_validate(vc);
+			BMEdge *eed_zbuf = NULL;
 			BMEdge *eed_test = EDBM_edge_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf);
-			if (eed && dist_center_p) {
+			if (hit.e.ele && dist_center_p) {
 				dist = min_ff(dist_margin, dist_center);
 			}
 			if (eed_test) {
-				*r_base = base_iter;
-				eed = eed_test;
+				hit.e.base = base_iter;
+				hit.e.ele  = eed_test;
+			}
+			if (eed_zbuf) {
+				hit.e_zbuf.base = base_iter;
+				hit.e_zbuf.ele  = eed_zbuf;
 			}
 		} /* bases */
 	}
@@ -996,8 +1014,8 @@ static int unified_findnearest(
 			ED_view3d_backbuf_validate(vc);
 			BMVert *eve_test = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle);
 			if (eve_test) {
-				*r_base = base_iter;
-				eve = eve_test;
+				hit.v.base = base_iter;
+				hit.v.ele  = eve_test;
 			}
 		} /* bases */
 	}
@@ -1005,32 +1023,48 @@ static int unified_findnearest(
 	MEM_SAFE_FREE(bases);
 
 	/* return only one of 3 pointers, for frontbuffer redraws */
-	if (eve) {
-		efa = NULL; eed = NULL;
+	if (hit.v.ele) {
+		hit.f.ele = NULL;
+		hit.e.ele = NULL;
 	}
-	else if (eed) {
-		efa = NULL;
+	else if (hit.e.ele) {
+		hit.f.ele = NULL;
 	}
 
 	/* there may be a face under the cursor, who's center if too far away
 	 * use this if all else fails, it makes sense to select this */
-	if ((eve || eed || efa) == 0) {
-		if (eed_zbuf) {
-			eed = eed_zbuf;
+	if ((hit.v.ele || hit.e.ele || hit.f.ele) == 0) {
+		if (hit.e_zbuf.ele) {
+			hit.e.base = hit.e_zbuf.base;
+			hit.e.ele  = hit.e_zbuf.ele;
 		}
-		else if (efa_zbuf) {
-			efa = efa_zbuf;
+		else if (hit.f_zbuf.ele) {
+			hit.f.base = hit.f_zbuf.base;
+			hit.f.ele  = hit.f_zbuf.ele;
 		}
 	}
 
 	mval_prev[0] = vc->mval[0];
 	mval_prev[1] = vc->mval[1];
+	
+	/* Only one element type will be non-null. */
+	BLI_assert(((hit.v.ele != NULL) + (hit.e.ele != NULL) + (hit.f.ele != NULL)) <= 1);
+
+	if (hit.v.ele) {
+		*r_base = hit.v.base;
+	}
+	if (hit.e.ele) {
+		*r_base = hit.e.base;
+	}
+	if (hit.f.ele) {
+		*r_base = hit.f.base;
+	}
 
-	*r_eve = eve;
-	*r_eed = eed;
-	*r_efa = efa;
+	*r_eve = hit.v.ele;
+	*r_eed = hit.e.ele;
+	*r_efa = hit.f.ele;
 
-	return (eve || eed || efa);
+	return (hit.v.ele || hit.e.ele || hit.f.ele);
 }
 
 /** \} */



More information about the Bf-blender-cvs mailing list