[Bf-blender-cvs] [bbc33e9] bmesh-boolean-experiment: basic intersection boolean now works
Campbell Barton
noreply at git.blender.org
Tue Oct 27 18:17:24 CET 2015
Commit: bbc33e9c24a42dcce3d9ba66f5d70d4d6f7fdfd4
Author: Campbell Barton
Date: Sat Nov 22 19:47:23 2014 +0100
Branches: bmesh-boolean-experiment
https://developer.blender.org/rBbbc33e9c24a42dcce3d9ba66f5d70d4d6f7fdfd4
basic intersection boolean now works
===================================================================
M source/blender/bmesh/intern/bmesh_core.c
M source/blender/bmesh/intern/bmesh_core.h
M source/blender/bmesh/tools/bmesh_intersect.c
M source/blender/bmesh/tools/bmesh_intersect.h
M source/blender/editors/mesh/editmesh_intersect.c
M source/blender/modifiers/intern/MOD_boolean.c
===================================================================
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index e67aa1d..1e80962 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -805,6 +805,66 @@ void BM_face_kill(BMesh *bm, BMFace *f)
bm_kill_only_face(bm, f);
}
+
+
+void BM_face_kill_loose(BMesh *bm, BMFace *f)
+{
+#ifdef USE_BMESH_HOLES
+ BMLoopList *ls, *ls_next;
+#endif
+
+ BM_CHECK_ELEMENT(f);
+
+#ifdef USE_BMESH_HOLES
+ for (ls = f->loops.first; ls; ls = ls_next)
+#else
+ if (f->l_first)
+#endif
+ {
+ BMLoop *l_iter, *l_next, *l_first;
+
+#ifdef USE_BMESH_HOLES
+ ls_next = ls->next;
+ l_iter = l_first = ls->first;
+#else
+ l_iter = l_first = f->l_first;
+#endif
+
+ do {
+ BMEdge *e;
+ l_next = l_iter->next;
+
+ e = l_iter->e;
+ bmesh_radial_loop_remove(l_iter, e);
+ bm_kill_only_loop(bm, l_iter);
+
+ if (e->l == NULL) {
+ BMVert *v1 = e->v1, *v2 = e->v2;
+
+ bmesh_disk_edge_remove(e, e->v1);
+ bmesh_disk_edge_remove(e, e->v2);
+ bm_kill_only_edge(bm, e);
+
+ if (v1->e == NULL) {
+ bm_kill_only_vert(bm, v1);
+ }
+ if (v2->e == NULL) {
+ bm_kill_only_vert(bm, v2);
+ }
+ }
+ } while ((l_iter = l_next) != l_first);
+
+#ifdef USE_BMESH_HOLES
+ BLI_mempool_free(bm->looplistpool, ls);
+#endif
+ }
+
+ bm_kill_only_face(bm, f);
+}
+
+
+
+
/**
* kills \a e and all faces that use it.
*/
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index 2b100eb..2292259 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -58,6 +58,8 @@ BMFace *BM_face_create_verts(
void BM_face_edges_kill(BMesh *bm, BMFace *f);
void BM_face_verts_kill(BMesh *bm, BMFace *f);
+void BM_face_kill_loose(BMesh *bm, BMFace *f);
+
void BM_face_kill(BMesh *bm, BMFace *f);
void BM_edge_kill(BMesh *bm, BMEdge *e);
void BM_vert_kill(BMesh *bm, BMVert *v);
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 8b36b43..969cda5 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -870,9 +870,10 @@ static void raycast_callback(void *userdata,
}
}
-static bool UNUSED_FUNCTION(isect_bvhtree_point_v3)(BVHTree *tree,
- BMLoop *(*looptris)[3],
- const float co[3])
+static bool isect_bvhtree_point_v3(
+ BVHTree *tree,
+ BMLoop *(*looptris)[3],
+ const float co[3])
{
RaycastData raycast_data = {
looptris,
@@ -884,7 +885,9 @@ static bool UNUSED_FUNCTION(isect_bvhtree_point_v3)(BVHTree *tree,
0
};
BVHTreeRayHit hit = {0};
- float D[3] = {1.0f, 0.0f, 0.0f};
+ float dir[3] = {1.0f, 0.0f, 0.0f};
+
+ // copy_v3_fl(dir, (float)M_SQRT1_3);
/* Need to initialize hit even tho it's not used.
* This is to make it so kdotree believes we didn't intersect anything and
@@ -894,7 +897,7 @@ static bool UNUSED_FUNCTION(isect_bvhtree_point_v3)(BVHTree *tree,
hit.dist = FLT_MAX;
BLI_bvhtree_ray_cast(tree,
- co, D,
+ co, dir,
0.0f,
&hit,
raycast_callback,
@@ -914,12 +917,14 @@ static bool UNUSED_FUNCTION(isect_bvhtree_point_v3)(BVHTree *tree,
* leaving the resulting edges tagged.
*
* \param test_fn Return value: -1: skip, 0: tree_a, 1: tree_b (use_self == false)
+ * \param boolean_mode 0: no-boolean, 1: intersection... etc.
*/
bool BM_mesh_intersect(
BMesh *bm,
struct BMLoop *(*looptris)[3], const int looptris_tot,
int (*test_fn)(BMFace *f, void *user_data), void *user_data,
const bool use_self, const bool use_separate,
+ const int boolean_mode,
const float eps)
{
struct ISectState s;
@@ -1043,9 +1048,13 @@ bool BM_mesh_intersect(
}
MEM_freeN(overlap);
}
- BLI_bvhtree_free(tree_a);
- if (tree_a != tree_b) {
- BLI_bvhtree_free(tree_b);
+
+ if (boolean_mode == 0) {
+ /* no booleans, just free immediate */
+ BLI_bvhtree_free(tree_a);
+ if (tree_a != tree_b) {
+ BLI_bvhtree_free(tree_b);
+ }
}
#else
@@ -1423,6 +1432,79 @@ bool BM_mesh_intersect(
(void)use_separate;
#endif /* USE_SEPARATE */
+ if ((boolean_mode != 0) && BLI_gset_size(s.wire_edges)) {
+
+ {
+ GSetIterator gs_iter;
+
+ /* TODO, avoid calling? */
+ BM_mesh_elem_hflag_disable_all(bm, BM_EDGE, BM_ELEM_TAG, false);
+
+ GSET_ITER (gs_iter, s.wire_edges) {
+ BMEdge *e = BLI_gsetIterator_getKey(&gs_iter);
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+ }
+
+ {
+ /* group vars */
+ int *groups_array;
+ int (*group_index)[2];
+ int group_tot;
+ int i;
+ bool is_inside;
+ BMFace **ftable;
+
+ BM_mesh_elem_table_ensure(bm, BM_FACE);
+ ftable = bm->ftable;
+
+ groups_array = MEM_mallocN(sizeof(*groups_array) * (size_t)bm->totface, __func__);
+ group_tot = BM_mesh_calc_face_groups(
+ bm, groups_array, &group_index,
+ NULL, NULL,
+ 0, BM_EDGE);
+
+ /* first check if island is inside */
+
+ /* TODO, find if islands are inside/outside,
+ * for now remove alternate islands, as simple testcase */
+
+
+ for (i = 0; i < group_tot; i++) {
+ int fg = group_index[i][0];
+ int fg_end = group_index[i][1] + fg;
+
+ is_inside = true;
+
+ {
+ /* for now assyme this is an OK face to test with (not degenerate!) */
+ BMFace *f = ftable[groups_array[fg]];
+ float co[3];
+ BM_face_calc_center_mean(f, co);
+ if (isect_bvhtree_point_v3(test_fn(f, user_data) == 1 ? tree_a : tree_b, looptris, co)) {
+ is_inside = false;
+ }
+ }
+
+ if (is_inside) {
+ for (; fg != fg_end; fg++) {
+ BM_face_kill_loose(bm, ftable[groups_array[fg]]);
+ }
+ }
+ is_inside = !is_inside;
+ }
+
+ MEM_freeN(groups_array);
+ MEM_freeN(group_index);
+ }
+
+ /* no booleans, just free immediate */
+ BLI_bvhtree_free(tree_a);
+ if (tree_a != tree_b) {
+ BLI_bvhtree_free(tree_b);
+ }
+ }
+
has_isect = (BLI_ghash_size(s.face_edges) != 0);
/* cleanup */
diff --git a/source/blender/bmesh/tools/bmesh_intersect.h b/source/blender/bmesh/tools/bmesh_intersect.h
index af6e510..543d8a8 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.h
+++ b/source/blender/bmesh/tools/bmesh_intersect.h
@@ -30,6 +30,7 @@ bool BM_mesh_intersect(
struct BMLoop *(*looptris)[3], const int looptris_tot,
int (*test_fn)(BMFace *f, void *user_data), void *user_data,
const bool use_self, const bool use_separate,
+ const int boolean_mode,
const float eps);
#endif /* __BMESH_INTERSECT_H__ */
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index e2e4638..8f04a5a 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -124,6 +124,7 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
em->looptris, em->tottri,
test_fn, NULL,
use_self, use_separate,
+ 0,
eps);
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 87eff87..a52ef3e 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -208,52 +208,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
bm,
looptris, tottri,
bm_face_isect_pair, &user_data,
- false, true, FLT_EPSILON);
+ false, true,
+ 1,
+ FLT_EPSILON);
MEM_freeN(looptris);
}
- {
- /* group vars */
- int *groups_array;
- int (*group_index)[2];
- int group_tot;
- int i;
- bool is_inside;
- BMFace **ftable;
-
- BM_mesh_elem_table_ensure(bm, BM_FACE);
- ftable = bm->ftable;
-
- groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totface, __func__);
- group_tot = BM_mesh_calc_face_groups(
- bm, groups_array, &group_index,
- NULL, NULL,
- 0, BM_EDGE);
-
- /* first check if island is inside */
-
- /* TODO, find if islands are inside/outside,
- * for now remove alternate islands, as simple testcase */
- is_inside = false;
-
-
- for (i = 0; i < group_tot; i++) {
- int fg = group_index[i][0];
- int fg_end = group_index[i][1] + fg;
-
- if (is_inside) {
- for (; fg != fg_end; fg++) {
- BM_face_kill(bm, ftable[groups_array[fg]]);
- }
- }
- is_inside = !is_inside;
- }
-
- MEM_freeN(groups_array);
- MEM_freeN(group_index);
- }
-
result = CDDM_from_bmesh(bm, true);
BM_mesh_free(bm);
@@ -297,12 +258,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
result = get_quick_derivedMesh(derivedData, dm, bmd->operation);
if (result == NULL) {
- // TIMEIT_START(NewBooleanDerivedMesh)
+ TIMEIT_START(NewBooleanDerivedMesh);
result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob,
1 + bmd->operation);
- // TIMEIT_END(NewBooleanDerivedMesh)
+ TIMEIT_END(NewBooleanDerivedMesh);
}
/* if new mesh returned, return it; otherwise there was
More information about the Bf-blender-cvs
mailing list