Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2019-08-24 01:45:09 +0300
committermano-wii <germano.costa@ig.com.br>2019-08-24 01:51:18 +0300
commita68e8ac993a169b63365ffc099d3f01581f6ce0b (patch)
tree78816abea17a1b16d5d8ae666f8d211eb2c0b62e /source/blender/blenkernel/intern/bvhutils.c
parent4c353205ea2d15c3cd314eeeaf60edc04f4c06ad (diff)
BKE bvhutils: create and use new `BKE_bvhtree_from_editmesh_get`
With this function it is easier to create and have control over editmeshes `BHVtree`s.
Diffstat (limited to 'source/blender/blenkernel/intern/bvhutils.c')
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c276
1 files changed, 180 insertions, 96 deletions
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 1210e6f18ce..04e3b4ff2ae 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -425,11 +425,11 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree(float epsilon,
int tree_type,
int axis,
BMEditMesh *em,
- const int verts_num,
const BLI_bitmap *verts_mask,
int verts_num_active)
{
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+ const int verts_num = em->bm->totvert;
if (verts_mask) {
BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num));
}
@@ -516,53 +516,53 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data,
int verts_num_active,
float epsilon,
int tree_type,
- int axis)
+ int axis,
+ const int bvh_cache_type,
+ BVHCache **bvh_cache)
{
- BVHTree *tree = bvhtree_from_editmesh_verts_create_tree(
- epsilon, tree_type, axis, em, em->bm->totvert, verts_mask, verts_num_active);
-
- if (tree) {
- memset(data, 0, sizeof(*data));
- data->tree = tree;
- data->em = em;
- data->nearest_callback = NULL;
- data->raycast_callback = editmesh_verts_spherecast;
- }
-
- return tree;
-}
+ BVHTree *tree = NULL;
-BVHTree *bvhtree_from_editmesh_verts(BVHTreeFromEditMesh *data,
- BMEditMesh *em,
- float epsilon,
- int tree_type,
- int axis,
- BVHCache **bvh_cache)
-{
if (bvh_cache) {
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree);
+ data->cached = bvhcache_find(*bvh_cache, bvh_cache_type, &data->tree);
BLI_rw_mutex_unlock(&cache_rwlock);
if (data->cached == false) {
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree);
+ data->cached = bvhcache_find(*bvh_cache, bvh_cache_type, &data->tree);
if (data->cached == false) {
- data->tree = bvhtree_from_editmesh_verts_ex(data, em, NULL, -1, epsilon, tree_type, axis);
+ tree = bvhtree_from_editmesh_verts_create_tree(
+ epsilon, tree_type, axis, em, verts_mask, verts_num_active);
/* Save on cache for later use */
/* printf("BVHTree built and saved on cache\n"); */
- bvhcache_insert(bvh_cache, data->tree, BVHTREE_FROM_EM_VERTS);
+ bvhcache_insert(bvh_cache, tree, bvh_cache_type);
data->cached = true;
}
BLI_rw_mutex_unlock(&cache_rwlock);
}
}
else {
- data->tree = bvhtree_from_editmesh_verts_ex(data, em, NULL, -1, epsilon, tree_type, axis);
+ tree = bvhtree_from_editmesh_verts_create_tree(
+ epsilon, tree_type, axis, em, verts_mask, verts_num_active);
+ }
+
+ if (tree) {
+ memset(data, 0, sizeof(*data));
+ data->tree = tree;
+ data->em = em;
+ data->nearest_callback = NULL;
+ data->raycast_callback = editmesh_verts_spherecast;
+ data->cached = bvh_cache != NULL;
}
- return data->tree;
+ return tree;
+}
+
+BVHTree *bvhtree_from_editmesh_verts(
+ BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis)
+{
+ return bvhtree_from_editmesh_verts_ex(data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL);
}
/**
@@ -628,11 +628,12 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(float epsilon,
int tree_type,
int axis,
BMEditMesh *em,
- const int edges_num,
const BLI_bitmap *edges_mask,
int edges_num_active)
{
BM_mesh_elem_table_ensure(em->bm, BM_EDGE);
+ const int edges_num = em->bm->totedge;
+
if (edges_mask) {
BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edges_num));
}
@@ -732,55 +733,53 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data,
int edges_num_active,
float epsilon,
int tree_type,
- int axis)
+ int axis,
+ const int bvh_cache_type,
+ BVHCache **bvh_cache)
{
- int edge_num = em->bm->totedge;
-
- BVHTree *tree = bvhtree_from_editmesh_edges_create_tree(
- epsilon, tree_type, axis, em, edge_num, edges_mask, edges_num_active);
-
- if (tree) {
- memset(data, 0, sizeof(*data));
- data->tree = tree;
- data->em = em;
- data->nearest_callback = NULL; /* TODO */
- data->raycast_callback = NULL; /* TODO */
- }
-
- return tree;
-}
+ BVHTree *tree = NULL;
-BVHTree *bvhtree_from_editmesh_edges(BVHTreeFromEditMesh *data,
- BMEditMesh *em,
- float epsilon,
- int tree_type,
- int axis,
- BVHCache **bvh_cache)
-{
if (bvh_cache) {
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree);
+ data->cached = bvhcache_find(*bvh_cache, bvh_cache_type, &data->tree);
BLI_rw_mutex_unlock(&cache_rwlock);
if (data->cached == false) {
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree);
+ data->cached = bvhcache_find(*bvh_cache, bvh_cache_type, &data->tree);
if (data->cached == false) {
- data->tree = bvhtree_from_editmesh_edges_ex(data, em, NULL, -1, epsilon, tree_type, axis);
+ tree = bvhtree_from_editmesh_edges_create_tree(
+ epsilon, tree_type, axis, em, edges_mask, edges_num_active);
/* Save on cache for later use */
/* printf("BVHTree built and saved on cache\n"); */
- bvhcache_insert(bvh_cache, data->tree, BVHTREE_FROM_EM_EDGES);
+ bvhcache_insert(bvh_cache, tree, bvh_cache_type);
data->cached = true;
}
BLI_rw_mutex_unlock(&cache_rwlock);
}
}
else {
- data->tree = bvhtree_from_editmesh_edges_ex(data, em, NULL, -1, epsilon, tree_type, axis);
+ tree = bvhtree_from_editmesh_edges_create_tree(
+ epsilon, tree_type, axis, em, edges_mask, edges_num_active);
+ }
+
+ if (tree) {
+ memset(data, 0, sizeof(*data));
+ data->tree = tree;
+ data->em = em;
+ data->nearest_callback = NULL; /* TODO */
+ data->raycast_callback = NULL; /* TODO */
+ data->cached = bvh_cache != NULL;
}
- return data->tree;
+ return tree;
+}
+
+BVHTree *bvhtree_from_editmesh_edges(
+ BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis)
+{
+ return bvhtree_from_editmesh_edges_ex(data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL);
}
/**
@@ -985,12 +984,11 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon,
int tree_type,
int axis,
BMEditMesh *em,
- const int looptri_num,
const BLI_bitmap *looptri_mask,
int looptri_num_active)
{
BVHTree *tree = NULL;
- int i;
+ const int looptri_num = em->tottri;
if (looptri_num) {
if (looptri_mask) {
@@ -1004,26 +1002,24 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon,
/* printf("%s: building BVH, total=%d\n", __func__, numFaces); */
tree = BLI_bvhtree_new(looptri_num_active, epsilon, tree_type, axis);
if (tree) {
- if (em) {
- const struct BMLoop *(*looptris)[3] = (void *)em->looptris;
-
- /* Insert BMesh-tessellation triangles into the bvh tree, unless they are hidden
- * and/or selected. Even if the faces themselves are not selected for the snapped
- * transform, having a vertex selected means the face (and thus it's tessellated
- * triangles) will be moving and will not be a good snap targets. */
- for (i = 0; i < looptri_num; i++) {
- const BMLoop **ltri = looptris[i];
- bool insert = looptri_mask ? BLI_BITMAP_TEST_BOOL(looptri_mask, i) : true;
-
- if (insert) {
- /* No reason found to block hit-testing the triangle for snap, so insert it now.*/
- float co[3][3];
- copy_v3_v3(co[0], ltri[0]->v->co);
- copy_v3_v3(co[1], ltri[1]->v->co);
- copy_v3_v3(co[2], ltri[2]->v->co);
-
- BLI_bvhtree_insert(tree, i, co[0], 3);
- }
+ const struct BMLoop *(*looptris)[3] = (void *)em->looptris;
+
+ /* Insert BMesh-tessellation triangles into the bvh tree, unless they are hidden
+ * and/or selected. Even if the faces themselves are not selected for the snapped
+ * transform, having a vertex selected means the face (and thus it's tessellated
+ * triangles) will be moving and will not be a good snap targets. */
+ for (int i = 0; i < looptri_num; i++) {
+ const BMLoop **ltri = looptris[i];
+ bool insert = looptri_mask ? BLI_BITMAP_TEST_BOOL(looptri_mask, i) : true;
+
+ if (insert) {
+ /* No reason found to block hit-testing the triangle for snap, so insert it now.*/
+ float co[3][3];
+ copy_v3_v3(co[0], ltri[0]->v->co);
+ copy_v3_v3(co[1], ltri[1]->v->co);
+ copy_v3_v3(co[2], ltri[2]->v->co);
+
+ BLI_bvhtree_insert(tree, i, co[0], 3);
}
}
BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active);
@@ -1116,33 +1112,34 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data,
float epsilon,
int tree_type,
int axis,
- BVHCache **bvhCache)
+ const int bvh_cache_type,
+ BVHCache **bvh_cache)
{
/* BMESH specific check that we have tessfaces,
* we _could_ tessellate here but rather not - campbell */
BVHTree *tree = NULL;
- if (bvhCache) {
+ if (bvh_cache) {
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- bool in_cache = bvhcache_find(*bvhCache, BVHTREE_FROM_EM_LOOPTRI, &tree);
+ bool in_cache = bvhcache_find(*bvh_cache, bvh_cache_type, &tree);
BLI_rw_mutex_unlock(&cache_rwlock);
if (in_cache == false) {
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- in_cache = bvhcache_find(*bvhCache, BVHTREE_FROM_EM_LOOPTRI, &tree);
+ in_cache = bvhcache_find(*bvh_cache, bvh_cache_type, &tree);
if (in_cache == false) {
tree = bvhtree_from_editmesh_looptri_create_tree(
- epsilon, tree_type, axis, em, em->tottri, looptri_mask, looptri_num_active);
+ epsilon, tree_type, axis, em, looptri_mask, looptri_num_active);
/* Save on cache for later use */
/* printf("BVHTree built and saved on cache\n"); */
- bvhcache_insert(bvhCache, tree, BVHTREE_FROM_EM_LOOPTRI);
+ bvhcache_insert(bvh_cache, tree, bvh_cache_type);
}
BLI_rw_mutex_unlock(&cache_rwlock);
}
}
else {
tree = bvhtree_from_editmesh_looptri_create_tree(
- epsilon, tree_type, axis, em, em->tottri, looptri_mask, looptri_num_active);
+ epsilon, tree_type, axis, em, looptri_mask, looptri_num_active);
}
if (tree) {
@@ -1150,19 +1147,15 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data,
data->nearest_callback = editmesh_looptri_nearest_point;
data->raycast_callback = editmesh_looptri_spherecast;
data->em = em;
- data->cached = bvhCache != NULL;
+ data->cached = bvh_cache != NULL;
}
return tree;
}
-BVHTree *bvhtree_from_editmesh_looptri(BVHTreeFromEditMesh *data,
- BMEditMesh *em,
- float epsilon,
- int tree_type,
- int axis,
- BVHCache **bvhCache)
+BVHTree *bvhtree_from_editmesh_looptri(
+ BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis)
{
- return bvhtree_from_editmesh_looptri_ex(data, em, NULL, -1, epsilon, tree_type, axis, bvhCache);
+ return bvhtree_from_editmesh_looptri_ex(data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL);
}
/**
@@ -1493,6 +1486,97 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
return tree;
}
+/**
+ * Builds or queries a bvhcache for the cache bvhtree of the request type.
+ */
+BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
+ struct BMEditMesh *em,
+ const int tree_type,
+ const int bvh_cache_type,
+ BVHCache **bvh_cache)
+{
+ BVHTree *tree = NULL;
+ bool is_cached = false;
+
+ memset(data, 0, sizeof(*data));
+
+ if (bvh_cache) {
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
+ bool is_cached = bvhcache_find(*bvh_cache, bvh_cache_type, &tree);
+ BLI_rw_mutex_unlock(&cache_rwlock);
+
+ if (is_cached && tree == NULL) {
+ return tree;
+ }
+ }
+ data->tree = tree;
+ data->em = em;
+ data->cached = is_cached;
+
+ switch (bvh_cache_type) {
+ case BVHTREE_FROM_EM_VERTS:
+ if (is_cached == false) {
+ tree = bvhtree_from_editmesh_verts_ex(
+ data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache);
+ }
+ else {
+ data->nearest_callback = NULL;
+ data->raycast_callback = editmesh_verts_spherecast;
+ }
+ break;
+
+ case BVHTREE_FROM_EM_EDGES:
+ if (is_cached == false) {
+ tree = bvhtree_from_editmesh_edges_ex(
+ data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache);
+ }
+ else {
+ /* Setup BVHTreeFromMesh */
+ data->nearest_callback = NULL; /* TODO */
+ data->raycast_callback = NULL; /* TODO */
+ }
+ break;
+
+ case BVHTREE_FROM_EM_LOOPTRI:
+ if (is_cached == false) {
+ tree = bvhtree_from_editmesh_looptri_ex(
+ data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache);
+ }
+ else {
+ /* Setup BVHTreeFromMesh */
+ data->nearest_callback = editmesh_looptri_nearest_point;
+ data->raycast_callback = editmesh_looptri_spherecast;
+ }
+ break;
+ case BVHTREE_FROM_VERTS:
+ case BVHTREE_FROM_EDGES:
+ case BVHTREE_FROM_FACES:
+ case BVHTREE_FROM_LOOPTRI:
+ case BVHTREE_FROM_LOOPTRI_NO_HIDDEN:
+ case BVHTREE_FROM_LOOSEVERTS:
+ case BVHTREE_FROM_LOOSEEDGES:
+ BLI_assert(false);
+ break;
+ }
+
+ if (data->tree != NULL) {
+#ifdef DEBUG
+ if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) {
+ printf("tree_type %d obtained instead of %d\n",
+ BLI_bvhtree_get_tree_type(data->tree),
+ tree_type);
+ }
+#endif
+ BLI_assert(data->cached);
+ }
+ else {
+ free_bvhtree_from_editmesh(data);
+ memset(data, 0, sizeof(*data));
+ }
+
+ return tree;
+}
+
/** \} */
/* Frees data allocated by a call to bvhtree_from_editmesh_*. */
@@ -1581,7 +1665,7 @@ void bvhcache_insert(BVHCache **cache_p, BVHTree *tree, int type)
{
BVHCacheItem *item = NULL;
- assert(bvhcache_find(*cache_p, type, &(BVHTree *){0}) == false);
+ assert(tree && bvhcache_find(*cache_p, type, &(BVHTree *){0}) == false);
item = MEM_mallocN(sizeof(BVHCacheItem), "BVHCacheItem");