[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44688] trunk/blender/source/blender: - simplify rip code not to expand/contract selection.

Campbell Barton ideasman42 at gmail.com
Wed Mar 7 01:08:06 CET 2012


Revision: 44688
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44688
Author:   campbellbarton
Date:     2012-03-07 00:08:00 +0000 (Wed, 07 Mar 2012)
Log Message:
-----------
- simplify rip code not to expand/contract selection.
- disable BVH edge visibility test (ifdef'd out. dont think its really needed)

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_polygon.c
    trunk/blender/source/blender/editors/mesh/bmesh_tools.c
    trunk/blender/source/blender/render/intern/include/rayobject.h

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_polygon.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_polygon.c	2012-03-06 21:54:33 UTC (rev 44687)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_polygon.c	2012-03-07 00:08:00 UTC (rev 44688)
@@ -220,39 +220,39 @@
 /**
  * computes center of face in 3d.  uses center of bounding box.
  */
-void BM_face_center_bounds_calc(BMesh *bm, BMFace *f, float r_cent[3])
+void BM_face_center_bounds_calc(BMesh *UNUSED(bm), BMFace *f, float r_cent[3])
 {
-	BMIter iter;
-	BMLoop *l;
+	BMLoop *l_iter;
+	BMLoop *l_first;
 	float min[3], max[3];
-	int i;
 
 	INIT_MINMAX(min, max);
-	l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
-	for (i = 0; l; l = BM_iter_step(&iter), i++) {
-		DO_MINMAX(l->v->co, min, max);
-	}
 
+	l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+	do {
+		DO_MINMAX(l_iter->v->co, min, max);
+	} while ((l_iter = l_iter->next) != l_first);
+
 	mid_v3_v3v3(r_cent, min, max);
 }
 
 /**
- * computes the centroid of a face, using the mean average
+ * computes the center of a face, using the mean average
  */
-void BM_face_center_mean_calc(BMesh *bm, BMFace *f, float r_cent[3])
+void BM_face_center_mean_calc(BMesh *UNUSED(bm), BMFace *f, float r_cent[3])
 {
-	BMIter iter;
-	BMLoop *l;
-	int i;
+	BMLoop *l_iter;
+	BMLoop *l_first;
 
 	zero_v3(r_cent);
 
-	l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
-	for (i = 0; l; l = BM_iter_step(&iter), i++) {
-		add_v3_v3(r_cent, l->v->co);
-	}
+	l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+	do {
+		add_v3_v3(r_cent, l_iter->v->co);
+	} while ((l_iter = l_iter->next) != l_first);
 
-	if (f->len) mul_v3_fl(r_cent, 1.0f / (float)f->len);
+	if (f->len)
+		mul_v3_fl(r_cent, 1.0f / (float) f->len);
 }
 
 /**
@@ -291,11 +291,6 @@
 		avgn[2] = 1.0f;
 	}
 	else {
-		/* XXX, why is this being divided and _then_ normalized
-		 * division could be removed? - campbell */
-		avgn[0] /= nverts;
-		avgn[1] /= nverts;
-		avgn[2] /= nverts;
 		normalize_v3(avgn);
 	}
 	

Modified: trunk/blender/source/blender/editors/mesh/bmesh_tools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/bmesh_tools.c	2012-03-06 21:54:33 UTC (rev 44687)
+++ trunk/blender/source/blender/editors/mesh/bmesh_tools.c	2012-03-07 00:08:00 UTC (rev 44688)
@@ -2327,26 +2327,40 @@
 	return dist_to_line_segment_v2(mvalf, vec1, vec2);
 }
 
+/* #define USE_BVH_VISIBILITY */
+
 /* based on mouse cursor position, it defines how is being ripped */
 static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	ARegion *ar = CTX_wm_region(C);
+#ifdef USE_BVH_VISIBILITY
+	BMBVHTree *bvhtree;
 	View3D *v3d = CTX_wm_view3d(C);
+#endif
 	RegionView3D *rv3d = CTX_wm_region_view3d(C);
 	BMEditMesh *em = BMEdit_FromObject(obedit);
 	BMesh *bm = em->bm;
 	BMOperator bmop;
-	BMBVHTree *bvhtree;
 	BMOIter siter;
