[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45812] trunk/blender/source/blender/ editors/mesh/editmesh_rip.c: refactor rip tool out into vert/edge functions , was getting too unweildy having them mixed in.

Campbell Barton ideasman42 at gmail.com
Fri Apr 20 16:36:07 CEST 2012


Revision: 45812
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45812
Author:   campbellbarton
Date:     2012-04-20 14:36:06 +0000 (Fri, 20 Apr 2012)
Log Message:
-----------
refactor rip tool out into vert/edge functions, was getting too unweildy having them mixed in.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/mesh/editmesh_rip.c

Modified: trunk/blender/source/blender/editors/mesh/editmesh_rip.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_rip.c	2012-04-20 13:45:38 UTC (rev 45811)
+++ trunk/blender/source/blender/editors/mesh/editmesh_rip.c	2012-04-20 14:36:06 UTC (rev 45812)
@@ -342,297 +342,201 @@
 }
 /* --- end 'ripsel' selection handling code --- */
 
-/* based on mouse cursor position, it defines how is being ripped */
-static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op)
 {
+	BMOperator bmop;
+
+	if (!EDBM_op_init(em, &bmop, op, "edgesplit edges=%he verts=%hv use_verts=%b",
+					  BM_ELEM_TAG, BM_ELEM_SELECT, TRUE)) {
+		return FALSE;
+	}
+	BMO_op_exec(em->bm, &bmop);
+	if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/**
+ * This is the main vert ripping function (rip when one vertex is selected)
+ */
+static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
+{
 	Object *obedit = CTX_data_edit_object(C);
 	ARegion *ar = CTX_wm_region(C);
 	RegionView3D *rv3d = CTX_wm_region_view3d(C);
 	BMEditMesh *em = BMEdit_FromObject(obedit);
 	BMesh *bm = em->bm;
-	BMOperator bmop;
-	BMIter iter, eiter, liter;
+	BMIter iter, liter;
 	BMLoop *l;
 	BMEdge *e, *e2;
 	BMVert *v, *ripvert = NULL;
-	int i, singlesel = FALSE;
+	int i;
 	float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]};
 	float dist = FLT_MAX;
 	float d;
-	const int totedge_orig = bm->totedge;
 
-	EdgeLoopPair *eloop_pairs = NULL;
+	BMEditSelection ese;
+	int totboundary_edge = 0;
 
-	/* running in face mode hardly makes sense, so convert to region loop and rip */
-	if (em->bm->totfacesel) {
-		WM_operator_name_call(C, "MESH_OT_region_to_loop", WM_OP_INVOKE_DEFAULT, NULL);
-	}
-
-	/* 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 */
-	BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
-		BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT));
+	/* find selected vert - same some time and check history first */
+	if (EDBM_editselection_active_get(em, &ese) && ese.htype == BM_VERT) {
+		v = (BMVert *)ese.ele;
 	}
+	else {
+		ese.ele = NULL;
 
-	/* handle case of one vert selected.  identify
-	 * closest edge around that vert to mouse cursor,
-	 * then rip two adjacent edges in the vert fan. */
+		BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+			if (BM_elem_flag_test(v, BM_ELEM_SELECT))
+				break;
+		}
+	}
 
-	if (bm->totvertsel == 1 && bm->totedgesel == 0 && bm->totfacesel == 0) {
-		/* --- Vert-Rip --- */
+	/* this should be impossible, but sanity checks are a good thing */
+	if (!v)
+		return OPERATOR_CANCELLED;
 
-		BMEditSelection ese;
-		int totboundary_edge = 0;
-		singlesel = TRUE;
+	e2 = NULL;
 
-		/* find selected vert - same some time and check history first */
-		if (EDBM_editselection_active_get(em, &ese) && ese.htype == BM_VERT) {
-			v = (BMVert *)ese.ele;
-		}
-		else {
-			ese.ele = NULL;
-
-			BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
-				if (BM_elem_flag_test(v, BM_ELEM_SELECT))
-					break;
+	if (v->e) {
+		/* find closest edge to mouse cursor */
+		BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
+			int is_boundary = BM_edge_is_boundary(e);
+			/* consider wire as boundary for this purpose,
+			 * otherwise we can't a face away from a wire edge */
+			totboundary_edge += (is_boundary != 0 || BM_edge_is_wire(e));
+			if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+				if (is_boundary == FALSE && BM_edge_is_manifold(e)) {
+					d = edbm_rip_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval);
+					if (d < dist) {
+						dist = d;
+						e2 = e;
+					}
+				}
 			}
 		}
 
