[Bf-blender-cvs] [4849583] master: BMesh: callback for bmbvh so caller can choose faces

Campbell Barton noreply at git.blender.org
Wed Jul 30 08:58:14 CEST 2014


Commit: 4849583e241baeadf965e2dcdb8b11052f3c2dac
Author: Campbell Barton
Date:   Wed Jul 30 16:48:20 2014 +1000
Branches: master
https://developer.blender.org/rB4849583e241baeadf965e2dcdb8b11052f3c2dac

BMesh: callback for bmbvh so caller can choose faces

===================================================================

M	source/blender/blenkernel/BKE_editmesh_bvh.h
M	source/blender/blenkernel/intern/editmesh_bvh.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_editmesh_bvh.h b/source/blender/blenkernel/BKE_editmesh_bvh.h
index 355e817..168f700 100644
--- a/source/blender/blenkernel/BKE_editmesh_bvh.h
+++ b/source/blender/blenkernel/BKE_editmesh_bvh.h
@@ -43,9 +43,16 @@ struct Scene;
 
 typedef struct BMBVHTree BMBVHTree;
 
-BMBVHTree      *BKE_bmbvh_new_from_editmesh(struct BMEditMesh *em, int flag, const float (*cos_cage)[3], const bool cos_cage_free);
-BMBVHTree      *BKE_bmbvh_new(struct BMesh *bm, struct BMLoop *(*looptris)[3], int looptris_tot, int flag,
-                              const float (*cos_cage)[3], const bool cos_cage_free);
+BMBVHTree      *BKE_bmbvh_new_from_editmesh(
+        struct BMEditMesh *em, int flag,
+        const float (*cos_cage)[3], const bool cos_cage_free);
+BMBVHTree      *BKE_bmbvh_new_ex(
+        struct BMesh *bm, struct BMLoop *(*looptris)[3], int looptris_tot, int flag,
+        const float (*cos_cage)[3], const bool cos_cage_free,
+        bool (*test_fn)(struct BMFace *, void *user_data), void *user_data);
+BMBVHTree      *BKE_bmbvh_new(
+        struct BMesh *bm, struct BMLoop *(*looptris)[3], int looptris_tot, int flag,
+        const float (*cos_cage)[3], const bool cos_cage_free);
 void            BKE_bmbvh_free(BMBVHTree *tree);
 struct BVHTree *BKE_bmbvh_tree_get(BMBVHTree *tree);
 struct BMFace  *BKE_bmbvh_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], const float radius,
diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c
index 76ea340..442ab26 100644
--- a/source/blender/blenkernel/intern/editmesh_bvh.c
+++ b/source/blender/blenkernel/intern/editmesh_bvh.c
@@ -53,13 +53,17 @@ struct BMBVHTree {
 	int flag;
 };
 
-BMBVHTree *BKE_bmbvh_new_from_editmesh(BMEditMesh *em, int flag, const float (*cos_cage)[3], const bool cos_cage_free)
+BMBVHTree *BKE_bmbvh_new_from_editmesh(
+        BMEditMesh *em, int flag,
+        const float (*cos_cage)[3], const bool cos_cage_free)
 {
 	return BKE_bmbvh_new(em->bm, em->looptris, em->tottri, flag, cos_cage, cos_cage_free);
 }
 
-BMBVHTree *BKE_bmbvh_new(BMesh *bm, BMLoop *(*looptris)[3], int looptris_tot, int flag, const float (*cos_cage)[3],
-const bool cos_cage_free)
+BMBVHTree *BKE_bmbvh_new_ex(
+        BMesh *bm, BMLoop *(*looptris)[3], int looptris_tot, int flag,
+        const float (*cos_cage)[3], const bool cos_cage_free,
+        bool (*test_fn)(BMFace *, void *user_data), void *user_data)
 {
 	/* could become argument */
 	const float epsilon = FLT_EPSILON * 2.0f;
@@ -69,6 +73,10 @@ const bool cos_cage_free)
 	int i;
 	int tottri;
 
+	/* avoid testing every tri */
+	BMFace *f_test, *f_test_prev;
+	bool test_fn_ret;
+
 	/* BKE_editmesh_tessface_calc() must be called already */
 	BLI_assert(looptris_tot != 0 || bm->totface == 0);
 