-	BMIter iter, eiter, liter;
+	BMIter iter, eiter;
 	BMLoop *l;
 	BMEdge *e, *e2, *closest = NULL;
 	BMVert *v, *ripvert = NULL;
-	int side = 0, i, singlesel = 0;
+	int side = 0, i, singlesel = FALSE;
 	float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]};
 	float dist = FLT_MAX, d;
 
+	/* note on selection:
+	 * When calling edge split we operate on tagged edges rather then selected
+	 * this is important because the edges to operate on are extended by one,
+	 * but the selection is left alone.
+	 *
+	 * After calling edge split - the duplicated edges have the same selection state as the
+	 * original, so all we do is de-select the far side from the mouse and we have a
+	 * useful selection for grabbing.
+	 */
+
 	ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat);
 
 	/* BM_ELEM_SELECT --> BM_ELEM_TAG */
@@ -2358,13 +2372,19 @@
 	 * closest edge around that vert to mouse cursor,
 	 * then rip two adjacent edges in the vert fan. */
 	if (bm->totvertsel == 1 && bm->totedgesel == 0 && bm->totfacesel == 0) {
-		singlesel = 1;
+		BMEditSelection ese;
+		singlesel = TRUE;
 
-		/* find selected vert */
-		BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
-			if (BM_elem_flag_test(v, BM_ELEM_SELECT))
-				break;
+		/* find selected vert - same some time and check history first */
+		if (EDBM_get_actSelection(em, &ese) && ese.htype == BM_VERT) {
+			v = (BMVert *)ese.ele;
 		}
+		else {
+			BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
+				if (BM_elem_flag_test(v, BM_ELEM_SELECT))
+					break;
+			}
+		}
 
 		/* this should be impossible, but sanity checks are a good thing */
 		if (!v)
@@ -2402,12 +2422,10 @@
 			l = e2->l;
 			e = BM_face_other_edge_loop(l->f, e2, v)->e;
 			BM_elem_flag_enable(e, BM_ELEM_TAG);
-			BM_elem_select_set(bm, e, TRUE);
 			
 			l = e2->l->radial_next;
 			e = BM_face_other_edge_loop(l->f, e2, v)->e;
 			BM_elem_flag_enable(e, BM_ELEM_TAG);
-			BM_elem_select_set(bm, e, TRUE);
 		}
 
 		dist = FLT_MAX;
@@ -2418,7 +2436,9 @@
 			e2 = NULL;
 			i = 0;
 			BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
-				if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+				/* important to check selection rather then tag here
+				 * else we get feedback loop */
+				if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
 					e2 = e;
 					i++;
 				}
@@ -2430,37 +2450,38 @@
 				l = BM_face_other_edge_loop(l->f, l->e, v);
 
 				if (l) {
-					BM_elem_select_set(bm, l->e, TRUE);
+					BM_elem_flag_enable(l->e, BM_ELEM_TAG);
 				}
 			}
 		}
 	}
 
-	if (!EDBM_InitOpf(em, &bmop, op, "edgesplit edges=%he", BM_ELEM_SELECT)) {
+	if (!EDBM_InitOpf(em, &bmop, op, "edgesplit edges=%he", BM_ELEM_TAG)) {
 		return OPERATOR_CANCELLED;
 	}
 	
 	BMO_op_exec(bm, &bmop);
 
+#ifdef USE_BVH_VISIBILITY
 	/* build bvh tree for edge visibility tests */
 	bvhtree = BMBVH_NewBVH(em, 0, NULL, NULL);
+#endif
 
 	for (i = 0; i < 2; i++) {
 		BMO_ITER(e, &siter, bm, &bmop, i ? "edgeout2":"edgeout1", BM_EDGE) {
 			float cent[3] = {0, 0, 0}, mid[3], vec[3];
 
+#ifdef USE_BVH_VISIBILITY
 			if (!BMBVH_EdgeVisible(bvhtree, e, ar, v3d, obedit) || !e->l)
 				continue;
+#endif
 
 			/* method for calculating distance:
 			 *
 			 * for each edge: calculate face center, then made a vector
 			 * from edge midpoint to face center.  offset edge midpoint
 			 * by a small amount along this vector. */
-			BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, e->l->f) {
-				add_v3_v3(cent, l->v->co);
-			}
-			mul_v3_fl(cent, 1.0f/(float)e->l->f->len);
+			BM_face_center_mean_calc(bm, e->l->f, cent);
 
 			mid_v3_v3v3(mid, e->v1->co, e->v2->co);
 			sub_v3_v3v3(vec, cent, mid);
@@ -2468,7 +2489,7 @@
 			mul_v3_fl(vec, 0.01f);
 			add_v3_v3v3(mid, mid, vec);
 
-			/* yay we have our comparison point, now project it */
+			/* We have our comparison point, now project it */
 			ED_view3d_project_float(ar, mid, mid, projectMat);
 
 			d = len_squared_v2v2(fmval, mid);
@@ -2480,35 +2501,14 @@
 			}
 		}
 	}
