[Bf-blender-cvs] [6539c1fc41c] blender2.8: Multi-Object-Editing : Support for MESH_OT_rip_edge by Miguel Pozo

Dalai Felinto noreply at git.blender.org
Wed May 9 10:31:31 CEST 2018


Commit: 6539c1fc41c6768df1943f89429c7ad9c137d313
Author: Dalai Felinto
Date:   Wed May 9 10:27:35 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB6539c1fc41c6768df1943f89429c7ad9c137d313

Multi-Object-Editing : Support for MESH_OT_rip_edge by Miguel Pozo

Maniphest Tasks: T54643
Differential Revision: https://developer.blender.org/D3268

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

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

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

diff --git a/source/blender/editors/mesh/editmesh_rip_edge.c b/source/blender/editors/mesh/editmesh_rip_edge.c
index a501dfc8c2c..d32b915facc 100644
--- a/source/blender/editors/mesh/editmesh_rip_edge.c
+++ b/source/blender/editors/mesh/editmesh_rip_edge.c
@@ -24,6 +24,8 @@
  * based on mouse cursor position, split of vertices along the closest edge.
  */
 
+#include "MEM_guardedalloc.h"
+
 #include "DNA_object_types.h"
 
 #include "BLI_math.h"
@@ -31,6 +33,7 @@
 #include "BKE_context.h"
 #include "BKE_report.h"
 #include "BKE_editmesh.h"
+#include "BKE_layer.h"
 
 #include "WM_types.h"
 
@@ -50,181 +53,187 @@ static int edbm_rip_edge_invoke(bContext *C, wmOperator *UNUSED(op), const wmEve
 {
 	ARegion *ar = CTX_wm_region(C);
 	RegionView3D *rv3d = CTX_wm_region_view3d(C);
-	Object *obedit = CTX_data_edit_object(C);
-	BMEditMesh *em = BKE_editmesh_from_object(obedit);
-	BMesh *bm = em->bm;
-	BMIter viter;
-	BMVert *v;
-	const float mval_fl[2] = {UNPACK2(event->mval)};
-	float cent_sco[2];
-	int cent_tot;
-	bool changed = false;
+	ViewLayer *view_layer = CTX_data_view_layer(C);
+	uint objects_len = 0;
+	Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
 
-	/* mouse direction to view center */
-	float mval_dir[2];
+	for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+		Object *obedit = objects[ob_index];
+		BMEditMesh *em = BKE_editmesh_from_object(obedit);
+		BMesh *bm = em->bm;
 
-	float projectMat[4][4];
+		BMIter viter;
+		BMVert *v;
+		const float mval_fl[2] = { UNPACK2(event->mval) };
+		float cent_sco[2];
+		int cent_tot;
+		bool changed = false;
 
-	if (bm->totvertsel == 0)
-		return OPERATOR_CANCELLED;
+		/* mouse direction to view center */
+		float mval_dir[2];
 
-	ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat);
+		float projectMat[4][4];
 
-	zero_v2(cent_sco);
-	cent_tot = 0;
+		if (bm->totvertsel == 0)
+			continue;
 
-	/* clear tags and calc screen center */
-	BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
-		BM_elem_flag_disable(v, BM_ELEM_TAG);
+		ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat);
 
-		if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
-			float v_sco[2];
-			ED_view3d_project_float_v2_m4(ar, v->co, v_sco, projectMat);
+		zero_v2(cent_sco);
+		cent_tot = 0;
+
+		/* clear tags and calc screen center */
+		BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+			BM_elem_flag_disable(v, BM_ELEM_TAG);
+
+			if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+				float v_sco[2];
+				ED_view3d_project_float_v2_m4(ar, v->co, v_sco, projectMat);
 
-			add_v2_v2(cent_sco, v_sco);
-			cent_tot += 1;
+				add_v2_v2(cent_sco, v_sco);
+				cent_tot += 1;
+			}
 		}
