Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_undo.c')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c171
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)) {