diff options
author | Bastien Montagne <bastien@blender.org> | 2020-12-29 16:43:12 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2021-01-06 18:25:39 +0300 |
commit | 6672cbeb236444541037e728759792b1208df0da (patch) | |
tree | 9b5248e4566a601673fcc538e007d2e6f549795a /source/blender/blenkernel/intern/paint.c | |
parent | a584aef4703aeefe0843f3b8aa2c1e863f825aef (diff) |
Fix T84202: Sculpt lasso mask crash after remesh.
'Caused'/revealed by rBd29a720c45e5: Operators that fully re-create the
mesh would previously rely on `sculpt_update_object` called from update
code to get required sculpt-specific data layers re-added to the new
mesh.
Now instead put all code adding data to orig mesh for sculpt purpose
into a new util function (`BKE_sculpt_ensure_orig_mesh_data`), and call
that function when entering sculpt mode, and from voxel remesher code.
This is contonuing effort to more clearly separate orig data from evaluated
data handling/usage in sculpt code.
TODO: there are likely other code paths that would need to call that
new function?
Reviewers: @sergey, @pablodp606
Subscribers:
Diffstat (limited to 'source/blender/blenkernel/intern/paint.c')
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 7c2fc40d537..4eecf3a3a87 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -2021,6 +2021,51 @@ void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *su BKE_sculpt_sync_face_sets_visibility_to_grids(mesh, subdiv_ccg); } +/** + * Ensures we do have expected mesh data in original mesh for the sculpt mode. + * + * \note IDs are expected to be original ones here, and calling code should ensure it updates its + * depsgraph properly after calling this function if it needs up-to-date evaluated data. + */ +void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object) +{ + Mesh *mesh = BKE_mesh_from_object(object); + MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, object); + + BLI_assert(object->mode == OB_MODE_SCULPT); + + /* Copy the current mesh visibility to the Face Sets. */ + BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(mesh); + if (object->sculpt != NULL) { + /* If a sculpt session is active, ensure we have its faceset data porperly up-to-date. */ + object->sculpt->face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS); + + /* Note: In theory we could add that on the fly when required by sculpt code. + * But this then requires proper update of depsgraph etc. For now we play safe, optimization is + * always possible later if it's worth it. */ + BKE_sculpt_mask_layers_ensure(object, mmd); + } + + /* Tessfaces aren't used and will become invalid. */ + BKE_mesh_tessface_clear(mesh); + + /* We always need to flush updates from depsgraph here, since at the very least + * `BKE_sculpt_face_sets_ensure_from_base_mesh_visibility()` will have updated some data layer of + * the mesh. + * + * All known potential sources of updates: + * - Addition of, or changes to, the `CD_SCULPT_FACE_SETS` data layer + * (`BKE_sculpt_face_sets_ensure_from_base_mesh_visibility`). + * - Addition of a `CD_PAINT_MASK` data layer (`BKE_sculpt_mask_layers_ensure`). + * - Object has any active modifier (modifier stack can be different in Sculpt mode). + * - Multires: + * + Differences of subdiv levels between sculpt and object modes + * (`mmd->sculptlvl != mmd->lvl`). + * + Addition of a `CD_GRID_PAINT_MASK` data layer (`BKE_sculpt_mask_layers_ensure`). + */ + DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); +} + static PBVH *build_pbvh_for_dynamic_topology(Object *ob) { PBVH *pbvh = BKE_pbvh_new(); |