[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