From 89c762dd991c64fa46803b3459a2197e25b6138a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 9 Jul 2019 12:12:18 +0200 Subject: Fix T57652: Multires undo broken with shared object data --- source/blender/blenkernel/BKE_multires.h | 4 +++- source/blender/blenkernel/intern/multires.c | 14 +++++++++++--- source/blender/editors/sculpt_paint/paint_hide.c | 7 ++++--- source/blender/editors/sculpt_paint/paint_mask.c | 6 +++--- source/blender/editors/sculpt_paint/sculpt.c | 4 +--- source/blender/editors/sculpt_paint/sculpt_undo.c | 4 ++-- 6 files changed, 24 insertions(+), 15 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 33672b5d397..c5955a9af8d 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -49,7 +49,9 @@ void multires_customdata_delete(struct Mesh *me); void multires_set_tot_level(struct Object *ob, struct MultiresModifierData *mmd, int lvl); -void multires_mark_as_modified(struct Object *ob, enum MultiresModifiedFlags flags); +void multires_mark_as_modified(struct Depsgraph *depsgraph, + struct Object *object, + enum MultiresModifiedFlags flags); void multires_force_update(struct Object *ob); void multires_force_render_update(struct Object *ob); diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 17d6b623b33..29337ca9985 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -385,12 +385,20 @@ static void multires_ccg_mark_as_modified(SubdivCCG *subdiv_ccg, MultiresModifie } } -void multires_mark_as_modified(Object *ob, MultiresModifiedFlags flags) +void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresModifiedFlags flags) { - if (ob == NULL) { + if (object == NULL) { return; } - Mesh *mesh = ob->data; + /* NOTE: CCG live inside of evaluated object. + * + * While this is a bit weird to tag the only one, this is how other areas were built + * historically: they are tagging multires for update and then rely on object re-evaluation to + * do an actual update. + * + * In a longer term maybe special dependency graph tag can help sanitizing this a bit. */ + Object *object_eval = DEG_get_evaluated_object(depsgraph, object); + Mesh *mesh = object_eval->data; SubdivCCG *subdiv_ccg = mesh->runtime.subdiv_ccg; if (subdiv_ccg == NULL) { return; diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index dded9fcf45a..d7e1b47d973 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -126,7 +126,8 @@ static void partialvis_update_mesh(Object *ob, /* Hide or show elements in multires grids with a special GridFlags * customdata layer. */ -static void partialvis_update_grids(Object *ob, +static void partialvis_update_grids(Depsgraph *depsgraph, + Object *ob, PBVH *pbvh, PBVHNode *node, PartialVisAction action, @@ -208,7 +209,7 @@ static void partialvis_update_grids(Object *ob, if (any_changed) { BKE_pbvh_node_mark_rebuild_draw(node); BKE_pbvh_node_fully_hidden_set(node, !any_visible); - multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED); + multires_mark_as_modified(depsgraph, ob, MULTIRES_HIDDEN_MODIFIED); } } @@ -378,7 +379,7 @@ static int hide_show_exec(bContext *C, wmOperator *op) partialvis_update_mesh(ob, pbvh, nodes[i], action, area, clip_planes); break; case PBVH_GRIDS: - partialvis_update_grids(ob, pbvh, nodes[i], action, area, clip_planes); + partialvis_update_grids(depsgraph, ob, pbvh, nodes[i], action, area, clip_planes); break; case PBVH_BMESH: partialvis_update_bmesh(ob, pbvh, nodes[i], action, area, clip_planes); diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 0dd2e8ee968..f60ea8410ef 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -167,7 +167,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) 0, totnode, &data, mask_flood_fill_task_cb, &settings); if (multires) { - multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); + multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); } sculpt_undo_push_end(); @@ -341,7 +341,7 @@ bool ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti * } if (multires) { - multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); + multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); } sculpt_undo_push_end(); @@ -528,7 +528,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) } if (multires) { - multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); + multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); } sculpt_undo_push_end(); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index ec7cb410f2c..173d6ed5085 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5186,15 +5186,13 @@ static void sculpt_flush_update_step(bContext *C) { Depsgraph *depsgraph = CTX_data_depsgraph(C); Object *ob = CTX_data_active_object(C); - Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); SculptSession *ss = ob->sculpt; ARegion *ar = CTX_wm_region(C); MultiresModifierData *mmd = ss->multires; View3D *v3d = CTX_wm_view3d(C); if (mmd != NULL) { - /* NOTE: SubdivCCG is living in the evaluated object. */ - multires_mark_as_modified(ob_eval, MULTIRES_COORDS_MODIFIED); + multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); } DEG_id_tag_update(&ob->id, ID_RECALC_SHADING); diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 8c8d4487ada..a20fe375ec7 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -554,10 +554,10 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) if (BKE_sculpt_multires_active(scene, ob)) { if (rebuild) { - multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED); + multires_mark_as_modified(depsgraph, ob, MULTIRES_HIDDEN_MODIFIED); } else { - multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); + multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); } } -- cgit v1.2.3