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

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to