diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h index 2570d70ec8c..5c15a431851 100644 --- a/source/blender/blenkernel/BKE_bvhutils.h +++ b/source/blender/blenkernel/BKE_bvhutils.h @@ -39,8 +39,6 @@ typedef struct BVHTreeFromEditMesh { BVHTree_NearestPointCallback nearest_callback; BVHTree_RayCastCallback raycast_callback; - struct BMEditMesh *em; - /* Private data */ bool cached; diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index 171dd1da9e7..abbb3e92397 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -300,8 +300,7 @@ static void editmesh_looptri_nearest_point(void *userdata, const float co[3], BVHTreeNearest *nearest) { - const BVHTreeFromEditMesh *data = (const BVHTreeFromEditMesh *)userdata; - BMEditMesh *em = data->em; + BMEditMesh *em = static_cast(userdata); const BMLoop **ltri = (const BMLoop **)em->looptris[index]; const float *t0, *t1, *t2; @@ -405,8 +404,7 @@ static void editmesh_looptri_spherecast(void *userdata, const BVHTreeRay *ray, BVHTreeRayHit *hit) { - const BVHTreeFromEditMesh *data = (BVHTreeFromEditMesh *)userdata; - BMEditMesh *em = data->em; + BMEditMesh *em = static_cast(userdata); const BMLoop **ltri = (const BMLoop **)em->looptris[index]; const float *t0, *t1, *t2; @@ -492,8 +490,8 @@ static void editmesh_verts_spherecast(void *userdata, const BVHTreeRay *ray, BVHTreeRayHit *hit) { - const BVHTreeFromEditMesh *data = (const BVHTreeFromEditMesh *)userdata; - BMVert *eve = BM_vert_at_index(data->em->bm, index); + BMEditMesh *em = static_cast(userdata); + BMVert *eve = BM_vert_at_index(em->bm, index); mesh_verts_spherecast_do(index, eve->co, ray, hit); } @@ -629,15 +627,12 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree, static void bvhtree_from_editmesh_setup_data(BVHTree *tree, const BVHCacheType bvh_cache_type, - 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_LOOSEVERTS: r_data->nearest_callback = nullptr; @@ -754,7 +749,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, bvhtree_balance(tree, false); if (data) { - bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOSEVERTS, em, data); + bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOSEVERTS, data); } return tree; @@ -870,7 +865,7 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data, bvhtree_balance(tree, false); if (data) { - bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_EDGES, em, data); + bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_EDGES, data); } return tree; @@ -1047,7 +1042,7 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, bvhtree_balance(tree, false); if (data) { - bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOPTRI, em, data); + bvhtree_from_editmesh_setup_data(tree, BVHTREE_FROM_EM_LOOPTRI, data); } return tree; } @@ -1281,7 +1276,7 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data, { bool lock_started = false; - bvhtree_from_editmesh_setup_data(nullptr, bvh_cache_type, em, data); + bvhtree_from_editmesh_setup_data(nullptr, bvh_cache_type, data); if (bvh_cache_p) { data->cached = bvhcache_find( diff --git a/source/blender/editors/transform/transform_snap_object_editmesh.cc b/source/blender/editors/transform/transform_snap_object_editmesh.cc index d428b1c57dc..d40d5e9463e 100644 --- a/source/blender/editors/transform/transform_snap_object_editmesh.cc +++ b/source/blender/editors/transform/transform_snap_object_editmesh.cc @@ -28,14 +28,17 @@ using namespace blender; * \{ */ struct SnapCache_EditMesh : public SnapObjectContext::SnapCache { - /* Loose Verts, Edges. */ - BVHTree *bvhtree[2]; - bool cached[2]; + /* Loose Verts, Edges, Tris. */ + BVHTree *bvhtree[3]; + bool cached[3]; - /* BVH tree from #BMEditMesh.looptris. */ - BVHTreeFromEditMesh treedata_editmesh; + struct BMEditMesh *em; - blender::bke::MeshRuntime *mesh_runtime; + /** Default callbacks to BVH nearest and ray-cast used only for tris. */ + BVHTree_NearestPointCallback nearest_callback; + BVHTree_RayCastCallback raycast_callback; + + bke::MeshRuntime *mesh_runtime; float min[3], max[3]; void clear() @@ -46,7 +49,6 @@ struct SnapCache_EditMesh : public SnapObjectContext::SnapCache { } this->bvhtree[i] = nullptr; } - free_bvhtree_from_editmesh(&this->treedata_editmesh); } ~SnapCache_EditMesh() @@ -112,7 +114,7 @@ static SnapCache_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx em_cache = static_cast(em_cache_p->get()); bool is_dirty = false; /* Check if the geometry has changed. */ - if (em_cache->treedata_editmesh.em != em) { + if (em_cache->em != em) { is_dirty = true; } else if (em_cache->mesh_runtime) { @@ -127,13 +129,6 @@ static SnapCache_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx is_dirty = true; } } - else if (em_cache->treedata_editmesh.tree && em_cache->treedata_editmesh.cached && - !bvhcache_has_tree(em_cache->mesh_runtime->bvh_cache, - em_cache->treedata_editmesh.tree)) - { - /* The tree is owned by the EditMesh and may have been freed since we last used! */ - is_dirty = true; - } else if (em_cache->bvhtree[0] && em_cache->cached[0] && !bvhcache_has_tree(em_cache->mesh_runtime->bvh_cache, em_cache->bvhtree[0])) { @@ -146,6 +141,12 @@ static SnapCache_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx /* The tree is owned by the EditMesh and may have been freed since we last used! */ is_dirty = true; } + else if (em_cache->bvhtree[2] && em_cache->cached[2] && + !bvhcache_has_tree(em_cache->mesh_runtime->bvh_cache, em_cache->bvhtree[2])) + { + /* The tree is owned by the EditMesh and may have been freed since we last used! */ + is_dirty = true; + } } if (is_dirty) { @@ -164,7 +165,7 @@ static SnapCache_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx /* Operators only update the editmesh looptris of the original mesh. */ BLI_assert(em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval))); - em_cache->treedata_editmesh.em = em; + em_cache->em = em; em_cache->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval); snap_editmesh_minmax(sctx, em->bm, em_cache->min, em_cache->max); } @@ -172,14 +173,11 @@ static SnapCache_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx return em_cache; } -static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapCache_EditMesh *em_cache, - SnapObjectContext *sctx, - BMEditMesh *em) +static void snap_cache_tri_ensure(SnapCache_EditMesh *em_cache, SnapObjectContext *sctx) { - BVHTreeFromEditMesh *treedata = &em_cache->treedata_editmesh; - - if (treedata->tree == nullptr) { - em = em_cache->treedata_editmesh.em; + if (em_cache->bvhtree[2] == nullptr) { + BVHTreeFromEditMesh treedata{}; + BMEditMesh *em = em_cache->em; if (sctx->callbacks.edit_mesh.test_face_fn) { BMesh *bm = em->bm; @@ -192,12 +190,12 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapCache_Edi sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data); - bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6); + bvhtree_from_editmesh_looptri_ex(&treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6); } else { /* Only cache if BVH-tree is created without a mask. * This helps keep a standardized BVH-tree in cache. */ - BKE_bvhtree_from_editmesh_get(treedata, + BKE_bvhtree_from_editmesh_get(&treedata, em, 4, BVHTREE_FROM_EM_LOOPTRI, @@ -205,12 +203,11 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapCache_Edi G.moving ? nullptr : &em_cache->mesh_runtime->bvh_cache, &em_cache->mesh_runtime->eval_mutex); } + em_cache->bvhtree[2] = treedata.tree; + em_cache->cached[2] = treedata.cached; + em_cache->nearest_callback = treedata.nearest_callback; + em_cache->raycast_callback = treedata.raycast_callback; } - if (treedata->tree == nullptr) { - return nullptr; - } - - return treedata; } /** \} */ @@ -269,8 +266,7 @@ static void editmesh_looptri_raycast_backface_culling_cb(void *userdata, const BVHTreeRay *ray, BVHTreeRayHit *hit) { - const BVHTreeFromEditMesh *data = (BVHTreeFromEditMesh *)userdata; - BMEditMesh *em = data->em; + BMEditMesh *em = static_cast(userdata); const BMLoop **ltri = (const BMLoop **)em->looptris[index]; const float *t0, *t1, *t2; @@ -340,16 +336,16 @@ static bool raycastEditMesh(SnapCache_EditMesh *em_cache, len_diff = 0.0f; } - BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(em_cache, sctx, em); - if (treedata == nullptr) { + snap_cache_tri_ensure(em_cache, sctx); + if (em_cache->bvhtree[2] == nullptr) { return retval; } if (sctx->ret.hit_list) { RayCastAll_Data data; - data.bvhdata = treedata; - data.raycast_callback = treedata->raycast_callback; + data.bvhdata = em; + data.raycast_callback = em_cache->raycast_callback; data.obmat = obmat; data.len_diff = len_diff; data.local_scale = local_scale; @@ -357,7 +353,7 @@ static bool raycastEditMesh(SnapCache_EditMesh *em_cache, data.hit_list = sctx->ret.hit_list; void *hit_last_prev = data.hit_list->last; - BLI_bvhtree_ray_cast_all(treedata->tree, + BLI_bvhtree_ray_cast_all(em_cache->bvhtree[2], ray_start_local, ray_normal_local, 0.0f, @@ -372,15 +368,15 @@ static bool raycastEditMesh(SnapCache_EditMesh *em_cache, hit.index = -1; hit.dist = local_depth; - if (BLI_bvhtree_ray_cast(treedata->tree, + if (BLI_bvhtree_ray_cast(em_cache->bvhtree[2], ray_start_local, ray_normal_local, 0.0f, &hit, sctx->runtime.params.use_backface_culling ? editmesh_looptri_raycast_backface_culling_cb : - treedata->raycast_callback, - treedata) != -1) + em_cache->raycast_callback, + em) != -1) { hit.dist += len_diff; hit.dist /= local_scale; @@ -395,7 +391,6 @@ static bool raycastEditMesh(SnapCache_EditMesh *em_cache, sctx->ret.ray_depth_max = hit.dist; - em = em_cache->treedata_editmesh.em; sctx->ret.index = BM_elem_index_get(em->looptris[hit.index][0]->f); retval = true; @@ -416,8 +411,8 @@ static bool nearest_world_editmesh(SnapCache_EditMesh *em_cache, BMEditMesh *em, const float4x4 &obmat) { - BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(em_cache, sctx, em); - if (treedata == nullptr) { + snap_cache_tri_ensure(em_cache, sctx); + if (em_cache->bvhtree[2] == nullptr) { return false; } @@ -427,7 +422,7 @@ static bool nearest_world_editmesh(SnapCache_EditMesh *em_cache, BVHTreeNearest nearest{}; nearest.dist_sq = sctx->ret.dist_px_sq; if (nearest_world_tree( - sctx, treedata->tree, treedata->nearest_callback, init_co, curr_co, treedata, &nearest)) + sctx, em_cache->bvhtree[2], em_cache->nearest_callback, init_co, curr_co, em, &nearest)) { SnapData::register_result(sctx, ob_eval, nullptr, obmat, &nearest); return true; @@ -697,8 +692,7 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx, return elem; } - BMEditMesh *em = em_cache->treedata_editmesh.em; - + BMEditMesh *em = em_cache->em; eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em->bm); if (snap_mode_used & (SNAP_TO_EDGE_ELEMENTS | SCE_SNAP_TO_POINT)) { elem = snapEditMesh(em_cache, sctx, ob_eval, em, obmat, snap_mode_used);