[Bf-blender-cvs] [e07a95b86d5] temp_bmesh_multires: Fix extremely nastly memory corruption bug in pbvh

Joseph Eagar noreply at git.blender.org
Mon Apr 12 13:20:13 CEST 2021


Commit: e07a95b86d533146ee17ddad8ae159baf97086cf
Author: Joseph Eagar
Date:   Mon Apr 12 04:19:49 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rBe07a95b86d533146ee17ddad8ae159baf97086cf

Fix extremely nastly memory corruption bug in pbvh

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

M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/editors/sculpt_paint/sculpt.c

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

diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index bb87b2b5054..8d44655e59c 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -2168,7 +2168,7 @@ bool ray_face_intersection_quad(const float ray_start[3],
   return false;
 }
 
-__attribute__((optnone)) bool ray_face_intersection_tri(const float ray_start[3],
+bool ray_face_intersection_tri(const float ray_start[3],
                                struct IsectRayPrecalc *isect_precalc,
                                const float t0[3],
                                const float t1[3],
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index ece9b81d8df..296c69f0d75 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -775,6 +775,38 @@ static void pbvh_bmesh_vert_ownership_transfer(PBVH *pbvh, PBVHNode *new_owner,
   new_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
 }
 
+static bool pbvh_bmesh_vert_relink(PBVH *pbvh, BMVert *v)
+{
+  const int cd_vert_node = pbvh->cd_vert_node_offset;
+  const int cd_face_node = pbvh->cd_face_node_offset;
+
+  BMFace *f;
+  BLI_assert(BM_ELEM_CD_GET_INT(v, cd_vert_node) == DYNTOPO_NODE_NONE);
+
+  bool added = false;
+
+  BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
+    const int ni = BM_ELEM_CD_GET_INT(f, cd_face_node);
+
+    if (ni == DYNTOPO_NODE_NONE) {
+      continue;
+    }
+
+    PBVHNode *node = pbvh->nodes + ni;
+
+    if (BM_ELEM_CD_GET_INT(v, cd_vert_node) == DYNTOPO_NODE_NONE) {
+      BLI_table_gset_add(node->bm_unique_verts, v);
+      BM_ELEM_CD_SET_INT(v, cd_vert_node, ni);
+    }
+    else {
+      BLI_table_gset_add(node->bm_other_verts, v);
+    }
+  }
+  BM_FACES_OF_VERT_ITER_END;
+
+  return added;
+}
+
 static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
 {
   /* never match for first time */
@@ -2326,35 +2358,34 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
    * really buy anything. */
   BLI_buffer_clear(deleted_faces);
 
-#define MAX_LS 64
-
   BMLoop *l;
-  BMLoop *ls[MAX_LS];
+  BMLoop **ls = NULL;
+  void **blocks = NULL;
+  float *ws = NULL;
+
+  BLI_array_staticdeclare(ls, 64);
+  BLI_array_staticdeclare(blocks, 64);
+  BLI_array_staticdeclare(ws, 64);
 
   int totl = 0;
 
   BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
-    if (totl >= MAX_LS) {
-      break;
-    }
-    ls[totl++] = l;
+    BLI_array_append(ls, l);
+    totl++;
   }
   BM_LOOPS_OF_VERT_ITER_END;
 
   BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
-    if (totl >= MAX_LS) {
-      break;
-    }
-    ls[totl++] = l;
+    BLI_array_append(ls, l);
+    totl++;
   }
   BM_LOOPS_OF_VERT_ITER_END;
 
-  void *blocks[MAX_LS];
-  float ws[MAX_LS], w = totl > 0 ? 1.0f / (float)(totl) : 1.0f;
+  float w = totl > 0 ? 1.0f / (float)(totl) : 1.0f;
 
   for (int i = 0; i < totl; i++) {
-    blocks[i] = ls[i]->head.data;
-    ws[i] = w;
+    BLI_array_append(blocks, ls[i]->head.data);
+    BLI_array_append(ws, w);
   }
 
   // snap customdata
@@ -2502,7 +2533,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   if (v_conn != NULL) {
     // log vert in bmlog, but don't update original customata layers, we want them to be
     // interpolated
-    BM_log_vert_before_modified(pbvh->bm_log, v_conn, eq_ctx->cd_vert_mask_offset, true);
+    BM_log_vert_before_modified(pbvh->bm_log, v_conn, eq_ctx->cd_vert_mask_offset, false);
 
     mid_v3_v3v3(v_conn->co, v_conn->co, v_del->co);
     add_v3_v3(v_conn->no, v_del->no);
@@ -2523,6 +2554,10 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   /* v_conn == NULL is OK */
   BLI_ghash_insert(deleted_verts, v_del, v_conn);
   BM_vert_kill(pbvh->bm, v_del);
+
+  BLI_array_free(ws);
+  BLI_array_free(blocks);
+  BLI_array_free(ls);
 }
 
 void BKE_pbvh_bmesh_update_origvert(
@@ -2672,15 +2707,15 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
 
 /************************* Called from pbvh.c *************************/
 
-__attribute__((optnone)) bool pbvh_bmesh_node_raycast(PBVHNode *node,
-                                                      const float ray_start[3],
-                                                      const float ray_normal[3],
-                                                      struct IsectRayPrecalc *isect_precalc,
-                                                      float *depth,
-                                                      bool use_original,
-                                                      SculptVertRef *r_active_vertex_index,
-                                                      SculptFaceRef *r_active_face_index,
-                                                      float *r_face_normal)
+bool pbvh_bmesh_node_raycast(PBVHNode *node,
+                             const float ray_start[3],
+                             const float ray_normal[3],
+                             struct IsectRayPrecalc *isect_precalc,
+                             float *depth,
+                             bool use_original,
+                             SculptVertRef *r_active_vertex_index,
+                             SculptFaceRef *r_active_face_index,
+                             float *r_face_normal)
 {
   bool hit = false;
   float nearest_vertex_co[3] = {0.0f};
@@ -3307,6 +3342,8 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
                                 const bool use_projected)
 {
   bool modified = false;
+  BMVert **relink_verts = NULL;
+  BLI_array_staticdeclare(relink_verts, 1024);
 
   float radius2 = radius * 1.25;
   float rsqr = radius2 * radius2;
@@ -3394,9 +3431,19 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
       pbvh_bmesh_vert_remove(pbvh, v);
       BM_log_vert_removed(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
 
+      BLI_array_clear(relink_verts);
+
       BMFace *f;
       BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
-        pbvh_bmesh_face_remove(pbvh, f);
+        int ni2 = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
+        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);
+
+          pbvh_bmesh_face_remove(pbvh, f);
+        }
       }
 
       modified = true;
