[Bf-blender-cvs] [0d8fb1464e0] sculpt-dev: Sculpt Dyntopo: Fixed memory leak

Joseph Eagar noreply at git.blender.org
Mon Sep 27 11:41:55 CEST 2021


Commit: 0d8fb1464e0b0d63c3895f1741420a7d8f8276a2
Author: Joseph Eagar
Date:   Mon Sep 27 02:39:05 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rB0d8fb1464e0b0d63c3895f1741420a7d8f8276a2

Sculpt Dyntopo: Fixed memory leak

* Fixed a particularly nasty memory leak
  where the entire process of entering sculpt
  mode was being done twice.

* Discovered that range tree is extremely slow.
  Got the alternative freelist version up and running,
  and replace a usage of GSet with a bitmap. However
  the new code is disabled pending further testing.
  Literally an order of magnutude improvement.

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

M	extern/rangetree/intern/range_tree.c
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/blenlib/BLI_mempool.h
M	source/blender/blenlib/intern/BLI_mempool.c
M	source/blender/bmesh/bmesh_class.h
M	source/blender/bmesh/intern/bmesh_construct.c
M	source/blender/bmesh/intern/bmesh_core.c
M	source/blender/bmesh/intern/bmesh_interp.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_mesh.c
M	source/blender/bmesh/intern/bmesh_mesh_convert.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt.cc
M	source/blender/editors/sculpt_paint/sculpt.hh
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c
M	source/blender/makesdna/DNA_meshdata_types.h

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

diff --git a/extern/rangetree/intern/range_tree.c b/extern/rangetree/intern/range_tree.c
index 77496e32fa3..87bae433101 100644
--- a/extern/rangetree/intern/range_tree.c
+++ b/extern/rangetree/intern/range_tree.c
@@ -794,6 +794,7 @@ void range_tree_uint_take(RangeTreeUInt *rt, const uint value)
 	range_tree_uint_take_impl(rt, value, node);
 }
 
+#pragma optimize("", off)
 bool range_tree_uint_retake(RangeTreeUInt *rt, const uint value)
 {
 	Node *node = rt_find_node_from_value(rt, value);
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 610ec7c1ad5..49211c01e80 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -513,6 +513,8 @@ class VIEW3D_PT_tools_persistent_base_channels(Panel, View3DPaintPanel):
 
         ch = UnifiedPaintPanel.get_channel(context, brush, "use_persistent")
 
+        capabilities = sculpt.brush.sculpt_capabilities
+
         ok = context.mode == "SCULPT"
         ok = ok and ch and ch.show_in_workspace
         ok = ok or capabilities.has_persistence
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index f7e1b7f0d81..8757e8f3017 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -480,6 +480,12 @@ void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *ldat
 void CustomData_bmesh_update_active_layers(struct CustomData *fdata, struct CustomData *ldata);
 void CustomData_bmesh_do_versions_update_active_layers(struct CustomData *fdata,
                                                        struct CustomData *ldata);
+
+void CustomData_bmesh_init_pool_ex(CustomData *data,
+                                   int totelem,
+                                   const char htype,
+                                   const char *memtag);
+
 void CustomData_bmesh_init_pool(struct CustomData *data, int totelem, const char htype);
 
 #ifndef NDEBUG
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index b26a1370cc6..dd6d5bf1bda 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -807,6 +807,8 @@ PBVHNode *BKE_pbvh_node_from_index(PBVH *pbvh, int node_i);
 struct BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh);
 void BKE_pbvh_update_vert_boundary(int cd_dyn_vert,
                                    int cd_faceset_offset,
+                                   int cd_vert_node_offset,
+                                   int cd_face_node_offset,
                                    struct BMVert *v,
                                    int symmetry);
 
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index b93c371cb03..90f042f7b34 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -3736,6 +3736,14 @@ void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, Custom
 }
 
 void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype)
