diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-07-30 10:48:20 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-07-30 10:50:28 +0400 |
commit | 4849583e241baeadf965e2dcdb8b11052f3c2dac (patch) | |
tree | 9db8446e1b0ec02f511da00c4d7a0bd1e8aa8c3e /source/blender/blenkernel | |
parent | 3a4e8f8184cfde3062bfad1a7745aba02984535d (diff) |
BMesh: callback for bmbvh so caller can choose faces
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_editmesh_bvh.h | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editmesh_bvh.c | 86 |
2 files changed, 76 insertions, 23 deletions
diff --git a/source/blender/blenkernel/BKE_editmesh_bvh.h b/source/blender/blenkernel/BKE_editmesh_bvh.h index 355e817f621..168f700d132 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 76ea340ecbd..442ab26ffc8 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); |