Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/bvhutils.cc
| Show First 20 Lines • Show All 556 Lines • ▼ Show 20 Lines | |||||
| /** \} */ | /** \} */ | ||||
| /* | /* | ||||
| * BVH builders | * BVH builders | ||||
| */ | */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Commom Utils | |||||
| * \{ */ | |||||
| static void bvhtree_from_mesh_setup_data(BVHTree *tree, | |||||
| const BVHCacheType bvh_cache_type, | |||||
| const MVert *vert, | |||||
| const MEdge *edge, | |||||
| const MFace *face, | |||||
| const MLoop *loop, | |||||
| const MLoopTri *looptri, | |||||
| const float (*vert_normals)[3], | |||||
| BVHTreeFromMesh *r_data) | |||||
| { | |||||
| memset(r_data, 0, sizeof(*r_data)); | |||||
| r_data->tree = tree; | |||||
| r_data->vert = vert; | |||||
| r_data->edge = edge; | |||||
| r_data->face = face; | |||||
| r_data->loop = loop; | |||||
| r_data->looptri = looptri; | |||||
| r_data->vert_normals = vert_normals; | |||||
| switch (bvh_cache_type) { | |||||
| case BVHTREE_FROM_VERTS: | |||||
| case BVHTREE_FROM_LOOSEVERTS: | |||||
| /* a nullptr nearest callback works fine | |||||
| * remember the min distance to point is the same as the min distance to BV of point */ | |||||
| r_data->nearest_callback = nullptr; | |||||
| r_data->raycast_callback = mesh_verts_spherecast; | |||||
| break; | |||||
| case BVHTREE_FROM_EDGES: | |||||
| case BVHTREE_FROM_LOOSEEDGES: | |||||
| r_data->nearest_callback = mesh_edges_nearest_point; | |||||
| r_data->raycast_callback = mesh_edges_spherecast; | |||||
| break; | |||||
| case BVHTREE_FROM_FACES: | |||||
| r_data->nearest_callback = mesh_faces_nearest_point; | |||||
| r_data->raycast_callback = mesh_faces_spherecast; | |||||
| break; | |||||
| case BVHTREE_FROM_LOOPTRI: | |||||
| case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: | |||||
| r_data->nearest_callback = mesh_looptri_nearest_point; | |||||
| r_data->raycast_callback = mesh_looptri_spherecast; | |||||
| break; | |||||
| case BVHTREE_FROM_EM_VERTS: | |||||
| case BVHTREE_FROM_EM_EDGES: | |||||
| case BVHTREE_FROM_EM_LOOPTRI: | |||||
| case BVHTREE_MAX_ITEM: | |||||
| BLI_assert(false); | |||||
| break; | |||||
| } | |||||
| } | |||||
| static void bvhtree_from_editmesh_setup_data(BVHTree *tree, | |||||
| const BVHCacheType bvh_cache_type, | |||||
| struct BMEditMesh *em, | |||||
| BVHTreeFromEditMesh *r_data) | |||||
| { | |||||
| memset(r_data, 0, sizeof(*r_data)); | |||||
| r_data->tree = tree; | |||||
| r_data->em = em; | |||||
| switch (bvh_cache_type) { | |||||
| case BVHTREE_FROM_EM_VERTS: | |||||
| r_data->nearest_callback = nullptr; | |||||
| r_data->raycast_callback = editmesh_verts_spherecast; | |||||
| break; | |||||
| case BVHTREE_FROM_EM_EDGES: | |||||
| r_data->nearest_callback = nullptr; /* TODO */ | |||||
| r_data->raycast_callback = nullptr; /* TODO */ | |||||
| break; | |||||
| case BVHTREE_FROM_EM_LOOPTRI: | |||||
| r_data->nearest_callback = editmesh_looptri_nearest_point; | |||||
| r_data->raycast_callback = editmesh_looptri_spherecast; | |||||
| break; | |||||
| case BVHTREE_FROM_VERTS: | |||||
| case BVHTREE_FROM_LOOSEVERTS: | |||||
| case BVHTREE_FROM_EDGES: | |||||
| case BVHTREE_FROM_LOOSEEDGES: | |||||
| case BVHTREE_FROM_FACES: | |||||
| case BVHTREE_FROM_LOOPTRI: | |||||
| case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: | |||||
| case BVHTREE_MAX_ITEM: | |||||
| BLI_assert(false); | |||||
| break; | |||||
| } | |||||
| } | |||||
| /** \} */ | |||||
| /* -------------------------------------------------------------------- */ | |||||
| /** \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, | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | if (tree) { | ||||
| } | } | ||||
| BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); | BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); | ||||
| } | } | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| static void bvhtree_from_mesh_verts_setup_data(BVHTreeFromMesh *data, | |||||
| BVHTree *tree, | |||||
| const bool is_cached, | |||||
| const MVert *vert, | |||||
| const bool vert_allocated) | |||||
| { | |||||
| memset(data, 0, sizeof(*data)); | |||||
| data->tree = tree; | |||||
| data->cached = is_cached; | |||||
| /* a nullptr nearest callback works fine | |||||
| * remember the min distance to point is the same as the min distance to BV of point */ | |||||
| data->nearest_callback = nullptr; | |||||
| data->raycast_callback = mesh_verts_spherecast; | |||||
| data->vert = vert; | |||||
| data->vert_allocated = vert_allocated; | |||||
| } | |||||
| 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 BVHCacheType bvh_cache_type, | const BVHCacheType bvh_cache_type, | ||||
| Show All 20 Lines | if (bvh_cache_p) { | ||||
| 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); | ||||
| bvhtree_balance(tree, false); | bvhtree_balance(tree, false); | ||||
| } | } | ||||
| if (tree) { | if (data) { | ||||
| memset(data, 0, sizeof(*data)); | bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_VERTS, em, data); | ||||
| data->tree = tree; | |||||
| data->em = em; | |||||
| data->nearest_callback = nullptr; | |||||
| data->raycast_callback = editmesh_verts_spherecast; | |||||
| data->cached = bvh_cache_p != nullptr; | data->cached = bvh_cache_p != nullptr; | ||||
| } | } | ||||
| 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) | ||||
| Show All 35 Lines | if (bvh_cache_p) { | ||||
| in_cache = true; | in_cache = true; | ||||
| } | } | ||||
| } | } | ||||
| if (bvh_cache_p) { | if (bvh_cache_p) { | ||||
| bvhcache_unlock(*bvh_cache_p, lock_started); | bvhcache_unlock(*bvh_cache_p, lock_started); | ||||
| } | } | ||||
| if (data) { | |||||
| /* Setup BVHTreeFromMesh */ | /* Setup BVHTreeFromMesh */ | ||||
| bvhtree_from_mesh_verts_setup_data(data, tree, in_cache, vert, vert_allocated); | bvhtree_from_mesh_setup_data( | ||||
| tree, BVHTREE_FROM_VERTS, vert, nullptr, nullptr, nullptr, nullptr, nullptr, data); | |||||
| data->vert_allocated = vert_allocated; | |||||
| data->cached = in_cache; | |||||
| } | |||||
| return tree; | return tree; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Edge Builder | /** \name Edge Builder | ||||
| ▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | if (tree) { | ||||
| BLI_bvhtree_insert(tree, i, co[0], 2); | BLI_bvhtree_insert(tree, i, co[0], 2); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| static void bvhtree_from_mesh_edges_setup_data(BVHTreeFromMesh *data, | |||||
| BVHTree *tree, | |||||
| const bool is_cached, | |||||
| const MVert *vert, | |||||
| const bool vert_allocated, | |||||
| const MEdge *edge, | |||||
| const bool edge_allocated) | |||||
| { | |||||
| memset(data, 0, sizeof(*data)); | |||||
| data->tree = tree; | |||||
| data->cached = is_cached; | |||||
| data->nearest_callback = mesh_edges_nearest_point; | |||||
| data->raycast_callback = mesh_edges_spherecast; | |||||
| data->vert = vert; | |||||
| data->vert_allocated = vert_allocated; | |||||
| data->edge = edge; | |||||
| data->edge_allocated = edge_allocated; | |||||
| } | |||||
| 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 BVHCacheType bvh_cache_type, | const BVHCacheType bvh_cache_type, | ||||
| Show All 19 Lines | if (bvh_cache_p) { | ||||
| 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); | ||||
| bvhtree_balance(tree, false); | bvhtree_balance(tree, false); | ||||
| } | } | ||||
| if (tree) { | if (data) { | ||||
| memset(data, 0, sizeof(*data)); | bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_EDGES, em, data); | ||||
| data->tree = tree; | |||||
| data->em = em; | |||||
| data->nearest_callback = nullptr; /* TODO */ | |||||
| data->raycast_callback = nullptr; /* TODO */ | |||||
| data->cached = bvh_cache_p != nullptr; | data->cached = bvh_cache_p != nullptr; | ||||
| } | } | ||||
| 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) | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | else { | ||||
| bvhtree_balance(tree, false); | bvhtree_balance(tree, false); | ||||
| } | } | ||||
| } | } | ||||
| if (bvh_cache_p) { | if (bvh_cache_p) { | ||||
| bvhcache_unlock(*bvh_cache_p, lock_started); | bvhcache_unlock(*bvh_cache_p, lock_started); | ||||
| } | } | ||||
| if (data) { | |||||
| /* Setup BVHTreeFromMesh */ | /* Setup BVHTreeFromMesh */ | ||||
| bvhtree_from_mesh_edges_setup_data( | bvhtree_from_mesh_setup_data( | ||||
| data, tree, in_cache, vert, vert_allocated, edge, edge_allocated); | tree, BVHTREE_FROM_EDGES, vert, edge, nullptr, nullptr, nullptr, nullptr, data); | ||||
| data->vert_allocated = vert_allocated; | |||||
| data->vert_allocated = edge_allocated; | |||||
| data->cached = in_cache; | |||||
| } | |||||
| return tree; | return tree; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Tessellated Face Builder | /** \name Tessellated Face Builder | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | if (tree) { | ||||
| } | } | ||||
| BLI_assert(BLI_bvhtree_get_len(tree) == faces_num_active); | BLI_assert(BLI_bvhtree_get_len(tree) == faces_num_active); | ||||
| } | } | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| static void bvhtree_from_mesh_faces_setup_data(BVHTreeFromMesh *data, | |||||
| BVHTree *tree, | |||||
| const bool is_cached, | |||||
| const MVert *vert, | |||||
| const bool vert_allocated, | |||||
| const MFace *face, | |||||
| const bool face_allocated) | |||||
| { | |||||
| memset(data, 0, sizeof(*data)); | |||||
| data->tree = tree; | |||||
| data->cached = is_cached; | |||||
| data->nearest_callback = mesh_faces_nearest_point; | |||||
| data->raycast_callback = mesh_faces_spherecast; | |||||
| data->vert = vert; | |||||
| data->vert_allocated = vert_allocated; | |||||
| data->face = face; | |||||
| data->face_allocated = face_allocated; | |||||
| } | |||||
| BVHTree *bvhtree_from_mesh_faces_ex(BVHTreeFromMesh *data, | BVHTree *bvhtree_from_mesh_faces_ex(BVHTreeFromMesh *data, | ||||
| const MVert *vert, | const MVert *vert, | ||||
| const bool vert_allocated, | const bool vert_allocated, | ||||
| const MFace *face, | const MFace *face, | ||||
| const int numFaces, | const int numFaces, | ||||
| const bool face_allocated, | const bool face_allocated, | ||||
| const BLI_bitmap *faces_mask, | const BLI_bitmap *faces_mask, | ||||
| int faces_num_active, | int faces_num_active, | ||||
| Show All 24 Lines | if (bvh_cache_p) { | ||||
| in_cache = true; | in_cache = true; | ||||
| } | } | ||||
| } | } | ||||
| if (bvh_cache_p) { | if (bvh_cache_p) { | ||||
| bvhcache_unlock(*bvh_cache_p, lock_started); | bvhcache_unlock(*bvh_cache_p, lock_started); | ||||
| } | } | ||||
| if (data) { | |||||
| /* Setup BVHTreeFromMesh */ | /* Setup BVHTreeFromMesh */ | ||||
| bvhtree_from_mesh_faces_setup_data( | bvhtree_from_mesh_setup_data( | ||||
| data, tree, in_cache, vert, vert_allocated, face, face_allocated); | tree, BVHTREE_FROM_FACES, vert, nullptr, face, nullptr, nullptr, nullptr, data); | ||||
| data->vert_allocated = vert_allocated; | |||||
| data->face_allocated = face_allocated; | |||||
| data->cached = in_cache; | |||||
| } | |||||
| return tree; | return tree; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name LoopTri Face Builder | /** \name LoopTri Face Builder | ||||
| ▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | if (tree) { | ||||
| } | } | ||||
| BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active); | BLI_assert(BLI_bvhtree_get_len(tree) == looptri_num_active); | ||||
| } | } | ||||
| } | } | ||||
| return tree; | return tree; | ||||
| } | } | ||||
| static void bvhtree_from_mesh_looptri_setup_data(BVHTreeFromMesh *data, | |||||
| BVHTree *tree, | |||||
| const bool is_cached, | |||||
| const MVert *vert, | |||||
| const bool vert_allocated, | |||||
| const MLoop *mloop, | |||||
| const bool loop_allocated, | |||||
| const MLoopTri *looptri, | |||||
| const bool looptri_allocated) | |||||
| { | |||||
| memset(data, 0, sizeof(*data)); | |||||
| data->tree = tree; | |||||
| data->cached = is_cached; | |||||
| data->nearest_callback = mesh_looptri_nearest_point; | |||||
| data->raycast_callback = mesh_looptri_spherecast; | |||||
| data->vert = vert; | |||||
| data->vert_allocated = vert_allocated; | |||||
| data->loop = mloop; | |||||
| data->loop_allocated = loop_allocated; | |||||
| data->looptri = looptri; | |||||
| data->looptri_allocated = looptri_allocated; | |||||
| } | |||||
| 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 BVHCacheType bvh_cache_type, | const BVHCacheType bvh_cache_type, | ||||
| Show All 21 Lines | if (bvh_cache_p) { | ||||
| 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); | ||||
| bvhtree_balance(tree, false); | bvhtree_balance(tree, false); | ||||
| } | } | ||||
| if (tree) { | if (data) { | ||||
| data->tree = tree; | bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOPTRI, em, data); | ||||
| data->nearest_callback = editmesh_looptri_nearest_point; | |||||
| data->raycast_callback = editmesh_looptri_spherecast; | |||||
| data->em = em; | |||||
| data->cached = bvh_cache_p != nullptr; | data->cached = bvh_cache_p != nullptr; | ||||
| } | } | ||||
| 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) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (bvh_cache_p) { | ||||
| in_cache = true; | in_cache = true; | ||||
| } | } | ||||
| } | } | ||||
| if (bvh_cache_p) { | if (bvh_cache_p) { | ||||
| bvhcache_unlock(*bvh_cache_p, lock_started); | bvhcache_unlock(*bvh_cache_p, lock_started); | ||||
| } | } | ||||
| if (data) { | |||||
| /* Setup BVHTreeFromMesh */ | /* Setup BVHTreeFromMesh */ | ||||
| bvhtree_from_mesh_looptri_setup_data(data, | bvhtree_from_mesh_setup_data( | ||||
| tree, | tree, BVHTREE_FROM_LOOPTRI, vert, nullptr, nullptr, mloop, looptri, nullptr, data); | ||||
| in_cache, | data->vert_allocated = vert_allocated; | ||||
| vert, | data->loop_allocated = loop_allocated; | ||||
| vert_allocated, | data->looptri_allocated = looptri_allocated; | ||||
| mloop, | data->cached = in_cache; | ||||
| loop_allocated, | } | ||||
| looptri, | |||||
| looptri_allocated); | |||||
| return tree; | return tree; | ||||
| } | } | ||||
| static BLI_bitmap *loose_verts_map_get(const MEdge *medge, | static BLI_bitmap *loose_verts_map_get(const MEdge *medge, | ||||
| int edges_num, | int edges_num, | ||||
| const MVert *UNUSED(mvert), | const MVert *UNUSED(mvert), | ||||
| int verts_num, | int verts_num, | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | static BLI_bitmap *looptri_no_hidden_map_get(const MPoly *mpoly, | ||||
| return looptri_mask; | return looptri_mask; | ||||
| } | } | ||||
| BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, | BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, | ||||
| const struct Mesh *mesh, | const struct Mesh *mesh, | ||||
| const BVHCacheType bvh_cache_type, | const BVHCacheType bvh_cache_type, | ||||
| const int tree_type) | const int tree_type) | ||||
| { | { | ||||
| BVHTree *tree = nullptr; | |||||
| BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime.bvh_cache; | BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime.bvh_cache; | ||||
| ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex; | ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex; | ||||
| const bool is_cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, nullptr, nullptr); | /* Setup BVHTreeFromMesh */ | ||||
| bvhtree_from_mesh_setup_data( | |||||
| nullptr, | |||||
| bvh_cache_type, | |||||
| mesh->mvert, | |||||
| mesh->medge, | |||||
| mesh->mface, | |||||
| mesh->mloop, | |||||
| ELEM(bvh_cache_type, BVHTREE_FROM_LOOPTRI, BVHTREE_FROM_LOOPTRI_NO_HIDDEN) ? | |||||
| BKE_mesh_runtime_looptri_ensure(mesh) : | |||||
| nullptr, | |||||
| BKE_mesh_vertex_normals_ensure(mesh), | |||||
| data); | |||||
| if (is_cached && tree == nullptr) { | data->cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &data->tree, nullptr, nullptr); | ||||
| memset(data, 0, sizeof(*data)); | |||||
| return tree; | if (data->cached) { | ||||
| /* NOTE: #data->tree can be nullptr. */ | |||||
| return data->tree; | |||||
| } | } | ||||
| switch (bvh_cache_type) { | switch (bvh_cache_type) { | ||||
| case BVHTREE_FROM_VERTS: | case BVHTREE_FROM_VERTS: | ||||
| case BVHTREE_FROM_LOOSEVERTS: | case BVHTREE_FROM_LOOSEVERTS: { | ||||
| if (is_cached == false) { | |||||
| BLI_bitmap *loose_verts_mask = nullptr; | BLI_bitmap *loose_verts_mask = nullptr; | ||||
| int loose_vert_len = -1; | int loose_vert_len = -1; | ||||
| int verts_len = mesh->totvert; | int verts_len = mesh->totvert; | ||||
| if (bvh_cache_type == BVHTREE_FROM_LOOSEVERTS) { | if (bvh_cache_type == BVHTREE_FROM_LOOSEVERTS) { | ||||
| loose_verts_mask = loose_verts_map_get( | loose_verts_mask = loose_verts_map_get( | ||||
| mesh->medge, mesh->totedge, mesh->mvert, verts_len, &loose_vert_len); | mesh->medge, mesh->totedge, mesh->mvert, verts_len, &loose_vert_len); | ||||
| } | } | ||||
| tree = bvhtree_from_mesh_verts_ex(data, | data->tree = bvhtree_from_mesh_verts_ex(nullptr, | ||||
| mesh->mvert, | mesh->mvert, | ||||
| verts_len, | verts_len, | ||||
| false, | false, | ||||
| loose_verts_mask, | loose_verts_mask, | ||||
| loose_vert_len, | loose_vert_len, | ||||
| 0.0f, | 0.0f, | ||||
| tree_type, | tree_type, | ||||
| 6, | 6, | ||||
| bvh_cache_type, | bvh_cache_type, | ||||
| bvh_cache_p, | bvh_cache_p, | ||||
| mesh_eval_mutex); | mesh_eval_mutex); | ||||
| if (loose_verts_mask != nullptr) { | if (loose_verts_mask != nullptr) { | ||||
| MEM_freeN(loose_verts_mask); | MEM_freeN(loose_verts_mask); | ||||
| } | } | ||||
| } | } break; | ||||
| else { | |||||
| /* Setup BVHTreeFromMesh */ | |||||
| bvhtree_from_mesh_verts_setup_data(data, tree, true, mesh->mvert, false); | |||||
| } | |||||
| break; | |||||
| case BVHTREE_FROM_EDGES: | case BVHTREE_FROM_EDGES: | ||||
| case BVHTREE_FROM_LOOSEEDGES: | case BVHTREE_FROM_LOOSEEDGES: { | ||||
| if (is_cached == false) { | |||||
| BLI_bitmap *loose_edges_mask = nullptr; | BLI_bitmap *loose_edges_mask = nullptr; | ||||
| int loose_edges_len = -1; | int loose_edges_len = -1; | ||||
| int edges_len = mesh->totedge; | int edges_len = mesh->totedge; | ||||
| if (bvh_cache_type == BVHTREE_FROM_LOOSEEDGES) { | if (bvh_cache_type == BVHTREE_FROM_LOOSEEDGES) { | ||||
| loose_edges_mask = loose_edges_map_get(mesh->medge, edges_len, &loose_edges_len); | loose_edges_mask = loose_edges_map_get(mesh->medge, edges_len, &loose_edges_len); | ||||
| } | } | ||||
| tree = bvhtree_from_mesh_edges_ex(data, | data->tree = bvhtree_from_mesh_edges_ex(nullptr, | ||||
| mesh->mvert, | mesh->mvert, | ||||
| false, | false, | ||||
| mesh->medge, | mesh->medge, | ||||
| edges_len, | edges_len, | ||||
| false, | false, | ||||
| loose_edges_mask, | loose_edges_mask, | ||||
| loose_edges_len, | loose_edges_len, | ||||
| 0.0, | 0.0, | ||||
| tree_type, | tree_type, | ||||
| 6, | 6, | ||||
| bvh_cache_type, | bvh_cache_type, | ||||
| bvh_cache_p, | bvh_cache_p, | ||||
| mesh_eval_mutex); | mesh_eval_mutex); | ||||
| if (loose_edges_mask != nullptr) { | if (loose_edges_mask != nullptr) { | ||||
| MEM_freeN(loose_edges_mask); | MEM_freeN(loose_edges_mask); | ||||
| } | } | ||||
| } | } break; | ||||
| else { | |||||
| /* Setup BVHTreeFromMesh */ | |||||
| bvhtree_from_mesh_edges_setup_data( | |||||
| data, tree, true, mesh->mvert, false, mesh->medge, false); | |||||
| } | |||||
| break; | |||||
| case BVHTREE_FROM_FACES: | case BVHTREE_FROM_FACES: { | ||||
| if (is_cached == false) { | |||||
| int num_faces = mesh->totface; | int num_faces = mesh->totface; | ||||
| BLI_assert(!(num_faces == 0 && mesh->totpoly != 0)); | BLI_assert(!(num_faces == 0 && mesh->totpoly != 0)); | ||||
| tree = bvhtree_from_mesh_faces_ex(data, | data->tree = bvhtree_from_mesh_faces_ex(nullptr, | ||||
| mesh->mvert, | mesh->mvert, | ||||
| false, | false, | ||||
| mesh->mface, | mesh->mface, | ||||
| num_faces, | num_faces, | ||||
| false, | false, | ||||
| nullptr, | nullptr, | ||||
| -1, | -1, | ||||
| 0.0, | 0.0, | ||||
| tree_type, | tree_type, | ||||
| 6, | 6, | ||||
| bvh_cache_type, | bvh_cache_type, | ||||
| bvh_cache_p, | bvh_cache_p, | ||||
| mesh_eval_mutex); | mesh_eval_mutex); | ||||
| } | } break; | ||||
| else { | |||||
| /* Setup BVHTreeFromMesh */ | |||||
| bvhtree_from_mesh_faces_setup_data( | |||||
| data, tree, true, mesh->mvert, false, mesh->mface, false); | |||||
| } | |||||
| break; | |||||
| case BVHTREE_FROM_LOOPTRI: | case BVHTREE_FROM_LOOPTRI: | ||||
| case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: | case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: { | ||||
| if (is_cached == false) { | |||||
| const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| int looptri_len = BKE_mesh_runtime_looptri_len(mesh); | int looptri_len = BKE_mesh_runtime_looptri_len(mesh); | ||||
| int looptri_mask_active_len = -1; | int looptri_mask_active_len = -1; | ||||
| BLI_bitmap *looptri_mask = nullptr; | BLI_bitmap *looptri_mask = nullptr; | ||||
| if (bvh_cache_type == BVHTREE_FROM_LOOPTRI_NO_HIDDEN) { | if (bvh_cache_type == BVHTREE_FROM_LOOPTRI_NO_HIDDEN) { | ||||
| looptri_mask = looptri_no_hidden_map_get( | looptri_mask = looptri_no_hidden_map_get( | ||||
| mesh->mpoly, looptri_len, &looptri_mask_active_len); | mesh->mpoly, looptri_len, &looptri_mask_active_len); | ||||
| } | } | ||||
| tree = bvhtree_from_mesh_looptri_ex(data, | data->tree = bvhtree_from_mesh_looptri_ex(nullptr, | ||||
| mesh->mvert, | mesh->mvert, | ||||
| false, | false, | ||||
| mesh->mloop, | mesh->mloop, | ||||
| false, | false, | ||||
| mlooptri, | mlooptri, | ||||
| looptri_len, | looptri_len, | ||||
| false, | false, | ||||
| looptri_mask, | looptri_mask, | ||||
| looptri_mask_active_len, | looptri_mask_active_len, | ||||
| 0.0, | 0.0, | ||||
| tree_type, | tree_type, | ||||
| 6, | 6, | ||||
| bvh_cache_type, | bvh_cache_type, | ||||
| bvh_cache_p, | bvh_cache_p, | ||||
| mesh_eval_mutex); | mesh_eval_mutex); | ||||
| if (looptri_mask != nullptr) { | if (looptri_mask != nullptr) { | ||||
| MEM_freeN(looptri_mask); | MEM_freeN(looptri_mask); | ||||
| } | } | ||||
| } | } break; | ||||
| else { | |||||
| /* Setup BVHTreeFromMesh */ | |||||
| const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | |||||
| bvhtree_from_mesh_looptri_setup_data( | |||||
| data, tree, true, mesh->mvert, false, mesh->mloop, false, mlooptri, false); | |||||
| } | |||||
| break; | |||||
| case BVHTREE_FROM_EM_VERTS: | case BVHTREE_FROM_EM_VERTS: | ||||
| case BVHTREE_FROM_EM_EDGES: | case BVHTREE_FROM_EM_EDGES: | ||||
| case BVHTREE_FROM_EM_LOOPTRI: | case BVHTREE_FROM_EM_LOOPTRI: | ||||
| case BVHTREE_MAX_ITEM: | case BVHTREE_MAX_ITEM: | ||||
| BLI_assert(false); | BLI_assert(false); | ||||
| break; | break; | ||||
| } | } | ||||
| if (data->tree != nullptr) { | /* Even if nullptr, the tree has been added to the cache. */ | ||||
| data->cached = true; | |||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| if (data->tree != nullptr) { | |||||
| if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) { | if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) { | ||||
| printf("tree_type %d obtained instead of %d\n", | printf("tree_type %d obtained instead of %d\n", | ||||
| BLI_bvhtree_get_tree_type(data->tree), | BLI_bvhtree_get_tree_type(data->tree), | ||||
| tree_type); | tree_type); | ||||
| } | } | ||||
| #endif | |||||
| BLI_assert(data->cached); | |||||
| } | } | ||||
| else { | #endif | ||||
| free_bvhtree_from_mesh(data); | |||||
| memset(data, 0, sizeof(*data)); | |||||
| } | |||||
| data->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); | |||||
| return tree; | return data->tree; | ||||
| } | } | ||||
| BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data, | BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data, | ||||
| struct BMEditMesh *em, | struct BMEditMesh *em, | ||||
| const int tree_type, | const int tree_type, | ||||
| 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 = nullptr; | bvhtree_from_editmesh_setup_data(nullptr, bvh_cache_type, em, data); | ||||
| bool is_cached = false; | |||||
| memset(data, 0, sizeof(*data)); | |||||
| if (bvh_cache_p) { | if (bvh_cache_p) { | ||||
| is_cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &tree, nullptr, nullptr); | data->cached = bvhcache_find(bvh_cache_p, bvh_cache_type, &data->tree, nullptr, nullptr); | ||||
| if (is_cached && tree == nullptr) { | if (data->cached) { | ||||
| return tree; | return data->tree; | ||||
| } | } | ||||
| } | } | ||||
| data->tree = tree; | |||||
| data->em = em; | |||||
| 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) { | data->tree = bvhtree_from_editmesh_verts_ex(nullptr, | ||||
| tree = bvhtree_from_editmesh_verts_ex(data, | |||||
| em, | em, | ||||
| nullptr, | nullptr, | ||||
| -1, | -1, | ||||
| 0.0f, | 0.0f, | ||||
| tree_type, | tree_type, | ||||
| 6, | 6, | ||||
| bvh_cache_type, | bvh_cache_type, | ||||
| bvh_cache_p, | bvh_cache_p, | ||||
| mesh_eval_mutex); | mesh_eval_mutex); | ||||
| } | |||||
| else { | |||||
| data->nearest_callback = nullptr; | |||||
| data->raycast_callback = editmesh_verts_spherecast; | |||||
| } | |||||
| break; | break; | ||||
| case BVHTREE_FROM_EM_EDGES: | case BVHTREE_FROM_EM_EDGES: | ||||
| if (is_cached == false) { | data->tree = bvhtree_from_editmesh_edges_ex(nullptr, | ||||
| tree = bvhtree_from_editmesh_edges_ex(data, | |||||
| em, | em, | ||||
| nullptr, | nullptr, | ||||
| -1, | -1, | ||||
| 0.0f, | 0.0f, | ||||
| tree_type, | tree_type, | ||||
| 6, | 6, | ||||
| bvh_cache_type, | bvh_cache_type, | ||||
| bvh_cache_p, | bvh_cache_p, | ||||
| mesh_eval_mutex); | mesh_eval_mutex); | ||||
| } | |||||
| else { | |||||
| /* Setup #BVHTreeFromMesh */ | |||||
| data->nearest_callback = nullptr; /* TODO */ | |||||
| data->raycast_callback = nullptr; /* TODO */ | |||||
| } | |||||
| break; | break; | ||||
| case BVHTREE_FROM_EM_LOOPTRI: | case BVHTREE_FROM_EM_LOOPTRI: | ||||
| if (is_cached == false) { | data->tree = bvhtree_from_editmesh_looptri_ex(nullptr, | ||||
| tree = bvhtree_from_editmesh_looptri_ex(data, | |||||
| em, | em, | ||||
| nullptr, | nullptr, | ||||
| -1, | -1, | ||||
| 0.0f, | 0.0f, | ||||
| tree_type, | tree_type, | ||||
| 6, | 6, | ||||
| bvh_cache_type, | bvh_cache_type, | ||||
| bvh_cache_p, | bvh_cache_p, | ||||
| mesh_eval_mutex); | mesh_eval_mutex); | ||||
| } | |||||
| else { | |||||
| /* Setup #BVHTreeFromMesh */ | |||||
| data->nearest_callback = editmesh_looptri_nearest_point; | |||||
| data->raycast_callback = editmesh_looptri_spherecast; | |||||
| } | |||||
| break; | break; | ||||
| case BVHTREE_FROM_VERTS: | case BVHTREE_FROM_VERTS: | ||||
| case BVHTREE_FROM_EDGES: | case BVHTREE_FROM_EDGES: | ||||
| case BVHTREE_FROM_FACES: | case BVHTREE_FROM_FACES: | ||||
| case BVHTREE_FROM_LOOPTRI: | case BVHTREE_FROM_LOOPTRI: | ||||
| case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: | case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: | ||||
| case BVHTREE_FROM_LOOSEVERTS: | case BVHTREE_FROM_LOOSEVERTS: | ||||
| case BVHTREE_FROM_LOOSEEDGES: | case BVHTREE_FROM_LOOSEEDGES: | ||||
| case BVHTREE_MAX_ITEM: | case BVHTREE_MAX_ITEM: | ||||
| BLI_assert(false); | BLI_assert(false); | ||||
| break; | break; | ||||
| } | } | ||||
| if (data->tree != nullptr) { | /* Even if the tree is nullptr, it has been added to the cache if available. */ | ||||
| data->cached = bvh_cache_p != nullptr; | |||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| if (data->tree != nullptr) { | |||||
| if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) { | if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) { | ||||
| printf("tree_type %d obtained instead of %d\n", | printf("tree_type %d obtained instead of %d\n", | ||||
| BLI_bvhtree_get_tree_type(data->tree), | BLI_bvhtree_get_tree_type(data->tree), | ||||
| tree_type); | tree_type); | ||||
| } | } | ||||
| #endif | |||||
| BLI_assert(data->cached); | |||||
| } | |||||
| else { | |||||
| free_bvhtree_from_editmesh(data); | |||||
| memset(data, 0, sizeof(*data)); | |||||
| } | } | ||||
| #endif | |||||
| return tree; | return data->tree; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Free Functions | /** \name Free Functions | ||||
| * \{ */ | * \{ */ | ||||
| ▲ Show 20 Lines • Show All 72 Lines • Show Last 20 Lines | |||||