[Bf-blender-cvs] [1825e67deaf] master: Transform Snap Object: Improve code that detects updates

Germano Cavalcante noreply at git.blender.org
Mon Apr 19 01:12:06 CEST 2021


Commit: 1825e67deaf7af318a47589ccca800b82f6c65d2
Author: Germano Cavalcante
Date:   Sun Apr 18 15:28:46 2021 -0300
Branches: master
https://developer.blender.org/rB1825e67deaf7af318a47589ccca800b82f6c65d2

Transform Snap Object: Improve code that detects updates

The previous code had unclear hacks to avoid updating while transforming,
it was also duplicated in two functions causing an inconsistent
initialization of the looptris bvhtree (which could even generate
unpredictable snapping results).

Now, detection update and inicializatiom of common members are contained in
`snap_object_data_mesh_get` and `snap_object_data_editmesh_get`.

Also, the "Hack to avoid updating while transforming" is more evident.

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

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 794af2ab40f..4facb46cde2 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -43,6 +43,7 @@
 #include "BKE_curve.h"
 #include "BKE_duplilist.h"
 #include "BKE_editmesh.h"
+#include "BKE_global.h"
 #include "BKE_layer.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_runtime.h"
@@ -251,7 +252,10 @@ static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *
   return sod;
 }
 