@@ -83,18 +91,22 @@ const bool cos_cage_free)
 	bmtree->cos_cage_free = cos_cage_free;
 	bmtree->flag = flag;
 
-	if (flag & (BMBVH_RESPECT_SELECT)) {
+	if (test_fn) {
+		/* callback must do... */
+		BLI_assert(!(flag & (BMBVH_RESPECT_SELECT | BMBVH_RESPECT_HIDDEN)));
+
+		f_test_prev = NULL;
+		test_fn_ret = false;
+
 		tottri = 0;
 		for (i = 0; i < looptris_tot; i++) {
-			if (BM_elem_flag_test(looptris[i][0]->f, BM_ELEM_SELECT)) {
-				tottri++;
+			f_test = looptris[i][0]->f;
+			if (f_test != f_test_prev) {
+				test_fn_ret = test_fn(f_test, user_data);
+				f_test_prev = f_test;
 			}
-		}
-	}
-	else if (flag & (BMBVH_RESPECT_HIDDEN)) {
-		tottri = 0;
-		for (i = 0; i < looptris_tot; i++) {
-			if (!BM_elem_flag_test(looptris[i][0]->f, BM_ELEM_HIDDEN)) {
+
+			if (test_fn_ret) {
 				tottri++;
 			}
 		}
@@ -105,17 +117,19 @@ const bool cos_cage_free)
 
 	bmtree->tree = BLI_bvhtree_new(tottri, epsilon, 8, 8);
 
-	for (i = 0; i < looptris_tot; i++) {
+	f_test_prev = NULL;
+	test_fn_ret = false;
 
-		if (flag & BMBVH_RESPECT_SELECT) {
+	for (i = 0; i < looptris_tot; i++) {
+		if (test_fn) {
 			/* note, the arrays wont align now! take care */
-			if (!BM_elem_flag_test(looptris[i][0]->f, BM_ELEM_SELECT)) {
-				continue;
+			f_test = looptris[i][0]->f;
+			if (f_test != f_test_prev) {
+				test_fn_ret = test_fn(f_test, user_data);
+				f_test_prev = f_test;
 			}
-		}
-		else if (flag & BMBVH_RESPECT_HIDDEN) {
-			/* note, the arrays wont align now! take care */
-			if (BM_elem_flag_test(looptris[i][0]->f, BM_ELEM_HIDDEN)) {
+
+			if (!test_fn_ret) {
 				continue;
 			}
 		}
@@ -139,6 +153,38 @@ const bool cos_cage_free)
 	return bmtree;
 }
 
+static bool bm_face_is_select(BMFace *f, void *UNUSED(user_data))
+{
+	return (BM_elem_flag_test(f, BM_ELEM_SELECT) != 0);
+}
+
+static bool bm_face_is_not_hidden(BMFace *f, void *UNUSED(user_data))
+{
+	return (BM_elem_flag_test(f, BM_ELEM_HIDDEN) == 0);
+}
+
+BMBVHTree *BKE_bmbvh_new(
+        BMesh *bm, BMLoop *(*looptris)[3], int looptris_tot, int flag,
+        const float (*cos_cage)[3], const bool cos_cage_free)
+{
+	bool (*test_fn)(BMFace *, void *user_data);
+
+	if (flag & BMBVH_RESPECT_SELECT) {
+		test_fn = bm_face_is_select;
+	}
+	else if (flag & BMBVH_RESPECT_HIDDEN) {
+		test_fn = bm_face_is_not_hidden;
+	}
+	else {
+		test_fn = NULL;
+	}
+
+	flag &= ~(BMBVH_RESPECT_SELECT | BMBVH_RESPECT_HIDDEN);
+
+	return BKE_bmbvh_new_ex(bm, looptris, looptris_tot, flag, cos_cage, cos_cage_free, test_fn, NULL);
+}
+
+
 void BKE_bmbvh_free(BMBVHTree *bmtree)
 {
 	BLI_bvhtree_free(bmtree->tree);




More information about the Bf-blender-cvs mailing list