diff options
author | Germano <germano.costa@ig.com.br> | 2018-05-04 17:15:21 +0300 |
---|---|---|
committer | Germano <germano.costa@ig.com.br> | 2018-05-04 17:15:21 +0300 |
commit | e78ef828271568fa8cc950e1bc7459d3b2123d0b (patch) | |
tree | 53cd1130190efcd22cb6cf28439c734ad9a0f773 /source/blender/blenkernel | |
parent | aa0380a6a53033a23b589cbb21708855b8523f49 (diff) |
BKE: bvhutils: Unifies static functions oh bvhtrees creation.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/intern/bvhutils.c | 415 |
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; } |