-		/* this should be impossible, but sanity checks are a good thing */
-		if (!v)
-			return OPERATOR_CANCELLED;
+	}
 
-		e2 = NULL;
+	/* should we go ahead with edge rip or do we need to do special case, split off vertex?:
+	 * split off vertex if...
+	 * - we cant find an edge - this means we are ripping a faces vert that is connected to other
+	 *   geometry only at the vertex.
+	 * - the boundary edge total is greater then 2,
+	 *   in this case edge split _can_ work but we get far nicer results if we use this special case. */
+	if (totboundary_edge > 2) {
+		BMVert **vout;
+		int vout_len;
 
-		if (v->e) {
-			/* find closest edge to mouse cursor */
-			BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
-				int is_boundary = BM_edge_is_boundary(e);
-				/* consider wire as boundary for this purpose,
-				 * otherwise we can't a face away from a wire edge */
-				totboundary_edge += (is_boundary != 0 || BM_edge_is_wire(e));
-				if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
-					if (is_boundary == FALSE && BM_edge_is_manifold(e)) {
-						d = edbm_rip_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval);
-						if (d < dist) {
-							dist = d;
-							e2 = e;
-						}
-					}
-				}
-			}
+		BM_elem_select_set(bm, v, FALSE);
+		bmesh_vert_separate(bm, v, &vout, &vout_len);
 
+		if (vout_len < 2) {
+			/* set selection back to avoid active-unselected vertex */
+			BM_elem_select_set(bm, v, TRUE);
+			/* should never happen */
+			BKE_report(op->reports, RPT_ERROR, "Error ripping vertex from faces");
+			return OPERATOR_CANCELLED;
 		}
