[Bf-blender-cvs] [e99cb91530f] master: Transform Snap Refactor: dedicate ghash to different SnapData types

Germano Cavalcante noreply at git.blender.org
Mon Apr 25 17:48:22 CEST 2022


Commit: e99cb91530f37a2b026a6280112e627d7764d0bf
Author: Germano Cavalcante
Date:   Wed Apr 20 16:44:14 2022 -0300
Branches: master
https://developer.blender.org/rBe99cb91530f37a2b026a6280112e627d7764d0bf

Transform Snap Refactor: dedicate ghash to different SnapData types

Changes:
- Remove `BLI_memarena` (Use `MEM_cnew` and `MEM_delete` to allocate cached data)
- Implement `snap_object_data_mesh_free_ensure` and `snap_object_data_editmesh_free_ensure` and skip need to get original key Object for editmesh data
- Use `BMEditMesh` as key for editmesh `Ghash`
- Make a better distinction between `SnapObjectData`s. (`SnapData_Mesh` and `SnapData_EditMesh`)

===================================================================

M	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 f533b2c298c..f92124306af 100644
--- a/source/blender/editors/transform/transform_snap_object.cc
+++ b/source/blender/editors/transform/transform_snap_object.cc
@@ -14,7 +14,6 @@
 #include "BLI_listbase.h"
 #include "BLI_math.h"
 #include "BLI_math_vector.hh"
-#include "BLI_memarena.h"
 #include "BLI_utildefines.h"
 
 #include "DNA_armature_types.h"
@@ -60,33 +59,32 @@ enum eViewProj {
   VIEW_PROJ_PERSP = -1,
 };
 