+{
+  return CustomData_bmesh_init_pool_ex(data, totelem, htype, __func__);
+}
+
+void CustomData_bmesh_init_pool_ex(CustomData *data,
+                                   int totelem,
+                                   const char htype,
+                                   const char *memtag)
 {
   int chunksize;
 
@@ -3763,7 +3771,7 @@ void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype)
 
   /* If there are no layers, no pool is needed just yet */
   if (data->totlayer) {
-    data->pool = BLI_mempool_create(data->totsize, totelem, chunksize, BLI_MEMPOOL_NOP);
+    data->pool = BLI_mempool_create_ex(data->totsize, totelem, chunksize, BLI_MEMPOOL_NOP, memtag);
   }
 }
 
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index b86e3ca2528..be12cb3c313 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -36,7 +36,7 @@
 
 //#define DYNTOPO_REPORT
 
-#define DYNVERT_VALENCE_TEMP (1 << 14)
+#define DYNVERT_VALENCE_TEMP DYNVERT_SPLIT_TEMP
 
 #define USE_NEW_SPLIT
 #define DYNVERT_SMOOTH_BOUNDARY (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY | DYNVERT_SHARP_BOUNDARY)
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index ccc217764db..8edd7443f07 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -2993,7 +2993,7 @@ void BKE_pbvh_update_normals(PBVH *pbvh, struct SubdivCCG *subdiv_ccg)
 
   if (totnode > 0) {
     if (pbvh->type == PBVH_BMESH) {
-      pbvh_bmesh_normals_update(nodes, totnode);
+      pbvh_bmesh_normals_update(pbvh->bm, nodes, totnode);
     }
     else if (pbvh->type == PBVH_FACES) {
       pbvh_faces_update_normals(pbvh, nodes, totnode);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 5c2239f1320..5a7dc0b9738 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -269,6 +269,9 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
 
     do {
       BMVert *v = l_iter->v;
+      MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
+      mv->flag |= DYNVERT_NEED_BOUNDARY;
+
       if (!BLI_table_gset_haskey(n->bm_unique_verts, v)) {
         if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
           BLI_table_gset_add(n->bm_other_verts, v);
@@ -400,7 +403,6 @@ static void pbvh_bmesh_node_split(
   /* Clear this node */
 
   BMVert *v;
-  TableGSet *bm_unique_verts = n->bm_unique_verts;
 
   /* Assign verts to c1 and c2.  Note that the previous
      method of simply marking them as untaken and rebuilding
@@ -409,8 +411,6 @@ static void pbvh_bmesh_node_split(
      faces.*/
   if (n->bm_unique_verts) {
     TGSET_ITER (v, n->bm_unique_verts) {
-      int ni;
-
       if (v->co[axis] < mid) {
         BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, (c1 - pbvh->nodes));
         BLI_table_gset_add(c1->bm_unique_verts, v);
@@ -1062,8 +1062,10 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVH *pbvh,
 }
 
 typedef struct UpdateNormalsTaskData {
-  PBVHNode **nodes;
-  int totnode;
+  PBVHNode *node;
+  BMVert **border_verts;
+  int tot_border_verts;
+  int cd_dyn_vert;
 } UpdateNormalsTaskData;
 
 static void pbvh_update_normals_task_cb(void *__restrict userdata,
@@ -1072,17 +1074,47 @@ static void pbvh_update_normals_task_cb(void *__restrict userdata,
 {
   BMVert *v;
   BMFace *f;
-  UpdateNormalsTaskData *data = (UpdateNormalsTaskData *)userdata;
-  PBVHNode *node = data->nodes[n];
+  UpdateNormalsTaskData *data = ((UpdateNormalsTaskData *)userdata) + n;
+  PBVHNode *node = data->node;
+
+  BMVert **bordervs = NULL;
+  BLI_array_declare(bordervs);
 
   node->flag |= PBVH_UpdateCurvatureDir;
 
+  TGSET_ITER (v, node->bm_unique_verts) {
+    MDynTopoVert *mv = BKE_PBVH_DYNVERT(data->cd_dyn_vert, v);
+
+    if (mv->flag & DYNVERT_PBVH_BOUNDARY) {
+      BLI_array_append(bordervs, v);
+    }
+    else {
+      zero_v3(v->no);
+    }
+  }
+  TGSET_ITER_END
+
   TGSET_ITER (f, node->bm_faces) {
     BM_face_normal_update(f);
+    BMLoop *l = f->l_first;
+    do {
+      MDynTopoVert *mv = BKE_PBVH_DYNVERT(data->cd_dyn_vert, l->v);
+
+      if (!(mv->flag & DYNVERT_PBVH_BOUNDARY)) {
+        add_v3_v3(l->v->no, f->no);
+      }
+    } while ((l = l->next) != f->l_first);
   }
   TGSET_ITER_END
 
   TGSET_ITER (v, node->bm_unique_verts) {
+    MDynTopoVert *mv = BKE_PBVH_DYNVERT(data->cd_dyn_vert, v);
+
+    if (!(mv->flag & DYNVERT_PBVH_BOUNDARY)) {
+      // BLI_array_append(bordervs, v);
+      normalize_v3(v->no);
+    }
+#if 0
     // BM_vert_normal_update(v);
     // optimized loop
     BMEdge *e = v->e;
@@ -1101,31 +1133,87 @@ static void pbvh_update_normals_task_cb(void *__restrict userdata,
         continue;
       }
 
-      do {
-        v->no[0] += l->f->no[0];
-        v->no[1] += l->f->no[1];
-        v->no[2] += l->f->no[2];
+      // no need to loop over radial list here,
+      // it's unneeded for manifold meshes and non-manifold
+      // won't give correct normals anyway by definition
 
-        l = l->radial_next;
-      } while (l != e->l);
+      v->no[0] += l->f->no[0];
+      v->no[1] += l->f->no[1];
+      v->no[2] += l->f->no[2];
 
       e = v == e->v1 ? e->v1_disk_link.next : e->v2_disk_link.next;
     } while (e != v->e);
 
     normalize_v3(v->no);
+#endif
   }
   TGSET_ITER_END
 
+  data->border_verts = bordervs;
+  data->tot_border_verts = BLI_array_len(bordervs);
+
   node->flag &= ~PBVH_UpdateNormals;
 }
 
-void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
+void pbvh_bmesh_normals_update(BMesh *bm, PBVHNode **nodes, int totnode)
 {
   TaskParallelSettings settings;
-  UpdateNormalsTaskData data = {nodes, totnode};
+  UpdateNormalsTaskData *datas = MEM_calloc_arrayN(totnode, sizeof(*datas), "bmesh normal update");
+
+  for (int i = 0; i < totnode; i++) {
+    datas[i].node = nodes[i];
+  }
 
   BKE_pbvh_parallel_range_settings(&settings, true, totnode);
-  BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_task_cb, &settings);
+  BLI_task_parallel_range(0, totnode, datas, pbvh_update_normals_task_cb, &settings);
+
+  BLI_bitmap *visit = BLI_BITMAP_NEW(bm->totvert, "visit");
+  BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+  for (int i = 0; i < totnode; i++) {
+    UpdateNormalsTaskData *data = datas + i;
+
+#if 0
+    printf("%.2f%% : %d %d\n",
+           100.0f * (float)data->tot_border_verts / (float)data->node->bm_unique_verts->length,
+           data->tot_border_verts,
+           data->node->bm_unique_verts->length);
+#endif
+
+    for (int j = 0; j < data->tot_border_verts; j++) {
+      BMVert *v = data->border_verts[j];
+
+      if (BLI_BITMAP_TEST(visit, v->head.index)) {
+        continue;
+      }
+
+      BLI_BITMAP_ENABLE(visit, v->head.index);
+
+      // manual iteration
+      BMEdge *e = v->e;
+
+      if (!e) {
+        continue;
+      }
+
+      zero_v3(v->no);
+
+      do 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list