From 1f270cf99b76d8a92b4c964882da2873afbd114d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 26 Apr 2022 18:33:05 -0500 Subject: Snap: Use Map and unique_ptr for snap cache Use C++ types instead of GHash to make code easier to read and simpler. Differential Revision: https://developer.blender.org/D14758 --- .../editors/transform/transform_snap_object.cc | 197 ++++++++------------- 1 file changed, 74 insertions(+), 123 deletions(-) (limited to 'source/blender/editors/transform/transform_snap_object.cc') diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 8f04725e521..584c9642e5a 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -9,9 +9,9 @@ #include "MEM_guardedalloc.h" #include "BLI_float4x4.hh" -#include "BLI_ghash.h" #include "BLI_kdopbvh.h" #include "BLI_listbase.h" +#include "BLI_map.hh" #include "BLI_math.h" #include "BLI_math_vector.hh" #include "BLI_utildefines.h" @@ -46,6 +46,7 @@ using blender::float3; using blender::float4x4; +using blender::Map; /* -------------------------------------------------------------------- */ /** \name Internal Data Types @@ -72,6 +73,26 @@ struct SnapData_Mesh { uint has_looptris : 1; uint has_loose_edge : 1; uint has_loose_vert : 1; + + void clear() + { + for (int i = 0; i < ARRAY_SIZE(this->bvhtree); i++) { + if (!this->cached[i]) { + BLI_bvhtree_free(this->bvhtree[i]); + } + this->bvhtree[i] = nullptr; + } + free_bvhtree_from_mesh(&this->treedata_mesh); + } + + ~SnapData_Mesh() + { + this->clear(); + } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("SnapData_Mesh") +#endif }; /* SnapObjectContext.cache.editmesh_map */ @@ -85,6 +106,26 @@ struct SnapData_EditMesh { struct Mesh_Runtime *mesh_runtime; float min[3], max[3]; + + void clear() + { + for (int i = 0; i < ARRAY_SIZE(this->bvhtree); i++) { + if (!this->cached[i]) { + BLI_bvhtree_free(this->bvhtree[i]); + } + this->bvhtree[i] = nullptr; + } + free_bvhtree_from_editmesh(&this->treedata_editmesh); + } + + ~SnapData_EditMesh() + { + this->clear(); + } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("SnapData_EditMesh") +#endif }; struct SnapObjectContext { @@ -92,13 +133,8 @@ struct SnapObjectContext { int flag; - struct { - /* Object -> SnapData_Mesh map */ - GHash *mesh_map; - - /* EditMesh -> SnapData_EditMesh map */ - GHash *editmesh_map; - } cache; + Map> mesh_caches; + Map> editmesh_caches; /* Filter data, returns true to check this value */ struct { @@ -194,91 +230,16 @@ static void snap_editmesh_minmax(SnapObjectContext *sctx, } } -static void snap_object_data_mesh_clear(SnapData_Mesh *sod) -{ - for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) { - if (!sod->cached[i]) { - BLI_bvhtree_free(sod->bvhtree[i]); - } - sod->bvhtree[i] = nullptr; - } - free_bvhtree_from_mesh(&sod->treedata_mesh); - memset(sod, 0x0, sizeof(*sod)); -} - -static void snap_object_data_editmesh_clear(SnapData_EditMesh *sod) -{ - for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) { - if (!sod->cached[i]) { - BLI_bvhtree_free(sod->bvhtree[i]); - } - sod->bvhtree[i] = nullptr; - } - free_bvhtree_from_editmesh(&sod->treedata_editmesh); - memset(sod, 0x0, sizeof(*sod)); -} - -static void snap_object_data_mesh_free(SnapData_Mesh *sod) -{ - snap_object_data_mesh_clear(sod); - MEM_delete(sod); -} - -static void snap_object_data_editmesh_free(SnapData_EditMesh *sod) -{ - snap_object_data_editmesh_clear(sod); - MEM_delete(sod); -} - -static SnapData_Mesh *snap_object_lookup_mesh(SnapObjectContext *sctx, Object *ob_eval) -{ - return static_cast(BLI_ghash_lookup(sctx->cache.mesh_map, ob_eval)); -} - -static SnapData_EditMesh *snap_object_lookup_editmesh(SnapObjectContext *sctx, Object *ob_eval) -{ - if (!sctx->cache.editmesh_map) { - return nullptr; - } - BMEditMesh *em = BKE_editmesh_from_object(ob_eval); - if (!em) { - return nullptr; - } - return static_cast(BLI_ghash_lookup(sctx->cache.editmesh_map, em)); -} - -static void snap_object_data_mesh_free_ensure(SnapObjectContext *sctx, Object *ob_eval) -{ - auto *sod = snap_object_lookup_mesh(sctx, ob_eval); - if (!sod) { - return; - } - BLI_ghash_remove(sctx->cache.mesh_map, ob_eval, nullptr, nullptr); - snap_object_data_mesh_free(sod); -} - -static void snap_object_data_editmesh_free_ensure(SnapObjectContext *sctx, Object *ob_eval) -{ - auto *sod = snap_object_lookup_editmesh(sctx, ob_eval); - if (!sod) { - return; - } - BMEditMesh *em = BKE_editmesh_from_object(ob_eval); - BLI_ghash_remove(sctx->cache.editmesh_map, em, nullptr, nullptr); - snap_object_data_editmesh_free(sod); -} - static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, Object *ob_eval, const Mesh *me_eval, bool use_hide) { SnapData_Mesh *sod; - void **sod_p; bool init = false; - if (BLI_ghash_ensure_p(sctx->cache.mesh_map, ob_eval, &sod_p)) { - sod = static_cast(*sod_p); + if (std::unique_ptr *sod_p = sctx->mesh_caches.lookup_ptr(ob_eval)) { + sod = sod_p->get(); bool is_dirty = false; if (sod->treedata_mesh.tree && sod->treedata_mesh.cached && !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->treedata_mesh.tree)) { @@ -312,15 +273,18 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, } if (is_dirty) { - snap_object_data_mesh_clear(sod); + sod->clear(); init = true; } } else { /* Any existing #SnapData_EditMesh is now invalid. */ - snap_object_data_editmesh_free_ensure(sctx, ob_eval); + sctx->editmesh_caches.remove(BKE_editmesh_from_object(ob_eval)); + + std::unique_ptr sod_ptr = std::make_unique(); + sod = sod_ptr.get(); + sctx->mesh_caches.add_new(ob_eval, std::move(sod_ptr)); - *sod_p = sod = MEM_cnew(__func__); init = true; } @@ -336,7 +300,6 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, BLI_assert(!me_eval->mvert || sod->treedata_mesh.vert_normals); BLI_assert(sod->treedata_mesh.loop == me_eval->mloop); BLI_assert(!me_eval->mpoly || sod->treedata_mesh.looptri); - BLI_assert(sod->has_looptris == false); sod->has_looptris = sod->treedata_mesh.tree != nullptr; @@ -374,18 +337,13 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx, BMEditMesh *em) { SnapData_EditMesh *sod; - void **sod_p; bool init = false; /* Any existing #SnapData_Mesh is now invalid. */ - snap_object_data_mesh_free_ensure(sctx, ob_eval); - - if (sctx->cache.editmesh_map == nullptr) { - sctx->cache.editmesh_map = BLI_ghash_ptr_new(__func__); - } + sctx->mesh_caches.remove(ob_eval); - if (BLI_ghash_ensure_p(sctx->cache.editmesh_map, em, &sod_p)) { - sod = static_cast(*sod_p); + if (std::unique_ptr *sod_p = sctx->editmesh_caches.lookup_ptr(em)) { + sod = sod_p->get(); bool is_dirty = false; /* Check if the geometry has changed. */ if (sod->treedata_editmesh.em != em) { @@ -420,12 +378,14 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx, } if (is_dirty) { - snap_object_data_editmesh_clear(sod); + sod->clear(); init = true; } } else { - *sod_p = sod = MEM_cnew(__func__); + std::unique_ptr sod_ptr = std::make_unique(); + sod = sod_ptr.get(); + sctx->editmesh_caches.add_new(em, std::move(sod_ptr)); init = true; } @@ -1596,16 +1556,16 @@ static short snap_mesh_polygon(SnapObjectContext *sctx, nearest.dist_sq = square_f(*dist_px); Nearest2dUserData nearest2d; - SnapData_Mesh *sod_mesh = snap_object_lookup_mesh(sctx, ob_eval); + std::unique_ptr *sod_mesh = sctx->mesh_caches.lookup_ptr(ob_eval); if (sod_mesh) { - nearest2d_data_init_mesh(sod_mesh, + nearest2d_data_init_mesh(sod_mesh->get(), sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d); - BVHTreeFromMesh *treedata = &sod_mesh->treedata_mesh; + BVHTreeFromMesh *treedata = &sod_mesh->get()->treedata_mesh; - const MPoly *mp = &sod_mesh->poly[*r_index]; + const MPoly *mp = &sod_mesh->get()->poly[*r_index]; const MLoop *ml = &treedata->loop[mp->loopstart]; if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) { elem = SCE_SNAP_MODE_EDGE; @@ -1633,10 +1593,11 @@ static short snap_mesh_polygon(SnapObjectContext *sctx, } else { /* The object's #BMEditMesh was used to snap instead. */ - SnapData_EditMesh *sod_editmesh = snap_object_lookup_editmesh(sctx, ob_eval); - BLI_assert(sod_editmesh != nullptr); + std::unique_ptr &sod_editmesh = sctx->editmesh_caches.lookup( + BKE_editmesh_from_object(ob_eval)); + BLI_assert(sod_editmesh.get() != nullptr); - nearest2d_data_init_editmesh(sod_editmesh, + nearest2d_data_init_editmesh(sod_editmesh.get(), sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d); @@ -1718,17 +1679,18 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, Nearest2dUserData nearest2d; { - SnapData_Mesh *sod_mesh = snap_object_lookup_mesh(sctx, ob_eval); + std::unique_ptr *sod_mesh = sctx->mesh_caches.lookup_ptr(ob_eval); if (sod_mesh) { - nearest2d_data_init_mesh(sod_mesh, + nearest2d_data_init_mesh(sod_mesh->get(), sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d); } else { /* The object's #BMEditMesh was used to snap instead. */ - SnapData_EditMesh *sod_editmesh = snap_object_lookup_editmesh(sctx, ob_eval); - nearest2d_data_init_editmesh(sod_editmesh, + std::unique_ptr &sod_editmesh = sctx->editmesh_caches.lookup( + BKE_editmesh_from_object(ob_eval)); + nearest2d_data_init_editmesh(sod_editmesh.get(), sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d); @@ -2877,29 +2839,18 @@ static short snapObjectsRay(SnapObjectContext *sctx, SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int flag) { - SnapObjectContext *sctx = MEM_cnew(__func__); + SnapObjectContext *sctx = MEM_new(__func__); sctx->flag = flag; sctx->scene = scene; - sctx->cache.mesh_map = BLI_ghash_ptr_new(__func__); - - /* Initialize as needed (edit-mode only). */ - sctx->cache.editmesh_map = nullptr; - return sctx; } void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx) { - BLI_ghash_free(sctx->cache.mesh_map, nullptr, (GHashValFreeFP)snap_object_data_mesh_free); - if (sctx->cache.editmesh_map) { - BLI_ghash_free( - sctx->cache.editmesh_map, nullptr, (GHashValFreeFP)snap_object_data_editmesh_free); - } - - MEM_freeN(sctx); + MEM_delete(sctx); } void ED_transform_snap_object_context_set_editmesh_callbacks( -- cgit v1.2.3