[Bf-blender-cvs] [954aa88ba4a] temp_bmesh_multires: Sculpt dyntopo: more undo fixes

Joseph Eagar noreply at git.blender.org
Tue Aug 17 08:10:23 CEST 2021


Commit: 954aa88ba4a159ee189fd5d23c4c772ac0fb7dd0
Author: Joseph Eagar
Date:   Tue Aug 17 00:09:43 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB954aa88ba4a159ee189fd5d23c4c772ac0fb7dd0

Sculpt dyntopo: more undo fixes

Yay for massively overdetermined bugs.

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

M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 3f36aa2b430..14131e765e1 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -277,19 +277,19 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
   }
 }
 
-static void pbvh_bmesh_copy_facedata(BMesh *bm, BMFace *dest, BMFace *src)
+ATTR_NO_OPT static void pbvh_bmesh_copy_facedata(BMesh *bm, BMFace *dest, BMFace *src)
 {
   dest->head.hflag = src->head.hflag;
   dest->mat_nr = src->mat_nr;
   CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, src->head.data, &dest->head.data);
 }
 
-static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
-                                      int node_index,
-                                      const float co[3],
-                                      const float no[3],
-                                      BMVert *v_example,
-                                      const int cd_vert_mask_offset)
+ATTR_NO_OPT static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
+                                                  int node_index,
+                                                  const float co[3],
+                                                  const float no[3],
+                                                  BMVert *v_example,
+                                                  const int cd_vert_mask_offset)
 {
   PBVHNode *node = &pbvh->nodes[node_index];
 
@@ -746,6 +746,11 @@ void BKE_pbvh_bmesh_add_face(PBVH *pbvh, struct BMFace *f, bool log_face, bool f
 {
   int ni = -1;
 
+  if (force_tree_walk) {
+    bke_pbvh_insert_face(pbvh, f);
+    return;
+  }
+
   // look for node in surrounding geometry
   BMLoop *l = f->l_first;
   do {
@@ -764,7 +769,7 @@ void BKE_pbvh_bmesh_add_face(PBVH *pbvh, struct BMFace *f, bool log_face, bool f
     l = l->next;
   } while (l != f->l_first);
 
-  if (ni < 0 || force_tree_walk) {
+  if (ni < 0) {
     bke_pbvh_insert_face(pbvh, f);
   }
   else {
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index f8f3beaccaa..63b541edcee 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -68,9 +68,43 @@ Topology rake:
 #include <stdio.h>
 #include <stdlib.h>
 
-void pbvh_bmesh_check_nodes(PBVH *pbvh)
+ATTR_NO_OPT void pbvh_bmesh_check_nodes(PBVH *pbvh)
 {
 #if 0
+  BMVert *v;
+  BMIter iter;
+
+  BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
+    int ni = BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset);
+
+    if (ni >= 0 && !v->e || !v->e->l) {
+      printf("wire vert had node reference\n");
+    }
+
+    if (ni < -1 || ni >= pbvh->totnode) {
+      printf("vert node ref was invalid");
+      continue;
+    }
+
+    if (ni == -1) {
+      continue;
+    }
+
+    PBVHNode *node = pbvh->nodes + ni;
+    if (!(node->flag & PBVH_Leaf) || !node->bm_unique_verts) {
+      printf("vert node ref was in non leaf node");
+      continue;
+    }
+
+    if (!BLI_table_gset_haskey(node->bm_unique_verts, v)) {
+      printf("vert not in node->bm_unique_verts\n");
+    }
+
+    if (BLI_table_gset_haskey(node->bm_other_verts, v)) {
+      printf("vert in node->bm_other_verts");
+    }
+  }
+
   for (int i = 0; i < pbvh->totnode; i++) {
     PBVHNode *node = pbvh->nodes + i;
     BMVert *v;
@@ -90,6 +124,19 @@ void pbvh_bmesh_check_nodes(PBVH *pbvh)
     }
 
     TGSET_ITER (v, node->bm_unique_verts) {
+      int ni = BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset);
+
+      if (ni != i) {
+        if (ni >= 0 && ni < pbvh->totnode) {
+          PBVHNode *node2 = pbvh->nodes + ni;
+          printf("v node offset is wrong, %d\n",
+                 !node2->bm_unique_verts ? 0 : BLI_table_gset_haskey(node2->bm_unique_verts, v));
+        }
+        else {
+          printf("v node offset is wrong\n");
+        }
+      }
+
       if (!v || v->head.htype != BM_VERT) {
         printf("corruption in pbvh! bm_unique_verts\n");
       }
@@ -404,11 +451,16 @@ static bool point_in_node(const PBVHNode *node, const float co[3])
          co[1] <= node->vb.bmax[1] && co[2] >= node->vb.bmin[2] && co[2] <= node->vb.bmax[2];
 }
 
-void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni)
+ATTR_NO_OPT void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni)
 {
   PBVHNode *node = pbvh->nodes + ni;
   BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, ni);
 
+  if (!(node->flag & PBVH_Leaf)) {
+    printf("major pbvh corruption error");
+    return;
+  }
+
   BLI_table_gset_add(node->bm_faces, f);
 
   int updateflag = PBVH_UpdateTris | PBVH_UpdateBB | PBVH_UpdateDrawBuffers |
@@ -447,13 +499,12 @@ void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni)
   } while (l != f->l_first);
 }
 
