[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