[Bf-blender-cvs] [a5c3d3476c3] sculpt-dev: Sculpt-dev: fix memory corruption

Joseph Eagar noreply at git.blender.org
Fri Dec 3 09:52:28 CET 2021


Commit: a5c3d3476c3e31e86e3bc6f7b87a4f1db566225e
Author: Joseph Eagar
Date:   Fri Dec 3 00:51:42 2021 -0800
Branches: sculpt-dev
https://developer.blender.org/rBa5c3d3476c3e31e86e3bc6f7b87a4f1db566225e

Sculpt-dev: fix memory corruption

* Forgot to change the face area
  customdata layer to CD_FLOAT2 everywhere,
  leading to nasty memory corruption.

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

M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/bmesh/intern/bmesh_log.c

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

diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index a05b42e2e5a..247b4e50e5d 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -1306,7 +1306,7 @@ void BKE_pbvh_bmesh_add_face(PBVH *pbvh, struct BMFace *f, bool log_face, bool f
 {
   bm_logstack_push();
 
-  int ni = -1;
+  int ni = DYNTOPO_NODE_NONE;
 
   if (force_tree_walk) {
     bke_pbvh_insert_face(pbvh, f);
@@ -3955,6 +3955,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
       lnext = l->radial_next;
 
       bool fbad = false;
+#if 1
       do {
 
         if (l2->v == l2->next->v) {
@@ -3973,6 +3974,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
           break;
         }
       } while ((l2 = l2->next) != l->f->l_first);
+#endif
 
       if (!fbad && BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset) == DYNTOPO_NODE_NONE) {
         BKE_pbvh_bmesh_add_face(pbvh, l->f, false, false);
@@ -5443,39 +5445,48 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
       ni = BM_ELEM_CD_GET_INT(v2, pbvh->cd_vert_node_offset);
     }
 
-    // this should never happen
-    if (true || ni == DYNTOPO_NODE_NONE) {
-      BMIter fiter;
-      BMFace *f;
+    if (ni >= pbvh->totnode || !(pbvh->nodes[ni].flag & PBVH_Leaf)) {
+      printf("%s: error\n", __func__);
+    }
+    /* this should rarely happen */
+    // if (ni < 0 || ni >= pbvh->totnode || !(pbvh->nodes[ni].flag & PBVH_Leaf)) {
+    if (ni == DYNTOPO_NODE_NONE) {
+      ni = DYNTOPO_NODE_NONE;
 
-      for (int j = 0; j < 3; j++) {
+      for (int j = 0; j < 2; j++) {
         BMVert *v = NULL;
 
         switch (j) {
           case 0:
-            v = newv;
-            break;
-          case 1:
             v = v1;
             break;
-          case 2:
+          case 1:
             v = v2;
             break;
         }
 
-        BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) {
-          int ni2 = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
+        if (!v->e) {
+          continue;
+        }
 
-          if (ni2 != DYNTOPO_NODE_NONE) {
-            ni = ni2;
+        BMEdge *e2 = v->e;
+        do {
+          if (!e2->l) {
             break;
           }
-        }
 
-        if (ni != DYNTOPO_NODE_NONE) {
-          break;
-        }
+          BMLoop *l = e2->l;
+          do {
+            int ni2 = BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset);
+
+            if (ni2 >= 0 && ni2 < pbvh->totnode && (pbvh->nodes[ni2].flag & PBVH_Leaf)) {
+              ni = ni2;
+              goto outerbreak;
+            }
+          } while ((l = l->radial_next) != e2->l);
+        } while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
       }
+    outerbreak:;
     }
 
     if (ni != DYNTOPO_NODE_NONE) {
@@ -5520,6 +5531,11 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
 
     int ni = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
 
+    if (ni < 0 || ni >= pbvh->totnode || !(pbvh->nodes[ni].flag & PBVH_Leaf)) {
+      printf("%s: error!\n", __func__);
+      ni = DYNTOPO_NODE_NONE;
+    }
+
     BMLoop *l = f->l_first;
     int j = 0;
     do {
@@ -5531,7 +5547,7 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
 
     int flen = j;
 
-    if (mask >= (int)ARRAY_SIZE(splitmap)) {
+    if (mask < 0 || mask >= (int)ARRAY_SIZE(splitmap)) {
       printf("splitmap error!\n");
       continue;
     }
@@ -5715,7 +5731,7 @@ DynTopoState *BKE_dyntopo_init(BMesh *bm, PBVH *existing_pbvh)
       {CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY}};
 
   BMCustomLayerReq flayers[] = {
-      {CD_PROP_FLOAT, dyntopop_faces_areas_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
+      {CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
       {CD_SCULPT_FACE_SETS, NULL, 0},
       {CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY}};
 
@@ -5733,7 +5749,7 @@ DynTopoState *BKE_dyntopo_init(BMesh *bm, PBVH *existing_pbvh)
       &bm->pdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
 
   pbvh->cd_face_area = CustomData_get_named_offset(
-      &bm->pdata, CD_PROP_FLOAT, dyntopop_faces_areas_layer_id);
+      &bm->pdata, CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id);
 
   pbvh->cd_sculpt_vert = CustomData_get_offset(&bm->vdata, CD_DYNTOPO_VERT);
   pbvh->cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 95ab239ca37..b9a1e7a8b0c 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -2938,7 +2938,7 @@ void BKE_sculptsession_bmesh_add_layers(Object *ob)
       {CD_DYNTOPO_VERT, NULL, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
       {CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY}};
 
-  BM_data_layers_ensure(ss->bm, &ss->bm->vdata, vlayers, 3);
+  BM_data_layers_ensure(ss->bm, &ss->bm->vdata, vlayers, ARRAY_SIZE(vlayers));
 
   ss->cd_vert_mask_offset = CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK);
 
@@ -2946,7 +2946,7 @@ void BKE_sculptsession_bmesh_add_layers(Object *ob)
       {CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
       {CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
   };
-  BM_data_layers_ensure(ss->bm, &ss->bm->pdata, flayers, 2);
+  BM_data_layers_ensure(ss->bm, &ss->bm->pdata, flayers, ARRAY_SIZE(flayers));
 
   // get indices again, as they might have changed after adding new layers
   cd_node_layer_index = CustomData_get_named_layer_index(
@@ -2971,8 +2971,9 @@ void BKE_sculptsession_bmesh_add_layers(Object *ob)
   ss->bm->pdata.layers[cd_face_node_layer_index].flag |= CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY;
   ss->cd_faceset_offset = CustomData_get_offset(&ss->bm->pdata, CD_SCULPT_FACE_SETS);
 
-  ss->cd_face_areas = CustomData_get_named_layer(
-      &ss->bm->pdata, CD_PROP_FLOAT, dyntopop_faces_areas_layer_id);
+  ss->cd_face_areas = CustomData_get_named_layer_index(
+      &ss->bm->pdata, CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id);
+
   ss->cd_face_areas = ss->bm->pdata.layers[ss->cd_face_areas].offset;
 
   AttributeDomain domain;
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index d6127f8b430..4a005bce522 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -5649,7 +5649,7 @@ void pbvh_bmesh_cache_test(CacheParams *params, BMesh **r_bm, PBVH **r_pbvh_out)
   int cd_face_node = CustomData_get_named_layer_index(
       &bm->pdata, CD_PROP_INT32, "__dyntopo_face_node");
   int cd_face_area = CustomData_get_named_layer_index(
-      &bm->pdata, CD_PROP_FLOAT, "__dyntopo_face_areas");
+      &bm->pdata, CD_PROP_FLOAT2, "__dyntopo_face_areas");
 
   cd_vert_node = bm->vdata.layers[cd_vert_node].offset;
   cd_face_node = bm->pdata.layers[cd_face_node].offset;
@@ -6070,7 +6070,8 @@ static void pbvh_bmesh_fetch_cdrefs(PBVH *pbvh)
   idx = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
   pbvh->cd_face_node_offset = bm->pdata.layers[idx].offset;
 
-  idx = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_FLOAT, dyntopop_faces_areas_layer_id);
+  idx = CustomData_get_named_layer_index(
+      &bm->pdata, CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id);
   pbvh->cd_face_area = bm->pdata.layers[idx].offset;
 
   pbvh->cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index c72f8e84887..315817fd5af 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -3185,7 +3185,7 @@ BMVert *BM_log_edge_split_do(BMLog *log, BMEdge *e, BMVert *v, BMEdge **newe, fl
 
   BM_log_edge_topo_pre(log, e);
   BMVert *newv = BM_edge_split(log->bm, e, v, newe, t);
-
+  
   BM_log_edge_topo_post(log, e);
   BM_log_edge_added(log, *newe);



More information about the Bf-blender-cvs mailing list