[Bf-blender-cvs] [0eeaeb3fc22] temp_bmesh_multires: Sculpt dyntopo: fix nasty node splitting bug

Joseph Eagar noreply at git.blender.org
Tue Sep 14 05:15:00 CEST 2021


Commit: 0eeaeb3fc22b80ef64271a17c1cc0ac88705d1f2
Author: Joseph Eagar
Date:   Mon Sep 13 20:14:46 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB0eeaeb3fc22b80ef64271a17c1cc0ac88705d1f2

Sculpt dyntopo: fix nasty node splitting bug

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

M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c

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

diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 7e02131d2c6..36e66a5376a 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -161,6 +161,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
 
 struct EdgeQueueContext;
 
+static bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root);
 static bool check_face_is_tri(PBVH *pbvh, BMFace *f);
 static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
 static void pbvh_split_edges(struct EdgeQueueContext *eq_ctx,
@@ -3693,7 +3694,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     int totl = 0;
 
     BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
-      MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->v);
+      MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->next->v);
       mv_l->flag |= mupdateflag;
 
       BLI_array_append(ls, l);
@@ -3702,7 +3703,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     BM_LOOPS_OF_VERT_ITER_END;
 
     BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
-      MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->v);
+      MDynTopoVert *mv_l = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->next->v);
       mv_l->flag |= mupdateflag;
 
       BLI_array_append(ls, l);
@@ -3962,6 +3963,16 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   MDynTopoVert *mv3 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v_conn);
   mv3->flag |= mupdateflag;
 
+  if (BM_ELEM_CD_GET_INT(v_conn, pbvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
+    printf("eek!\n");
+  }
+
+  for (int i = 0; i < 3; i++) {
+    if (!check_for_fins(pbvh, v_conn)) {
+      break;
+    }
+  }
+
   if (wasbad) {
     fix_mesh(pbvh, pbvh->bm);
     return;
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 9010c71f733..c3e967b0bc7 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -251,7 +251,9 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
   bool has_visible = false;
 
   /* Create vert hash sets */
-  n->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
+  if (!n->bm_unique_verts) {
+    n->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
+  }
   n->bm_other_verts = BLI_table_gset_new("bm_other_verts");
 
   BB_reset(&n->vb);
@@ -356,7 +358,9 @@ static void pbvh_bmesh_node_split(
   c1->bm_faces = BLI_table_gset_new_ex("bm_faces", BLI_table_gset_len(n->bm_faces) / 2);
   c2->bm_faces = BLI_table_gset_new_ex("bm_faces", BLI_table_gset_len(n->bm_faces) / 2);
 
-  c1->bm_unique_verts = c2->bm_unique_verts = NULL;
+  c1->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
+  c2->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
+
   c1->bm_other_verts = c2->bm_other_verts = NULL;
 
   /* Partition the parent node's faces between the two children */
@@ -389,17 +393,32 @@ static void pbvh_bmesh_node_split(
       BLI_table_gset_insert(empty, key);
       BLI_table_gset_remove(other, key, NULL);
       break;
-    } TGSET_ITER_END
+    }
+    TGSET_ITER_END
   }
 #endif
   /* Clear this node */
 
   BMVert *v;
+  TableGSet *bm_unique_verts = n->bm_unique_verts;
 
-  /* Mark this node's unique verts as unclaimed */
+  /* Assign verts to c1 and c2.  Note that the previous
+     method of simply marking them as untaken and rebuilding
+     unique verts later doesn't work, as it assumes that dyntopo
+     never assigns verts to nodes that don't contain their
+     faces.*/
   if (n->bm_unique_verts) {
     TGSET_ITER (v, n->bm_unique_verts) {
-      BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
+      int ni;
+
+      if (v->co[axis] < mid) {
+        BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, (c1 - pbvh->nodes));
+        BLI_table_gset_add(c1->bm_unique_verts, v);
+      }
+      else {
+        BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, (c2 - pbvh->nodes));
+        BLI_table_gset_add(c2->bm_unique_verts, v);
+      }
     }
     TGSET_ITER_END



More information about the Bf-blender-cvs mailing list