[Bf-blender-cvs] [95e0bea7bfd] sculpt-dev: Sculpt: More BMLog fixes and cleanups

Joseph Eagar noreply at git.blender.org
Thu Oct 14 03:40:51 CEST 2021


Commit: 95e0bea7bfdf33e3e5edd9d32f85c93431ac8bde
Author: Joseph Eagar
Date:   Wed Oct 13 18:30:56 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rB95e0bea7bfdf33e3e5edd9d32f85c93431ac8bde

Sculpt: More BMLog fixes and cleanups

This commit rewrites much of the core BMLog
serialization logic.

BMLog originally did not support mesh
elements changing their internal topology,
which created ID conflicts in the log. Thus
it was impossible to use much of the BMesh API.
Instead DynTopo had its own implementations of
BM_edge_collapse and triangle edge splitting
that worked by recreating local mesh topology
from scratch.

I got rid of these functions a while ago and
tried to add support for elements changing
topology to BMLog. Unfortunatey I struggled to work
out all of  the edge cases, and it turned out easier to
refactor the core serializer methods wholesale.

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

M	source/blender/blenkernel/intern/dyntopo.c
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/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 1f9bcd87216..baf36423b6d 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -673,15 +673,21 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
   // atomic_cas_int32(&mv1->stroke_id, stroke_id, pbvh->stroke_id);
 }
 
