[Bf-blender-cvs] [7ef7843ada9] temp_bmesh_multires: Sculpt Dyntopo: Fix memory corruption in dyntopo undo

Joseph Eagar noreply at git.blender.org
Sat Jun 26 02:10:56 CEST 2021


Commit: 7ef7843ada944a5530ff4de812a5684e39809142
Author: Joseph Eagar
Date:   Fri Jun 25 17:10:12 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB7ef7843ada944a5530ff4de812a5684e39809142

Sculpt Dyntopo: Fix memory corruption in dyntopo undo

ss->active_XXX_index wasn't being handled properly.

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

M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_log.h
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index bd3aec20d00..54acd45d9af 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -3726,6 +3726,7 @@ CLANG_OPT_BUG static bool cleanup_valence_3_4(PBVH *pbvh,
       }
 
       BM_log_vert_removed(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
+      pbvh_bmesh_vert_remove(pbvh, v);
 
       BMFace *f;
       BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
@@ -3734,15 +3735,13 @@ CLANG_OPT_BUG static bool cleanup_valence_3_4(PBVH *pbvh,
         if (ni2 != DYNTOPO_NODE_NONE) {
           PBVHNode *node2 = pbvh->nodes + ni2;
 
-          BLI_table_gset_remove(node2->bm_unique_verts, v, NULL);
-          BLI_table_gset_remove(node2->bm_other_verts, v, NULL);
+          // BLI_table_gset_remove(node2->bm_unique_verts, v, NULL);
+          // BLI_table_gset_remove(node2->bm_other_verts, v, NULL);
 
           pbvh_bmesh_face_remove(pbvh, f, true, true);
         }
       }
 
-      // pbvh_bmesh_vert_remove(pbvh, v);
-
       modified = true;
 
       l = v->e->l;
@@ -3758,7 +3757,7 @@ CLANG_OPT_BUG static bool cleanup_valence_3_4(PBVH *pbvh,
             f1->no, f1->l_first->v->co, f1->l_first->next->v->co, f1->l_first->prev->v->co);
       }
       else {
-        printf("eek!\n");
+        //printf("eek1!\n");
       }
 
       if (val == 4 && vs[0] != vs[2] && vs[2] != vs[3] && vs[0] != vs[3]) {
@@ -3779,7 +3778,7 @@ CLANG_OPT_BUG static bool cleanup_valence_3_4(PBVH *pbvh,
         BM_log_face_added(pbvh->bm_log, f2);
       }
       else {
-        printf("eek2!\n");
+        //printf("eek2!\n");
       }
 
       if (f1) {
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index db5daf69b60..d7b387d2450 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -261,6 +261,26 @@ static uint bm_log_face_id_get(BMLog *log, BMFace *f)
   return POINTER_AS_UINT(log_ghash_lookup(log, log->elem_to_id, f));
 }
 
+uint BM_log_vert_id_get(BMLog *log, BMVert *v)
+{
+  return bm_log_vert_id_get(log, v);
+}
+
+BMVert *BM_log_id_vert_get(BMLog *log, uint id)
+{
+  return log_ghash_lookup(log, log->id_to_elem, POINTER_FROM_UINT(id));
+}
+
+uint BM_log_face_id_get(BMLog *log, BMFace *f)
+{
+  return bm_log_face_id_get(log, f);
+}
+
+BMFace *BM_log_id_face_get(BMLog *log, uint id)
+{
+  return log_ghash_lookup(log, log->id_to_elem, POINTER_FROM_UINT(id));
+}
+
 /* Set the face's unique ID in the log */
 static void bm_log_face_id_set(BMLog *log, BMFace *f, uint id)
 {
@@ -1667,6 +1687,8 @@ void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
       bm_log_vert_customdata(log->bm, log, entry, v, lv);
     }
   }
+
+  log_ghash_remove(log, log->id_to_elem, key, NULL, NULL);
 }
 
 /* Log a face as removed from the BMesh
@@ -1705,6 +1727,8 @@ void BM_log_face_removed(BMLog *log, BMFace *f)
       bm_log_face_customdata(log->bm, log, f, lf);
     }
   }
+
+  log_ghash_remove(log, log->id_to_elem, key, NULL, NULL);
 }
 
 /* Log all vertices/faces in the BMesh as added */
diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h
index a0628914d8d..a824d38e00e 100644
--- a/source/blender/bmesh/intern/bmesh_log.h
+++ b/source/blender/bmesh/intern/bmesh_log.h
@@ -124,3 +124,8 @@ void BM_log_original_vert_data(BMLog *log, BMVert *v, const float **r_co, const
 /* For internal use only (unit testing) */
 BMLogEntry *BM_log_current_entry(BMLog *log);
 struct RangeTreeUInt *BM_log_unused_ids(BMLog *log);
+
+uint BM_log_vert_id_get(BMLog *log, BMVert *v);
+BMVert *BM_log_id_vert_get(BMLog *log, uint id);
+uint BM_log_face_id_get(BMLog *log, BMFace *f);
+BMFace *BM_log_id_face_get(BMLog *log, uint id);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 9923505addc..4ed39a63a5c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -735,30 +735,61 @@ static int sculpt_undo_bmesh_restore(bContext *C,
   if (ss->bm_log && ss->bm) {
     SCULPT_dyntopo_node_layers_update_offsets(ss);
     BM_log_set_cd_offsets(ss->bm_log, ss->cd_dyn_vert);
+
+    if (ss->active_face_index.i) {
+      ss->active_face_index.i = (intptr_t)BM_log_face_id_get(ss->bm_log,
+                                                             (BMFace *)ss->active_face_index.i);
+    }
+    else {
+      ss->active_face_index.i = -1;
+    }
+
+    if (ss->active_vertex_index.i) {
+      ss->active_vertex_index.i = (intptr_t)BM_log_vert_id_get(
+          ss->bm_log, (BMVert *)ss->active_vertex_index.i);
+    }
+    else {
+      ss->active_vertex_index.i = -1;
+    }
   }
 
+  bool ret = false;
+
   switch (unode->type) {
     case SCULPT_UNDO_DYNTOPO_BEGIN:
       sculpt_undo_bmesh_restore_begin(C, unode, ob, ss);
       SCULPT_vertex_random_access_ensure(ss);
-      return true;
-
+      ret = true;
+      break;
     case SCULPT_UNDO_DYNTOPO_END:
       if (ss->bm) {
         sculpt_undo_bmesh_restore_end(C, unode, ob, ss);
       }
       SCULPT_vertex_random_access_ensure(ss);
-      return true;
+      ret = true;
+      break;
     default:
       if (ss->bm_log) {
         sculpt_undo_bmesh_restore_generic(unode, ob, ss);
         SCULPT_vertex_random_access_ensure(ss);
-        return true;
+        ret = true;
       }
       break;
   }
 
-  return false;
+  if (ss->bm_log && ss->bm) {
+    if (ss->active_face_index.i != -1) {
+      ss->active_face_index.i = (intptr_t)BM_log_id_face_get(ss->bm_log,
+                                                             (uint)ss->active_face_index.i);
+    }
+
+    if (ss->active_vertex_index.i != -1) {
+      ss->active_vertex_index.i = (intptr_t)BM_log_id_vert_get(ss->bm_log,
+                                                               (uint)ss->active_vertex_index.i);
+    }
+  }
+
+  return ret;
 }
 
 /* Geometry updates (such as Apply Base, for example) will re-evaluate the object and refine its



More information about the Bf-blender-cvs mailing list