-	
+
+#ifdef USE_BVH_VISIBILITY
 	BMBVH_FreeBVH(bvhtree);
+#endif
 
-	EDBM_flag_disable_all(em, BM_ELEM_SELECT);
-	BMO_slot_buffer_hflag_enable(bm, &bmop, side?"edgeout2":"edgeout1", BM_ELEM_SELECT, BM_EDGE, TRUE);
+	/* de-select one of the sides */
+	BMO_slot_buffer_hflag_disable(bm, &bmop, side ? "edgeout1" : "edgeout2", BM_ELEM_SELECT, BM_EDGE, TRUE);
 
-	BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
-		BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT));
-	}
-
-	/* constrict edge selection again */
-	BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
-		e2 = NULL;
-		i = 0;
-		BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
-			if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
-				e2 = e;
-				i++;
-			}
-		}
-		
-		if (i == 1) {
-			if (singlesel)
-				BM_elem_select_set(bm, v, FALSE);
-			else
-				BM_elem_select_set(bm, e2, FALSE);
-		}
-	}
-
 	if (ripvert) {
 		BM_elem_select_set(bm, ripvert, TRUE);
 	}
@@ -2962,7 +2962,7 @@
 		}
 	}
 	
-	/* now check for edge interesect (may produce vertex intersection as well)*/
+	/* now check for edge intersect (may produce vertex intersection as well) */
 	for (i = 0; i < len; i++) {
 		if (i > 0) {
 			x11 = x12;

Modified: trunk/blender/source/blender/render/intern/include/rayobject.h
===================================================================
--- trunk/blender/source/blender/render/intern/include/rayobject.h	2012-03-06 21:54:33 UTC (rev 44687)
+++ trunk/blender/source/blender/render/intern/include/rayobject.h	2012-03-07 00:08:00 UTC (rev 44688)
@@ -43,11 +43,10 @@
 struct VlakRen;
 
 /* RayObject
-
-   Can be a face/triangle, bvh tree, object instance, etc. This is the
-   public API used by the renderer, see rayobject_internal.h for the
-   internal implementation details. */
-
+ * Can be a face/triangle, bvh tree, object instance, etc. This is the
+ * public API used by the renderer, see rayobject_internal.h for the
+ * internal implementation details.
+ * */
 typedef struct RayObject RayObject;
 
 /* Intersection, see rayintersection.h */
@@ -74,8 +73,8 @@
 void RE_rayobject_set_control(RayObject *r, void *data, int (*test_break)(void *data));
 
 /* RayObject representing faces, all data is locally available instead
-   of referring to some external data structure, for possibly faster
-   intersection tests. */
+ * of referring to some external data structure, for possibly faster
+ * intersection tests. */
 
 typedef struct RayFace {
 	float v1[4], v2[4], v3[4], v4[3];
@@ -89,8 +88,8 @@
 RayObject* RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr);
 
 /* RayObject representing faces directly from a given VlakRen structure. Thus
-   allowing to save memory, but making code triangle intersection dependent on
-   render structures. */
+ * allowing to save memory, but making code triangle intersection dependent on
+ * render structures. */
 
 typedef struct VlakPrimitive {
 	struct ObjectInstanceRen *ob;
@@ -104,10 +103,10 @@
 /* extend min/max coords so that the rayobject is inside them */
 void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max);
 
-/* initializes an hint for optiming raycast where it is know that a ray will pass by the given BB often the origin point */
+/* initializes an hint for optimizing raycast where it is know that a ray will pass by the given BB often the origin point */
 void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float *min, float *max);
 
-/* initializes an hint for optiming raycast where it is know that a ray will be contained inside the given cone*/

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list