-static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
+static void pbvh_kill_vert(PBVH *pbvh, BMVert *v, bool log_vert, bool log_edges)
 {
   BMEdge *e = v->e;
   bm_logstack_push();
 
-  if (e) {
-    do {
-      BM_log_edge_removed(pbvh->bm_log, e);
-    } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+  if (log_edges) {
+    if (e) {
+      do {
+        BM_log_edge_removed(pbvh->bm_log, e);
+      } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+    }
+  }
+
+  if (log_vert) {
+    BM_log_vert_removed(pbvh->bm_log, v, -1);
   }
 
   BM_vert_kill(pbvh->bm, v);
@@ -1200,7 +1206,7 @@ static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
       f_node_index_prev = f_node_index;
 
       PBVHNode *f_node = &pbvh->nodes[f_node_index];
-      f_node->flag |= updateflag;
+      f_node->flag |= updateflag;  // flag update of bm_other_verts
 
       BLI_assert(!BLI_table_gset_haskey(f_node->bm_unique_verts, v));
     }
@@ -1219,6 +1225,8 @@ static void pbvh_bmesh_face_remove(
     return;
   }
 
+  bm_logstack_push();
+
   /* Check if any of this face's vertices need to be removed
    * from the node */
   if (check_verts) {
@@ -1261,6 +1269,8 @@ static void pbvh_bmesh_face_remove(
   /* mark node for update */
   f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_UpdateTris |
                   PBVH_UpdateOtherVerts;
+
+  bm_logstack_pop();
 }
 
 void BKE_pbvh_bmesh_remove_face(PBVH *pbvh, BMFace *f, bool log_face)
@@ -1288,6 +1298,8 @@ void BKE_pbvh_bmesh_remove_vertex(PBVH *pbvh, BMVert *v, bool log_vert)
 
 void BKE_pbvh_bmesh_add_face(PBVH *pbvh, struct BMFace *f, bool log_face, bool force_tree_walk)
 {
+  bm_logstack_push();
+
   int ni = -1;
 
   if (force_tree_walk) {
@@ -1296,6 +1308,8 @@ void BKE_pbvh_bmesh_add_face(PBVH *pbvh, struct BMFace *f, bool log_face, bool f
     if (log_face) {
       BM_log_face_added(pbvh->bm_log, f);
     }
+
+    bm_logstack_pop();
     return;
   }
 
@@ -1328,6 +1342,8 @@ void BKE_pbvh_bmesh_add_face(PBVH *pbvh, struct BMFace *f, bool log_face, bool f
   if (log_face) {
     BM_log_face_added(pbvh->bm_log, f);
   }
+
+  bm_logstack_pop();
 }
 
 static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
@@ -2348,6 +2364,8 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
     return false;
   }
 
+  bm_logstack_push();
+
   BMFace **fs = NULL;
   BMEdge **es = NULL;
   LinkNode *dbl = NULL;
@@ -2364,7 +2382,8 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
   } while ((l = l->next) != f->l_first);
 
   // BKE_pbvh_bmesh_remove_face(pbvh, f, true);
-  pbvh_bmesh_face_remove(pbvh, f, true, true, true);
+  pbvh_bmesh_face_remove(pbvh, f, false, true, true);
+  BM_log_face_topo_pre(pbvh->bm_log, f);
 
   int len = (f->len - 2) * 3;
 
@@ -2398,15 +2417,20 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
     BMFace *f2 = dbl->link;
     LinkNode *next = dbl->next;
 
-    for (int i = 0; i < totface; i++) {
-      if (fs[i] == f2) {
-        // fs[i] = NULL;
+    if (1 || dbl->link != f) {
+      for (int i = 0; i < totface; i++) {
+        if (fs[i] == f2) {
+          fs[i] = NULL;
+        }
       }
-    }
 
-    if (dbl->link != f) {
-      // f = NULL;
-      // BM_face_kill(pbvh->bm, dbl->link);
+      if (f == f2) {
+        BM_log_face_topo_post(pbvh->bm_log, f);
+        BM_log_face_removed(pbvh->bm_log, f);
+        f = NULL;
+      }
+
+      BM_face_kill(pbvh->bm, dbl->link);
     }
 
     MEM_freeN(dbl);
@@ -2435,11 +2459,15 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
     } while ((l = l->next) != f2->l_first);
 
     validate_face(pbvh, pbvh->bm, f2, false, true);
-    BKE_pbvh_bmesh_add_face(pbvh, f2, true, true);
+
+    BKE_pbvh_bmesh_add_face(pbvh, f2, false, true);
+    // BM_log_face_topo_post(pbvh->bm_log, f2);
+    BM_log_face_added(pbvh->bm_log, f2);
   }
 
   if (f) {
-    BKE_pbvh_bmesh_add_face(pbvh, f, true, true);
+    BKE_pbvh_bmesh_add_face(pbvh, f, false, true);
+    BM_log_face_topo_post(pbvh->bm_log, f);
   }
 
   BLI_array_free(fs);
@@ -2453,11 +2481,14 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
     BLI_heap_free(heap, NULL);
   }
 
+  bm_logstack_pop();
+
   return false;
 }
 
 static bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
 {
+  // return;
   bm_logstack_push();
 
   static int max_faces = 64;
@@ -2786,6 +2817,7 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
 
   EdgeQueueThreadData *tdata = NULL;
   BLI_array_declare(tdata);
+  bool push_subentry = false;
 
   int totleaf = 0;
 
@@ -2862,6 +2894,7 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
       if (e->l && e->l != e->l->radial_next->radial_next) {
         // deal with non-manifold iffyness
         destroy_nonmanifold_fins(pbvh, e);
+        push_subentry = true;
       }
 
       MSculptVert *mv1 = BKE_PBVH_SCULPTVERT(cd_sculpt_vert, e->v1);
@@ -2874,8 +2907,8 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
         BKE_pbvh_bmesh_update_valence(pbvh->cd_sculpt_vert, (SculptVertRef){.i = (intptr_t)e->v2});
       }
 
-      check_vert_fan_are_tris(pbvh, e->v1);
-      check_vert_fan_are_tris(pbvh, e->v2);
+      // check_vert_fan_are_tris(pbvh, e->v1);
+      // check_vert_fan_are_tris(pbvh, e->v2);
 
       float w = -calc_weighted_edge_split(eq_ctx, e->v1, e->v2);
       float w2 = maskcb_get(eq_ctx, e);
@@ -2889,6 +2922,10 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
     MEM_SAFE_FREE(td->val34_verts);
   }
   BLI_array_free(tdata);
+
+  if (push_subentry) {
+    BM_log_entry_add_ex(pbvh->bm, pbvh->bm_log, true);
+  }
 }
 
 static void edge_queue_create_local(EdgeQueueContext *eq_ctx,
@@ -3503,13 +3540,13 @@ static bool bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
   return false;
 }
 
