[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