From 2c1a44d1f061f8f4b859a91545dd9037ff381140 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Wed, 14 Jun 2023 20:18:28 -0700 Subject: [PATCH 1/2] 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 a0693bc1877..3ac085c2220 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -865,7 +865,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 5a1421c48d2..e8a3050d560 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1978,8 +1978,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(); @@ -1991,8 +1994,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 6c40df47574..f63ccb4509a 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -784,7 +784,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; @@ -1404,8 +1404,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 1583cabd98e..a4bf3899fcd 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -5889,8 +5889,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 c9962bb04e4..ad8efd86d91 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -2199,7 +2199,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 430ad30258a..74738cad543 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); @@ -651,7 +651,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) { @@ -1410,7 +1410,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 9be8af9f37a..5159a3b5ea0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -618,10 +618,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; From f0cd966750e3e503dd4a8738e7a9979125b03318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Thu, 15 Jun 2023 05:44:09 +0200 Subject: [PATCH 2/2] Fix #100485: Alembic export crash with names containing a forward slash As Alembic stores hierarchies as paths separated by a forward slash, such character cannot be used in a name. This resulted in an uncaught thrown exception. To fix this, replace '/' with '_' like for other illegal characters. --- source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc index d7d6858a04c..6e7597de6eb 100644 --- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc +++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc @@ -84,6 +84,7 @@ std::string ABCHierarchyIterator::make_valid_name(const std::string &name) const std::replace(abc_name.begin(), abc_name.end(), ' ', '_'); std::replace(abc_name.begin(), abc_name.end(), '.', '_'); std::replace(abc_name.begin(), abc_name.end(), ':', '_'); + std::replace(abc_name.begin(), abc_name.end(), '/', '_'); return abc_name; }