diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_undo.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_undo.c | 171 |
1 files changed, 161 insertions, 10 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index af94cad88f3..eb92c865f18 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -56,7 +56,6 @@ #include "BKE_layer.h" #include "BKE_main.h" #include "BKE_mesh.h" -#include "BKE_mesh_mapping.h" #include "BKE_mesh_runtime.h" #include "BKE_multires.h" #include "BKE_object.h" @@ -82,6 +81,9 @@ #include "bmesh.h" #include "sculpt_intern.h" +/* Uncomment to print the undo stack in the console on push/undo/redo. */ +//#define SCULPT_UNDO_DEBUG + /* Implementation of undo system for objects in sculpt mode. * * Each undo step in sculpt mode consists of list of nodes, each node contains: @@ -148,11 +150,130 @@ typedef struct SculptUndoStep { SculptAttrRef active_color_end; bContext *C; + +#ifdef SCULPT_UNDO_DEBUG + int id; +#endif } SculptUndoStep; static UndoSculpt *sculpt_undo_get_nodes(void); static bool sculpt_attribute_ref_equals(SculptAttrRef *a, SculptAttrRef *b); static void sculpt_save_active_attribute(Object *ob, SculptAttrRef *attr); +static UndoSculpt *sculpt_undosys_step_get_nodes(UndoStep *us_p); + +#ifdef SCULPT_UNDO_DEBUG +# ifdef _ +# undef _ +# endif +# define _(type) \ + case type: \ + return #type; +static char *undo_type_to_str(int type) +{ + switch (type) { + _(SCULPT_UNDO_DYNTOPO_BEGIN) + _(SCULPT_UNDO_DYNTOPO_END) + _(SCULPT_UNDO_COORDS) + _(SCULPT_UNDO_GEOMETRY) + _(SCULPT_UNDO_DYNTOPO_SYMMETRIZE) + _(SCULPT_UNDO_FACE_SETS) + _(SCULPT_UNDO_HIDDEN) + _(SCULPT_UNDO_MASK) + _(SCULPT_UNDO_COLOR) + default: + return "unknown node type"; + } +} +# undef _ + +static int nodeidgen = 1; + +static void print_sculpt_node(Object *ob, SculptUndoNode *node) +{ + printf(" %s:%s {applied=%d}\n", undo_type_to_str(node->type), node->idname, node->applied); + + if (node->bm_entry) { + BM_log_print_entry(ob->sculpt ? ob->sculpt->bm : NULL, node->bm_entry); + } +} + +static void print_sculpt_undo_step(Object *ob, UndoStep *us, UndoStep *active, int i) +{ + SculptUndoNode *node; + + if (us->type != BKE_UNDOSYS_TYPE_SCULPT) { + printf("%d %s (non-sculpt): '%s', type:%s, use_memfile_step:%s\n", + i, + us == active ? "->" : " ", + us->name, + us->type->name, + us->use_memfile_step ? "true" : "false"); + return; + } + + int id = -1; + + SculptUndoStep *su = (SculptUndoStep *)us; + if (!su->id) { + su->id = nodeidgen++; + } + + id = su->id; + + printf("id=%d %s %d %s (use_memfile_step=%s)\n", + id, + us == active ? "->" : " ", + i, + us->name, + us->use_memfile_step ? "true" : "false"); + + if (us->type == BKE_UNDOSYS_TYPE_SCULPT) { + UndoSculpt *usculpt = sculpt_undosys_step_get_nodes(us); + + for (node = usculpt->nodes.first; node; node = node->next) { + print_sculpt_node(ob, node); + } + } +} +void sculpt_undo_print_nodes(Object *ob, void *active) +{ + + printf("=================== Sculpt undo steps ==============\n"); + + UndoStack *ustack = ED_undo_stack_get(); + UndoStep *us = ustack->steps.first; + if (active == NULL) { + active = ustack->step_active; + } + + if (!us) { + return; + } + + printf("\n"); + if (ustack->step_init) { + printf("===Undo initialization stepB===\n"); + print_sculpt_undo_step(ob, ustack->step_init, active, -1); + printf("===============\n"); + } + + int i = 0, act_i = -1; + for (; us; us = us->next, i++) { + if (active == us) { + act_i = i; + } + + print_sculpt_undo_step(ob, us, active, i); + } + + if (ustack->step_active) { + printf("\n\n==Active step:==\n"); + print_sculpt_undo_step(ob, ustack->step_active, active, act_i); + } +} +#else +# define sculpt_undo_print_nodes(ob, active) while (0) +#endif static void update_cb(PBVHNode *node, void *rebuild) { @@ -253,7 +374,9 @@ static bool sculpt_undo_restore_deformed( static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, SculptUndoNode *unode) { + const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); SculptSession *ss = ob->sculpt; SubdivCCG *subdiv_ccg = ss->subdiv_ccg; @@ -365,7 +488,9 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool *modified_vertices) { + const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); SculptSession *ss = ob->sculpt; SubdivCCG *subdiv_ccg = ss->subdiv_ccg; @@ -395,7 +520,9 @@ static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode, bool *modified_vertices) { + const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); SculptSession *ss = ob->sculpt; @@ -427,7 +554,9 @@ static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode, bool * static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *modified_vertices) { + const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); SculptSession *ss = ob->sculpt; SubdivCCG *subdiv_ccg = ss->subdiv_ccg; @@ -473,11 +602,18 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *m static bool sculpt_undo_restore_face_sets(bContext *C, SculptUndoNode *unode) { + const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); Mesh *me = BKE_object_get_original_mesh(ob); - int *face_sets = CustomData_add_layer( - &me->pdata, CD_SCULPT_FACE_SETS, CD_CONSTRUCT, NULL, me->totpoly); + + int *face_sets = CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, ".sculpt_face_set"); + if (!face_sets) { + face_sets = CustomData_add_layer_named( + &me->pdata, CD_PROP_INT32, CD_CONSTRUCT, NULL, me->totpoly, ".sculpt_face_set"); + } + for (int i = 0; i < me->totpoly; i++) { SWAP(int, face_sets[i], unode->face_sets[i]); } @@ -537,7 +673,7 @@ static void sculpt_undo_bmesh_enable(Object *ob, SculptUndoNode *unode) .use_toolflags = false, })); BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK); - SCULPT_dyntopo_node_layers_add(ss); + me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY; /* Restore the BMLog using saved entries. */ @@ -721,7 +857,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); + BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); SculptSession *ss = ob->sculpt; SubdivCCG *subdiv_ccg = ss->subdiv_ccg; @@ -729,8 +866,13 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase bool update = false, rebuild = false, update_mask = false, update_visibility = false; bool need_mask = false; bool need_refine_subdiv = false; + bool clear_automask_cache = false; for (unode = lb->first; unode; unode = unode->next) { + if (!ELEM(unode->type, SCULPT_UNDO_COLOR, SCULPT_UNDO_MASK)) { + clear_automask_cache = true; + } + /* Restore pivot. */ copy_v3_v3(ss->pivot_pos, unode->pivot_pos); copy_v3_v3(ss->pivot_rot, unode->pivot_rot); @@ -744,6 +886,10 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase } } + if (clear_automask_cache) { + ss->last_automasking_settings_hash = 0; + } + DEG_id_tag_update(&ob->id, ID_RECALC_SHADING); if (lb->first) { @@ -756,7 +902,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase BKE_sculpt_update_object_for_edit(depsgraph, ob, true, need_mask, false); - SCULPT_visibility_sync_all_face_sets_to_verts(ob); + SCULPT_visibility_sync_all_from_faces(ob); BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility); @@ -765,7 +911,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase } DEG_id_tag_update(&ob->id, ID_RECALC_SHADING); - if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) { + if (!BKE_sculptsession_use_pbvh_draw(ob, rv3d)) { DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); } @@ -912,7 +1058,6 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase } if (update_visibility) { - SCULPT_visibility_sync_all_vertex_to_face_sets(ss); BKE_pbvh_update_visibility(ss->pbvh); } @@ -925,7 +1070,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase } } - tag_update |= ID_REAL_USERS(ob->data) > 1 || !BKE_sculptsession_use_pbvh_draw(ob, v3d) || + tag_update |= ID_REAL_USERS(ob->data) > 1 || !BKE_sculptsession_use_pbvh_draw(ob, rv3d) || ss->shapekey_active || ss->deform_modifiers_active; if (tag_update) { @@ -1354,7 +1499,7 @@ static SculptUndoNode *sculpt_undo_face_sets_push(Object *ob, SculptUndoType typ unode->face_sets = MEM_callocN(me->totpoly * sizeof(int), "sculpt face sets"); - const int *face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS); + const int *face_sets = CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, ".sculpt_face_set"); if (face_sets) { for (int i = 0; i < me->totpoly; i++) { unode->face_sets[i] = face_sets[i]; @@ -1645,6 +1790,7 @@ void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo) ustack, BKE_UNDOSYS_TYPE_SCULPT); sculpt_save_active_attribute(ob, &us->active_color_end); + sculpt_undo_print_nodes(ob, NULL); } /* -------------------------------------------------------------------- */ @@ -1744,6 +1890,8 @@ 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(CTX_data_active_object(C), NULL); } static void sculpt_undosys_step_decode_redo_impl(struct bContext *C, @@ -1754,6 +1902,8 @@ 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(CTX_data_active_object(C), NULL); } static void sculpt_undosys_step_decode_undo(struct bContext *C, @@ -1823,6 +1973,7 @@ static void sculpt_undosys_step_decode( { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); if (ob && (ob->type == OB_MESH)) { if (ob->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT)) { |