[Bf-blender-cvs] [37bce7b701f] temp_bmesh_multires: commit working code

Joseph Eagar noreply at git.blender.org
Wed Sep 8 10:32:25 CEST 2021


Commit: 37bce7b701ff5825409ae9523cafe197b45560a1
Author: Joseph Eagar
Date:   Thu Sep 2 23:19:11 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB37bce7b701ff5825409ae9523cafe197b45560a1

commit working code

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/blenlib/BLI_ghash.h
M	source/blender/blenlib/BLI_smallhash.h
M	source/blender/blenlib/CMakeLists.txt
M	source/blender/blenlib/intern/BLI_ghash_utils.c
A	source/blender/blenlib/intern/BLI_table_gset.c
M	source/blender/blenlib/intern/smallhash.c

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index afed28d8120..c017c42aee1 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -29,6 +29,8 @@
 #include "BKE_ccg.h"
 #include <stdint.h>
 
+#define DEFRAGMENT_MEMORY
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -74,6 +76,10 @@ BLI_INLINE SculptFaceRef BKE_pbvh_make_fref(intptr_t i)
 
 #define SCULPT_REF_NONE ((intptr_t)-1)
 
+#ifdef DEFRAGMENT_MEMORY
+#  include "BLI_smallhash.h"
+#endif
+
 typedef struct PBVHTri {
   int v[3];       // references into PBVHTriBuf->verts
   intptr_t l[3];  // loops
@@ -90,6 +96,8 @@ typedef struct PBVHTriBuf {
   int totvert, totedge, tottri;
   int verts_size, edges_size, tris_size;
 
+  SmallHash vertmap;  // maps vertex ptrs to indices within verts
+
   // private field
   intptr_t *loops;
   int totloop, mat_nr;
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 65411abb552..c6f9b8a6437 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -18,6 +18,7 @@
 #include "BLI_math.h"
 #include "BLI_memarena.h"
 #include "BLI_rand.h"
+#include "BLI_smallhash.h"
 #include "BLI_task.h"
 #include "BLI_utildefines.h"
 #include "PIL_time.h"
@@ -1412,6 +1413,18 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
 {
   BMLoop *l = f->l_first;
 
+#if 0
+  float cent[3];
+
+  zero_v3(cent);
+  add_v3_v3(cent, l->v->co);
+  add_v3_v3(cent, l->next->v->co);
+  add_v3_v3(cent, l->prev->v->co);
+
+  mul_v3_fl(cent, 1.0f / 3.0f);
+  return len_squared_v3v3(cent, q->center) < q->radius_squared;
+#endif
+
   /* Check if triangle intersects the sphere */
   float dis = dist_to_tri_sphere_simple((float *)q->center,
                                         (float *)l->v->co,
@@ -3909,7 +3922,49 @@ typedef struct SwapData {
   PBVH *pbvh;
 } SwapData;
 
-static void on_vert_swap(BMVert *v1, BMVert *v2, void *userdata)
+ATTR_NO_OPT void pbvh_tribuf_swap_verts(
+    PBVH *pbvh, PBVHNode *node, PBVHTriBuf *tribuf, BMVert *v1, BMVert *v2)
+{
+
+  void *val;
+
+  bool ok = BLI_smallhash_remove_p(&tribuf->vertmap, (uintptr_t)v1, &val);
+
+  if (!ok) {
+    printf("eek, missing vertex!");
+    // return;
+  }
+
+  int idx = POINTER_AS_INT(val);
+
+  tribuf->verts[idx].i = (intptr_t)v2;
+
+  void **val2;
+  if (BLI_smallhash_ensure_p(&tribuf->vertmap, (intptr_t)v2, &val2)) {
+    // v2 was already in hash? add v1 back in then with v2's index
+
+    int idx2 = POINTER_AS_INT(*val2);
+    BLI_smallhash_insert(&tribuf->vertmap, (intptr_t)v1, POINTER_FROM_INT(idx2));
+  }
+
+  *val2 = POINTER_FROM_INT(idx);
+}
+
+ATTR_NO_OPT void pbvh_node_tribuf_swap_verts(PBVH *pbvh, PBVHNode *node, BMVert *v1, BMVert *v2)
+{
+  BLI_table_gset_remove(node->bm_unique_verts, v1, NULL);
+  BLI_table_gset_add(node->bm_unique_verts, v2);
+
+  if (node->tribuf) {
+    pbvh_tribuf_swap_verts(pbvh, node, node->tribuf, v1, v2);
+  }
+
+  for (int i = 0; i < node->tot_tri_buffers; i++) {
+    pbvh_tribuf_swap_verts(pbvh, node, node->tri_buffers + i, v1, v2);
+  }
+}
+
+ATTR_NO_OPT static void on_vert_swap(BMVert *v1, BMVert *v2, void *userdata)
 {
   SwapData *sdata = (SwapData *)userdata;
   PBVH *pbvh = sdata->pbvh;
@@ -3926,21 +3981,14 @@ static void on_vert_swap(BMVert *v1, BMVert *v2, void *userdata)
     printf("node error! %s\n", __func__);
   }
 
-  int updateflag = PBVH_UpdateOtherVerts | PBVH_UpdateNormals | PBVH_UpdateTris | PBVH_UpdateTris;
-  updateflag |= PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw |
-                PBVH_RebuildDrawBuffers | PBVH_UpdateVisibility;
-  updateflag |= PBVH_UpdateDrawBuffers;
+  int updateflag = PBVH_UpdateOtherVerts;
 
   if (node1) {
-    node1->flag |= updateflag;
-    BLI_table_gset_remove(node1->bm_unique_verts, v1, NULL);
-    BLI_table_gset_insert(node1->bm_unique_verts, v2);
+    pbvh_node_tribuf_swap_verts(pbvh, node1, v1, v2);
   }
 
-  if (node2) {
-    node2->flag |= updateflag;
-    BLI_table_gset_remove(node2->bm_unique_verts, v2, NULL);
-    BLI_table_gset_insert(node2->bm_unique_verts, v1);
+  if (node2 && node2 != node1) {
+    pbvh_node_tribuf_swap_verts(pbvh, node2, v2, v1);
   }
 
   if (!node1 || !node2) {
@@ -4183,6 +4231,7 @@ typedef struct EdgeQueueContext {
     brusharea = brusharea * brusharea * M_PI;
 
     int max_steps = (int)((float)DYNTOPO_MAX_ITER * ratio);
+    max_steps = MIN2(max_steps, DYNTOPO_MAX_ITER);
 
     printf("max_steps %d\n", max_steps);
 
@@ -4253,6 +4302,8 @@ typedef struct EdgeQueueContext {
     int max_steps = (int)((float)DYNTOPO_MAX_ITER * ratio);
     max_steps = (int)(brusharea * ratio * 2.0f);
 
+    max_steps = MIN2(max_steps, DYNTOPO_MAX_ITER);
+
     printf("brusharea: %.2f, ratio: %.2f\n", brusharea, ratio);
     printf("subdivide max_steps %d\n", max_steps);
 
@@ -4278,7 +4329,6 @@ typedef struct EdgeQueueContext {
 
   int dcount = 0;
 
-//#define DEFRAGMENT_MEMORY
 #ifdef DEFRAGMENT_MEMORY
   RNG *rng = BLI_rng_new(rseed++);
   SwapData swapdata = {.pbvh = pbvh};
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 11f9ae7a616..9da70df13c0 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1885,6 +1885,8 @@ static void pbvh_free_tribuf(PBVHTriBuf *tribuf)
   MEM_SAFE_FREE(tribuf->loops);
   MEM_SAFE_FREE(tribuf->edges);
 
+  BLI_smallhash_release(&tribuf->vertmap);
+
   tribuf->verts = NULL;
   tribuf->tris = NULL;
   tribuf->loops = NULL;
@@ -2041,7 +2043,7 @@ static bool pbvh_bmesh_split_tris(PBVH *pbvh, PBVHNode *node)
   return true;
 }
 
-BLI_INLINE PBVHTri *pbvh_tribuf_add_tri(PBVHTriBuf *tribuf)
+ATTR_NO_OPT BLI_INLINE PBVHTri *pbvh_tribuf_add_tri(PBVHTriBuf *tribuf)
 {
   tribuf->tottri++;
 
@@ -2133,11 +2135,29 @@ void pbvh_bmesh_check_other_verts(PBVHNode *node)
   TGSET_ITER_END;
 }
 
+static void pbvh_init_tribuf(PBVHNode *node, PBVHTriBuf *tribuf)
+{
+  tribuf->tottri = 0;
+  tribuf->tris_size = 0;
+  tribuf->verts_size = 0;
+  tribuf->mat_nr = 0;
+  tribuf->tottri = 0;
+  tribuf->totvert = 0;
+  tribuf->totloop = 0;
+  tribuf->totedge = 0;
+
+  tribuf->edges = NULL;
+  tribuf->verts = NULL;
+  tribuf->tris = NULL;
+  tribuf->loops = NULL;
+
+  BLI_smallhash_init_ex(&tribuf->vertmap, node->bm_unique_verts->length);
+}
 /* In order to perform operations on the original node coordinates
  * (currently just raycast), store the node's triangles and vertices.
  *
  * Skips triangles that are hidden. */
-bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
+ATTR_NO_OPT bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
 {
   BMesh *bm = pbvh->bm;
 
@@ -2147,14 +2167,10 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
 
   node->flag |= PBVH_UpdateOtherVerts;
 
-  GHash *vmap = BLI_ghash_ptr_new("pbvh_bmesh.c vmap");
-  GHash *mat_vmaps[MAXMAT];
-
   int mat_map[MAXMAT];
 
   for (int i = 0; i < MAXMAT; i++) {
     mat_map[i] = -1;
-    mat_vmaps[i] = NULL;
   }
 
   if (node->tribuf || node->tri_buffers) {
@@ -2162,6 +2178,7 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
   }
 
   node->tribuf = MEM_callocN(sizeof(*node->tribuf), "node->tribuf");
+  pbvh_init_tribuf(node, node->tribuf);
 
   BMLoop **loops = NULL;
   uint(*loops_idx)[3] = NULL;
@@ -2172,12 +2189,6 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
   PBVHTriBuf *tribufs = NULL;  // material-specific tribuffers
   BLI_array_declare(tribufs);
 
-  node->tribuf->mat_nr = 0;
-  node->tribuf->tottri = 0;
-  node->tribuf->totvert = 0;
-  node->tribuf->totloop = 0;
-  node->tribuf->totedge = 0;
-
   node->flag &= ~PBVH_UpdateTris;
 
   const int edgeflag = BM_ELEM_TAG_ALT;
@@ -2216,11 +2227,10 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
     if (mat_map[mat_nr] == -1) {
       PBVHTriBuf _tribuf = {0};
 
-      _tribuf.mat_nr = mat_nr;
-
       mat_map[mat_nr] = BLI_array_len(tribufs);
-      mat_vmaps[mat_nr] = BLI_ghash_ptr_new("pbvh_bmesh.c vmap");
 
+      pbvh_init_tribuf(node, &_tribuf);
+      _tribuf.mat_nr = mat_nr;
       BLI_array_append(tribufs, _tribuf);
     }
 
@@ -2258,7 +2268,7 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
           mat_tri->eflag |= 1 << j;
         }
 
-        if (!BLI_ghash_ensure_p(vmap, l->v, &val)) {
+        if (!BLI_smallhash_ensure_p(&node->tribuf->vertmap, l->v, &val)) {
           SculptVertRef sv = {(intptr_t)l->v};
 
           minmax_v3v3_v3(min, max, l->v->co);
@@ -2271,7 +2281,7 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
         tri->l[j] = (intptr_t)l;
 
         val = NULL;
-        if (!BLI_ghash_ensure_p(mat_vmaps[mat_nr], l->v, &val)) {
+        if (!BLI_smallhash_ensure_p(&tribufs[mat_nr].vertmap, l->v, &val)) {
           SculptVertRef sv = {(intptr_t)l->v};
 
           minmax_v3v3_v3(min, max, l->v->co);
@@ -2356,13 +2366,13 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
 
       l->e->head.hflag |= edgeflag;
 
-      int v1 = (int)BLI_ghash_lookup(vmap, (void *)l->e->v1);
-      int v2 = (int)BLI_ghash_lookup(vmap, (void *)l->e->v2);
+      int v1 = (int)BLI_smallhash_lookup(&node->tribuf->vertmap, (void *)l->e->v1);
+      int v2 = (int)BLI_smallhash_lookup(&node->tribuf->vertmap, (void *)l->e->v2);
 
       pbvh_tribuf_add_edge(node->tribuf, v1, v2);
 
-      v1 = (int)BLI_ghash_lookup(mat_vmaps[mat_nr], (void *)l->e->v1);
-      v2 = (int)BLI_ghash_lookup(mat_vmaps[mat_nr], (void *)l->e->v2);
+      v1 = (int)BLI_smallhash_lookup(&tribufs[mat_nr].vertmap, (void *)l->e->v1);
+      v2 = (int)BLI_smallhash_lookup(&tribufs[mat_nr].vertmap, (void *)l->e->v2);
 
       pbvh_tribuf_add_edge(mat_tribuf, v1, v2);
     } while ((l = l->next) != f->l_first);
@@ -2386,13 +2396,6 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
     zero_v3(node->tribuf->max);
   }
 
-  BLI_ghash_free(vmap, NULL, NULL);
-  for (int i = 0; i < MAXMAT; i++) {
-    if (mat_vmaps[i]) {
-      BLI_ghash_free(mat_vmaps[i], NULL, NULL);
-    }
-  }
-
   return true;
 }
 
@@ -4999,6 +5002,91 @@ void pbvh_bmesh_cache_test(CacheParams *params,

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list