[Bf-blender-cvs] [019700583bb] temp_bmesh_multires: Sculpt dyntopo: undo bugfixes

Joseph Eagar noreply at git.blender.org
Fri Aug 27 11:01:26 CEST 2021


Commit: 019700583bb5bcd937957e3766011ea26d0612f9
Author: Joseph Eagar
Date:   Fri Aug 27 01:51:56 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB019700583bb5bcd937957e3766011ea26d0612f9

Sculpt dyntopo: undo bugfixes

* Fixed nasty undo bug related
  to now rewinding BMLogEntry subchains properly.
* Fixed bug in dyntopo collapse

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

M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/paint.c
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/bmesh/intern/bmesh_mesh_convert.c
M	source/blender/bmesh/intern/bmesh_mesh_convert.h
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.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 05a14219bc1..b8d170ca450 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -159,6 +159,7 @@ static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
 static void pbvh_split_edges(
     PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge, bool ignore_isolated_edges);
 void bm_log_message(const char *fmt, ...);
+void pbvh_bmesh_check_nodes_simple(PBVH *pbvh);
 
 static BMEdge *bmesh_edge_create_log(PBVH *pbvh, BMVert *v1, BMVert *v2, BMEdge *e_example)
 {
@@ -804,7 +805,7 @@ static void pbvh_bmesh_face_remove(
           else if (ensure_ownership_transfer && !BM_vert_face_count_is_equal(v, 1)) {
             pbvh_bmesh_vert_remove(pbvh, v);
 
-            f_node->flag |= PBVH_RebuildNodeVerts;
+            f_node->flag |= PBVH_RebuildNodeVerts | PBVH_UpdateOtherVerts;
             // printf("failed to find new_node\n");
           }
         }
@@ -2391,6 +2392,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   check_vert_fan_are_tris(pbvh, e->v1);
   check_vert_fan_are_tris(pbvh, e->v2);
 
+  // pbvh_bmesh_check_nodes_simple(pbvh);
+
   bm_log_message("  == collapse == ");
 
   // make sure origdata is up to date prior to interpolation
@@ -2440,6 +2443,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   /* Remove the merge vertex from the PBVH */
   pbvh_bmesh_vert_remove(pbvh, v_del);
 
+  // pbvh_bmesh_check_nodes_simple(pbvh);
+
   /* Remove all faces adjacent to the edge */
   BMLoop *l_adj;
   while ((l_adj = e->l)) {
@@ -2473,6 +2478,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     BM_face_kill(pbvh->bm, f_adj);
   }
 
+  // pbvh_bmesh_check_nodes_simple(pbvh);
+
   /* Kill the edge */
   BLI_assert(BM_edge_is_wire(e));
 
@@ -2553,6 +2560,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     //*/
   }
 
+  // pbvh_bmesh_check_nodes_simple(pbvh);
+
 #if 1
   BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
     BMFace *existing_face;
@@ -2601,6 +2610,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
       PBVHNode *n = pbvh_bmesh_node_from_face(pbvh, f);
       int ni = n - pbvh->nodes;
 
+      n->flag |= PBVH_UpdateOtherVerts;
+
       bm_edges_from_tri(pbvh, old_tri, e_tri);
       bm_edges_from_tri_example(pbvh, v_tri, e_tri);
 
@@ -2633,6 +2644,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   BM_LOOPS_OF_VERT_ITER_END;
 #endif
 
+  // pbvh_bmesh_check_nodes_simple(pbvh);
+
   /* Delete the tagged faces */
   for (int i = 0; i < (int)deleted_faces->count; i++) {
     BMFace *f_del = BLI_buffer_at(deleted_faces, BMFace *, i);
@@ -2729,12 +2742,41 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     mv_conn->flag |= DYNVERT_NEED_DISK_SORT | DYNVERT_NEED_VALENCE | DYNVERT_NEED_BOUNDARY;
   }
 
+  if (v_del->e) {
+    BMEdge *e = v_del->e;
+
+    do {
+      if (e->l) {
+        BMLoop *l = e->l;
+        do {
+          printf("error in collapse_edge\n");
+          int ni = BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset);
+
+          BM_log_face_removed(pbvh->bm_log, l->f);
+
+          if (ni >= 0) {
+            PBVHNode *node = pbvh->nodes + ni;
+            BLI_table_gset_remove(node->bm_faces, l->f, NULL);
+            BM_ELEM_CD_SET_INT(l->f, pbvh->cd_face_node_offset, DYNTOPO_NODE_NONE);
+          }
+          else {
+            printf("face did not have a node ref\n");
+          }
+        } while ((l = l->radial_next) != e->l);
+      }
+
+      e = BM_DISK_EDGE_NEXT(e, v_del);
+    } while (e != v_del->e);
+  }
+
   /* Delete v_del */
   pbvh_kill_vert(pbvh, v_del);
 
   BLI_array_free(ws);
   BLI_array_free(blocks);
   BLI_array_free(ls);
+
+  // pbvh_bmesh_check_nodes_simple(pbvh);
 }
 
 static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index be0dd435526..1c7a4303754 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -79,9 +79,11 @@
 
 #include "bmesh.h"
 
-// XXX todo: work our bad module cross ref
+// XXX todo: figure out bad cross module refs
 void SCULPT_dynamic_topology_sync_layers(Object *ob, Mesh *me);
 void SCULPT_on_sculptsession_bmesh_free(SculptSession *ss);