-	}
-	mul_v2_fl(cent_sco, 1.0f / (float)cent_tot);
-
-	/* not essential, but gives more expected results with edge selection */
-	if (bm->totedgesel) {
-		/* angle against center can give odd result,
-		 * try re-position the center to the closest edge */
-		BMIter eiter;
-		BMEdge *e;
-		float dist_sq_best = len_squared_v2v2(cent_sco, mval_fl);
-
-		BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
-			if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
-				float e_sco[2][2];
-				float cent_sco_test[2];
-				float dist_sq_test;
-
-				ED_view3d_project_float_v2_m4(ar, e->v1->co, e_sco[0], projectMat);
-				ED_view3d_project_float_v2_m4(ar, e->v2->co, e_sco[1], projectMat);
-
-				closest_to_line_segment_v2(cent_sco_test, mval_fl, e_sco[0], e_sco[1]);
-				dist_sq_test = len_squared_v2v2(cent_sco_test, mval_fl);
-				if (dist_sq_test < dist_sq_best) {
-					dist_sq_best = dist_sq_test;
-
-					/* we have a new screen center */
-					copy_v2_v2(cent_sco, cent_sco_test);
+		mul_v2_fl(cent_sco, 1.0f / (float)cent_tot);
+
+		/* not essential, but gives more expected results with edge selection */
+		if (bm->totedgesel) {
+			/* angle against center can give odd result,
+			* try re-position the center to the closest edge */
+			BMIter eiter;
+			BMEdge *e;
+			float dist_sq_best = len_squared_v2v2(cent_sco, mval_fl);
+
+			BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) {
+				if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+					float e_sco[2][2];
+					float cent_sco_test[2];
+					float dist_sq_test;
+
+					ED_view3d_project_float_v2_m4(ar, e->v1->co, e_sco[0], projectMat);
+					ED_view3d_project_float_v2_m4(ar, e->v2->co, e_sco[1], projectMat);
+
+					closest_to_line_segment_v2(cent_sco_test, mval_fl, e_sco[0], e_sco[1]);
+					dist_sq_test = len_squared_v2v2(cent_sco_test, mval_fl);
+					if (dist_sq_test < dist_sq_best) {
+						dist_sq_best = dist_sq_test;
+
+						/* we have a new screen center */
+						copy_v2_v2(cent_sco, cent_sco_test);
+					}
 				}
 			}
 		}
-	}
 
-	sub_v2_v2v2(mval_dir, mval_fl, cent_sco);
-	normalize_v2(mval_dir);
+		sub_v2_v2v2(mval_dir, mval_fl, cent_sco);
+		normalize_v2(mval_dir);
 
-	/* operate on selected verts */
-	BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
-		BMIter eiter;
-		BMEdge *e;
-		float v_sco[2];
+		/* operate on selected verts */
+		BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+			BMIter eiter;
+			BMEdge *e;
+			float v_sco[2];
 
-		if (BM_elem_flag_test(v, BM_ELEM_SELECT) &&
-		    BM_elem_flag_test(v, BM_ELEM_TAG) == false)
-		{
-			/* Rules for */
-			float angle_best = FLT_MAX;
-			BMEdge *e_best = NULL;
+			if (BM_elem_flag_test(v, BM_ELEM_SELECT) &&
+				BM_elem_flag_test(v, BM_ELEM_TAG) == false)
+			{
+				/* Rules for */
+				float angle_best = FLT_MAX;
+				BMEdge *e_best = NULL;
 
 #ifdef USE_TRICKY_EXTEND
-			/* first check if we can select the edge to split based on selection-only */
-			int tot_sel = 0, tot = 0;
-
-			BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
-				if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
-					if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
-						e_best = e;
-						tot_sel += 1;
+				/* first check if we can select the edge to split based on selection-only */
+				int tot_sel = 0, tot = 0;
+
+				BM_ITER_ELEM(e, &eiter, v, BM_EDGES_OF_VERT) {
+					if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+						if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+							e_best = e;
+							tot_sel += 1;
+						}
+						tot += 1;
 					}
-					tot += 1;
 				}
-			}
-			if (tot_sel != 1) {
-				e_best = NULL;
-			}
+				if (tot_sel != 1) {
+					e_best = NULL;
+				}
 
-			/* only one edge selected, operate on that */
-			if (e_best) {
-				goto found_edge;
-			}
-			/* none selected, fall through and find one */
-			else if (tot_sel == 0) {
-				/* pass */
-			}
-			/* selection not 0 or 1, do nothing */
-			else {
-				goto found_edge;
-			}
+				/* only one edge selected, operate on that */
+				if (e_best) {
+					goto found_edge;
+				}
+				/* none selected, fall through and find one */
+				else if (tot_sel == 0) {
+					/* pass */
+				}
+				/* selection not 0 or 1, do nothing */
+				else {
+					goto found_edge;
+				}
 #endif
