[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49075] trunk/blender/source/blender/ editors/mesh/editmesh_tools.c: Separate meshes by loose parts and materials now works in object mode as well as editmode .

Campbell Barton ideasman42 at gmail.com
Fri Jul 20 12:33:15 CEST 2012


Revision: 49075
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49075
Author:   campbellbarton
Date:     2012-07-20 10:33:15 +0000 (Fri, 20 Jul 2012)
Log Message:
-----------
Separate meshes by loose parts and materials now works in object mode as well as editmode.

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

Modified: trunk/blender/source/blender/editors/mesh/editmesh_tools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2012-07-20 09:49:54 UTC (rev 49074)
+++ trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2012-07-20 10:33:15 UTC (rev 49075)
@@ -2790,121 +2790,110 @@
 	RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
 }
 
-static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
+static int mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 {
-	Base *basenew;
+	Base *base_new;
 	BMIter iter;
 	BMVert *v;
 	BMEdge *e;
-	Object *obedit = editbase->object;
-	Mesh *me = obedit->data;
-	BMEditMesh *em = me->edit_btmesh;
+	Object *obedit = base_old->object;
 	BMesh *bm_new;
-	
-	if (!em)
-		return FALSE;
-		
+
 	bm_new = BM_mesh_create(&bm_mesh_allocsize_default);
-	CustomData_copy(&em->bm->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
-	CustomData_copy(&em->bm->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
-	CustomData_copy(&em->bm->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
-	CustomData_copy(&em->bm->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
+	CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 
 	CustomData_bmesh_init_pool(&bm_new->vdata, bm_mesh_allocsize_default.totvert, BM_VERT);
 	CustomData_bmesh_init_pool(&bm_new->edata, bm_mesh_allocsize_default.totedge, BM_EDGE);
 	CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
 	CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
-		
-	basenew = ED_object_add_duplicate(bmain, scene, editbase, USER_DUP_MESH);
+
+	base_new = ED_object_add_duplicate(bmain, scene, base_old, USER_DUP_MESH);
 	/* DAG_scene_sort(bmain, scene); */ /* normally would call directly after but in this case delay recalc */
-	assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
+	assign_matarar(base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
 
-	ED_base_object_select(basenew, BA_DESELECT);
-	
-	EDBM_op_callf(em, wmop, "duplicate geom=%hvef dest=%p", BM_ELEM_SELECT, bm_new);
-	EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_FACES);
+	ED_base_object_select(base_new, BA_SELECT);
 
+	BMO_op_callf(bm_old, "duplicate geom=%hvef dest=%p", BM_ELEM_SELECT, bm_new);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_FACES);
+
 	/* clean up any loose edges */
-	BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
+	BM_ITER_MESH (e, &iter, bm_old, BM_EDGES_OF_MESH) {
 		if (BM_elem_flag_test(e, BM_ELEM_HIDDEN))
 			continue;
 
 		if (!BM_edge_is_wire(e)) {
-			BM_edge_select_set(em->bm, e, FALSE);
+			BM_edge_select_set(bm_old, e, FALSE);
 		}
 	}
-	EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_EDGES);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_EDGES);
 
 	/* clean up any loose verts */
-	BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
+	BM_ITER_MESH (v, &iter, bm_old, BM_VERTS_OF_MESH) {
 		if (BM_elem_flag_test(v, BM_ELEM_HIDDEN))
 			continue;
 
 		if (BM_vert_edge_count(v) != 0) {
-			BM_vert_select_set(em->bm, v, FALSE);
+			BM_vert_select_set(bm_old, v, FALSE);
 		}
 	}
 
-	EDBM_op_callf(em, wmop, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_VERTS);
+	BMO_op_callf(bm_old, "delete geom=%hvef context=%i", BM_ELEM_SELECT, DEL_VERTS);
 
 	BM_mesh_normals_update(bm_new, TRUE);
 
-	BM_mesh_bm_to_me(bm_new, basenew->object->data, FALSE);
-		
+	BM_mesh_bm_to_me(bm_new, base_new->object->data, FALSE);
+
 	BM_mesh_free(bm_new);
-	((Mesh *)basenew->object->data)->edit_btmesh = NULL;
+	((Mesh *)base_new->object->data)->edit_btmesh = NULL;
 	
 	return TRUE;
 }
 
-static int mesh_separate_material(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
+static int mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 {
 	BMFace *f_cmp, *f;
 	BMIter iter;
 	int result = FALSE;
-	Object *obedit = editbase->object;
-	BMEditMesh *em = BMEdit_FromObject(obedit);
-	BMesh *bm = em->bm;
 
-	EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+	BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
 
-	while ((f_cmp = BM_iter_at_index(bm, BM_FACES_OF_MESH, NULL, 0))) {
+	while ((f_cmp = BM_iter_at_index(bm_old, BM_FACES_OF_MESH, NULL, 0))) {
 		const short mat_nr = f_cmp->mat_nr;
 		int tot = 0;
 
-		BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+		BM_ITER_MESH (f, &iter, bm_old, BM_FACES_OF_MESH) {
 			if (f->mat_nr == mat_nr) {
-				BM_face_select_set(bm, f, TRUE);
+				BM_face_select_set(bm_old, f, TRUE);
 				tot++;
 			}
 		}
 
 		/* leave the current object with some materials */
-		if (tot == bm->totface) {
+		if (tot == bm_old->totface) {
 			break;
 		}
 
 		/* Move selection into a separate object */
-		result |= mesh_separate_selected(bmain, scene, editbase, wmop);
+		result |= mesh_separate_selected(bmain, scene, base_old, bm_old);
 	}
 
 	return result;
 }
 
-static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase, wmOperator *wmop)
+static int mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 {
 	int i;
 	BMEdge *e;
 	BMVert *v_seed;
 	BMWalker walker;
 	int result = FALSE;
-	Object *obedit = editbase->object;
-	BMEditMesh *em = BMEdit_FromObject(obedit);
-	BMesh *bm = em->bm;
-	int max_iter = bm->totvert;
+	int max_iter = bm_old->totvert;
 
 	/* Clear all selected vertices */
-	EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+	BM_mesh_elem_hflag_disable_all(bm_old, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
 
 	/* A "while (true)" loop should work here as each iteration should
 	 * select and remove at least one vertex and when all vertices
@@ -2913,7 +2902,7 @@
 	 * original mesh.*/
 	for (i = 0; i < max_iter; i++) {
 		/* Get a seed vertex to start the walk */
-		v_seed = BM_iter_at_index(bm, BM_VERTS_OF_MESH, NULL, 0);
+		v_seed = BM_iter_at_index(bm_old, BM_VERTS_OF_MESH, NULL, 0);
 
 		/* No vertices available, can't do anything */
 		if (v_seed == NULL) {
@@ -2921,33 +2910,33 @@
 		}
 
 		/* Select the seed explicitly, in case it has no edges */
-		BM_vert_select_set(bm, v_seed, TRUE);
+		BM_vert_select_set(bm_old, v_seed, TRUE);
 
 		/* Walk from the single vertex, selecting everything connected
 		 * to it */
-		BMW_init(&walker, bm, BMW_SHELL,
+		BMW_init(&walker, bm_old, BMW_SHELL,
 		         BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
 		         BMW_FLAG_NOP, /* BMESH_TODO - should be BMW_FLAG_TEST_HIDDEN ? */
 		         BMW_NIL_LAY);
 
 		e = BMW_begin(&walker, v_seed);
 		for (; e; e = BMW_step(&walker)) {
-			BM_vert_select_set(bm, e->v1, TRUE);
-			BM_vert_select_set(bm, e->v2, TRUE);
+			BM_vert_select_set(bm_old, e->v1, TRUE);
+			BM_vert_select_set(bm_old, e->v2, TRUE);
 		}
 		BMW_end(&walker);
-				
+
 		/* Flush the selection to get edge/face selections matching
 		 * the vertex selection */
-		EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);
+		BM_mesh_select_mode_flush_ex(bm_old, SCE_SELECT_VERTEX);
 
-		if (bm->totvert == bm->totvertsel) {
+		if (bm_old->totvert == bm_old->totvertsel) {
 			/* Every vertex selected, nothing to separate, work is done */
 			break;
 		}
 
 		/* Move selection into a separate object */
-		result |= mesh_separate_selected(bmain, scene, editbase, wmop);
+		result |= mesh_separate_selected(bmain, scene, base_old, bm_old);
 	}
 
 	return result;
@@ -2957,24 +2946,66 @@
 {
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
-	Base *base = CTX_data_active_base(C);
 	int retval = 0, type = RNA_enum_get(op->ptr, "type");
 	
-	if (type == 0)
-		retval = mesh_separate_selected(bmain, scene, base, op);
-	else if (type == 1)
-		retval = mesh_separate_material(bmain, scene, base, op);
-	else if (type == 2)
-		retval = mesh_separate_loose(bmain, scene, base, op);
+	if (ED_operator_editmesh(C)) {
+		Base *base = CTX_data_active_base(C);
+		BMEditMesh *em = BMEdit_FromObject(base->object);
 
+		/* editmode separate */
+		if      (type == 0) retval = mesh_separate_selected(bmain, scene, base, em->bm);
+		else if (type == 1) retval = mesh_separate_material(bmain, scene, base, em->bm);
+		else if (type == 2) retval = mesh_separate_loose(bmain, scene, base, em->bm);
+		else                BLI_assert(0);
+
+		if (retval) {
+			EDBM_update_generic(C, em, TRUE);
+		}
+	}
+	else {
+		if (type == 0) {
+			BKE_report(op->reports, RPT_ERROR, "Selecton not supported in object mode");
+			return OPERATOR_CANCELLED;
+		}
+
+		/* object mode separate */
+		CTX_DATA_BEGIN(C, Base *, base_iter, selected_editable_bases)
+		{
+			Object *ob = base_iter->object;
+			if (ob->type == OB_MESH) {
+				Mesh *me = ob->data;
+				if (me->id.lib == NULL) {
+					BMesh *bm_old = NULL;
+					int retval_iter = 0;
+
+					bm_old = BM_mesh_create(&bm_mesh_allocsize_default);
+
+					BM_mesh_bm_from_me(bm_old, me, FALSE, 0);
+
+					if      (type == 1) retval_iter = mesh_separate_material(bmain, scene, base_iter, bm_old);
+					else if (type == 2) retval_iter = mesh_separate_loose(bmain, scene, base_iter, bm_old);
+					else                BLI_assert(0);
+
+					if (retval_iter) {
+						BM_mesh_bm_to_me(bm_old, me, FALSE);
+
+						DAG_id_tag_update(&me->id, OB_RECALC_DATA);
+						WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
+					}
+
+					BM_mesh_free(bm_old);
+
+					retval |= retval_iter;
+				}
+			}
+		}
+		CTX_DATA_END;
+	}
+
 	if (retval) {
-		BMEditMesh *em = BMEdit_FromObject(base->object);
-
 		/* delay depsgraph recalc until all objects are duplicated */
 		DAG_scene_sort(bmain, scene);
 
-		EDBM_update_generic(C, em, TRUE);
-
 		return OPERATOR_FINISHED;
 	}
 
@@ -3000,7 +3031,7 @@
 	/* api callbacks */
 	ot->invoke = WM_menu_invoke;
 	ot->exec = edbm_separate_exec;
-	ot->poll = ED_operator_editmesh;
+	ot->poll = ED_operator_scene_editable; /* object and editmode */
 	
 	/* flags */
 	ot->flag = OPTYPE_UNDO;
@@ -5106,7 +5137,7 @@
 	Object *obedit = CTX_data_edit_object(C);
 	BMEditMesh *em = BMEdit_FromObject(obedit);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list