+void SCULPT_dyntopo_node_layers_add(SculptSession *ss);
+BMesh *SCULPT_dyntopo_empty_bmesh();
 
 static void palette_init_data(ID *id)
 {
@@ -1383,17 +1385,29 @@ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
 
   if (ss->bm) {
     if (ob->data) {
-      if (reorder && ss->bm_log) {
-        BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
-      }
+      Mesh *me = BKE_object_get_original_mesh(ob);
+
+      BM_mesh_bm_to_me(
+          NULL,
+          NULL,
+          ss->bm,
+          ob->data,
+          (&(struct BMeshToMeshParams){.calc_object_remap = false,
+#ifdef WHEN_GLOBAL_UNDO_WORKS
+
+                                       /*
+                                        for memfile undo steps we need to
+                                        save id and temporary layers
+                                       */
+                                       .copy_temp_cdlayers = true,
+                                       .copy_mesh_id_layers = true,
+                                       .cd_mask_extra = CD_MASK_MESH_ID | CD_MASK_DYNTOPO_VERT
+#else
+                                       .copy_temp_cdlayers = false,
+                                       .copy_mesh_id_layers = false
+#endif
 
-      BM_mesh_bm_to_me(NULL,
-                       NULL,
-                       ss->bm,
-                       ob->data,
-                       (&(struct BMeshToMeshParams){
-                           .calc_object_remap = false,
-                       }));
+          }));
     }
   }
 }
@@ -2254,6 +2268,46 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
     ob->sculpt->pbvh = pbvh;
   }
   else {
+#ifdef WHEN_GLOBAL_UNDO_WORKS
+    /*detect if we are loading from an undo memfile step*/
+    Mesh *mesh_orig = BKE_object_get_original_mesh(ob);
+    bool is_dyntopo = (mesh_orig->flag & ME_SCULPT_DYNAMIC_TOPOLOGY);
+
+    is_dyntopo = is_dyntopo && CustomData_has_layer(&mesh_orig->vdata, CD_MESH_ID);
+    is_dyntopo = is_dyntopo && CustomData_has_layer(&mesh_orig->edata, CD_MESH_ID);
+    is_dyntopo = is_dyntopo && CustomData_has_layer(&mesh_orig->pdata, CD_MESH_ID);
+
+    if (is_dyntopo) {
+      BMesh *bm = SCULPT_dyntopo_empty_bmesh();
+
+      ob->sculpt->bm = bm;
+
+      BM_mesh_bm_from_me(NULL,
+                         bm,
+                         mesh_orig,
+                         (&(struct BMeshFromMeshParams){.calc_face_normal = true,
+                                                        .use_shapekey = true,
+                                                        .active_shapekey = ob->shapenr,
+                                                        .copy_id_layers = true,
+                                                        .copy_temp_cdlayers = true,
+                                                        .cd_mask_extra = CD_MASK_DYNTOPO_VERT}));
+
+      SCULPT_dyntopo_node_layers_add(ob->sculpt);
+
+      pbvh = build_pbvh_for_dynamic_topology(ob);
+    }
+    else {
+      Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
+      Mesh *mesh_eval = object_eval->data;
+      if (mesh_eval->runtime.subdiv_ccg != NULL) {
+        pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg, respect_hide);
+      }
+      else if (ob->type == OB_MESH) {
+        Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
+        pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
+      }
+    }
+#else
     Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
     Mesh *mesh_eval = object_eval->data;
     if (mesh_eval->runtime.subdiv_ccg != NULL) {
@@ -2263,6 +2317,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
       Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
       pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
     }
+#endif
   }
 
   ob->sculpt->pbvh = pbvh;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 84c45b7bafc..cbf95a035e0 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1418,7 +1418,9 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
 
         for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
           if (i >= node->tot_tri_buffers) {
-            printf("pbvh corruption!\n");
+            printf("node->tot_mat_draw_buffers >= node->tot_tri_buffers! %d %d\n",
+                   node->tot_mat_draw_buffers,
+                   node->tot_tri_buffers);
             continue;
           }
 
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index f8d16b2e7db..d8dadd707e2 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -70,6 +70,42 @@ Topology rake:
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <stdarg.h>
+
+static void _debugprint(const char *fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+  vprintf(fmt, args);
+  va_end(args);
+}
+
+void pbvh_bmesh_check_nodes_simple(PBVH *pbvh)
+{
+#if 0
+  for (int i = 0; i < pbvh->totnode; i++) {
+    PBVHNode *node = pbvh->nodes + i;
+    BMFace *f;
+
+    if (!(node->flag & PBVH_Leaf)) {
+      continue;
+    }
+
+    TGSET_ITER (f, node->bm_faces) {
+      if (!f || f->head.htype != BM_FACE) {
+        _debugprint("Corrupted (freed?) face in node->bm_faces\n");
+        continue;
+      }
+
+      if (BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != i) {
+        _debugprint("Face in more then one node\n");
+      }
+    }
+    TGSET_ITER_END;
+  }
+#endif
+}
+
 void pbvh_bmesh_check_nodes(PBVH *pbvh)
 {
 #if 0
@@ -88,11 +124,12 @@ void pbvh_bmesh_check_nodes(PBVH *pbvh)
     int ni = BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset);
 
     if (ni >= 0 && !v->e || !v->e->l) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list