-static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, Object *ob)
+static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx,
+                                                 Object *ob,
+                                                 Mesh *me,
+                                                 bool use_hide)
 {
   SnapObjectData *sod;
   void **sod_p;
@@ -259,7 +263,43 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, Object
 
   if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
     sod = *sod_p;
+    bool is_dirty = false;
     if (sod->type != SNAP_MESH) {
+      is_dirty = true;
+    }
+    else if (sod->treedata_mesh.tree && sod->treedata_mesh.cached &&
+             !bvhcache_has_tree(me->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;
+    }
+    else if (sod->bvhtree[0] && sod->cached[0] &&
+             !bvhcache_has_tree(me->runtime.bvh_cache, sod->bvhtree[0])) {
+      /* The tree is owned by the Mesh and may have been freed since we last used. */
+      is_dirty = true;
+    }
+    else if (sod->bvhtree[1] && sod->cached[1] &&
+             !bvhcache_has_tree(me->runtime.bvh_cache, sod->bvhtree[1])) {
+      /* The tree is owned by the Mesh and may have been freed since we last used. */
+      is_dirty = true;
+    }
+    else if (!sod->treedata_mesh.looptri_allocated &&
+             sod->treedata_mesh.looptri != me->runtime.looptris.array) {
+      is_dirty = true;
+    }
+    else if (!sod->treedata_mesh.vert_allocated && sod->treedata_mesh.vert != me->mvert) {
+      is_dirty = true;
+    }
+    else if (!sod->treedata_mesh.loop_allocated && sod->treedata_mesh.loop != me->mloop) {
+      is_dirty = true;
+    }
+    else if (!sod->treedata_mesh.edge_allocated && sod->treedata_mesh.edge != me->medge) {
+      is_dirty = true;
+    }
+    else if (sod->poly != me->mpoly) {
+      is_dirty = true;
+    }
+
+    if (is_dirty) {
       snap_object_data_clear(sod);
       init = true;
     }
@@ -271,8 +311,32 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, Object
 
   if (init) {
     sod->type = SNAP_MESH;
-    /* start assuming that it has each of these element types */
-    sod->has_looptris = true;
+
+    /* The BVHTree from looptris is always required. */
+    BLI_assert(sod->treedata_mesh.tree == NULL);
+    BKE_bvhtree_from_mesh_get(&sod->treedata_mesh,
+                              me,
+                              use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI,
+                              4);
+
+    if (sod->treedata_mesh.tree == NULL) {
+      sod->treedata_mesh.vert = me->mvert;
+      sod->treedata_mesh.loop = me->mloop;
+      sod->treedata_mesh.looptri = BKE_mesh_runtime_looptri_ensure(me);
+      BLI_assert(sod->has_looptris == false);
+    }
+    else {
+      BLI_assert(sod->treedata_mesh.vert != NULL);
+      BLI_assert(sod->treedata_mesh.loop != NULL);
+      BLI_assert(sod->treedata_mesh.looptri != NULL);
+      sod->has_looptris = true;
+    }
+
+    /* Required for snapping with occlusion. */
+    sod->treedata_mesh.edge = me->medge;
+    sod->poly = me->mpoly;
+
+    /* Start assuming that it has each of these element types. */
     sod->has_loose_edge = true;
     sod->has_loose_vert = true;
   }
@@ -299,7 +363,7 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
 {
   SnapObjectData *sod;
   void **sod_p;
-  bool init = false, init_min_max = true, clear_cache = false;
+  bool init = false;
 
   {
     /* Use object-data as the key in ghash since the editmesh
@@ -318,38 +382,43 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
 
   if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
     sod = *sod_p;
-    bool clear = false;
+    bool is_dirty = false;
     /* Check if the geometry has changed. */
     if (sod->type != SNAP_EDIT_MESH) {
-      clear = true;
+      is_dirty = true;
     }
     else if (sod->treedata_editmesh.em != em) {
-      clear_cache = true;
-      init = true;
+      is_dirty = true;
     }
     else if (sod->mesh_runtime) {
       if (sod->mesh_runtime != snap_object_data_editmesh_runtime_get(ob)) {
-        clear_cache = true;
-        init = true;
+        if (G.moving) {
+          /* Hack to avoid updating while transforming. */
+          BLI_assert(!sod->treedata_editmesh.cached && !sod->cached[0] && !sod->cached[1]);
+          sod->mesh_runtime = snap_object_data_editmesh_runtime_get(ob);
+        }
+        else {
+          is_dirty = true;
+        }
       }
       else if (sod->treedata_editmesh.tree && sod->treedata_editmesh.cached &&
                !bvhcache_has_tree(sod->mesh_runtime->bvh_cache, sod->treedata_editmesh.tree)) {
         /* The tree is owned by the EditMesh and may have been freed since we last used! */
-        clear = true;
+        is_dirty = true;
       }
       else if (sod->bvhtree[0] && sod->cached[0] &&
                !bvhcache_has_tree(sod->mesh_runtime->bvh_cache, sod->bvhtree[0])) {
         /* The tree is owned by the EditMesh and may have been freed since we last used! */
-        clear = true;
+        is_dirty = true;
       }
       else if (sod->bvhtree[1] && sod->cached[1] &&
                !bvhcache_has_tree(sod->mesh_runtime->bvh_cache, sod->bvhtree[1])) {
         /* The tree is owned by the EditMesh and may have been freed since we last used! */
-        clear = true;
+        is_dirty = true;
       }
     }
 
-    if (clear) {
+    if (is_dirty) {
       snap_object_data_clear(sod);
       init = true;
     }
@@ -362,27 +431,8 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
   if (init) {
     sod->type = SNAP_EDIT_MESH;
     sod->treedata_editmesh.em = em;
-
-    if (clear_cache) {
-      /* Only init min and max when you have a non-custom bvhtree pending. */
-      init_min_max = false;
-      if (sod->treedata_editmesh.cached) {
-        sod->treedata_editmesh.tree = NULL;
-        init_min_max = true;
-      }
-      for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) {
-        if (sod->cached[i]) {
-          sod->bvhtree[i] = NULL;
-          init_min_max = true;
-        }
-      }
-    }
-
-    if (init_min_max) {
-      bm_mesh_minmax(em->bm, sod->min, sod->max);
-    }
-
     sod->mesh_runtime = snap_object_data_editmesh_runtime_get(ob);
+    bm_mesh_minmax(em->bm, sod->min, sod->max);
   }
 
   return sod;
@@ -693,53 +743,18 @@ static bool raycastMesh(SnapObjectContext *sctx,
     len_diff = 0.0f;
   }
 
-  SnapObjectData *sod = snap_object_data_mesh_get(sctx, ob);
+  SnapObjectData *sod = snap_object_data_mesh_get(sctx, ob, me, use_hide);
 
   BVHTreeFromMesh *treedata = &sod->treedata_mesh;
 
-  /* The tree is owned by the Mesh and may have been freed since we last used. */
-  if (treedata->tree) {
-    BLI_assert(treedata->cached);
-    if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
-      free_bvhtree_from_mesh(treedata);
-    }
-    else {
-      /* Update Pointers. */
-      if (treedata->vert && treedata->vert_allocated == false) {
-        treedata->vert = me->mvert;
-      }
-      if (treedata->loop && treedata->loop_allocated == false) {
-        treedata->loop = me->mloop;
-      }
-      if (treedata->looptri && treedata->looptri_allocated == false) {
-        treedata->looptri = BKE_mesh_runtime_looptri_ensure(me);
-      }
-      /* required for snapping with occlusion. */
-      treedata->edge = me->medge;
-      sod->poly = me->mpoly;
-    }
-  }
-
   if (treedata->tree == NULL) {
-    if (use_hide) {
-      BKE_bvhtree_from_mesh_get(treedata, me, BVHTREE_FROM_LOOPTRI_NO_HIDDEN, 4);
-    }
-    else {
-      BKE_bvhtree_from_mesh_get(treedata, me, BVHTREE_FROM_LOOPTRI, 4);
-    }
-
-    /* required for snapping with occlusion. */
-    treedata->edge = me->medge;
-    sod->poly = me->mpoly;
-
-    if (treedata->tree == NULL) {
-      return retval;
-    }
+    return retval;
   }
 
   float timat[3][3]; /* transpose inverse matrix for normals */
   transpose_m3_m4(timat, imat);
 
+  BLI_assert(treedata->raycast_callback != NULL);
   if (r_hit_list) {
     struct RayCastAll_Data data;
 
@@ -2248,6 +2263,7 @@ static short snapMesh(SnapObjectContext *sctx,
                       Object *ob,
                       Mesh *me,
                       const float obmat[4][4],
+                      bool use_hide,
                       bool use_backface_culling,
                       /* read/write args */
                       float *dist_px,
@@ -2276,59 +2292,38 @@ static short snapMesh(SnapObjectContext *sctx,
     return 0;
   }
 
-  SnapObjectData *sod = snap_object_data_mesh_get(sctx, ob);
+  SnapObjectData *sod = snap_object_data_mesh_get(sctx, ob, me, use_hide);
 
-  BVHTreeFromMesh *treedata, dummy_treedata;
+  BVHTreeFromMesh *treedata, treedata_tmp;
   treedata = &sod->treedata_mesh;
 
-  /* The tree is owned by the Mesh and may have been freed since we last used! */
-  if (treedata->cached && treedata->tree &&
-      !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
-    free_bvhtree_from_mesh(treedata);
-  }
-  if (sod->cached[0] && sod->bvhtree[0] &&
-      !bvhcache_has_tree(me->runtime.bvh_cache, sod->bvhtree[0])) {
-    sod->bvhtree[0] = NULL;
-  }
-  if (sod->cached[1] && sod->bvhtree[1] &&
-      !bvhcache_has_tree(me->runtime.bvh_cache, sod->bvhtree[1])) {
-    sod->bvhtree[1] = NULL;
-  }
-
-  if (sod->has_looptris && tre

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list