[Bf-blender-cvs] [b53339edfac] sculpt-dev: Sculpt-dev: fix crash in pbvh cache

Joseph Eagar noreply at git.blender.org
Thu Mar 24 07:59:42 CET 2022


Commit: b53339edfacc26bf6d7763b4f69155d3cb732b78
Author: Joseph Eagar
Date:   Wed Mar 23 23:59:29 2022 -0700
Branches: sculpt-dev
https://developer.blender.org/rBb53339edfacc26bf6d7763b4f69155d3cb732b78

Sculpt-dev: fix crash in pbvh cache

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/multires.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_expand.c
M	source/blender/editors/sculpt_paint/sculpt_face_set.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index c34f9406c5d..93e17bff9f5 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -722,8 +722,7 @@ typedef struct SculptSession {
 
   /* Mesh connectivity maps. */
   /* Vertices to adjacent polys. */
-  struct MeshElemMap *pmap;
-  int *pmap_mem;
+  SculptPMap *pmap;
 
   /* Edges to adjacent polys. */
   struct MeshElemMap *epmap;
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 8d1020a2c4e..c558edbffee 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -50,6 +50,12 @@ typedef struct SculptFaceRef {
 
 #define SCULPT_REF_NONE ((intptr_t)-1)
 
+typedef struct SculptPMap {
+  struct MeshElemMap *pmap;
+  int *pmap_mem;
+  int refcount;
+} SculptPMap;
+
 #if 0
 typedef struct SculptLoopRef {
   intptr_t i;
@@ -288,7 +294,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
                          int looptri_num,
                          bool fast_draw,
                          float *face_areas,
-                         struct MeshElemMap *pmap);
+                         SculptPMap *pmap);
 /**
  * Do a full rebuild with on Grids data structure.
  */
@@ -1128,17 +1134,23 @@ void BKE_pbvh_pmap_to_edges(PBVH *pbvh,
 void BKE_pbvh_set_vemap(PBVH *pbvh, struct MeshElemMap *vemap);
 
 void BKE_pbvh_ignore_uvs_set(PBVH *pbvh, bool value);
-bool BKE_pbvh_cache_is_valid(const struct Object *ob, const struct Mesh *me, const PBVH *old, int pbvh_type);
+bool BKE_pbvh_cache_is_valid(const struct Object *ob,
+                             const struct Mesh *me,
+                             const PBVH *old,
+                             int pbvh_type);
 bool BKE_pbvh_cache(const struct Mesh *me, PBVH *pbvh);
 PBVH *BKE_pbvh_get_or_free_cached(struct Object *ob, struct Mesh *me, PBVHType pbvh_type);
 void BKE_pbvh_set_cached(struct Object *ob, PBVH *pbvh);
 void BKE_pbvh_set_face_areas(PBVH *pbvh, float *face_areas);
 void BKE_pbvh_set_sculpt_verts(PBVH *pbvh, struct MSculptVert *sverts);
-void BKE_pbvh_set_pmap(PBVH *pbvh, struct MeshElemMap *pmap, void *pmap_mem);
-struct MeshElemMap *BKE_pbvh_get_pmap(PBVH *pbvh);
-struct MeshElemMap *BKE_pbvh_get_pmap_ex(PBVH *pbvh, int **r_mem);
+void BKE_pbvh_set_pmap(PBVH *pbvh, SculptPMap *pmap);
+SculptPMap *BKE_pbvh_get_pmap(PBVH *pbvh);
 void BKE_pbvh_cache_remove(PBVH *pbvh);
 void BKE_pbvh_set_bmesh(PBVH *pbvh, struct BMesh *bm);
 void BKE_pbvh_free_bmesh(PBVH *pbvh, struct BMesh *bm);
 void BKE_pbvh_system_init();
 void BKE_pbvh_system_exit();
+
+SculptPMap *BKE_pbvh_make_pmap(const struct Mesh *me);
+void BKE_pbvh_pmap_aquire(SculptPMap *pmap);
+bool BKE_pbvh_pmap_release(SculptPMap *pmap);
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 0c066fb6658..2d8aa3de394 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -460,9 +460,8 @@ void multires_force_sculpt_rebuild(Object *object)
     object->sculpt->pbvh = NULL;
   }
 
-  MEM_SAFE_FREE(ss->pmap);
-
-  MEM_SAFE_FREE(ss->pmap_mem);
+  BKE_pbvh_pmap_release(ss->pmap);
+  ss->pmap = NULL;
 }
 
 void multires_force_external_reload(Object *object)
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 38e15708795..06499374a9c 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1451,10 +1451,6 @@ static void sculptsession_free_pbvh(Object *object)
     BKE_pbvh_set_cached(object, ss->pbvh);
     ss->pbvh = NULL;
   }
