[Bf-blender-cvs] [1014b6f4555] temp_bmesh_multires: More fixes for sculpt vertex color undo. Moved one of the undo pushes outside a thread, since dyntopo undo is not thread safe.

Joseph Eagar noreply at git.blender.org
Sat Oct 31 19:06:47 CET 2020


Commit: 1014b6f4555c220e522f87e4ade9e522f18fce2a
Author: Joseph Eagar
Date:   Sat Oct 31 11:06:15 2020 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB1014b6f4555c220e522f87e4ade9e522f18fce2a

More fixes for sculpt vertex color undo.  Moved one of the undo pushes
outside a thread, since dyntopo undo is not thread safe.

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 71c2b447d1f..81596fc10da 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -624,6 +624,8 @@ struct MVert *BKE_pbvh_get_verts(const PBVH *pbvh);
 PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node);
 void BKE_pbvh_node_color_buffer_free(PBVH *pbvh);
 
+int BKE_pbvh_get_node_index(PBVH *pbvh, PBVHNode *node);
+
 #define DYNTOPO_CD_INTERP
 
 #ifdef __cplusplus
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index d373f75b59c..102eaefc245 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -3153,6 +3153,10 @@ void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide)
   pbvh->respect_hide = respect_hide;
 }
 
+int BKE_pbvh_get_node_index(PBVH *pbvh, PBVHNode *node) {
+  return (int)(node - pbvh->nodes);
+}
+
 void BKE_pbvh_get_nodes(PBVH *pbvh, int flag, PBVHNode ***r_array, int *r_totnode)
 {
   BKE_pbvh_search_gather(pbvh, update_search_cb, POINTER_FROM_INT(flag), r_array, r_totnode);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 7ba722d05ab..5d19582f83d 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5770,15 +5770,10 @@ static void do_brush_action_task_cb(void *__restrict userdata,
     BKE_pbvh_node_mark_update_mask(data->nodes[n]);
   }
   else if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) {
-    // make sure we have at least one undo_color node
-    if (!ss->bm || SCULPT_stroke_is_first_brush_step(ss->cache)) {
+    if (!ss->bm) {  // this is thread safe for faces and grids pbvh?
       SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COLOR);
     }
 
-    if (ss->bm) {
-      BKE_pbvh_update_origcolor_bmesh(ss->pbvh, data->nodes[n]);
-    }
-
     BKE_pbvh_node_mark_update_color(data->nodes[n]);
   }
   else {
@@ -5889,6 +5884,15 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
         .nodes = nodes,
     };
 
+    // dyntopo can't push undo nodes inside a thread
+    if (ss->bm) {
+      for (int i = 0; i < totnode; i++) {
+        //SCULPT_ensure_dyntopo_node_undo(ob, nodes[i], SCULPT_UNDO_COLOR);
+        SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COLOR);
+        BKE_pbvh_update_origcolor_bmesh(ss->pbvh, nodes[i]);
+      }
+    }
+
     TaskParallelSettings settings;
     BKE_pbvh_parallel_range_settings(&settings, true, totnode);
     BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
@@ -7710,6 +7714,8 @@ bool all_nodes_callback(PBVHNode *node, void *data)
   return true;
 }
 
+void sculpt_undo_print_nodes(void *active);
+
 void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType update_flags)
 {
   /* After we are done drawing the stroke, check if we need to do a more
@@ -7762,12 +7768,12 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
 
   if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
     BKE_pbvh_bmesh_after_stroke(ss->pbvh);
-
+#if 0
     if (update_flags & SCULPT_UPDATE_COLOR) {
       PBVHNode **nodes;
       int totnode = 0;
 
-      //BKE_pbvh_get_nodes(ss->pbvh, PBVH_UpdateColor, &nodes, &totnode);
+      // BKE_pbvh_get_nodes(ss->pbvh, PBVH_UpdateColor, &nodes, &totnode);
       BKE_pbvh_search_gather(ss->pbvh, all_nodes_callback, NULL, &nodes, &totnode);
 
       for (int i = 0; i < totnode; i++) {
@@ -7778,6 +7784,9 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
         MEM_freeN(nodes);
       }
     }
+#endif
+
+    sculpt_undo_print_nodes(NULL);
   }
 
   if (update_flags & SCULPT_UPDATE_COLOR) {
@@ -7959,7 +7968,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
     SCULPT_undo_push_end();
 
     if (brush->sculpt_tool == SCULPT_TOOL_PAINT || brush->sculpt_tool == SCULPT_TOOL_SMEAR) {
-      SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS|SCULPT_UPDATE_COLOR);
+      SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS | SCULPT_UPDATE_COLOR);
     }
     else if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
       SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index ba9e11d6704..ea047265b8f 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -636,6 +636,9 @@ typedef struct SculptUndoNode {
   /* Sculpt Face Sets */
   int *face_sets;
 
+  bool *nodemap;
+  int nodemap_size;
+
   size_t undo_size;
 } SculptUndoNode;
 
@@ -1159,3 +1162,6 @@ void SCULPT_OT_set_detail_size(struct wmOperatorType *ot);
 
 /* Dyntopo. */
 void SCULPT_OT_dynamic_topology_toggle(struct wmOperatorType *ot);
