More fixes for sculpt vertex color undo. Moved one of the undo pushes
outside a thread, since dyntopo undo is not thread safe.
This commit is contained in:
parent
093e29f3c2
commit
1014b6f455
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue