[Bf-blender-cvs] [3e1aa6cbf3d] master: Transform Snap: Clear 'SnapObjectData' after changes in the geometry

Germano Cavalcante noreply at git.blender.org
Tue Mar 3 04:11:19 CET 2020


Commit: 3e1aa6cbf3df6f9f0f96380386a7c8d64c07cc64
Author: Germano Cavalcante
Date:   Tue Mar 3 00:08:16 2020 -0300
Branches: master
https://developer.blender.org/rB3e1aa6cbf3df6f9f0f96380386a7c8d64c07cc64

Transform Snap: Clear 'SnapObjectData' after changes in the geometry

Differential Revision: https://developer.blender.org/D6927

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

M	source/blender/editors/transform/transform_snap_object.c

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

diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index ecd267d6f2a..3992c3a3036 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -104,6 +104,7 @@ typedef struct SnapObjectData {
       /* SNAP_EDIT_MESH */
       BVHTreeFromEditMesh treedata_editmesh;
       float min[3], max[3];
+      struct LinkNode **bvh_cache_p;
     };
   };
 } SnapObjectData;
@@ -218,14 +219,23 @@ static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *
 
 static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, Object *ob)
 {
+  SnapObjectData *sod;
   void **sod_p;
+  bool init = false;
+
   if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
-    BLI_assert(((SnapObjectData *)*sod_p)->type == SNAP_MESH);
+    sod = *sod_p;
+    if (sod->type != SNAP_MESH) {
+      snap_object_data_clear(sod);
+      init = true;
+    }
   }
   else {
-    SnapObjectData *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+    sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+    init = true;
+  }
 
-    /* Init. */
+  if (init) {
     sod->type = SNAP_MESH;
     /* start assuming that it has each of these element types */
     sod->has_looptris = true;
@@ -233,14 +243,16 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, Object
     sod->has_loose_vert = true;
   }
 
-  return *sod_p;
+  return sod;
 }
 
 static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
                                                      Object *ob,
                                                      BMEditMesh *em)
 {
+  SnapObjectData *sod;
   void **sod_p;
+  bool init = false, init_min_max = true;
 
   {
     /* Use object-data as the key in ghash since the editmesh
@@ -258,18 +270,70 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
   }
 
   if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
-    BLI_assert(((SnapObjectData *)*sod_p)->type == SNAP_EDIT_MESH);
+    sod = *sod_p;
+    bool clear = false;
+    /* Check if the geometry has changed. */
+    if (sod->type != SNAP_EDIT_MESH) {
+      clear = true;
+    }
+    else if (sod->treedata_editmesh.em != em) {
+      /* Clear only cached. */
+      init_min_max = false;
+      for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) {
+        if (sod->cached[i]) {
+          sod->bvhtree[i] = NULL;
+          /* Only init min and max when you have a non-custom bvhtree pending. */
+          init_min_max = true;
+        }
+      }
+      init = true;
+    }
+    else if (sod->bvh_cache_p) {
+      if (sod->treedata_editmesh.tree && sod->treedata_editmesh.cached &&
+          !bvhcache_has_tree(*sod->bvh_cache_p, sod->treedata_editmesh.tree)) {
+        /* The tree is owned by the EditMesh and may have been freed since we last used! */
+        clear = true;
+      }
+      else if (sod->bvhtree[0] && sod->cached[0] &&
+               !bvhcache_has_tree(*sod->bvh_cache_p, sod->bvhtree[0])) {
+        /* The tree is owned by the EditMesh and may have been freed since we last used! */
+        clear = true;
+      }
+      else if (sod->bvhtree[1] && sod->cached[1] &&
+               !bvhcache_has_tree(*sod->bvh_cache_p, sod->bvhtree[1])) {
+        /* The tree is owned by the EditMesh and may have been freed since we last used! */
+        clear = true;
+      }
+    }
+
+    if (clear) {
+      snap_object_data_clear(sod);
+      init = true;
+    }
   }
   else {
-    SnapObjectData *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+    sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+    init = true;
+  }
 
-    /* Init. */
+  if (init) {
     sod->type = SNAP_EDIT_MESH;
     sod->treedata_editmesh.em = em;
-    bm_mesh_minmax(em->bm, sod->min, sod->max);
+    if (init_min_max) {
+      bm_mesh_minmax(em->bm, sod->min, sod->max);
+    }
+    if (em->mesh_eval_final) {
+      sod->bvh_cache_p = &em->mesh_eval_final->runtime.bvh_cache;
+    }
+    else if (em->mesh_eval_cage) {
+      sod->bvh_cache_p = &em->mesh_eval_cage->runtime.bvh_cache;
+    }
+    else {
+      sod->bvh_cache_p = &((Mesh *)ob->data)->runtime.bvh_cache;
+    }
   }
 
-  return *sod_p;
+  return sod;
 }
 
 /** \} */
@@ -737,18 +801,9 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
 
   BVHTreeFromEditMesh *treedata = &sod->treedata_editmesh;
 
