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:
authorGermano <germano.costa@ig.com.br>2018-05-04 17:15:21 +0300
committerGermano <germano.costa@ig.com.br>2018-05-04 17:15:21 +0300
commite78ef828271568fa8cc950e1bc7459d3b2123d0b (patch)
tree53cd1130190efcd22cb6cf28439c734ad9a0f773 /source/blender/blenkernel/intern/bvhutils.c
parentaa0380a6a53033a23b589cbb21708855b8523f49 (diff)
BKE: bvhutils: Unifies static functions oh bvhtrees creation.
Diffstat (limited to 'source/blender/blenkernel/intern/bvhutils.c')
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c415
1 files changed, 166 insertions, 249 deletions
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 440db911298..181afdcaf1e 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -499,61 +499,6 @@ BVHTree *bvhtree_from_editmesh_verts(
epsilon, tree_type, axis);
}
-/* Builds a bvh tree where nodes are the vertices of the given dm
- * and stores the BVHTree in dm->bvhCache */
-static BVHTree *bvhtree_from_mesh_verts(
- BVHTreeFromMesh *data, DerivedMesh *dm,
- float epsilon, int tree_type, int axis)
-{
- BVHTree *tree;
- MVert *vert;
- bool vert_allocated;
-
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_VERTS);
- BLI_rw_mutex_unlock(&cache_rwlock);
-
- vert = DM_get_vert_array(dm, &vert_allocated);
-
- /* Not in cache */
- if (tree == NULL) {
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_VERTS);
- if (tree == NULL) {
-
- int vert_num = dm->getNumVerts(dm);
- BLI_assert(vert_num != 0);
-
- tree = bvhtree_from_mesh_verts_create_tree(
- epsilon, tree_type, axis,
- vert, vert_num, NULL, -1);
-
- if (tree) {
- /* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
- bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_VERTS);
- }
- }
- BLI_rw_mutex_unlock(&cache_rwlock);
- }
- else {
- /* printf("BVHTree is already build, using cached tree\n"); */
- }
-
- if (tree) {
- /* Setup BVHTreeFromMesh */
- bvhtree_from_mesh_verts_setup_data(
- data, tree, true, epsilon, vert, vert_allocated);
- }
- else {
- if (vert_allocated) {
- MEM_freeN(vert);
- }
- memset(data, 0, sizeof(*data));
- }
- return tree;
-}
-
/**
* Builds a bvh tree where nodes are the given vertices (note: does not copy given mverts!).
* \param vert_allocated if true, vert freeing will be done when freeing data.
@@ -708,59 +653,6 @@ BVHTree *bvhtree_from_editmesh_edges(
epsilon, tree_type, axis);
}
-/* Builds a bvh tree where nodes are the edges of the given dm */
-static BVHTree *bvhtree_from_mesh_edges(
- BVHTreeFromMesh *data, DerivedMesh *dm,
- float epsilon, int tree_type, int axis)
-{
- BVHTree *tree;
- MVert *vert;
- MEdge *edge;
- bool vert_allocated, edge_allocated;
-
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_EDGES);
- BLI_rw_mutex_unlock(&cache_rwlock);
-
- vert = DM_get_vert_array(dm, &vert_allocated);
- edge = DM_get_edge_array(dm, &edge_allocated);
-
- /* Not in cache */
- if (tree == NULL) {
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_EDGES);
- if (tree == NULL) {
- tree = bvhtree_from_mesh_edges_create_tree(
- vert, edge, dm->getNumEdges(dm),
- NULL, -1, epsilon, tree_type, axis);
-
- /* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
- bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_EDGES);
- }
- BLI_rw_mutex_unlock(&cache_rwlock);
- }
- else {
- /* printf("BVHTree is already build, using cached tree\n"); */
- }
-
- if (tree) {
- /* Setup BVHTreeFromMesh */
- bvhtree_from_mesh_edges_setup_data(
- data, tree, true, epsilon, vert, vert_allocated, edge, edge_allocated);
- }
- else {
- if (vert_allocated) {
- MEM_freeN(vert);
- }
- if (edge_allocated) {
- MEM_freeN(edge);
- }
- memset(data, 0, sizeof(*data));
- }
- return tree;
-}
-
/**
* Builds a bvh tree where nodes are the given edges .
* \param vert/edge_allocated if true, elem freeing will be done when freeing data.
@@ -858,63 +750,6 @@ static void bvhtree_from_mesh_faces_setup_data(
data->sphere_radius = epsilon;
}
-/* Builds a bvh tree where nodes are the tesselated faces of the given dm */
-static BVHTree *bvhtree_from_mesh_faces(
- BVHTreeFromMesh *data, DerivedMesh *dm,
- float epsilon, int tree_type, int axis)
-{
- BVHTree *tree;
- MVert *vert = NULL;
- MFace *face = NULL;
- bool vert_allocated = false, face_allocated = false;
-
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_FACES);
- BLI_rw_mutex_unlock(&cache_rwlock);
-
- vert = DM_get_vert_array(dm, &vert_allocated);
- face = DM_get_tessface_array(dm, &face_allocated);
-
- /* Not in cache */
- if (tree == NULL) {
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_FACES);
- if (tree == NULL) {
- int numFaces = dm->getNumTessFaces(dm);
- BLI_assert(!(numFaces == 0 && dm->getNumPolys(dm) != 0));
-
- tree = bvhtree_from_mesh_faces_create_tree(
- epsilon, tree_type, axis,
- vert, face, numFaces, NULL, -1);
- if (tree) {
- /* Save on cache for later use */
- /* printf("BVHTree built and saved on cache\n"); */
- bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_FACES);
- }
- }
- BLI_rw_mutex_unlock(&cache_rwlock);
- }
- else {
- /* printf("BVHTree is already build, using cached tree\n"); */
- }
-
- if (tree) {
- /* Setup BVHTreeFromMesh */
- bvhtree_from_mesh_faces_setup_data(
- data, tree, true, epsilon, vert, vert_allocated, face, face_allocated);
- }
- else {
- if (vert_allocated) {
- MEM_freeN(vert);
- }
- if (face_allocated) {
- MEM_freeN(face);
- }
- memset(data, 0, sizeof(*data));
- }
- return tree;
-}
-
/**
* Builds a bvh tree where nodes are the given tessellated faces (note: does not copy given mfaces!).
* \param vert_allocated: if true, vert freeing will be done when freeing data.
@@ -1125,83 +960,8 @@ BVHTree *bvhtree_from_editmesh_looptri(
/**
* Builds a bvh tree where nodes are the looptri faces of the given dm
*
- * \note for editmesh this is currently a duplicate of bvhtree_from_mesh_faces
+ * \note for editmesh this is currently a duplicate of bvhtree_from_mesh_faces_ex
*/
-static BVHTree *bvhtree_from_mesh_looptri(
- BVHTreeFromMesh *data, DerivedMesh *dm,
- float epsilon, int tree_type, int axis)
-{
- BVHTree *tree;
- MVert *mvert = NULL;
- MLoop *mloop = NULL;
- const MLoopTri *looptri = NULL;
- bool vert_allocated = false;
- bool loop_allocated = false;
-
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_LOOPTRI);
- BLI_rw_mutex_unlock(&cache_rwlock);
-
- MPoly *mpoly;
- bool poly_allocated = false;
-
- mvert = DM_get_vert_array(dm, &vert_allocated);
- mpoly = DM_get_poly_array(dm, &poly_allocated);
-
- mloop = DM_get_loop_array(dm, &loop_allocated);
- looptri = dm->getLoopTriArray(dm);
-
- if (poly_allocated) {
- MEM_freeN(mpoly);
- }
-
- /* Not in cache */
- if (tree == NULL) {
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_LOOPTRI);
- if (tree == NULL) {
- int looptri_num = dm->getNumLoopTri(dm);
-
- /* this assert checks we have looptris,
- * if not caller should use DM_ensure_looptri() */
- BLI_assert(!(looptri_num == 0 && dm->getNumPolys(dm) != 0));
-
- tree = bvhtree_from_mesh_looptri_create_tree(
- epsilon, tree_type, axis,
- 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(&dm->bvhCache, tree, BVHTREE_FROM_LOOPTRI);
- }
- }
- BLI_rw_mutex_unlock(&cache_rwlock);
- }
- else {
- /* printf("BVHTree is already build, using cached tree\n"); */
- }
-
- if (tree) {
- /* Setup BVHTreeFromMesh */
- bvhtree_from_mesh_looptri_setup_data(
- data, tree, true, epsilon,
- mvert, vert_allocated,
- mloop, loop_allocated,
- looptri, false);
- }
- else {
- if (vert_allocated) {
- MEM_freeN(mvert);
- }
- if (loop_allocated) {
- MEM_freeN(mloop);
- }
- memset(data, 0, sizeof(*data));
- }
-
- return tree;
-}
-
BVHTree *bvhtree_from_mesh_looptri_ex(
BVHTreeFromMesh *data,
const struct MVert *vert, const bool vert_allocated,
@@ -1229,29 +989,186 @@ BVHTree *bvhtree_from_mesh_looptri_ex(
* Builds or queries a bvhcache for the cache bvhtree of the request type.
*/
BVHTree *bvhtree_from_mesh_get(
- struct BVHTreeFromMesh *data, struct DerivedMesh *mesh,
+ struct BVHTreeFromMesh *data, struct DerivedMesh *dm,
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(dm->bvhCache, type);
+ BLI_rw_mutex_unlock(&cache_rwlock);
+
switch (type) {
case BVHTREE_FROM_VERTS:
- tree = bvhtree_from_mesh_verts(data, mesh, 0.0f, tree_type, 6);
+ raycast_callback = mesh_verts_spherecast;
+
+ mvert = DM_get_vert_array(dm, &vert_allocated);
+
+ if (tree == NULL) {
+ /* Not in cache */
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_VERTS);
+ if (tree == NULL) {
+ tree = bvhtree_from_mesh_verts_create_tree(
+ 0.0, tree_type, 6, mvert, dm->getNumVerts(dm), NULL, -1);
+
+ if (tree) {
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_VERTS);
+ }
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
break;
+
case BVHTREE_FROM_EDGES:
- tree = bvhtree_from_mesh_edges(data, mesh, 0.0f, tree_type, 6);
+ nearest_callback = mesh_edges_nearest_point;
+ raycast_callback = mesh_edges_spherecast;
+
+ mvert = DM_get_vert_array(dm, &vert_allocated);
+ medge = DM_get_edge_array(dm, &edge_allocated);
+
+ if (tree == NULL) {
+ /* Not in cache */
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_EDGES);
+ if (tree == NULL) {
+ tree = bvhtree_from_mesh_edges_create_tree(
+ mvert, medge, dm->getNumEdges(dm),
+ 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(&dm->bvhCache, tree, BVHTREE_FROM_EDGES);
+ }
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
break;
+
case BVHTREE_FROM_FACES:
- tree = bvhtree_from_mesh_faces(data, mesh, 0.0f, tree_type, 6);
+ nearest_callback = mesh_faces_nearest_point;
+ raycast_callback = mesh_faces_spherecast;
+
+ mvert = DM_get_vert_array(dm, &vert_allocated);
+ mface = DM_get_tessface_array(dm, &face_allocated);
+
+ if (tree == NULL) {
+ /* Not in cache */
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_FACES);
+ if (tree == NULL) {
+ int numFaces = dm->getNumTessFaces(dm);
+ BLI_assert(!(numFaces == 0 && dm->getNumPolys(dm) != 0));
+
+ tree = bvhtree_from_mesh_faces_create_tree(
+ 0.0, tree_type, 6, mvert, mface, numFaces, NULL, -1);
+
+ if (tree) {
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_FACES);
+ }
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
break;
+
case BVHTREE_FROM_LOOPTRI:
- tree = bvhtree_from_mesh_looptri(data, mesh, 0.0f, tree_type, 6);
+ nearest_callback = mesh_looptri_nearest_point;
+ raycast_callback = mesh_looptri_spherecast;
+
+ mvert = DM_get_vert_array(dm, &vert_allocated);
+ mloop = DM_get_loop_array(dm, &loop_allocated);
+ looptri = dm->getLoopTriArray(dm);
+
+ if (tree == NULL) {
+ /* Not in cache */
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_LOOPTRI);
+ if (tree == NULL) {
+ int looptri_num = dm->getNumLoopTri(dm);
+
+ /* this assert checks we have looptris,
+ * if not caller should use DM_ensure_looptri() */
+ BLI_assert(!(looptri_num == 0 && dm->getNumPolys(dm) != 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(&dm->bvhCache, 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);
- }
+ 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 = mesh_looptri_nearest_point;
+ data->raycast_callback = mesh_looptri_spherecast;
+
+ 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->sphere_radius = 0.0;
+
+ 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;
}