+		else {
+			int vi_best = 0;
 
-		/* should we go ahead with edge rip or do we need to do special case, split off vertex?:
-		 * split off vertex if...
-		 * - we cant find an edge - this means we are ripping a faces vert that is connected to other
-		 *   geometry only at the vertex.
-		 * - the boundary edge total is greater then 2,
-		 *   in this case edge split _can_ work but we get far nicer results if we use this special case. */
-		if (totboundary_edge > 2) {
-			BMVert **vout;
-			int vout_len;
-
-			BM_elem_select_set(bm, v, FALSE);
-			bmesh_vert_separate(bm, v, &vout, &vout_len);
-
-			if (vout_len < 2) {
-				/* set selection back to avoid active-unselected vertex */
-				BM_elem_select_set(bm, v, TRUE);
-				/* should never happen */
-				BKE_report(op->reports, RPT_ERROR, "Error ripping vertex from faces");
-				return OPERATOR_CANCELLED;
+			if (ese.ele) {
+				EDBM_editselection_remove(em, &ese.ele->head);
 			}
-			else {
-				int vi_best = 0;
 
-				if (ese.ele) {
-					EDBM_editselection_remove(em, &ese.ele->head);
-				}
+			dist = FLT_MAX;
 
-				dist = FLT_MAX;
+			for (i = 0; i < vout_len; i++) {
+				BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) {
+					if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
+						float l_mid_co[3];
+						BM_loop_face_tangent(l, l_mid_co);
 
-				for (i = 0; i < vout_len; i++) {
-					BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) {
-						if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
-							float l_mid_co[3];
-							BM_loop_face_tangent(l, l_mid_co);
+						/* scale to average of surrounding edge size, only needs to be approx */
+						mul_v3_fl(l_mid_co, (BM_edge_length_calc(l->e) + BM_edge_length_calc(l->prev->e)) / 2.0f);
+						add_v3_v3(l_mid_co, v->co);
 
-							/* scale to average of surrounding edge size, only needs to be approx */
-							mul_v3_fl(l_mid_co, (BM_edge_length_calc(l->e) + BM_edge_length_calc(l->prev->e)) / 2.0f);
-							add_v3_v3(l_mid_co, v->co);
+						d = edbm_rip_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval);
 
-							d = edbm_rip_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval);
-
-							if (d < dist) {
-								dist = d;
-								vi_best = i;
-							}
+						if (d < dist) {
+							dist = d;
+							vi_best = i;
 						}
 					}
 				}
+			}
 
-				/* select the vert from the best region */
-				v = vout[vi_best];
-				BM_elem_select_set(bm, v, TRUE);
+			/* select the vert from the best region */
+			v = vout[vi_best];
+			BM_elem_select_set(bm, v, TRUE);
 
-				if (ese.ele) {
-					EDBM_editselection_store(em, &v->head);
-				}
+			if (ese.ele) {
+				EDBM_editselection_store(em, &v->head);
+			}
 
-				/* splice all others back together */
-				if (vout_len > 2) {
+			/* splice all others back together */
+			if (vout_len > 2) {
 
-					/* vout[0]  == best
-					 * vout[1]  == glue
-					 * vout[2+] == splice with glue
-					 */
-					if (vi_best != 0) {
-						SWAP(BMVert *, vout[0], vout[vi_best]);
-						vi_best = 0;
-					}
+				/* vout[0]  == best
+				 * vout[1]  == glue
+				 * vout[2+] == splice with glue
+				 */
+				if (vi_best != 0) {
+					SWAP(BMVert *, vout[0], vout[vi_best]);
+					vi_best = 0;
+				}
 
-					for (i = 2; i < vout_len; i++) {
-						BM_vert_splice(bm, vout[i], vout[1]);
-					}
+				for (i = 2; i < vout_len; i++) {
+					BM_vert_splice(bm, vout[i], vout[1]);
 				}
-
-				MEM_freeN(vout);
-
-				return OPERATOR_FINISHED;
 			}
-		}
 
-		if (!e2) {
-			BKE_report(op->reports, RPT_ERROR, "Selected vertex has no edge/face pairs attached");
-			return OPERATOR_CANCELLED;
-		}
+			MEM_freeN(vout);
 
-		/* rip two adjacent edges */
-		if (BM_edge_is_boundary(e2) || BM_vert_face_count(v) == 2) {
-			l = e2->l;
-			ripvert = BM_face_vert_separate(bm, l->f, v);
-
-			BLI_assert(ripvert);
-			if (!ripvert) {
-				return OPERATOR_CANCELLED;
-			}
+			return OPERATOR_FINISHED;
 		}
-		else if (BM_edge_is_manifold(e2)) {
-			l = e2->l;
-			e = BM_face_other_edge_loop(l->f, e2, v)->e;
-			BM_elem_flag_enable(e, BM_ELEM_TAG);
-			
-			l = e2->l->radial_next;
-			e = BM_face_other_edge_loop(l->f, e2, v)->e;
-			BM_elem_flag_enable(e, BM_ELEM_TAG);
-		}
+	}
 
-		dist = FLT_MAX;
+	if (!e2) {
+		BKE_report(op->reports, RPT_ERROR, "Selected vertex has no edge/face pairs attached");
+		return OPERATOR_CANCELLED;
 	}
-	else {
-		/* --- Edge-Rip --- */
-		int totedge;
-		int all_minifold;
 
-		/* important this runs on the original selection, before tempering with tagging */
-		eloop_pairs = edbm_ripsel_looptag_helper(bm);
+	/* rip two adjacent edges */
+	if (BM_edge_is_boundary(e2) || BM_vert_face_count(v) == 2) {
+		l = e2->l;
+		ripvert = BM_face_vert_separate(bm, l->f, v);
 
-		/* expand edge selection */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list