BMesh: remove BMEditMesh.ob pointer

Remove this pointer since it's linking Mesh data back to the object,
where a single edit-mesh may have multiple object users,
causing incorrect assumptions in the code.

Resolves dangling pointer part of the T72667 crash,
although there are other issues which still need to be fixed.

In EDBM_op_finish and EDBM_update_generic,
full Main lookups have been added which should be replaced with mesh
argument or the update tagging moved elsewhere.
This commit is contained in:
Campbell Barton
2020-01-07 17:38:16 +11:00
parent 1ef59d0eb5
commit 11292edba6
6 changed files with 24 additions and 18 deletions

View File

@@ -35,6 +35,7 @@ struct Depsgraph;
struct EditMeshData;
struct Mesh;
struct MeshStatVis;
struct Object;
struct Scene;
/**
@@ -70,9 +71,6 @@ typedef struct BMEditMesh {
short selectmode;
short mat_nr;
/* Object this editmesh came from (if it came from one) */
struct Object *ob;
/*temp variables for x-mirror editing*/
int mirror_cdlayer; /* -1 is invalid */

View File

@@ -1839,7 +1839,7 @@ static void editbmesh_build_data(struct Depsgraph *depsgraph,
BMEditMesh *em,
CustomData_MeshMasks *dataMask)
{
BLI_assert(em->ob->id.tag & LIB_TAG_COPIED_ON_WRITE);
BLI_assert(obedit->id.tag & LIB_TAG_COPIED_ON_WRITE);
BKE_object_free_derived_caches(obedit);
if (DEG_is_active(depsgraph)) {

View File

@@ -163,9 +163,6 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
BMEditMesh *em = (ob->mode & OB_MODE_EDIT) ? BKE_editmesh_from_object(ob) : NULL;
#else
BMEditMesh *em = (ob->mode & OB_MODE_EDIT) ? ((Mesh *)ob->data)->edit_mesh : NULL;
if (em && em->ob != ob) {
em = NULL;
}
#endif
CustomData_MeshMasks cddata_masks = scene->customdata_mask;

View File

@@ -610,7 +610,7 @@ void update_lattice_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
lt_cow->editlatt = lt_orig->editlatt;
}
void update_mesh_edit_mode_pointers(const Depsgraph *depsgraph, const ID *id_orig, ID *id_cow)
void update_mesh_edit_mode_pointers(const ID *id_orig, ID *id_cow)
{
/* For meshes we need to update edit_mesh to make it to point
* to the CoW version of object.
@@ -624,7 +624,6 @@ void update_mesh_edit_mode_pointers(const Depsgraph *depsgraph, const ID *id_ori
return;
}
mesh_cow->edit_mesh = (BMEditMesh *)MEM_dupallocN(mesh_orig->edit_mesh);
mesh_cow->edit_mesh->ob = (Object *)depsgraph->get_cow_id(&mesh_orig->edit_mesh->ob->id);
mesh_cow->edit_mesh->mesh_eval_cage = NULL;
mesh_cow->edit_mesh->mesh_eval_final = NULL;
}
@@ -639,7 +638,7 @@ void update_edit_mode_pointers(const Depsgraph *depsgraph, const ID *id_orig, ID
update_armature_edit_mode_pointers(depsgraph, id_orig, id_cow);
break;
case ID_ME:
update_mesh_edit_mode_pointers(depsgraph, id_orig, id_cow);
update_mesh_edit_mode_pointers(id_orig, id_cow);
break;
case ID_CU:
update_curve_edit_mode_pointers(depsgraph, id_orig, id_cow);

View File

@@ -605,7 +605,6 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em, Key *
em->selectmode = um->selectmode;
bm->selectmode = um->selectmode;
em->ob = ob;
bm->spacearr_dirty = BM_SPACEARR_DIRTY_ALL;

View File

@@ -41,6 +41,7 @@
#include "BKE_report.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_bvh.h"
#include "BKE_global.h"
#include "DEG_depsgraph.h"
@@ -166,8 +167,15 @@ bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool
BKE_editmesh_looptri_calc(em);
}
if (em->ob) {
DEG_id_tag_update(&((Mesh *)em->ob->data)->id, ID_RECALC_COPY_ON_WRITE);
{
/* FIXME: pass in mesh. */
Main *bmain = G_MAIN;
for (Mesh *mesh = bmain->meshes.first; mesh; mesh = mesh->id.next) {
if (mesh->edit_mesh == em) {
DEG_id_tag_update(&mesh->id, ID_RECALC_COPY_ON_WRITE);
break;
}
}
}
return false;
@@ -316,7 +324,6 @@ void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
me->edit_mesh->selectmode = me->edit_mesh->bm->selectmode = select_mode;
me->edit_mesh->mat_nr = (ob->actcol > 0) ? ob->actcol - 1 : 0;
me->edit_mesh->ob = ob;
/* we need to flush selection because the mode may have changed from when last in editmode */
EDBM_selectmode_flush(me->edit_mesh);
@@ -1416,10 +1423,16 @@ void EDBM_stats_update(BMEditMesh *em)
*/
void EDBM_update_generic(BMEditMesh *em, const bool do_tessellation, const bool is_destructive)
{
Object *ob = em->ob;
/* order of calling isn't important */
DEG_id_tag_update(ob->data, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, ob->data);
/* FIXME: pass in mesh. */
Main *bmain = G_MAIN;
for (Mesh *mesh = bmain->meshes.first; mesh; mesh = mesh->id.next) {
if (mesh->edit_mesh == em) {
/* Order of calling isn't important. */
DEG_id_tag_update(&mesh->id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, &mesh->id);
break;
}
}
if (do_tessellation) {
BKE_editmesh_looptri_calc(em);