diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-07-28 16:12:38 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-07-28 17:11:42 +0300 |
commit | 3e45f01494bcadc0f4d644f3c7d4b936b6553c9b (patch) | |
tree | c8510135c6725d564d40c8d8544529db9f458cf8 /source/blender | |
parent | c4cf14d16118183a3b1367489b3b4aa583adfc0b (diff) |
Fix T67385: Bind in Laplacian Deform Modifier with new vertex group in Edit Mode crashes Blender.
Main issue in that report was that meshes generated from
`mesh_create_eval_final_view()` and the like need some
special freeing handling (as, among other things, they borrow and do not
own their potential editmesh data...).
Factorized that into a helper func also used by
`BKE_object_free_derived_caches()`.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 10 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 2 |
4 files changed, 14 insertions, 9 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 54fbda1fa31..d6b4fa72281 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -123,6 +123,8 @@ struct Mesh *BKE_mesh_new_nomain_from_template(const struct Mesh *me_src, int loops_len, int polys_len); +void BKE_mesh_eval_delete(struct Mesh *me_eval); + /* Performs copy for use during evaluation, * optional referencing original arrays to reduce memory. */ struct Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index f5e93dcf9b7..9e01bfe62d6 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -697,6 +697,15 @@ Mesh *BKE_mesh_new_nomain_from_template(const Mesh *me_src, me_src, verts_len, edges_len, tessface_len, loops_len, polys_len, CD_MASK_EVERYTHING); } +void BKE_mesh_eval_delete(struct Mesh *mesh_eval) +{ + /* Evaluated mesh may point to edit mesh, but never owns it. */ + mesh_eval->edit_mesh = NULL; + BKE_mesh_free(mesh_eval); + BKE_libblock_free_data(&mesh_eval->id, false); + MEM_freeN(mesh_eval); +} + Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference) { int flags = LIB_ID_COPY_LOCALIZE; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d7256cc9604..69ba7ccab8e 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -442,19 +442,13 @@ void BKE_object_free_derived_caches(Object *ob) if (ob->runtime.mesh_eval != NULL) { if (ob->runtime.is_mesh_eval_owned) { Mesh *mesh_eval = ob->runtime.mesh_eval; - /* Evaluated mesh points to edit mesh, but does not own it. */ - mesh_eval->edit_mesh = NULL; - BKE_mesh_free(mesh_eval); - BKE_libblock_free_data(&mesh_eval->id, false); - MEM_freeN(mesh_eval); + BKE_mesh_eval_delete(mesh_eval); } ob->runtime.mesh_eval = NULL; } if (ob->runtime.mesh_deform_eval != NULL) { Mesh *mesh_deform_eval = ob->runtime.mesh_deform_eval; - BKE_mesh_free(mesh_deform_eval); - BKE_libblock_free_data(&mesh_deform_eval->id, false); - MEM_freeN(mesh_deform_eval); + BKE_mesh_eval_delete(mesh_deform_eval); ob->runtime.mesh_deform_eval = NULL; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 08012842c37..e72bf1ea10a 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -99,7 +99,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object * BKE_object_eval_reset(ob_eval); if (ob->type == OB_MESH) { Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); - BKE_id_free(NULL, me_eval); + BKE_mesh_eval_delete(me_eval); } else if (ob->type == OB_LATTICE) { BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval); |