-  BVHCache **em_bvh_cache = &((Mesh *)ob->data)->runtime.bvh_cache;
-
-  if (treedata->tree && treedata->cached) {
-    /* The tree is owned by the Mesh and may have been freed since we last used! */
-    if (!bvhcache_has_tree(*em_bvh_cache, treedata->tree)) {
-      treedata->tree = NULL;
-    }
-  }
-
   if (treedata->tree == NULL) {
     /* Get original version of the edit_mesh. */
-    BLI_assert(sod->treedata_editmesh.em == BKE_editmesh_from_object(DEG_get_original_object(ob)));
+    BLI_assert(sod->treedata_editmesh.em == BKE_editmesh_from_object(ob));
     BMEditMesh *em_orig = sod->treedata_editmesh.em;
 
     if (sctx->callbacks.edit_mesh.test_face_fn) {
@@ -770,7 +825,8 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
     else {
       /* Only cache if bvhtree is created without a mask.
        * This helps keep a standardized bvhtree in cache. */
-      BKE_bvhtree_from_editmesh_get(treedata, em_orig, 4, BVHTREE_FROM_EM_LOOPTRI, em_bvh_cache);
+      BKE_bvhtree_from_editmesh_get(
+          treedata, em_orig, 4, BVHTREE_FROM_EM_LOOPTRI, sod->bvh_cache_p);
     }
 
     if (treedata->tree == NULL) {
@@ -892,10 +948,7 @@ static bool raycastObj(SnapObjectContext *sctx,
       Mesh *me = ob->data;
       bool use_hide = false;
       if (BKE_object_is_in_editmode(ob)) {
-        /* Strange, sometimes the `em` of the evaluated object has
-         * uninitialized memory. Need to be investigated.
-         * Use the `em` of the original object then. */
-        BMEditMesh *em = BKE_editmesh_from_object(DEG_get_original_object(ob));
+        BMEditMesh *em = BKE_editmesh_from_object(ob);
         if (use_obedit) {
           retval = raycastEditMesh(sctx,
                                    ray_start,
@@ -2447,18 +2500,9 @@ static short snapEditMesh(SnapObjectContext *sctx,
     return 0;
   }
 
-  BVHCache **em_bvh_cache = &((Mesh *)ob->data)->runtime.bvh_cache;
-
   if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) {
     BVHTreeFromEditMesh treedata = {.tree = sod->bvhtree[0]};
 
-    if (treedata.tree && sod->cached[0]) {
-      /* The tree is owned by the Mesh and may have been freed since we last used! */
-      if (!bvhcache_has_tree(*em_bvh_cache, treedata.tree)) {
-        treedata.tree = sod->bvhtree[0] = NULL;
-      }
-    }
-
     if (treedata.tree == NULL) {
       BLI_bitmap *verts_mask = NULL;
       int verts_num_active = -1;
@@ -2476,7 +2520,7 @@ static short snapEditMesh(SnapObjectContext *sctx,
         MEM_freeN(verts_mask);
       }
       else {
-        BKE_bvhtree_from_editmesh_get(&treedata, em, 2, BVHTREE_FROM_EM_VERTS, em_bvh_cache);
+        BKE_bvhtree_from_editmesh_get(&treedata, em, 2, BVHTREE_FROM_EM_VERTS, sod->bvh_cache_p);
       }
       sod->bvhtree[0] = treedata.tree;
       sod->cached[0] = treedata.cached;
@@ -2486,13 +2530,6 @@ static short snapEditMesh(SnapObjectContext *sctx,
   if (snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE) {
     BVHTreeFromEditMesh treedata = {.tree = sod->bvhtree[1]};
 
-    if (treedata.tree && sod->cached[1]) {
-      /* The tree is owned by the Mesh and may have been freed since we last used! */
-      if (!bvhcache_has_tree(*em_bvh_cache, treedata.tree)) {
-        treedata.tree = sod->bvhtree[1] = NULL;
-      }
-    }
-
     if (treedata.tree == NULL) {
       BLI_bitmap *edges_mask = NULL;
       int edges_num_active = -1;
@@ -2510,7 +2547,7 @@ static short snapEditMesh(SnapObjectContext *sctx,
         MEM_freeN(edges_mask);
       }
       else {
-        BKE_bvhtree_from_editmesh_get(&treedata, em, 2, BVHTREE_FROM_EM_EDGES, em_bvh_cache);
+        BKE_bvhtree_from_editmesh_get(&treedata, em, 2, BVHTREE_FROM_EM_EDGES, sod->bvh_cache_p);
       }
       sod->bvhtree[1] = treedata.tree;
       sod->cached[1] = treedata.cached;
@@ -2625,10 +2662,7 @@ static short snapObject(SnapObjectContext *sctx,
     case OB_MESH: {
       Mesh *me = ob->data;
       if (BKE_object_is_in_editmode(ob)) {
-        /* Strange, sometimes the `em` of the evaluated object has
-         * uninitialized memory. Need to be investigated.
-         * Use the `em` of the original object then. */
-        BMEditMesh *em = BKE_editmesh_from_object(DEG_get_original_object(ob));
+        BMEditMesh *em = BKE_editmesh_from_object(ob);
         if (use_obedit) {
           retval = snapEditMesh(
               sctx, snapdata, ob, em, obmat, use_backface_culling, dist_px, r_loc, r_no, r_index);



More information about the Bf-blender-cvs mailing list