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:
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h5
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c193
-rw-r--r--source/blender/blenkernel/intern/mesh.c6
4 files changed, 198 insertions, 8 deletions
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index 1157e20d6ac..24f4765bd9e 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -157,6 +157,10 @@ BVHTree *bvhtree_from_mesh_get(
struct BVHTreeFromMesh *data, struct DerivedMesh *mesh,
const int type, const int tree_type);
+BVHTree *BKE_bvhtree_from_mesh_get(
+ struct BVHTreeFromMesh *data, struct Mesh *mesh,
+ const int type, const int tree_type);
+
/**
* Frees data allocated by a call to bvhtree_from_mesh_*.
*/
@@ -192,7 +196,6 @@ enum {
BVHTree *bvhcache_find(BVHCache *cache, int type);
bool bvhcache_has_tree(const BVHCache *cache, const BVHTree *tree);
void bvhcache_insert(BVHCache **cache_p, BVHTree *tree, int type);
-void bvhcache_init(BVHCache **cache_p);
void bvhcache_free(BVHCache **cache_p);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index dacc0c35e0f..003d80c29cc 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -322,7 +322,7 @@ void DM_init_funcs(DerivedMesh *dm)
dm->getPolyDataArray = DM_get_poly_data_layer;
dm->getLoopDataArray = DM_get_loop_data_layer;
- bvhcache_init(&dm->bvhCache);
+ dm->bvhCache = NULL;
}
/**
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 5c2d81f5841..4731b444221 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -1227,6 +1227,192 @@ BVHTree *BKE_bvhtree_from_mesh_looptri(
return tree;
}
+/**
+ * Builds or queries a bvhcache for the cache bvhtree of the request type.
+ */
+BVHTree *BKE_bvhtree_from_mesh_get(
+ struct BVHTreeFromMesh *data, struct Mesh *mesh,
+ const int type, const int tree_type)
+{
+ BVHTree *tree = NULL;
+
+ BVHTree_NearestPointCallback nearest_callback = NULL;
+ BVHTree_RayCastCallback raycast_callback = NULL;
+
+ MVert *mvert = NULL;
+ MEdge *medge = NULL;
+ MFace *mface = NULL;
+ MLoop *mloop = NULL;
+ const MLoopTri *looptri = NULL;
+ bool vert_allocated = false;
+ bool edge_allocated = false;
+ bool face_allocated = false;
+ bool loop_allocated = false;
+ bool looptri_allocated = false;
+
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
+ tree = bvhcache_find(mesh->runtime.bvh_cache, type);
+ BLI_rw_mutex_unlock(&cache_rwlock);
+
+ switch (type) {
+ case BVHTREE_FROM_VERTS:
+ raycast_callback = mesh_verts_spherecast;
+
+ mvert = mesh->mvert;
+
+ if (tree == NULL) {
+ /* Not in cache */
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(mesh->runtime.bvh_cache, BVHTREE_FROM_VERTS);
+ if (tree == NULL) {
+ tree = bvhtree_from_mesh_verts_create_tree(
+ 0.0, tree_type, 6, mvert, mesh->totvert, NULL, -1);
+
+ if (tree) {
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&mesh->runtime.bvh_cache, tree, BVHTREE_FROM_VERTS);
+ }
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
+ break;
+
+ case BVHTREE_FROM_EDGES:
+ nearest_callback = mesh_edges_nearest_point;
+ raycast_callback = mesh_edges_spherecast;
+
+ mvert = mesh->mvert;
+ medge = mesh->medge;
+
+ if (tree == NULL) {
+ /* Not in cache */
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(mesh->runtime.bvh_cache, BVHTREE_FROM_EDGES);
+ if (tree == NULL) {
+ tree = bvhtree_from_mesh_edges_create_tree(
+ mvert, medge, mesh->totedge,
+ NULL, -1, 0.0, tree_type, 6);
+
+ if (tree) {
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&mesh->runtime.bvh_cache, tree, BVHTREE_FROM_EDGES);
+ }
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
+ break;
+
+ case BVHTREE_FROM_FACES:
+ nearest_callback = mesh_faces_nearest_point;
+ raycast_callback = mesh_faces_spherecast;
+
+ mvert = mesh->mvert;
+ mface = mesh->mface;
+
+ if (tree == NULL) {
+ /* Not in cache */
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(mesh->runtime.bvh_cache, BVHTREE_FROM_FACES);
+ if (tree == NULL) {
+ int num_faces = mesh->totface;
+ BLI_assert(!(num_faces == 0 && mesh->totpoly != 0));
+
+ tree = bvhtree_from_mesh_faces_create_tree(
+ 0.0, tree_type, 6, mvert, mface, num_faces, NULL, -1);
+
+ if (tree) {
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&mesh->runtime.bvh_cache, tree, BVHTREE_FROM_FACES);
+ }
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
+ break;
+
+ case BVHTREE_FROM_LOOPTRI:
+ nearest_callback = mesh_looptri_nearest_point;
+ raycast_callback = mesh_looptri_spherecast;
+
+ mvert = mesh->mvert;
+ mloop = mesh->mloop;
+
+ /* TODO: store looptris somewhere? */
+ looptri = BKE_mesh_runtime_looptri_ensure(mesh);
+
+ if (tree == NULL) {
+ /* Not in cache */
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(mesh->runtime.bvh_cache, BVHTREE_FROM_LOOPTRI);
+ if (tree == NULL) {
+ int looptri_num = BKE_mesh_runtime_looptri_len(mesh);
+ /* this assert checks we have looptris,
+ * if not caller should use DM_ensure_looptri() */
+ BLI_assert(!(looptri_num == 0 && mesh->totpoly != 0));
+
+ tree = bvhtree_from_mesh_looptri_create_tree(
+ 0.0, tree_type, 6,
+ mvert, mloop, looptri, looptri_num, NULL, -1);
+ if (tree) {
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&mesh->runtime.bvh_cache, tree, BVHTREE_FROM_LOOPTRI);
+ }
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
+ break;
+ }
+
+ if (tree != NULL) {
+#ifdef DEBUG
+ if (BLI_bvhtree_get_tree_type(tree) != tree_type) {
+ printf("tree_type %d obtained instead of %d\n", BLI_bvhtree_get_tree_type(tree), tree_type);
+ }
+#endif
+ data->tree = tree;
+
+ data->nearest_callback = nearest_callback;
+ data->raycast_callback = raycast_callback;
+
+ data->vert = mvert;
+ data->edge = medge;
+ data->face = mface;
+ data->loop = mloop;
+ data->looptri = looptri;
+ data->vert_allocated = vert_allocated;
+ data->edge_allocated = edge_allocated;
+ data->edge_allocated = edge_allocated;
+ data->loop_allocated = loop_allocated;
+ data->looptri_allocated = looptri_allocated;
+
+ data->cached = true;
+ }
+ else {
+ if (vert_allocated) {
+ MEM_freeN(mvert);
+ }
+ if (edge_allocated) {
+ MEM_freeN(medge);
+ }
+ if (face_allocated) {
+ MEM_freeN(mface);
+ }
+ if (loop_allocated) {
+ MEM_freeN(mloop);
+ }
+ if (looptri_allocated) {
+ MEM_freeN((void*)looptri);
+ }
+
+ memset(data, 0, sizeof(*data));
+ }
+
+ return tree;
+}
+
/** \} */
@@ -1330,13 +1516,8 @@ void bvhcache_insert(BVHCache **cache_p, BVHTree *tree, int type)
}
/**
- * inits and frees a bvhcache
+ * frees a bvhcache
*/
-void bvhcache_init(BVHCache **cache_p)
-{
- *cache_p = NULL;
-}
-
static void bvhcacheitem_free(void *_item)
{
BVHCacheItem *item = (BVHCacheItem *)_item;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index b0fb9b735ff..aa64ed181e4 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -505,6 +505,9 @@ void BKE_mesh_free(Mesh *me)
MEM_SAFE_FREE(me->bb);
MEM_SAFE_FREE(me->mselect);
MEM_SAFE_FREE(me->edit_btmesh);
+
+ MEM_SAFE_FREE(me->runtime.looptris.array);
+ bvhcache_free(&me->runtime.bvh_cache);
}
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
@@ -541,6 +544,8 @@ void BKE_mesh_init(Mesh *me)
CustomData_reset(&me->fdata);
CustomData_reset(&me->pdata);
CustomData_reset(&me->ldata);
+
+ me->runtime.bvh_cache = NULL;
}
Mesh *BKE_mesh_add(Main *bmain, const char *name)
@@ -583,6 +588,7 @@ void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int
me_dst->edit_btmesh = NULL;
me_dst->runtime.batch_cache = NULL;
+ me_dst->runtime.bvh_cache = NULL;
me_dst->mselect = MEM_dupallocN(me_dst->mselect);
me_dst->bb = MEM_dupallocN(me_dst->bb);