-  else {
-    MEM_SAFE_FREE(ss->pmap);
-    MEM_SAFE_FREE(ss->pmap_mem);
-  }
 
   MEM_SAFE_FREE(ss->face_areas);
 
@@ -1525,8 +1521,7 @@ void BKE_sculptsession_free(Object *ob)
     CustomData_free(&ss->temp_pdata, ss->temp_pdata_elems);
 
     if (!ss->pbvh) {
-      MEM_SAFE_FREE(ss->pmap);
-      MEM_SAFE_FREE(ss->pmap_mem);
+      BKE_pbvh_pmap_release(ss->pmap);
     }
 
     sculptsession_free_pbvh(ob);
@@ -1827,23 +1822,18 @@ static void sculpt_update_object(Depsgraph *depsgraph,
 
   if (need_pmap && ob->type == OB_MESH && !ss->pmap) {
     if (!ss->pmap && ss->pbvh) {
-      ss->pmap = BKE_pbvh_get_pmap_ex(ss->pbvh, &ss->pmap_mem);
+      ss->pmap = BKE_pbvh_get_pmap(ss->pbvh);
+
+      if (ss->pmap) {
+        BKE_pbvh_pmap_aquire(ss->pmap);
+      }
     }
 
     if (!ss->pmap) {
-      BKE_mesh_vert_poly_map_create(&ss->pmap,
-                                    &ss->pmap_mem,
-                                    me->mvert,
-                                    me->medge,
-                                    me->mpoly,
-                                    me->mloop,
-                                    me->totvert,
-                                    me->totpoly,
-                                    me->totloop,
-                                    false);
+      ss->pmap = BKE_pbvh_make_pmap(me);
 
       if (ss->pbvh) {
-        BKE_pbvh_set_pmap(ss->pbvh, ss->pmap, ss->pmap_mem);
+        BKE_pbvh_set_pmap(ss->pbvh, ss->pmap);
       }
     }
   }
@@ -2471,23 +2461,13 @@ ATTR_NO_OPT static PBVH *build_pbvh_from_regular_mesh(Object *ob,
 
   PBVH *pbvh = BKE_pbvh_get_or_free_cached(ob, me, PBVH_FACES);
 
-  struct MeshElemMap *BKE_pbvh_get_pmap_ex(PBVH * pbvh, int **r_mem);
-
   if (!ss->pmap && pbvh) {
-    ss->pmap = BKE_pbvh_get_pmap_ex(pbvh, &ss->pmap_mem);
+    ss->pmap = BKE_pbvh_get_pmap(pbvh);
+    BKE_pbvh_pmap_aquire(ss->pmap);
   }
 
   if (!ss->pmap) {
-    BKE_mesh_vert_poly_map_create(&ss->pmap,
-                                  &ss->pmap_mem,
-                                  me->mvert,
-                                  me->medge,
-                                  me->mpoly,
-                                  me->mloop,
-                                  me->totvert,
-                                  me->totpoly,
-                                  me->totloop,
-                                  false);
+    ss->pmap = BKE_pbvh_make_pmap(me);
   }
 
   if (!pbvh) {
@@ -2519,7 +2499,7 @@ ATTR_NO_OPT static PBVH *build_pbvh_from_regular_mesh(Object *ob,
     pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets);
   }
 
-  BKE_pbvh_set_pmap(pbvh, ss->pmap, ss->pmap_mem);
+  BKE_pbvh_set_pmap(pbvh, ss->pmap);
   BKE_sculptsession_check_sculptverts(ob->sculpt, pbvh, me->totvert);
 
   MEM_SAFE_FREE(ss->face_areas);
@@ -2632,7 +2612,7 @@ static void init_mdyntopo_layer_faces(SculptSession *ss, PBVH *pbvh, int totvert
                                         ss->mloop,
                                         ss->mpoly,
                                         ss->mdyntopo_verts,
-                                        ss->pmap,
+                                        ss->pmap->pmap,
                                         vertex);
 
     // can't fully update boundary here, so still flag for update
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index e8c5be3fc50..a8511562acc 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -663,7 +663,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
                          int looptri_num,
                          bool fast_draw,
                          float *face_areas,
-                         struct MeshElemMap *pmap)
+                         SculptPMap *pmap)
 {
   BBC *prim_bbc = NULL;
   BB cb;
@@ -794,6 +794,8 @@ PBVH *BKE_pbvh_new(void)
 
 ATTR_NO_OPT void BKE_pbvh_free(PBVH *pbvh)
 {
+  BKE_pbvh_cache_remove(pbvh);
+
   for (int i = 0; i < pbvh->totnode; i++) {
     PBVHNode *node = &pbvh->nodes[i];
 
@@ -832,6 +834,8 @@ ATTR_NO_OPT void BKE_pbvh_free(PBVH *pbvh)
 
       MEM_freeN((void *)pbvh->verts);
     }
+
+    pbvh->verts = NULL;
   }
 
   if (pbvh->looptri) {
@@ -848,8 +852,10 @@ ATTR_NO_OPT void BKE_pbvh_free(PBVH *pbvh)
 
   MEM_SAFE_FREE(pbvh->vert_bitmap);
 
-  MEM_SAFE_FREE(pbvh->pmap);
-  MEM_SAFE_FREE(pbvh->pmap_mem);
+  BKE_pbvh_pmap_release(pbvh->pmap);
+  pbvh->pmap = NULL;
+
+  pbvh->invalid = true;
 
   MEM_freeN(pbvh);
 }
@@ -4420,7 +4426,7 @@ void BKE_pbvh_pmap_to_edges(PBVH *pbvh,
                             bool *r_heap_alloc,
                             int **r_polys)
 {
-  MeshElemMap *map = pbvh->pmap + vertex.i;
+  MeshElemMap *map = pbvh->pmap->pmap + vertex.i;
   int len = 0;
 
   for (int i = 0; i < map->count; i++) {
@@ -4793,6 +4799,11 @@ bool BKE_pbvh_cache(const struct Mesh *me, PBVH *pbvh)
 {
   memset(&pbvh->cached_data, 0, sizeof(pbvh->cached_data));
 
+  if (pbvh->invalid) {
+    printf("invalid pbvh!\n");
+    return false;
+  }
+
   switch (pbvh->type) {
     case PBVH_BMESH:
       if (!pbvh->bm) {
@@ -4850,6 +4861,10 @@ ATTR_NO_OPT bool BKE_pbvh_cache_is_valid(const Object *ob,
                                          const PBVH *pbvh,
                                          PBVHType pbvh_type)
 {
+  if (pbvh->invalid) {
+    printf("pbvh invalid!\n");
+  }
+
   if (pbvh->type != pbvh_type) {
     return false;
   }
@@ -4968,7 +4983,10 @@ ATTR_NO_OPT PBVH *BKE_pbvh_get_or_free_cached(Object *ob, Mesh *me, PBVHType pbv
       case PBVH_FACES:
         pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(me);
       case PBVH_GRIDS:
-        pbvh->verts = me->mvert;
+        if (!pbvh->deformed) {
+          pbvh->verts = me->mvert;
+        }
+
         pbvh->mloop = me->mloop;
         pbvh->mpoly = me->mpoly;
         pbvh->vdata = &me->vdata;
@@ -4993,6 +5011,14 @@ ATTR_NO_OPT void BKE_pbvh_set_cached(Object *ob, PBVH *pbvh)
 
   PBVH *exist = BLI_ghash_lookup(cached_pbvhs, ob_orig->id.name);
 
+  if (pbvh->invalid) {
+    printf("pbvh invalid!");
+  }
+
+  if (exist && exist->invalid) {
+    printf("pbvh invalid!");
+  }
+
   if (!exist || exist != pbvh) {
     pbvh_clear_cached_pbvhs(pbvh);
     BLI_ghash_insert(cached_pbvhs, BLI_strdup(ob_orig->id.name), pbvh);
@@ -5001,24 +5027,18 @@ ATTR_NO_OPT void BKE_pbvh_set_cached(Object *ob, PBVH *pbvh)
   BKE_pbvh_cache(BKE_object_get_original_mesh(ob_orig), pbvh);
 }
 
-struct MeshElemMap *BKE_pbvh_get_pmap(PBVH *pbvh)
+struct SculptPMap *BKE_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list