Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/bvhutils.c
| Show First 20 Lines • Show All 278 Lines • ▼ Show 20 Lines | static void editmesh_looptri_nearest_point(void *userdata, | ||||
| const float co[3], | const float co[3], | ||||
| BVHTreeNearest *nearest) | BVHTreeNearest *nearest) | ||||
| { | { | ||||
| const BVHTreeFromEditMesh *data = userdata; | const BVHTreeFromEditMesh *data = userdata; | ||||
| BMEditMesh *em = data->em; | BMEditMesh *em = data->em; | ||||
| const BMLoop **ltri = (const BMLoop **)em->looptris[index]; | const BMLoop **ltri = (const BMLoop **)em->looptris[index]; | ||||
| const float *t0, *t1, *t2; | const float *t0, *t1, *t2; | ||||
| if (data->cageco) { | |||||
| t0 = data->cageco[BM_elem_index_get(ltri[0]->v)]; | |||||
| t1 = data->cageco[BM_elem_index_get(ltri[1]->v)]; | |||||
| t2 = data->cageco[BM_elem_index_get(ltri[2]->v)]; | |||||
| } | |||||
| else { | |||||
| t0 = ltri[0]->v->co; | t0 = ltri[0]->v->co; | ||||
| t1 = ltri[1]->v->co; | t1 = ltri[1]->v->co; | ||||
| t2 = ltri[2]->v->co; | t2 = ltri[2]->v->co; | ||||
| } | |||||
| { | { | ||||
| float nearest_tmp[3], dist_sq; | float nearest_tmp[3], dist_sq; | ||||
| closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); | closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); | ||||
| dist_sq = len_squared_v3v3(co, nearest_tmp); | dist_sq = len_squared_v3v3(co, nearest_tmp); | ||||
| if (dist_sq < nearest->dist_sq) { | if (dist_sq < nearest->dist_sq) { | ||||
| ▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | static void editmesh_looptri_spherecast(void *userdata, | ||||
| const BVHTreeRay *ray, | const BVHTreeRay *ray, | ||||
| BVHTreeRayHit *hit) | BVHTreeRayHit *hit) | ||||
| { | { | ||||
| const BVHTreeFromEditMesh *data = (BVHTreeFromEditMesh *)userdata; | const BVHTreeFromEditMesh *data = (BVHTreeFromEditMesh *)userdata; | ||||
| BMEditMesh *em = data->em; | BMEditMesh *em = data->em; | ||||
| const BMLoop **ltri = (const BMLoop **)em->looptris[index]; | const BMLoop **ltri = (const BMLoop **)em->looptris[index]; | ||||
| const float *t0, *t1, *t2; | const float *t0, *t1, *t2; | ||||
| if (data->cageco) { | |||||
| t0 = data->cageco[BM_elem_index_get(ltri[0]->v)]; | |||||
| t1 = data->cageco[BM_elem_index_get(ltri[1]->v)]; | |||||
| t2 = data->cageco[BM_elem_index_get(ltri[2]->v)]; | |||||
| } | |||||
| { | |||||
| t0 = ltri[0]->v->co; | t0 = ltri[0]->v->co; | ||||
| t1 = ltri[1]->v->co; | t1 = ltri[1]->v->co; | ||||
| t2 = ltri[2]->v->co; | t2 = ltri[2]->v->co; | ||||
| } | |||||
| { | { | ||||
| float dist; | float dist; | ||||
| if (ray->radius == 0.0f) { | if (ray->radius == 0.0f) { | ||||
| dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); | dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); | ||||
| } | } | ||||
| else { | else { | ||||
| dist = bvhtree_sphereray_tri_intersection(ray, ray->radius, hit->dist, t0, t1, t2); | dist = bvhtree_sphereray_tri_intersection(ray, ray->radius, hit->dist, t0, t1, t2); | ||||
| ▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
| static void editmesh_verts_spherecast(void *userdata, | static void editmesh_verts_spherecast(void *userdata, | ||||
| int index, | int index, | ||||
| const BVHTreeRay *ray, | const BVHTreeRay *ray, | ||||
| BVHTreeRayHit *hit) | BVHTreeRayHit *hit) | ||||
| { | { | ||||
| const BVHTreeFromEditMesh *data = userdata; | const BVHTreeFromEditMesh *data = userdata; | ||||
| BMVert *eve = BM_vert_at_index(data->em->bm, index); | BMVert *eve = BM_vert_at_index(data->em->bm, index); | ||||
| mesh_verts_spherecast_do(index, eve->co, ray, hit); | mesh_verts_spherecast_do( | ||||
| index, data->cageco ? data->cageco[BM_elem_index_get(eve)] : eve->co, ray, hit); | |||||
| } | } | ||||
| /* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_verts. | /* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_verts. | ||||
| * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ | * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ | ||||
| static void mesh_verts_spherecast(void *userdata, | static void mesh_verts_spherecast(void *userdata, | ||||
| int index, | int index, | ||||
| const BVHTreeRay *ray, | const BVHTreeRay *ray, | ||||
| BVHTreeRayHit *hit) | BVHTreeRayHit *hit) | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
| /** \name Vertex Builder | /** \name Vertex Builder | ||||
| * \{ */ | * \{ */ | ||||
| static BVHTree *bvhtree_from_editmesh_verts_create_tree(float epsilon, | static BVHTree *bvhtree_from_editmesh_verts_create_tree(float epsilon, | ||||
| int tree_type, | int tree_type, | ||||
| int axis, | int axis, | ||||
| BMEditMesh *em, | BMEditMesh *em, | ||||
| const BLI_bitmap *verts_mask, | const BLI_bitmap *verts_mask, | ||||
| int verts_num_active) | int verts_num_active, | ||||
| const float (*cageco)[3]) | |||||
| { | { | ||||
| BM_mesh_elem_table_ensure(em->bm, BM_VERT); | BM_mesh_elem_table_ensure(em->bm, BM_VERT); | ||||
| const int verts_num = em->bm->totvert; | const int verts_num = em->bm->totvert; | ||||
| if (verts_mask) { | if (verts_mask) { | ||||
| BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num)); | BLI_assert(IN_RANGE_INCL(verts_num_active, 0, verts_num)); | ||||
| } | } | ||||
| else { | else { | ||||
| verts_num_active = verts_num; | verts_num_active = verts_num; | ||||
| } | } | ||||
| BVHTree *tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis); | BVHTree *tree = BLI_bvhtree_new(verts_num_active, epsilon, tree_type, axis); | ||||
| if (tree) { | if (tree) { | ||||
| for (int i = 0; i < verts_num; i++) { | for (int i = 0; i < verts_num; i++) { | ||||
| if (verts_mask && !BLI_BITMAP_TEST_BOOL(verts_mask, i)) { | if (verts_mask && !BLI_BITMAP_TEST_BOOL(verts_mask, i)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| BMVert *eve = BM_vert_at_index(em->bm, i); | BMVert *eve = BM_vert_at_index(em->bm, i); | ||||
| BLI_bvhtree_insert(tree, i, eve->co, 1); | BLI_bvhtree_insert(tree, i, cageco ? cageco[BM_elem_index_get(eve)] : eve->co, 1); | ||||
| } | } | ||||
| BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); | BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); | ||||
| BLI_bvhtree_balance(tree); | BLI_bvhtree_balance(tree); | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
| /* Builds a bvh tree where nodes are the vertices of the given em */ | /* Builds a bvh tree where nodes are the vertices of the given em */ | ||||
| BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, | BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, | ||||
| BMEditMesh *em, | BMEditMesh *em, | ||||
| const BLI_bitmap *verts_mask, | const BLI_bitmap *verts_mask, | ||||
| int verts_num_active, | int verts_num_active, | ||||
| float epsilon, | float epsilon, | ||||
| int tree_type, | int tree_type, | ||||
| int axis, | int axis, | ||||
| const float (*cageco)[3], | |||||
| const BVHCacheType bvh_cache_type, | const BVHCacheType bvh_cache_type, | ||||
| BVHCache **bvh_cache_p, | BVHCache **bvh_cache_p, | ||||
| ThreadMutex *mesh_eval_mutex) | ThreadMutex *mesh_eval_mutex) | ||||
| { | { | ||||
| BVHTree *tree = NULL; | BVHTree *tree = NULL; | ||||
| if (bvh_cache_p) { | if (bvh_cache_p) { | ||||
| bool lock_started = false; | bool lock_started = false; | ||||
| data->cached = bvhcache_find( | data->cached = bvhcache_find( | ||||
| bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex); | bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex); | ||||
| if (data->cached == false) { | if (data->cached == false) { | ||||
| tree = bvhtree_from_editmesh_verts_create_tree( | tree = bvhtree_from_editmesh_verts_create_tree( | ||||
| epsilon, tree_type, axis, em, verts_mask, verts_num_active); | epsilon, tree_type, axis, em, verts_mask, verts_num_active, cageco); | ||||
| /* Save on cache for later use */ | /* Save on cache for later use */ | ||||
| /* printf("BVHTree built and saved on cache\n"); */ | /* printf("BVHTree built and saved on cache\n"); */ | ||||
| bvhcache_insert(*bvh_cache_p, tree, bvh_cache_type); | bvhcache_insert(*bvh_cache_p, tree, bvh_cache_type); | ||||
| data->cached = true; | data->cached = true; | ||||
| } | } | ||||
| bvhcache_unlock(*bvh_cache_p, lock_started); | bvhcache_unlock(*bvh_cache_p, lock_started); | ||||
| } | } | ||||
| else { | else { | ||||
| tree = bvhtree_from_editmesh_verts_create_tree( | tree = bvhtree_from_editmesh_verts_create_tree( | ||||
| epsilon, tree_type, axis, em, verts_mask, verts_num_active); | epsilon, tree_type, axis, em, verts_mask, verts_num_active, cageco); | ||||
| } | } | ||||
| if (tree) { | if (tree) { | ||||
| memset(data, 0, sizeof(*data)); | memset(data, 0, sizeof(*data)); | ||||
| data->tree = tree; | data->tree = tree; | ||||
| data->em = em; | data->em = em; | ||||
| data->nearest_callback = NULL; | data->nearest_callback = NULL; | ||||
| data->raycast_callback = editmesh_verts_spherecast; | data->raycast_callback = editmesh_verts_spherecast; | ||||
| data->cageco = cageco; | |||||
| data->cached = bvh_cache_p != NULL; | data->cached = bvh_cache_p != NULL; | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| BVHTree *bvhtree_from_editmesh_verts( | BVHTree *bvhtree_from_editmesh_verts( | ||||
| BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) | BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) | ||||
| { | { | ||||
| return bvhtree_from_editmesh_verts_ex( | return bvhtree_from_editmesh_verts_ex( | ||||
| data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL, NULL); | data, em, NULL, -1, epsilon, tree_type, axis, NULL, 0, NULL, NULL); | ||||
| } | } | ||||
| /** | /** | ||||
| * Builds a bvh tree where nodes are the given vertices (note: does not copy given mverts!). | * 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. | * \param vert_allocated: if true, vert freeing will be done when freeing data. | ||||
| * \param verts_mask: if not null, true elements give which vert to add to BVH tree. | * \param verts_mask: if not null, true elements give which vert to add to BVH tree. | ||||
| * \param verts_num_active: if >= 0, number of active verts to add to BVH tree | * \param verts_num_active: if >= 0, number of active verts to add to BVH tree | ||||
| * (else will be computed from mask). | * (else will be computed from mask). | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
| /** \name Edge Builder | /** \name Edge Builder | ||||
| * \{ */ | * \{ */ | ||||
| static BVHTree *bvhtree_from_editmesh_edges_create_tree(float epsilon, | static BVHTree *bvhtree_from_editmesh_edges_create_tree(float epsilon, | ||||
| int tree_type, | int tree_type, | ||||
| int axis, | int axis, | ||||
| BMEditMesh *em, | BMEditMesh *em, | ||||
| const BLI_bitmap *edges_mask, | const BLI_bitmap *edges_mask, | ||||
| int edges_num_active) | int edges_num_active, | ||||
| const float (*cageco)[3]) | |||||
| { | { | ||||
| BM_mesh_elem_table_ensure(em->bm, BM_EDGE); | BM_mesh_elem_table_ensure(em->bm, BM_EDGE); | ||||
| const int edges_num = em->bm->totedge; | const int edges_num = em->bm->totedge; | ||||
| if (edges_mask) { | if (edges_mask) { | ||||
| BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edges_num)); | BLI_assert(IN_RANGE_INCL(edges_num_active, 0, edges_num)); | ||||
| } | } | ||||
| else { | else { | ||||
| edges_num_active = edges_num; | edges_num_active = edges_num; | ||||
| } | } | ||||
| BVHTree *tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis); | BVHTree *tree = BLI_bvhtree_new(edges_num_active, epsilon, tree_type, axis); | ||||
| if (tree) { | if (tree) { | ||||
| int i; | int i; | ||||
| BMIter iter; | BMIter iter; | ||||
| BMEdge *eed; | BMEdge *eed; | ||||
| BM_ITER_MESH_INDEX (eed, &iter, em->bm, BM_EDGES_OF_MESH, i) { | BM_ITER_MESH_INDEX (eed, &iter, em->bm, BM_EDGES_OF_MESH, i) { | ||||
| if (edges_mask && !BLI_BITMAP_TEST_BOOL(edges_mask, i)) { | if (edges_mask && !BLI_BITMAP_TEST_BOOL(edges_mask, i)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| float co[2][3]; | float co[2][3]; | ||||
| if (cageco) { | |||||
| copy_v3_v3(co[0], cageco[BM_elem_index_get(eed->v1)]); | |||||
| copy_v3_v3(co[1], cageco[BM_elem_index_get(eed->v2)]); | |||||
| } | |||||
| else { | |||||
| copy_v3_v3(co[0], eed->v1->co); | copy_v3_v3(co[0], eed->v1->co); | ||||
| copy_v3_v3(co[1], eed->v2->co); | copy_v3_v3(co[1], eed->v2->co); | ||||
| } | |||||
| BLI_bvhtree_insert(tree, i, co[0], 2); | BLI_bvhtree_insert(tree, i, co[0], 2); | ||||
| } | } | ||||
| BLI_assert(BLI_bvhtree_get_len(tree) == edges_num_active); | BLI_assert(BLI_bvhtree_get_len(tree) == edges_num_active); | ||||
| BLI_bvhtree_balance(tree); | BLI_bvhtree_balance(tree); | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
| /* Builds a bvh tree where nodes are the edges of the given em */ | /* Builds a bvh tree where nodes are the edges of the given em */ | ||||
| BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data, | BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data, | ||||
| BMEditMesh *em, | BMEditMesh *em, | ||||
| const BLI_bitmap *edges_mask, | const BLI_bitmap *edges_mask, | ||||
| int edges_num_active, | int edges_num_active, | ||||
| float epsilon, | float epsilon, | ||||
| int tree_type, | int tree_type, | ||||
| int axis, | int axis, | ||||
| const float (*cageco)[3], | |||||
| const BVHCacheType bvh_cache_type, | const BVHCacheType bvh_cache_type, | ||||
| BVHCache **bvh_cache_p, | BVHCache **bvh_cache_p, | ||||
| ThreadMutex *mesh_eval_mutex) | ThreadMutex *mesh_eval_mutex) | ||||
| { | { | ||||
| BVHTree *tree = NULL; | BVHTree *tree = NULL; | ||||
| if (bvh_cache_p) { | if (bvh_cache_p) { | ||||
| bool lock_started = false; | bool lock_started = false; | ||||
| data->cached = bvhcache_find( | data->cached = bvhcache_find( | ||||
| bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex); | bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex); | ||||
| BVHCache *bvh_cache = *bvh_cache_p; | BVHCache *bvh_cache = *bvh_cache_p; | ||||
| if (data->cached == false) { | if (data->cached == false) { | ||||
| tree = bvhtree_from_editmesh_edges_create_tree( | tree = bvhtree_from_editmesh_edges_create_tree( | ||||
| epsilon, tree_type, axis, em, edges_mask, edges_num_active); | epsilon, tree_type, axis, em, edges_mask, edges_num_active, cageco); | ||||
| /* Save on cache for later use */ | /* Save on cache for later use */ | ||||
| /* printf("BVHTree built and saved on cache\n"); */ | /* printf("BVHTree built and saved on cache\n"); */ | ||||
| bvhcache_insert(bvh_cache, tree, bvh_cache_type); | bvhcache_insert(bvh_cache, tree, bvh_cache_type); | ||||
| data->cached = true; | data->cached = true; | ||||
| } | } | ||||
| bvhcache_unlock(bvh_cache, lock_started); | bvhcache_unlock(bvh_cache, lock_started); | ||||
| } | } | ||||
| else { | else { | ||||
| tree = bvhtree_from_editmesh_edges_create_tree( | tree = bvhtree_from_editmesh_edges_create_tree( | ||||
| epsilon, tree_type, axis, em, edges_mask, edges_num_active); | epsilon, tree_type, axis, em, edges_mask, edges_num_active, cageco); | ||||
| } | } | ||||
| if (tree) { | if (tree) { | ||||
| memset(data, 0, sizeof(*data)); | memset(data, 0, sizeof(*data)); | ||||
| data->tree = tree; | data->tree = tree; | ||||
| data->em = em; | data->em = em; | ||||
| data->nearest_callback = NULL; /* TODO */ | data->nearest_callback = NULL; /* TODO */ | ||||
| data->raycast_callback = NULL; /* TODO */ | data->raycast_callback = NULL; /* TODO */ | ||||
| data->cageco = cageco; | |||||
| data->cached = bvh_cache_p != NULL; | data->cached = bvh_cache_p != NULL; | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| BVHTree *bvhtree_from_editmesh_edges( | BVHTree *bvhtree_from_editmesh_edges( | ||||
| BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) | BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) | ||||
| { | { | ||||
| return bvhtree_from_editmesh_edges_ex( | return bvhtree_from_editmesh_edges_ex( | ||||
| data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL, NULL); | data, em, NULL, -1, epsilon, tree_type, axis, NULL, 0, NULL, NULL); | ||||
| } | } | ||||
| /** | /** | ||||
| * Builds a bvh tree where nodes are the given edges . | * Builds a bvh tree where nodes are the given edges . | ||||
| * \param vert, vert_allocated: if true, elem freeing will be done when freeing data. | * \param vert, vert_allocated: if true, elem freeing will be done when freeing data. | ||||
| * \param edge, edge_allocated: if true, elem freeing will be done when freeing data. | * \param edge, edge_allocated: if true, elem freeing will be done when freeing data. | ||||
| * \param edges_mask: if not null, true elements give which vert to add to BVH tree. | * \param edges_mask: if not null, true elements give which vert to add to BVH tree. | ||||
| * \param edges_num_active: if >= 0, number of active edges to add to BVH tree | * \param edges_num_active: if >= 0, number of active edges to add to BVH tree | ||||
| ▲ Show 20 Lines • Show All 182 Lines • ▼ Show 20 Lines | |||||
| /** \name LoopTri Face Builder | /** \name LoopTri Face Builder | ||||
| * \{ */ | * \{ */ | ||||
| static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon, | static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon, | ||||
| int tree_type, | int tree_type, | ||||
| int axis, | int axis, | ||||
| BMEditMesh *em, | BMEditMesh *em, | ||||
| const BLI_bitmap *looptri_mask, | const BLI_bitmap *looptri_mask, | ||||
| int looptri_num_active) | int looptri_num_active, | ||||
| const float (*cageco)[3]) | |||||
| { | { | ||||
| BVHTree *tree = NULL; | BVHTree *tree = NULL; | ||||
| const int looptri_num = em->tottri; | const int looptri_num = em->tottri; | ||||
| if (looptri_num) { | if (looptri_num) { | ||||
| if (looptri_mask) { | if (looptri_mask) { | ||||
| BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptri_num)); | BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptri_num)); | ||||
| } | } | ||||
| Show All 13 Lines | if (tree) { | ||||
| * triangles) will be moving and will not be a good snap targets. */ | * triangles) will be moving and will not be a good snap targets. */ | ||||
| for (int i = 0; i < looptri_num; i++) { | for (int i = 0; i < looptri_num; i++) { | ||||
| const BMLoop **ltri = looptris[i]; | const BMLoop **ltri = looptris[i]; | ||||
| bool insert = looptri_mask ? BLI_BITMAP_TEST_BOOL(looptri_mask, i) : true; | bool insert = looptri_mask ? BLI_BITMAP_TEST_BOOL(looptri_mask, i) : true; | ||||
| if (insert) { | if (insert) { | ||||
| /* No reason found to block hit-testing the triangle for snap, so insert it now.*/ | /* No reason found to block hit-testing the triangle for snap, so insert it now.*/ | ||||
| float co[3][3]; | float co[3][3]; | ||||
| if (cageco) { | |||||
| copy_v3_v3(co[0], cageco[BM_elem_index_get(ltri[0]->v)]); | |||||
| copy_v3_v3(co[1], cageco[BM_elem_index_get(ltri[1]->v)]); | |||||
| copy_v3_v3(co[2], cageco[BM_elem_index_get(ltri[2]->v)]); | |||||
| } | |||||
| else { | |||||
| copy_v3_v3(co[0], ltri[0]->v->co); | copy_v3_v3(co[0], ltri[0]->v->co); | ||||
| copy_v3_v3(co[1], ltri[1]->v->co); | copy_v3_v3(co[1], ltri[1]->v->co); | ||||
| copy_v3_v3(co[2], ltri[2]->v->co); | copy_v3_v3(co[2], ltri[2]->v->co); | ||||
| } | |||||
| BLI_bvhtree_insert(tree, i, co[0], 3); | BLI_bvhtree_insert(tree, i, co[0], 3); | ||||
| } | } | ||||
| } | } | ||||
| BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active); | BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active); | ||||
| BLI_bvhtree_balance(tree); | BLI_bvhtree_balance(tree); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | |||||
| */ | */ | ||||
| BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, | BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, | ||||
| BMEditMesh *em, | BMEditMesh *em, | ||||
| const BLI_bitmap *looptri_mask, | const BLI_bitmap *looptri_mask, | ||||
| int looptri_num_active, | int looptri_num_active, | ||||
| float epsilon, | float epsilon, | ||||
| int tree_type, | int tree_type, | ||||
| int axis, | int axis, | ||||
| const float (*cageco)[3], | |||||
| const BVHCacheType bvh_cache_type, | const BVHCacheType bvh_cache_type, | ||||
| BVHCache **bvh_cache_p, | BVHCache **bvh_cache_p, | ||||
| ThreadMutex *mesh_eval_mutex) | ThreadMutex *mesh_eval_mutex) | ||||
| { | { | ||||
| /* BMESH specific check that we have tessfaces, | /* BMESH specific check that we have tessfaces, | ||||
| * we _could_ tessellate here but rather not - campbell */ | * we _could_ tessellate here but rather not - campbell */ | ||||
| BVHTree *tree = NULL; | BVHTree *tree = NULL; | ||||
| if (bvh_cache_p) { | if (bvh_cache_p) { | ||||
| bool lock_started = false; | bool lock_started = false; | ||||
| bool in_cache = bvhcache_find( | bool in_cache = bvhcache_find( | ||||
| bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex); | bvh_cache_p, bvh_cache_type, &tree, &lock_started, mesh_eval_mutex); | ||||
| BVHCache *bvh_cache = *bvh_cache_p; | BVHCache *bvh_cache = *bvh_cache_p; | ||||
| if (in_cache == false) { | if (in_cache == false) { | ||||
| tree = bvhtree_from_editmesh_looptri_create_tree( | tree = bvhtree_from_editmesh_looptri_create_tree( | ||||
| epsilon, tree_type, axis, em, looptri_mask, looptri_num_active); | epsilon, tree_type, axis, em, looptri_mask, looptri_num_active, cageco); | ||||
| /* Save on cache for later use */ | /* Save on cache for later use */ | ||||
| /* printf("BVHTree built and saved on cache\n"); */ | /* printf("BVHTree built and saved on cache\n"); */ | ||||
| bvhcache_insert(bvh_cache, tree, bvh_cache_type); | bvhcache_insert(bvh_cache, tree, bvh_cache_type); | ||||
| } | } | ||||
| bvhcache_unlock(bvh_cache, lock_started); | bvhcache_unlock(bvh_cache, lock_started); | ||||
| } | } | ||||
| else { | else { | ||||
| tree = bvhtree_from_editmesh_looptri_create_tree( | tree = bvhtree_from_editmesh_looptri_create_tree( | ||||
| epsilon, tree_type, axis, em, looptri_mask, looptri_num_active); | epsilon, tree_type, axis, em, looptri_mask, looptri_num_active, cageco); | ||||
| } | } | ||||
| if (tree) { | if (tree) { | ||||
| data->tree = tree; | data->tree = tree; | ||||
| data->nearest_callback = editmesh_looptri_nearest_point; | data->nearest_callback = editmesh_looptri_nearest_point; | ||||
| data->raycast_callback = editmesh_looptri_spherecast; | data->raycast_callback = editmesh_looptri_spherecast; | ||||
| data->em = em; | data->em = em; | ||||
| data->cageco = cageco; | |||||
| data->cached = bvh_cache_p != NULL; | data->cached = bvh_cache_p != NULL; | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| BVHTree *bvhtree_from_editmesh_looptri( | BVHTree *bvhtree_from_editmesh_looptri( | ||||
| BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) | BVHTreeFromEditMesh *data, BMEditMesh *em, float epsilon, int tree_type, int axis) | ||||
| { | { | ||||
| return bvhtree_from_editmesh_looptri_ex( | return bvhtree_from_editmesh_looptri_ex( | ||||
| data, em, NULL, -1, epsilon, tree_type, axis, 0, NULL, NULL); | data, em, NULL, -1, epsilon, tree_type, axis, NULL, 0, NULL, NULL); | ||||
| } | } | ||||
| /** | /** | ||||
| * Builds a bvh tree where nodes are the looptri faces of the given dm | * 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_ex | * \note for editmesh this is currently a duplicate of bvhtree_from_mesh_faces_ex | ||||
| */ | */ | ||||
| BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, | BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, | ||||
| ▲ Show 20 Lines • Show All 346 Lines • ▼ Show 20 Lines | BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data, | ||||
| } | } | ||||
| data->tree = tree; | data->tree = tree; | ||||
| data->em = em; | data->em = em; | ||||
| data->cached = is_cached; | data->cached = is_cached; | ||||
| switch (bvh_cache_type) { | switch (bvh_cache_type) { | ||||
| case BVHTREE_FROM_EM_VERTS: | case BVHTREE_FROM_EM_VERTS: | ||||
| if (is_cached == false) { | if (is_cached == false) { | ||||
| tree = bvhtree_from_editmesh_verts_ex( | tree = bvhtree_from_editmesh_verts_ex(data, | ||||
| data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache_p, mesh_eval_mutex); | em, | ||||
| NULL, | |||||
| -1, | |||||
| 0.0f, | |||||
| tree_type, | |||||
| 6, | |||||
| NULL, | |||||
| bvh_cache_type, | |||||
| bvh_cache_p, | |||||
| mesh_eval_mutex); | |||||
| } | } | ||||
| else { | else { | ||||
| data->nearest_callback = NULL; | data->nearest_callback = NULL; | ||||
| data->raycast_callback = editmesh_verts_spherecast; | data->raycast_callback = editmesh_verts_spherecast; | ||||
| } | } | ||||
| break; | break; | ||||
| case BVHTREE_FROM_EM_EDGES: | case BVHTREE_FROM_EM_EDGES: | ||||
| if (is_cached == false) { | if (is_cached == false) { | ||||
| tree = bvhtree_from_editmesh_edges_ex( | tree = bvhtree_from_editmesh_edges_ex(data, | ||||
| data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache_p, mesh_eval_mutex); | em, | ||||
| NULL, | |||||
| -1, | |||||
| 0.0f, | |||||
| tree_type, | |||||
| 6, | |||||
| NULL, | |||||
| bvh_cache_type, | |||||
| bvh_cache_p, | |||||
| mesh_eval_mutex); | |||||
| } | } | ||||
| else { | else { | ||||
| /* Setup BVHTreeFromMesh */ | /* Setup BVHTreeFromMesh */ | ||||
| data->nearest_callback = NULL; /* TODO */ | data->nearest_callback = NULL; /* TODO */ | ||||
| data->raycast_callback = NULL; /* TODO */ | data->raycast_callback = NULL; /* TODO */ | ||||
| } | } | ||||
| break; | break; | ||||
| case BVHTREE_FROM_EM_LOOPTRI: | case BVHTREE_FROM_EM_LOOPTRI: | ||||
| if (is_cached == false) { | if (is_cached == false) { | ||||
| tree = bvhtree_from_editmesh_looptri_ex( | tree = bvhtree_from_editmesh_looptri_ex(data, | ||||
| data, em, NULL, -1, 0.0f, tree_type, 6, bvh_cache_type, bvh_cache_p, mesh_eval_mutex); | em, | ||||
| NULL, | |||||
| -1, | |||||
| 0.0f, | |||||
| tree_type, | |||||
| 6, | |||||
| NULL, | |||||
| bvh_cache_type, | |||||
| bvh_cache_p, | |||||
| mesh_eval_mutex); | |||||
| } | } | ||||
| else { | else { | ||||
| /* Setup BVHTreeFromMesh */ | /* Setup BVHTreeFromMesh */ | ||||
| data->nearest_callback = editmesh_looptri_nearest_point; | data->nearest_callback = editmesh_looptri_nearest_point; | ||||
| data->raycast_callback = editmesh_looptri_spherecast; | data->raycast_callback = editmesh_looptri_spherecast; | ||||
| } | } | ||||
| break; | break; | ||||
| case BVHTREE_FROM_VERTS: | case BVHTREE_FROM_VERTS: | ||||
| Show All 26 Lines | #endif | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* Frees data allocated by a call to bvhtree_from_editmesh_*. */ | /* Frees data allocated by a call to bvhtree_from_editmesh_*. */ | ||||
| void free_bvhtree_from_editmesh(struct BVHTreeFromEditMesh *data) | void free_bvhtree_from_editmesh(struct BVHTreeFromEditMesh *data) | ||||
| { | { | ||||
| if (data->tree) { | if (data->tree && !data->cached) { | ||||
| if (!data->cached) { | |||||
| BLI_bvhtree_free(data->tree); | BLI_bvhtree_free(data->tree); | ||||
| } | } | ||||
| memset(data, 0, sizeof(*data)); | memset(data, 0, sizeof(*data)); | ||||
| } | } | ||||
| } | |||||
| /* Frees data allocated by a call to bvhtree_from_mesh_*. */ | /* Frees data allocated by a call to bvhtree_from_mesh_*. */ | ||||
| void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data) | void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data) | ||||
| { | { | ||||
| if (data->tree && !data->cached) { | if (data->tree && !data->cached) { | ||||
| BLI_bvhtree_free(data->tree); | BLI_bvhtree_free(data->tree); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines | |||||