@@ -3409,7 +3456,7 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
 
       BMFace *f1 = NULL;
       if (vs[0] != vs[1] && vs[1] != vs[2] && vs[0] != vs[2]) {
-        f1 = pbvh_bmesh_face_create(pbvh, n, vs, NULL, l->f, true, false);
+        f1 = pbvh_bmesh_face_create(pbvh, n, vs, NULL, l->f, false, false);
       }
 
       if (val == 4 && vs[0] != vs[2] && vs[2] != vs[3] && vs[0] != vs[3]) {
@@ -3417,7 +3464,7 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
         vs[1] = ls[2]->v;
         vs[2] = ls[3]->v;
 
-        BMFace *f2 = pbvh_bmesh_face_create(pbvh, n, vs, NULL, v->e->l->f, true, false);
+        BMFace *f2 = pbvh_bmesh_face_create(pbvh, n, vs, NULL, v->e->l->f, false, false);
         SWAP(void *, f2->l_first->prev->head.data, ls[3]->head.data);
 
         CustomData_bmesh_copy_data(
@@ -3437,10 +3484,24 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
       }
 
       BM_vert_kill(pbvh->bm, v);
+#if 0
+      for (int j = 0; j < pbvh->totnode; j++) {
+        PBVHNode *node2 = pbvh->nodes + j;
+
+        if (!node2->bm_unique_verts || !node2->bm_other_verts) {  //(node2->flag & PBVH_Leaf)) {
+          continue;
+        }
+
+        BLI_table_gset_remove(node2->bm_unique_verts, v, NULL);
+        BLI_table_gset_remove(node2->bm_other_verts, v, NULL);
+      }
+#endif
     }
     TGSET_ITER_END
   }
 
+  BLI_array_free(relink_verts);
+
   if (modified) {
     pbvh->bm->elem_index_dirty |= BM_VERT | BM_FACE | BM_EDGE;
     pbvh->bm->elem_table_dirty |= BM_VERT | BM_FACE | BM_EDGE;
@@ -3566,7 +3627,8 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
           if (!pbvh_bmesh_node_limit_ensure(pbvh, i)) {
             BKE_pbvh_bmesh_node_save_ortri(pbvh->bm, pbvh->nodes + i);
           }
-        } else {
+        }
+        else {
           BKE_pbvh_bmesh_node_save_ortri(pbvh->bm, pbvh->nodes + i);
         }
       }
@@ -3596,7 +3658,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
  * (currently just raycast), store the node's triangles and vertices.
  *
  * Skips triangles that are hidden. */
-__attribute__((optnone)) void BKE_pbvh_bmesh_node_save_ortri(BMesh *bm, PBVHNode *node)
+void BKE_pbvh_bmesh_node_save_ortri(BMesh *bm, PBVHNode *node)
 {
   /* Skip if original coords/triangles are already saved */
   if (node->bm_orco) {
@@ -4024,7 +4086,7 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh)
   check_heap();
   int totnode = pbvh->totnode;
 
-  pbvh_bmesh_join_nodes(pbvh);
+  // pbvh_bmesh_join_nodes(pbvh);
 
   check_heap();
 
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index cb104e94a8d..73dfd17a9fb 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -330,7 +330,7 @@ static void vert_mask_set(BMVert *v, const float new_mask, const int cd_vert_mas
 
 /* Update a BMLogVert with data from a BMVert */
 static void bm_log_vert_bmvert_copy(BMLog *log,
-                                    BMLog *entry,
+                                    BMLogEntry *entry,
                                     BMLogVert *lv,
                                     BMVert *v,
                                     const int cd_vert_mask_offset,
@@ -426,7 +426,7 @@ static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces, BMLogEntry
       e_tri[i] = l_iter->e;
     }
 
-    //ensure we have final customdata for face in log
+    // ensure we have final customdata for face in log
 #ifdef CUSTOMDATA
     if (lf->customdata_f) {
       CustomData_bmesh_copy_data(&bm->pdata, &entry->pdata, f->head.data, &lf->customdata_f);
@@ -539,7 +539,7 @@ static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts, BMLogEn
   }
 }
 
-__attribute__ ((optnone)) static void bm_log_face_values_swap(BMLog *log, GHash *faces, BMLogEntry *entry)
+static void bm_log_face_values_swap(BMLog *log, GHa

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list