[Bf-blender-cvs] [9e32312] bmesh-boolean-experiment: Add boolean as an edit-mode tool

Campbell Barton noreply at git.blender.org
Fri Dec 11 07:36:10 CET 2015


Commit: 9e32312fa1fe62a00039635737bc58e8c6b0a722
Author: Campbell Barton
Date:   Fri Dec 11 17:29:06 2015 +1100
Branches: bmesh-boolean-experiment
https://developer.blender.org/rB9e32312fa1fe62a00039635737bc58e8c6b0a722

Add boolean as an edit-mode tool

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

M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/mesh/editmesh_intersect.c
M	source/blender/editors/mesh/mesh_intern.h
M	source/blender/editors/mesh/mesh_ops.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index b28a00e..c8c0c27 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2380,6 +2380,7 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
         layout.operator("mesh.bevel").vertex_only = False
         layout.operator("mesh.solidify")
         layout.operator("mesh.intersect")
+        layout.operator("mesh.intersect_boolean")
         layout.operator("mesh.wireframe")
 
         layout.separator()
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index 0641701..02dd24e6 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -53,6 +53,10 @@
 /* -------------------------------------------------------------------- */
 /* Cut intersections into geometry */
 
+/** \name Simple Intersect (self-intersect)
+ * \{
+ */
+
 /**
  * Compare selected with its self.
  */
@@ -75,6 +79,23 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
 		return -1;
 	}
 	else if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+		return 1;
+	}
+	else {
+		return 0;
+	}
+}
+
+/**
+ * A flipped version of #bm_face_isect_pair
+ * use for boolean 'difference', which depends on order.
+ */
+static int bm_face_isect_pair_swap(BMFace *f, void *UNUSED(user_data))
+{
+	if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+		return -1;
+	}
+	else if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
 		return 0;
 	}
 	else {
@@ -87,14 +108,6 @@ enum {
 	ISECT_SEL_UNSEL     = 1,
 };
 
-static EnumPropertyItem isect_mode_items[] = {
-	{ISECT_SEL, "SELECT", 0, "Self Intersect",
-	 "Self intersect selected faces"},
-	{ISECT_SEL_UNSEL, "SELECT_UNSELECT", 0, "Selected/Unselected",
-	 "Intersect selected with unselected faces"},
-	{0, NULL, 0, NULL, NULL}
-};
-
 static int edbm_intersect_exec(bContext *C, wmOperator *op)
 {
 	Object *obedit = CTX_data_edit_object(C);
@@ -154,6 +167,14 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
 
 void MESH_OT_intersect(struct wmOperatorType *ot)
 {
+	static EnumPropertyItem isect_mode_items[] = {
+		{ISECT_SEL, "SELECT", 0, "Self Intersect",
+		 "Self intersect selected faces"},
+		{ISECT_SEL_UNSEL, "SELECT_UNSELECT", 0, "Selected/Unselected",
+		 "Intersect selected with unselected faces"},
+		{0, NULL, 0, NULL, NULL}
+	};
+
 	/* identifiers */
 	ot->name = "Intersect";
 	ot->description = "Cut an intersection into faces";
@@ -172,10 +193,99 @@ void MESH_OT_intersect(struct wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+/** \} */
+
 
 /* -------------------------------------------------------------------- */
-/* Face Split by Edges */
+/* Boolean (a kind of intersect) */
+
+/** \name Boolean Intersect
+ *
+ * \note internally this is nearly exactly the same as 'MESH_OT_intersect',
+ * however from a user perspective they are quite different, so expose as different tools.
+ *
+ * \{
+ */
+
+static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
+{
+	Object *obedit = CTX_data_edit_object(C);
+	BMEditMesh *em = BKE_editmesh_from_object(obedit);
+	BMesh *bm = em->bm;
+	const int boolean_operation = RNA_enum_get(op->ptr, "operation");
+	bool use_swap = RNA_boolean_get(op->ptr, "use_swap");
+	const float eps = RNA_float_get(op->ptr, "threshold");
+	int (*test_fn)(BMFace *, void *);
+	bool has_isect;
+
+
+	test_fn = use_swap ? bm_face_isect_pair_swap : bm_face_isect_pair;
+
+	has_isect = BM_mesh_intersect(
+	        bm,
+	        em->looptris, em->tottri,
+	        test_fn, NULL,
+	        false, false, true, true,
+	        boolean_operation,
+	        eps);
+
 
+	if (has_isect) {
+		BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
+
+		if (em->bm->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
+			BMIter iter;
+			BMEdge *e;
+
+			BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+				if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+					BM_edge_select_set(bm, e, true);
+				}
+			}
+		}
+
+		EDBM_mesh_normals_update(em);
+		EDBM_update_generic(em, true, true);
+	}
+	else {
+		BKE_report(op->reports, RPT_WARNING, "No intersections found");
+	}
+
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_intersect_boolean(struct wmOperatorType *ot)
+{
+	static EnumPropertyItem isect_boolean_operation_items[] = {
+		{BMESH_ISECT_BOOLEAN_NONE, "NONE", 0, "None", ""},
+		{BMESH_ISECT_BOOLEAN_ISECT, "INTERSECT", 0, "Intersect", ""},
+		{BMESH_ISECT_BOOLEAN_UNION, "UNION", 0, "Union", ""},
+		{BMESH_ISECT_BOOLEAN_DIFFERENCE, "DIFFERENCE", 0, "Difference", ""},
+		{0, NULL, 0, NULL, NULL}
+	};
+
+	/* identifiers */
+	ot->name = "Boolean Intersect";
+	ot->description = "Cut solid geometry from selected to unselected";
+	ot->idname = "MESH_OT_intersect_boolean";
+
+	/* api callbacks */
+	ot->exec = edbm_intersect_boolean_exec;
+	ot->poll = ED_operator_editmesh;
+
+	/* props */
+	RNA_def_enum(ot->srna, "operation", isect_boolean_operation_items, BMESH_ISECT_BOOLEAN_DIFFERENCE, "Boolean", "");
+	RNA_def_boolean(ot->srna, "use_swap", false, "Swap", "Use with difference intersection to swap which side is kept");
+	RNA_def_float_distance(ot->srna, "threshold", 0.000001f, 0.0, 0.01, "Merge threshold", "", 0.0, 0.001);
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/* Face Split by Edges */
 
 /** \name Face/Edge Split
  * \{ */
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index c56465f..3b018ea 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -109,6 +109,7 @@ void MESH_OT_inset(struct wmOperatorType *ot);
 
 /* *** editmesh_intersect.c *** */
 void MESH_OT_intersect(struct wmOperatorType *ot);
+void MESH_OT_intersect_boolean(struct wmOperatorType *ot);
 void MESH_OT_face_split_by_edges(struct wmOperatorType *ot);
 
 
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 9718e63..e24dfa3 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -179,6 +179,7 @@ void ED_operatortypes_mesh(void)
 	WM_operatortype_append(MESH_OT_inset);
 	WM_operatortype_append(MESH_OT_offset_edge_loops);
 	WM_operatortype_append(MESH_OT_intersect);
+	WM_operatortype_append(MESH_OT_intersect_boolean);
 	WM_operatortype_append(MESH_OT_face_split_by_edges);
 	WM_operatortype_append(MESH_OT_poke);
 	WM_operatortype_append(MESH_OT_wireframe);




More information about the Bf-blender-cvs mailing list