-static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
-                                     BMEdge *e,
-                                     BMVert *v1,
-                                     BMVert *v2,
-                                     GHash *deleted_verts,
-                                     BLI_Buffer *deleted_faces,
-                                     EdgeQueueContext *eq_ctx)
+static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
+                                        BMEdge *e,
+                                        BMVert *v1,
+                                        BMVert *v2,
+                                        GHash *deleted_verts,
+                                        BLI_Buffer *deleted_faces,
+                                        EdgeQueueContext *eq_ctx)
 {
   bm_logstack_push();
 
@@ -3517,7 +3554,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 
   if (pbvh->dyntopo_stop) {
     bm_logstack_pop();
-    return;
+    return NULL;
   }
 
   pbvh_check_vert_boundary(pbvh, v1);
@@ -3551,7 +3588,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   if ((mv1->flag & SCULPTVERT_ALL_CORNER) ||
       (mv1->flag & SCULPTVERT_ALL_BOUNDARY) != (mv2->flag & SCULPTVERT_ALL_BOUNDARY)) {
     bm_logstack_pop();
-    return;
+    return NULL;
   }
 
   int uvidx = pbvh->bm->ldata.typemap[CD_MLOOPUV];
@@ -3572,11 +3609,11 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     can sometimes let bad edges through*/
   if ((mv1->flag & SCULPTVERT_SHARP_BOUNDARY) && (e->head.hflag & BM_ELEM_SMOOTH)) {
     bm_logstack_pop();
-    return;
+    return NULL;
   }
   if ((mv1->flag & SCULPTVERT_SEAM_BOUNDARY) && !(e->head.hflag & BM_ELEM_SEAM)) {
     bm_logstack_pop();
-    return;
+    return NULL;
   }
 
   bool snap = !(mv2->flag & SCULPTVERT_ALL_CORNER);
@@ -3879,7 +3916,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 
   if (!v_conn) {
     bm_logstack_pop();
-    return;
+    return NULL;
   }
 
   MSculptVert *mv_conn = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, v_conn);
@@ -3959,16 +3996,10 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     printf("%s: error\n", __func__);
   }
 
-  for (int i = 0; i < 3; i++) {
-    if (!check_for_fins(pbvh, v_conn)) {
-      break;
-    }
-  }
-
   if (wasbad) {
     fix_mesh(pbvh, pbvh->bm);
     bm_logstack_pop();
-    return;
+    return NULL;
   }
 
 #if 0
@@ -3988,6 +4019,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   validate_vert_faces(pbvh, pbvh->bm, v_conn, false, true);
 
   bm_logstack_pop();
+
+  return v_conn;
 }
 
 static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
@@ -3995,6 +4028,9 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
                                             BLI_Buffer *deleted_faces,
                                             int max_steps)
 {
+
+  bm_log_message("  == collapse edges == ");
+
   if (pbvh->dyntopo_stop) {
     return false;
   }
@@ -4012,6 +4048,8 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
 #endif
 
   int step = 0;
+  BMVert **checkvs = NULL;
+  BLI_array_declare(checkvs);
 
   while (!BLI_heapsimple_is_empty(eq_ctx->q->heap)) {
     if (step++ > max_steps) {
@@ -4083,7 +4121,12 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
     any_collapsed = true;
 
     eq_ctx->q->limit_len_squared = limit_len_squared;
-    pbvh_bmesh_collapse_edge(pbvh, e, v1, v2, deleted_verts, deleted_faces, eq_ctx);
+    BMVert *v_conn = pbvh_bmesh_collapse_edge(
+        pbvh, e, v1, v2, deleted_verts, deleted_faces, eq_ctx);
+
+    if (v_conn) {
+      BLI_array_append(checkvs, v_conn);
+    }
 
 #ifdef TEST_COLLAPSE
     if (_i++ > 10) {
@@ -4092,24 +4135,19 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
 #endif
   }
 
-#if !defined(DYNTOPO_USE_HEAP) && defined(USE_EDGEQUEUE_TAG)
-  for (int i = 0; i < eq_ctx->q->totelems; i++) {
-    BMVert **pair = eq_ctx->q->elems[i];
-    BMVert *v1 = pair[0], *v2 = pair[1];
+  // add log subentry
+ 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list