[Bf-blender-cvs] [7fd19bcbe17] blender2.8: BKE: bvhutils: Port bvhtree_from_mesh_get to take a Mesh param instead of a DerivedMesh.

Germano noreply at git.blender.org
Wed May 9 01:01:03 CEST 2018


Commit: 7fd19bcbe17771c1150e938b95a2d148ca51ca54
Author: Germano
Date:   Tue May 8 20:00:51 2018 -0300
Branches: blender2.8
https://developer.blender.org/rB7fd19bcbe17771c1150e938b95a2d148ca51ca54

BKE: bvhutils: Port bvhtree_from_mesh_get to take a Mesh param instead of a DerivedMesh.

Differential Revision: https://developer.blender.org/D3227

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

M	source/blender/blenkernel/BKE_bvhutils.h
M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/blenkernel/intern/bvhutils.c
M	source/blender/blenkernel/intern/mesh.c

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

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);



More information about the Bf-blender-cvs mailing list