-void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f)
+ATTR_NO_OPT void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f)
 {
   int i = 0;
   bool ok = false;
   int ni = -1;
 
-#if 1
   while (i < pbvh->totnode) {
     PBVHNode *node = pbvh->nodes + i;
     bool ok2 = false;
@@ -496,7 +547,6 @@ void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f)
       break;
     }
   }
-#endif
 
   if (!ok) {
     // find closest node
@@ -534,7 +584,7 @@ void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f)
     }
   }
 
-  if (ni < 0) {
+  if (ni < 0 || !(pbvh->nodes[ni].flag & PBVH_Leaf)) {
     fprintf(stderr, "pbvh error!\n");
     fflush(stderr);
     return;
@@ -543,16 +593,23 @@ void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f)
   bke_pbvh_insert_face_finalize(pbvh, f, ni);
 }
 
-static void pbvh_bmesh_regen_node_verts(PBVH *pbvh, PBVHNode *node)
+ATTR_NO_OPT static void pbvh_bmesh_regen_node_verts(PBVH *pbvh, PBVHNode *node)
 {
   node->flag &= ~PBVH_RebuildNodeVerts;
 
   int usize = BLI_table_gset_len(node->bm_unique_verts);
   int osize = BLI_table_gset_len(node->bm_other_verts);
 
-  BLI_table_gset_free(node->bm_unique_verts, NULL);
+  TableGSet *old_unique_verts = node->bm_unique_verts;
+
   BLI_table_gset_free(node->bm_other_verts, NULL);
 
+  BMVert *v;
+  TGSET_ITER (v, old_unique_verts) {
+    BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, -1);
+  }
+  TGSET_ITER_END;
+
   node->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
   node->bm_other_verts = BLI_table_gset_new("bm_other_verts");
 
@@ -583,6 +640,35 @@ static void pbvh_bmesh_regen_node_verts(PBVH *pbvh, PBVHNode *node)
   }
   TGSET_ITER_END;
 