+bool SCULPT_ensure_dyntopo_node_undo(struct Object *ob,
+                                     struct PBVHNode *node,
+                                     SculptUndoType type);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 14c18b0cca4..fdc9bcb0814 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -116,7 +116,7 @@ typedef struct UndoSculpt {
 } UndoSculpt;
 
 static UndoSculpt *sculpt_undo_get_nodes(void);
-static void sculpt_undo_print_nodes(void *active);
+void sculpt_undo_print_nodes(void *active);
 
 static void update_cb(PBVHNode *node, void *rebuild)
 {
@@ -599,7 +599,7 @@ static int sculpt_undo_bmesh_restore(bContext *C,
 {
   if (ss->bm_log) {
     BM_log_set_cd_offsets(
-      ss->bm_log, ss->cd_origco_offset, ss->cd_origno_offset, ss->cd_origvcol_offset);
+        ss->bm_log, ss->cd_origco_offset, ss->cd_origno_offset, ss->cd_origvcol_offset);
   }
 
   switch (unode->type) {
@@ -846,6 +846,9 @@ static void sculpt_undo_free_list(ListBase *lb)
     if (unode->co) {
       MEM_freeN(unode->co);
     }
+    if (unode->nodemap) {
+      MEM_freeN(unode->nodemap);
+    }
     if (unode->no) {
       MEM_freeN(unode->no);
     }
@@ -1240,7 +1243,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
         {
           void *dummy;
           BKE_pbvh_bmesh_update_origvert(ss->pbvh, vd.bm_vert, &dummy, &dummy, &dummy);
-          //BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset, false);
+          // BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset, false);
         }
         BKE_pbvh_vertex_iter_end;
         break;
@@ -1284,12 +1287,49 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
   }
 
   if (new_node) {
-    // sculpt_undo_print_nodes(NULL);
+    sculpt_undo_print_nodes(NULL);
   }
 
   return unode;
 }
 
+bool SCULPT_ensure_dyntopo_node_undo(Object *ob, PBVHNode *node, SculptUndoType type)
+{
+  SculptSession *ss = ob->sculpt;
+  UndoSculpt *usculpt = sculpt_undo_get_nodes();
+  SculptUndoNode *unode = usculpt->nodes.first;
+
+  if (!unode || unode->type != type) {
+    sculpt_undo_bmesh_push(ob, node, type);
+    SCULPT_ensure_dyntopo_node_undo(ob, node, type);
+    return true;
+  }
+
+  int n = BKE_pbvh_get_node_index(ss->pbvh, node);
+
+  if (unode->nodemap_size <= n) {
+    int newsize = (n + 1) * 2;
+
+    if (!unode->nodemap) {
+      unode->nodemap = MEM_callocN(sizeof(*unode->nodemap) * newsize, "unode->nodemap");
+    }
+    else {
+      unode->nodemap = MEM_recallocN(unode->nodemap, sizeof(*unode->nodemap) * newsize);
+    }
+
+    unode->nodemap_size = newsize;
+  }
+
+  if (unode->nodemap[n]) {
+    return false;
+  }
+
+  unode->nodemap[n] = 1;
+  sculpt_undo_bmesh_push(ob, node, type);
+
+  return true;
+}
+
 SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
 {
   SculptSession *ss = ob->sculpt;
@@ -1469,7 +1509,7 @@ static void sculpt_undosys_step_decode_undo_impl(struct bContext *C,
   sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
   us->step.is_applied = false;
 
-  // sculpt_undo_print_nodes(us);
+  sculpt_undo_print_nodes(us);
 }
 
 static void sculpt_undosys_step_decode_redo_impl(struct bContext *C,
@@ -1480,7 +1520,7 @@ static void sculpt_undosys_step_decode_redo_impl(struct bContext *C,
   sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
   us->step.is_applied = true;
 
-  // sculpt_undo_print_nodes(us);
+  sculpt_undo_print_nodes(us);
 }
 
 static void sculpt_undosys_step_decode_undo(struct bContext *C,
@@ -1737,8 +1777,9 @@ static char *undo_type_to_str(int type)
 
 static int nodeidgen = 1;
 
-static void sculpt_undo_print_nodes(void *active)
+void sculpt_undo_print_nodes(void *active)
 {
+#if 0
   UndoStack *ustack = ED_undo_stack_get();
   UndoStep *us = ustack->steps.first;
   if (active == NULL) {
@@ -1771,12 +1812,14 @@ static void sculpt_undo_print_nodes(void *active)
       UndoSculpt *usculpt = sculpt_undosys_step_get_nodes(us);
 
       for (node = usculpt->nodes.first; node; node = node->next) {
-        printf("    %s:%s {applied=%d bm_entry=%p}\n",
+        printf("    %s:%s {applied=%d bm_entry=%p node=%p}\n",
                undo_type_to_str(node->type),
                node->idname,
                node->applied,
-               node->bm_entry);
+               node->bm_entry,
+               node->node);
       }
     }
   }
+#endif
 }



More information about the Bf-blender-cvs mailing list