-struct SnapObjectData {
-  enum class Type {
-    Mesh,
-    EditMesh,
-  };
-  Type type;
+/* SnapObjectContext.cache.mesh_map */
+struct SnapData_Mesh {
+  /* Loose edges, loose verts. */
+  BVHTree *bvhtree[2];
+  bool cached[2];
+
+  /* Looptris. */
+  BVHTreeFromMesh treedata_mesh;
+
+  const struct MPoly *poly;
+  uint has_looptris : 1;
+  uint has_loose_edge : 1;
+  uint has_loose_vert : 1;
+};
 
-  BVHTree *bvhtree[2]; /* MESH: loose edges, loose verts
-                        * EDIT_MESH: verts, edges. */
+/* SnapObjectContext.cache.editmesh_map */
+struct SnapData_EditMesh {
+  /* Verts, Edges. */
+  BVHTree *bvhtree[2];
   bool cached[2];
 
-  union {
-    struct {
-      /* Type::Mesh */
-      BVHTreeFromMesh treedata_mesh;
-      const struct MPoly *poly;
-      uint has_looptris : 1;
-      uint has_loose_edge : 1;
-      uint has_loose_vert : 1;
-    };
-    struct {
-      /* Type::EditMesh */
-      BVHTreeFromEditMesh treedata_editmesh;
-      float min[3], max[3];
-      struct Mesh_Runtime *mesh_runtime;
-    };
-  };
+  /* Looptris. */
+  BVHTreeFromEditMesh treedata_editmesh;
+
+  struct Mesh_Runtime *mesh_runtime;
+  float min[3], max[3];
 };
 
 struct SnapObjectContext {
@@ -94,12 +92,12 @@ struct SnapObjectContext {
 
   int flag;
 
-  /* Object -> SnapObjectData map */
   struct {
-    GHash *object_map;
-    /** Map object-data to objects so objects share edit mode data. */
-    GHash *data_to_object_map;
-    MemArena *mem_arena;
+    /* Object -> SnapData_Mesh map */
+    GHash *mesh_map;
+
+    /* EditMesh -> SnapData_EditMesh map */
+    GHash *editmesh_map;
   } cache;
 
   /* Filter data, returns true to check this value */
@@ -196,9 +194,8 @@ static void snap_editmesh_minmax(SnapObjectContext *sctx,
   }
 }
 
-static void snap_object_data_mesh_clear(SnapObjectData *sod)
+static void snap_object_data_mesh_clear(SnapData_Mesh *sod)
 {
-  BLI_assert(sod->type == SnapObjectData::Type::Mesh);
   for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) {
     if (!sod->cached[i]) {
       BLI_bvhtree_free(sod->bvhtree[i]);
@@ -206,11 +203,11 @@ static void snap_object_data_mesh_clear(SnapObjectData *sod)
     sod->bvhtree[i] = nullptr;
   }
   free_bvhtree_from_mesh(&sod->treedata_mesh);
+  memset(sod, 0x0, sizeof(*sod));
 }
 
-static void snap_object_data_editmesh_clear(SnapObjectData *sod)
+static void snap_object_data_editmesh_clear(SnapData_EditMesh *sod)
 {
-  BLI_assert(sod->type == SnapObjectData::Type::EditMesh);
   for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) {
     if (!sod->cached[i]) {
       BLI_bvhtree_free(sod->bvhtree[i]);
@@ -218,57 +215,73 @@ static void snap_object_data_editmesh_clear(SnapObjectData *sod)
     sod->bvhtree[i] = nullptr;
   }
   free_bvhtree_from_editmesh(&sod->treedata_editmesh);
+  memset(sod, 0x0, sizeof(*sod));
 }
 
-static void snap_object_data_clear(SnapObjectData *sod)
+static void snap_object_data_mesh_free(SnapData_Mesh *sod)
 {
-  switch (sod->type) {
-    case SnapObjectData::Type::Mesh: {
-      snap_object_data_mesh_clear(sod);
-      break;
-    }
-    case SnapObjectData::Type::EditMesh: {
-      snap_object_data_editmesh_clear(sod);
-      break;
-    }
+  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<SnapData_Mesh *>(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;
   }
-  memset(&sod->type, 0x0, sizeof(*sod) - offsetof(SnapObjectData, type));
+  BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
+  if (!em) {
+    return nullptr;
+  }
+  return static_cast<SnapData_EditMesh *>(BLI_ghash_lookup(sctx->cache.editmesh_map, em));
 }
 
-static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *ob_eval)
+static void snap_object_data_mesh_free_ensure(SnapObjectContext *sctx, Object *ob_eval)
 {
-  SnapObjectData *sod = static_cast<SnapObjectData *>(
-      BLI_ghash_lookup(sctx->cache.object_map, ob_eval));
-  if (sod == nullptr) {
-    if (sctx->cache.data_to_object_map != nullptr) {
-      ob_eval = static_cast<Object *>(
-          BLI_ghash_lookup(sctx->cache.data_to_object_map, ob_eval->runtime.data_orig));
-      /* Could be NULl when mixing edit-mode and non edit-mode objects. */
-      if (ob_eval != nullptr) {
-        sod = static_cast<SnapObjectData *>(BLI_ghash_lookup(sctx->cache.object_map, ob_eval));
-      }
-    }
+  auto *sod = snap_object_lookup_mesh(sctx, ob_eval);
+  if (!sod) {
+    return;
   }
-  return sod;
+  BLI_ghash_popkey(sctx->cache.mesh_map, ob_eval, NULL);
+  snap_object_data_mesh_free(sod);
 }
 
-static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx,
-                                                 Object *ob_eval,
-                                                 const Mesh *me_eval,
-                                                 bool use_hide)
+static void snap_object_data_editmesh_free_ensure(SnapObjectContext *sctx, Object *ob_eval)
 {
-  SnapObjectData *sod;
+  auto *sod = snap_object_lookup_editmesh(sctx, ob_eval);
+  if (!sod) {
+    return;
+  }
+  BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
+  BLI_ghash_popkey(sctx->cache.editmesh_map, em, NULL);
+  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.object_map, ob_eval, &sod_p)) {
-    sod = static_cast<SnapObjectData *>(*sod_p);
+  if (BLI_ghash_ensure_p(sctx->cache.mesh_map, ob_eval, &sod_p)) {
+    sod = static_cast<SnapData_Mesh *>(*sod_p);
     bool is_dirty = false;
-    if (sod->type != SnapObjectData::Type::Mesh) {
-      is_dirty = true;
-    }
-    else if (sod->treedata_mesh.tree && sod->treedata_mesh.cached &&
-             !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->treedata_mesh.tree)) {
+    if (sod->treedata_mesh.tree && sod->treedata_mesh.cached &&
+        !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->treedata_mesh.tree)) {
       /* The tree is owned by the Mesh and may have been freed since we last used. */
       is_dirty = true;
     }
@@ -299,19 +312,19 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx,
     }
 
     if (is_dirty) {
-      snap_object_data_clear(sod);
+      snap_object_data_mesh_clear(sod);
       init = true;
     }
   }
   else {
-    *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
-    sod = static_cast<SnapObjectData *>(*sod_p);
+    /* Any existing #SnapData_EditMesh is now invalid. */
+    snap_object_data_editmesh_free_ensure(sctx, ob_eval);
+
+    *sod_p = sod = MEM_cnew<SnapData_Mesh>(__func__);
     init = true;
   }
 
   if (init) {
-    sod->type = SnapObjectData::Type::Mesh;
-
     /* The BVHTree from looptris is always required. */
     BLI_assert(sod->treedata_mesh.tree == nullptr);
     BKE_bvhtree_from_mesh_get(&sod->treedata_mesh,
@@ -339,6 +352,8 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx,
   return sod;
 }
 
+/* Searches for the #Mesh_Runtime associated with the object that is most likely to be updated due
+ * to changes in the `edit_mesh`. */
 static struct Mesh_Runtime *snap_object_data_editmesh_runtime_get(Object *ob_eval)
 {
   Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval);
@@ -354,37 +369,26 @@ static struct Mesh_Runtime *snap_object_data_editmesh_runtime_get(Object *ob_eva
   return &((Mesh *)ob_eval->data)->runtime;
 }
 
-static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
-                                                     Object *ob_eval,
-                                                     BMEditMesh *em)
+static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
+                                                        Object *ob_eval,
+                                                        BMEditMesh *em)
 {
-  SnapObjectData *sod;
+  SnapData_EditMesh *sod;
   void **sod_p;
   bool init = false;
 
-  {
-    /* Use object-data as the key in ghash since the editmesh
-     * is used to create bvhtree and is the same for each linked object. */
-    if (sctx->cache.data_to_object_map == nullptr) {
-      sctx->cache.data_to_object_map = BLI_ghash_ptr_new(__func__);
-    }
-    void **ob_p;
-    if (BLI_ghash_ensure_p(sctx->cache.data_to_object_map, ob_eval->runtime.data_orig, &ob_p)) {
-      ob_eval = static_cast<Object *>(*ob_p);
-    }
-    else {
-      *ob_p = ob_eval;
-    }
+  /* 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__);
   }
 
-  if (BLI_ghash_ensure_p(sctx->cache.object_map, ob_eval, &sod_p)) {
-    sod = static_cast<SnapObjectData *>(*sod_p);
+  if (BLI_ghash_ensure_p(sctx->cache.editmesh_map, em, &sod_p)) {
+    sod = static_cast<SnapData_EditMesh *>(*sod_p);
     bool is_dirty = false;
     /* Check if the geometry has changed. */
-    if (sod->type != SnapObjectData::Type::EditMesh) {
-   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list