+  TGSET_ITER (v, old_unique_verts) {
+    if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) == -1) {
+      // try to find node to insert into
+      BMIter iter2;
+      BMFace *f2;
+      bool ok = false;
+
+      BM_ITER_ELEM (f2, &iter2, v, BM_FACES_OF_VERT) {
+        int ni2 = BM_ELEM_CD_GET_INT(f2, pbvh->cd_face_node_offset);
+
+        if (ni2 >= 0) {
+          BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, ni2);
+          PBVHNode *node = pbvh->nodes + ni2;
+
+          BLI_table_gset_add(node->bm_unique_verts, v);
+          BLI_table_gset_remove(node->bm_other_verts, v, NULL);
+
+          ok = true;
+          break;
+        }
+      }
+
+      if (!ok) {
+        printf("pbvh error: orphaned vert node reference\n");
+      }
+    }
+  }
+  TGSET_ITER_END;
+
   if (usize != BLI_table_gset_len(node->bm_unique_verts)) {
     update = true;
     printf("possible pbvh error: bm_unique_verts might have had bad data. old: %d, new: %d\n",
@@ -603,6 +689,8 @@ static void pbvh_bmesh_regen_node_verts(PBVH *pbvh, PBVHNode *node)
     node->flag |= PBVH_UpdateOriginalBB | PBVH_UpdateRedraw | PBVH_UpdateColor | PBVH_UpdateTris |
                   PBVH_UpdateVisibility;
   }
+
+  BLI_table_gset_free(old_unique_verts, NULL);
 }
 
 void BKE_pbvh_bmesh_mark_node_regen(PBVH *pbvh, PBVHNode *node)
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 1cc928525ec..cf3089e4490 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -417,15 +417,6 @@ static bool sculpt_undo_restore_face_sets(bContext *C, SculptUndoNode *unode)
   return false;
 }
 
-static void sculpt_undo_bmesh_restore_generic_task_cb(
-    void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
-{
-  PBVHNode **nodes = userdata;
-
-  BKE_pbvh_node_mark_redraw(nodes[n]);
-  BKE_pbvh_node_mark_normals_update(nodes[n]);
-}
-
 extern const char dyntopop_node_idx_layer_id[];
 
 typedef struct BmeshUndoData {
@@ -458,11 +449,12 @@ static void bmesh_undo_on_vert_kill(BMVert *v, void *userdata)
 static void bmesh_undo_on_vert_add(BMVert *v, void *userdata)
 {
   BmeshUndoData *data = (BmeshUndoData *)userdata;
-  BM_ELEM_CD_SET_INT(v, data->cd_vert_node_offset, -1);
-  // data->do_full_recalc = true;
 
   data->balance_pbvh = true;
 
+  // let face add vert
+  BM_ELEM_CD_SET_INT(v, data->cd_vert_node_offset, -1);
+
   MDynTopoVert *mv = BKE_PBVH_DYNVERT(data->cd_dyn_vert, v);
   mv->flag |= DYNVERT_NEED_DISK_SORT;
 }
@@ -482,7 +474,8 @@ static void bmesh_undo_on_face_kill(BMFace *f, void *userdata)
   // data->do_full_recalc = true;
   data->balance_pbvh = true;
 }
-static void bmesh_undo_on_face_add(BMFace *f, void *userdata)
+
+ATTR_NO_OPT static void bmesh_undo_on_face_add(BMFace *f, void *userdata)
 {
   BmeshUndoData *data = (BmeshUndoData *)userdata;
   // data->do_full_recalc = true;
@@ -490,11 +483,22 @@ static void bmesh_undo_on_face_add(BMFace *f, void *userdata)
   BM_ELEM_CD_SET_INT(f, data->cd_face_node_offset, -1);
   BKE_pbvh_bmesh_add_face(data->pbvh, f, false, true);
 
+  int ni = BM_ELEM_CD_GET_INT(f, data->cd_face_node_offset);
+  PBVHNode *node = BKE_pbvh_get_node(data->pbvh, ni);
+
   BMLoop *l = f->l_first;
   do {
     MDynTopoVert *mv = BKE_PBVH_DYNVERT(data->cd_dyn_vert, l->v);
     mv->flag |= DYNVERT_NEED_DISK_SORT;
 
+    int ni_l = BM_ELEM_CD_GET_INT(l->v, data->cd_vert_node_offset);
+
+    if (ni_l < 0 && ni >= 0) {
+      BM_ELEM_CD_SET_INT(l->v, ni_l, ni);
+      TableGSet *bm_unique_verts = BKE_pbvh_bmesh_node_unique_verts(node);
+
+      BLI_table_gset_add(bm_unique_verts, l->v);
+    }
   } whil

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list