[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