-			ED_view3d_project_float_v2_m4(ar, v->co, v_sco, projectMat);
+				ED_view3d_project_float_v2_m4(ar, v->co, v_sco, projectMat);
 
-			BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
-				if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
-					BMVert *v_other = BM_edge_other_vert(e, v);
-					float v_other_sco[2];
-					float angle_test;
+				BM_ITER_ELEM(e, &eiter, v, BM_EDGES_OF_VERT) {
+					if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+						BMVert *v_other = BM_edge_other_vert(e, v);
+						float v_other_sco[2];
+						float angle_test;
 
-					ED_view3d_project_float_v2_m4(ar, v_other->co, v_other_sco, projectMat);
+						ED_view3d_project_float_v2_m4(ar, v_other->co, v_other_sco, projectMat);
 
-					/* avoid comparing with view-axis aligned edges (less than a pixel) */
-					if (len_squared_v2v2(v_sco, v_other_sco) > 1.0f) {
-						float v_dir[2];
+						/* avoid comparing with view-axis aligned edges (less than a pixel) */
+						if (len_squared_v2v2(v_sco, v_other_sco) > 1.0f) {
+							float v_dir[2];
 
-						sub_v2_v2v2(v_dir, v_other_sco, v_sco);
-						normalize_v2(v_dir);
+							sub_v2_v2v2(v_dir, v_other_sco, v_sco);
+							normalize_v2(v_dir);
 
-						angle_test = angle_normalized_v2v2(mval_dir, v_dir);
+							angle_test = angle_normalized_v2v2(mval_dir, v_dir);
 
-						if (angle_test < angle_best) {
-							angle_best = angle_test;
-							e_best = e;
+							if (angle_test < angle_best) {
+								angle_best = angle_test;
+								e_best = e;
+							}
 						}
 					}
 				}
-			}
 
 #ifdef USE_TRICKY_EXTEND
-found_edge:
+found_edge :
 #endif
-			if (e_best) {
-				const bool e_select = BM_elem_flag_test_bool(e_best, BM_ELEM_SELECT);
-				BMVert *v_new;
-				BMEdge *e_new;
+				if (e_best) {
+					const bool e_select = BM_elem_flag_test_bool(e_best, BM_ELEM_SELECT);
+					BMVert *v_new;
+					BMEdge *e_new;
 
-				v_new = BM_edge_split(bm, e_best, v, &e_new, 0.0f);
+					v_new = BM_edge_split(bm, e_best, v, &e_new, 0.0f);
 
-				BM_vert_select_set(bm, v, false);
-				BM_edge_select_set(bm, e_new, false);
+					BM_vert_select_set(bm, v, false);
+					BM_edge_select_set(bm, e_new, false);
 
-				BM_vert_select_set(bm, v_new, true);
-				if (e_select) {
-					BM_edge_select_set(bm, e_best, true);
-				}
-				BM_elem_flag_enable(v_new, BM_ELEM_TAG);  /* prevent further splitting */
+					BM_vert_select_set(bm, v_new, true);
+					if (e_select) {
+						BM_edge_select_set(bm, e_best, true);
+					}
+					BM_elem_flag_enable(v_new, BM_ELEM_TAG);  /* prevent further splitting */
 
-				changed = true;
+					changed = true;
+				}
 			}
 		}
-	}
-
-	if (changed) {
-		BM_select_history_clear(bm);
 
-		BM_mesh_select_mode_flush(bm);
+		if (changed) {
+			BM_select_history_clear(bm);
 
-		EDBM_update_generic(em, true, true);
+			BM_mesh_select_mode_flush(bm);
 
-		return OPERATOR_FINISHED;
-	}
-	else {
-		return OPERATOR_CANCELLED;
+			EDBM_update_generic(em, true, true);
+		}
 	}
+
+	MEM_freeN(objects);
+
+	return OPERATOR_FINISHED;
 }



More information about the Bf-blender-cvs mailing list