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:
authorBastien Montagne <bastien@blender.org>2020-12-23 14:19:45 +0300
committerBastien Montagne <bastien@blender.org>2020-12-23 18:03:42 +0300
commitd29a720c45e55047e4f0e02df4652ba03a49c528 (patch)
treed229f47bfbc93f333ad3928515e3463c2750fb0d /source/blender/blenkernel/intern/paint.c
parent9d04fa39d13b75b207fa7ab0315cb7731ecfff06 (diff)
Fix T84002: Sculpt: Masking operations crash if multires is in play.
This fixes the main issue there (essentially a followup to rB90e12e823ff0: Fix T81854: crash when undoing switch between sculpt and edit mode). We basically remove more (hopefully all the remaining!) modifications of orig mesh from `sculpt_update_object`, as those done here will not be immediately available in the evaluated data (that specific bug happened because masking data was added to orig mesh there, but not flushed to depsgraph evaluated one). This also goes towards a better separation between handling of evaluated data and orig one. Note that modification of orig mesh data can still happen, e.g. values in some cdlayers, but at least all pointers should now be valid in the evaluated mesh. There are still some issues, e.g. we now get an assert/crash in `multires_reshape_assign_final_coords_from_ccg` when undoing out of the Sculpt mode, presumably because subdiv_ccg data remains unchanged then (and hence still has the `has_mask` flag set), while actual mesh data do not have that cdlayer anymore... This commit also cleans up/simplifies some code, `ED_object_sculptmode_enter_ex` was (indirectly) calling `BKE_sculpt_face_sets_ensure_from_base_mesh_visibility` twice e.g.
Diffstat (limited to 'source/blender/blenkernel/intern/paint.c')
-rw-r--r--source/blender/blenkernel/intern/paint.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d726a4b1e37..7c2fc40d537 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1596,7 +1596,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
Scene *scene = DEG_get_input_scene(depsgraph);
Sculpt *sd = scene->toolsettings->sculpt;
SculptSession *ss = ob->sculpt;
- Mesh *me = BKE_object_get_original_mesh(ob);
+ const Mesh *me = BKE_object_get_original_mesh(ob);
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
@@ -1612,20 +1612,13 @@ static void sculpt_update_object(Depsgraph *depsgraph,
if (need_mask) {
if (mmd == NULL) {
- if (!CustomData_has_layer(&me->vdata, CD_PAINT_MASK)) {
- BKE_sculpt_mask_layers_ensure(ob, NULL);
- }
+ BLI_assert(CustomData_has_layer(&me->vdata, CD_PAINT_MASK));
}
else {
- if (!CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
- BKE_sculpt_mask_layers_ensure(ob, mmd);
- }
+ BLI_assert(CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK));
}
}
- /* tessfaces aren't used and will become invalid */
- BKE_mesh_tessface_clear(me);
-
ss->shapekey_active = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL;
/* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
@@ -1660,12 +1653,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
/* Sculpt Face Sets. */
if (use_face_sets) {
- if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
- /* By checking here if the data-layer already exist this avoids copying the visibility from
- * the mesh and looping over all vertices on every sculpt editing operation, using this
- * function only the first time the Face Sets data-layer needs to be created. */
- BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(me);
- }
+ BLI_assert(CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS));
ss->face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
}
else {
@@ -1928,6 +1916,10 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
return deformed;
}
+/**
+ * Ensures that a Face Set data-layers exists. If it does not, it creates one respecting the
+ * visibility stored in the vertices of the mesh. If it does, it copies the visibility from the
+ * mesh to the Face Sets. */
void BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(Mesh *mesh)
{
const int face_sets_default_visible_id = 1;