[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