[Bf-blender-cvs] [983ffec] bmesh-boolean-experiment: Minor changes needed for for accessing booleans in editmode
Campbell Barton
noreply at git.blender.org
Fri Dec 11 07:36:09 CET 2015
Commit: 983ffec3e56b4633824c3a0737383003d7d53a57
Author: Campbell Barton
Date: Fri Dec 11 16:43:19 2015 +1100
Branches: bmesh-boolean-experiment
https://developer.blender.org/rB983ffec3e56b4633824c3a0737383003d7d53a57
Minor changes needed for for accessing booleans in editmode
- Replace hard coded edge-delimiter checks with a call that
forwards face-side check to the callback passed to BM_mesh_intersect.
- Copy the hflag exactly when splitting a by the edge-net.
Also remove experimental bvh-overlap test.
===================================================================
M source/blender/bmesh/intern/bmesh_polygon_edgenet.c
M source/blender/bmesh/tools/bmesh_intersect.c
M source/blender/bmesh/tools/bmesh_intersect.h
M source/blender/modifiers/intern/MOD_boolean.c
===================================================================
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 1493fb6..39fd445 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -451,6 +451,13 @@ bool BM_face_split_edgenet(
BLI_array_append(face_arr, f_new);
copy_v3_v3(f_new->no, f->no);
+ /* warning, normally don't do this,
+ * its needed for mesh intersection - which tracks face-sides based on selection */
+ f_new->head.hflag = f->head.hflag;
+ if (f->head.hflag & BM_ELEM_SELECT) {
+ bm->totfacesel++;
+ }
+
BM_ELEM_API_FLAG_ENABLE(f_new, FACE_NET);
/* add new verts to keep finding loops for
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 8804b09..5492526 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -80,7 +80,6 @@
#define USE_BVH
#define USE_BOOLEAN_RAYCAST_DRAW
-// #define USE_BOOLEAN_RAYCAST_OVERLAP /* use bvhtree overlap otherwise raycast */
#ifdef USE_BOOLEAN_RAYCAST_DRAW
/* add these locally when using these functions for testing */
@@ -90,15 +89,6 @@ extern void bl_debug_draw_edge_add(const float v0[3], const float v1[3]);
extern void bl_debug_color_set(const unsigned int col);
#endif
-enum {
- BOOLEAN_NONE = -1,
- /* aligned with BooleanModifierOp */
- BOOLEAN_ISECT = 0,
- BOOLEAN_UNION = 1,
- BOOLEAN_DIFFERENCE = 2,
-};
-
-
static void tri_v3_scale(
float v1[3], float v2[3], float v3[3],
const float t)
@@ -504,18 +494,27 @@ static BMVert *bm_isect_edge_tri(
return NULL;
}
-static bool bm_loop_filter_fn(const BMLoop *l, void *UNUSED(user_data))
+struct LoopFilterWrap {
+ int (*test_fn)(BMFace *f, void *user_data);
+ void *user_data;
+};
+
+static bool bm_loop_filter_fn(const BMLoop *l, void *user_data)
{
if (BM_elem_flag_test(l->e, BM_ELEM_TAG)) {
return false;
}
if (l->radial_next != l) {
+ struct LoopFilterWrap *data = user_data;
BMLoop *l_iter = l->radial_next;
- const char hflag_test = BM_ELEM_DRAW; /* XXX, set in MOD_boolean.c */
- const char hflag = BM_elem_flag_test(l->f, hflag_test);
+ const int face_side = data->test_fn(l->f, data->user_data);
do {
- if (BM_elem_flag_test(l_iter->f, hflag_test) != hflag) {
+ const int face_side_other = data->test_fn(l_iter->f, data->user_data);
+ if (UNLIKELY(face_side_other == -1)) {
+ /* pass */
+ }
+ else if (face_side_other != face_side) {
return false;
}
} while ((l_iter = l_iter->radial_next) != l);
@@ -839,76 +838,6 @@ static void bm_isect_tri_tri(
#ifdef USE_BVH
-
-/* overlap or raycast */
-#ifdef USE_BOOLEAN_RAYCAST_OVERLAP
-struct OverlapData {
- const float **looptris;
-
- const float *co;
- float dir[3];
-
- int num_isect;
-};
-
-static bool bmbvh_overlap_cb(void *userdata, int index_a, int UNUSED(index_b), int UNUSED(thread))
-{
- struct OverlapData *raycast_data = userdata;
- const float **looptris = raycast_data->looptris;
- const float *v0 = looptris[index_a * 3 + 0];
- const float *v1 = looptris[index_a * 3 + 1];
- const float *v2 = looptris[index_a * 3 + 2];
- float dist;
- float uv[2];
-
- if (isect_ray_tri_watertight_v3_simple(raycast_data->co, raycast_data->dir, v0, v1, v2, &dist, uv)) {
- raycast_data->num_isect++;
- return true;
- }
- return false;
-}
-
-static int isect_bvhtree_point_v3(
- BVHTree *tree,
- const float **looptris,
- const float co[3])
-{
- struct OverlapData raycast_data = {
- looptris,
- };
-
-
- float plane_cos[6];
- BVHTree *planetree;
- unsigned int tot = 0;
- BVHTreeOverlap *results;
-
- raycast_data.num_isect = 0;
- raycast_data.co = co;
- raycast_data.dir[0] = 1;
- raycast_data.dir[1] = 0;
- raycast_data.dir[2] = 0;
-
-
- planetree = BLI_bvhtree_new(2, 0, 8, 8);
-
- copy_v3_v3(plane_cos + 0, co);
- copy_v3_v3(plane_cos + 3, co);
- plane_cos[0] += 10;
- BLI_bvhtree_insert(planetree, 0, plane_cos, 2);
- BLI_bvhtree_balance(planetree);
-
- results = BLI_bvhtree_overlap(tree, planetree, &tot, bmbvh_overlap_cb, &raycast_data);
- BLI_bvhtree_free(planetree);
- if (results)
- MEM_freeN(results);
-// return (tot & 1) == 1;
-// return (raycast_data.num_isect & 1) == 1;
- return raycast_data.num_isect;
-}
-
-#else // raycast
-
struct RaycastData {
const float **looptris;
BLI_Buffer *z_buffer;
@@ -1029,17 +958,15 @@ static int isect_bvhtree_point_v3(
// return (num_isect & 1) == 1;
return num_isect;
}
-#endif // USE_BOOLEAN_RAYCAST_OVERLAP
-
-#endif
+#endif /* USE_BVH */
/**
* Intersect tessellated faces
* 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.
+ * \param boolean_mode -1: no-boolean, 0: intersection... see #BOOLEAN_ISECT.
*/
bool BM_mesh_intersect(
BMesh *bm,
@@ -1118,7 +1045,7 @@ bool BM_mesh_intersect(
printf("data = [\n");
#endif
- if (boolean_mode != BOOLEAN_NONE) {
+ if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE) {
/* keep original geometrty for raycast callbacks */
float **cos;
int i, j;
@@ -1194,7 +1121,7 @@ bool BM_mesh_intersect(
MEM_freeN(overlap);
}
- if (boolean_mode == BOOLEAN_NONE) {
+ if (boolean_mode == BMESH_ISECT_BOOLEAN_NONE) {
/* no booleans, just free immediate */
BLI_bvhtree_free(tree_a);
if (tree_a != tree_b) {
@@ -1315,7 +1242,7 @@ bool BM_mesh_intersect(
/* important to handle before edgenet */
#ifdef USE_DISSOLVE
- if (use_dissolve && (boolean_mode == BOOLEAN_NONE)) {
+ if (use_dissolve && (boolean_mode == BMESH_ISECT_BOOLEAN_NONE)) {
/* first pass */
BMVert *(*splice_ls)[2];
STACK_DECLARE(splice_ls);
@@ -1580,7 +1507,7 @@ bool BM_mesh_intersect(
BM_mesh_edgesplit(bm, false, true, false);
}
- else if (boolean_mode != BOOLEAN_NONE) {
+ else if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE) {
GSetIterator gs_iter;
/* no need to clear for boolean */
@@ -1594,7 +1521,7 @@ bool BM_mesh_intersect(
(void)use_separate;
#endif /* USE_SEPARATE */
- if ((boolean_mode != BOOLEAN_NONE)) {
+ if ((boolean_mode != BMESH_ISECT_BOOLEAN_NONE)) {
BVHTree *tree_pair[2] = {tree_a, tree_b};
/* group vars */
@@ -1607,10 +1534,16 @@ bool BM_mesh_intersect(
BM_mesh_elem_table_ensure(bm, BM_FACE);
ftable = bm->ftable;
+ /* wrap the face-test callback to make it into an edge-loop delimiter */
+ struct LoopFilterWrap user_data_wrap = {
+ .test_fn = test_fn,
+ .user_data = user_data,
+ };
+
groups_array = MEM_mallocN(sizeof(*groups_array) * (size_t)bm->totface, __func__);
group_tot = BM_mesh_calc_face_groups(
bm, groups_array, &group_index,
- bm_loop_filter_fn, NULL,
+ bm_loop_filter_fn, &user_data_wrap,
0, BM_EDGE);
#ifdef USE_DUMP
@@ -1641,15 +1574,15 @@ bool BM_mesh_intersect(
hits = isect_bvhtree_point_v3(tree_pair[side], looptri_coords, co);
switch (boolean_mode) {
- case BOOLEAN_ISECT:
+ case BMESH_ISECT_BOOLEAN_ISECT:
do_remove = ((hits & 1) != 1);
do_flip = false;
break;
- case BOOLEAN_UNION:
+ case BMESH_ISECT_BOOLEAN_UNION:
do_remove = ((hits & 1) == 1);
do_flip = false;
break;
- case BOOLEAN_DIFFERENCE:
+ case BMESH_ISECT_BOOLEAN_DIFFERENCE:
do_remove = ((hits & 1) == 1) == side;
do_flip = (side == 0);
break;
@@ -1724,7 +1657,7 @@ bool BM_mesh_intersect(
}
}
- if (boolean_mode != BOOLEAN_NONE) {
+ if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE) {
MEM_freeN(looptri_coords);
/* no booleans, just free immediate */
diff --git a/source/blender/bmesh/tools/bmesh_intersect.h b/source/blender/bmesh/tools/bmesh_intersect.h
index 1049013..d0cc416 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.h
+++ b/source/blender/bmesh/tools/bmesh_intersect.h
@@ -33,4 +33,12 @@ bool BM_mesh_intersect(
const int boolean_mode,
const float eps);
+enum {
+ BMESH_ISECT_BOOLEAN_NONE = -1,
+ /* aligned with BooleanModifierOp */
+ BMESH_ISECT_BOOLEAN_ISECT = 0,
+ BMESH_ISECT_BOOLEAN_UNION = 1,
+ BMESH_ISECT_BOOLEAN_DIFFERENCE = 2,
+};
+
#endif /* __BMESH_INTERSECT_H__ */
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 4a72926..031131f 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -167,7 +167,7 @@ static DerivedMesh *get_quick_derivedMesh(DerivedMesh *derivedData, DerivedMesh
*/
static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
{
- return BM_elem_flag_test_bool(f, BM_FACE_TAG);
+ return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0;
}
static DerivedMesh *applyModifier_bmesh(
More information about the Bf-blender-cvs
mailing list