From 136fcec288d74bd16a114f71fbbac51db467aee6 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Wed, 14 Jun 2023 20:18:28 -0700 Subject: [PATCH] Sculpt: Fix #108267: Broken face set undo BKE_sculpt_face_sets_ensure now takes an Object as an argument and updates the internal PBVH's face sets pointer. --- source/blender/blenkernel/BKE_paint.h | 2 +- source/blender/blenkernel/intern/paint.cc | 13 +++++++++++-- source/blender/editors/sculpt_paint/paint_mask.cc | 5 ++--- source/blender/editors/sculpt_paint/sculpt.cc | 3 +-- .../blender/editors/sculpt_paint/sculpt_expand.cc | 2 +- .../blender/editors/sculpt_paint/sculpt_face_set.cc | 6 +++--- source/blender/editors/sculpt_paint/sculpt_undo.cc | 3 +-- 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index a67d836b058..ac552846753 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -877,7 +877,7 @@ void BKE_sculpt_update_object_after_eval(struct Depsgraph *depsgraph, struct Obj */ struct MultiresModifierData *BKE_sculpt_multires_active(const struct Scene *scene, struct Object *ob); -int *BKE_sculpt_face_sets_ensure(struct Mesh *mesh); +int *BKE_sculpt_face_sets_ensure(struct Object *ob); /** * Create the attribute used to store face visibility and retrieve its data. * Note that changes to the face visibility have to be propagated to other domains diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 7238f7f18ac..a5f7cb3c553 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1977,8 +1977,11 @@ void BKE_sculpt_update_object_for_edit( sculpt_update_object(depsgraph, ob_orig, ob_eval, need_pmap, is_paint_tool); } -int *BKE_sculpt_face_sets_ensure(Mesh *mesh) +int *BKE_sculpt_face_sets_ensure(Object *ob) { + SculptSession *ss = ob->sculpt; + Mesh *mesh = static_cast(ob->data); + using namespace blender; using namespace blender::bke; MutableAttributeAccessor attributes = mesh->attributes_for_write(); @@ -1990,8 +1993,14 @@ int *BKE_sculpt_face_sets_ensure(Mesh *mesh) face_sets.finish(); } - return static_cast(CustomData_get_layer_named_for_write( + int *face_sets = static_cast(CustomData_get_layer_named_for_write( &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly)); + + if (ss->pbvh && ELEM(BKE_pbvh_type(ss->pbvh), PBVH_FACES, PBVH_GRIDS)) { + BKE_pbvh_face_sets_set(ss->pbvh, face_sets); + } + + return face_sets; } bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh) diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index 8e398d83811..2aa3101d2e1 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -785,7 +785,7 @@ static void sculpt_gesture_init_face_set_properties(SculptGestureContext *sgcont sgcontext->operation = reinterpret_cast( MEM_cnew(__func__)); - sgcontext->ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); + sgcontext->ss->face_sets = BKE_sculpt_face_sets_ensure(sgcontext->vc.obact); SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) sgcontext->operation; @@ -1405,8 +1405,7 @@ static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgconte { Object *object = sgcontext->vc.obact; SculptSession *ss = object->sculpt; - Mesh *mesh = (Mesh *)object->data; - ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); + ss->face_sets = BKE_sculpt_face_sets_ensure(object); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); sculpt_gesture_trim_calculate_depth(sgcontext); diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 720b76a7c98..0966bdc1eb2 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -5882,8 +5882,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent BKE_sculpt_mask_layers_ensure(CTX_data_depsgraph_pointer(C), CTX_data_main(C), ob, mmd); } if (SCULPT_tool_is_face_sets(brush->sculpt_tool)) { - Mesh *mesh = BKE_object_get_original_mesh(ob); - ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); + ss->face_sets = BKE_sculpt_face_sets_ensure(ob); } stroke = paint_stroke_new(C, diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index 729198acfe4..345e93e01a0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -2197,7 +2197,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even Mesh *mesh = static_cast(ob->data); if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_FACE_SETS) { - ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); + ss->face_sets = BKE_sculpt_face_sets_ensure(ob); } /* Face Set operations are not supported in dyntopo. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 1e00a6ee9ee..1b5e449b080 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -344,8 +344,8 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + ss->face_sets = BKE_sculpt_face_sets_ensure(ob); Mesh *mesh = static_cast(ob->data); - ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); BKE_sculpt_update_object_for_edit(depsgraph, ob, true, mode == SCULPT_FACE_SET_MASKED, false); @@ -636,7 +636,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) const float threshold = RNA_float_get(op->ptr, "threshold"); Mesh *mesh = static_cast(ob->data); - ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); + ss->face_sets = BKE_sculpt_face_sets_ensure(ob); const bke::AttributeAccessor attributes = mesh->attributes(); switch (mode) { @@ -1387,7 +1387,7 @@ static bool sculpt_face_set_edit_init(bContext *C, wmOperator *op) return false; } - ss->face_sets = BKE_sculpt_face_sets_ensure(BKE_mesh_from_object(ob)); + ss->face_sets = BKE_sculpt_face_sets_ensure(ob); BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); return true; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index c649fa77561..4e22fc90642 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -619,10 +619,9 @@ static bool sculpt_undo_restore_face_sets(bContext *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); SculptSession *ss = ob->sculpt; - ss->face_sets = BKE_sculpt_face_sets_ensure(me); + ss->face_sets = BKE_sculpt_face_sets_ensure(ob); BKE_pbvh_face_sets_set(ss->pbvh, ss->face_sets); bool modified = false;