From 07a959067d5a3c05fcbd65105525d6e139be5c5f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Jan 2020 22:20:45 +1100 Subject: Fix T72667: Collection delete hierarchy in edit-mode crashes Also resolves T72848, although updating multiple windows doesn't work, this matches 2.7x behavior. --- .../blender/draw/engines/overlay/overlay_engine.c | 2 +- source/blender/draw/intern/draw_cache_extract.h | 1 + .../blender/draw/intern/draw_cache_extract_mesh.c | 6 ++-- source/blender/draw/intern/draw_cache_impl_mesh.c | 32 +++++++++++++++++++--- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index fe39b8580e3..50e2589c7e3 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -185,7 +185,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) const bool is_select = DRW_state_is_select(); const bool renderable = DRW_object_is_renderable(ob); const bool in_pose_mode = ob->type == OB_ARMATURE && OVERLAY_armature_is_pose_mode(ob, draw_ctx); - const bool in_edit_mode = BKE_object_is_in_editmode(ob); + const bool in_edit_mode = (ob->mode & OB_MODE_EDIT) && BKE_object_is_in_editmode(ob); const bool in_particle_edit_mode = ob->mode == OB_MODE_PARTICLE_EDIT; const bool in_paint_mode = (ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT); diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index 8c3777a9b1b..2d10199782b 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -253,6 +253,7 @@ typedef struct MeshBatchCache { void mesh_buffer_cache_create_requested(MeshBatchCache *cache, MeshBufferCache mbc, Mesh *me, + const bool is_editmode, const float obmat[4][4], const bool do_final, const bool do_uvedit, diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index cce1710423b..e43c45a953d 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -128,6 +128,7 @@ typedef struct MeshRenderData { } MeshRenderData; static MeshRenderData *mesh_render_data_create(Mesh *me, + const bool is_editmode, const float obmat[4][4], const bool do_final, const bool do_uvedit, @@ -145,7 +146,7 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0; const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI; - if (me->edit_mesh) { + if (is_editmode) { BLI_assert(me->edit_mesh->mesh_eval_cage && me->edit_mesh->mesh_eval_final); mr->bm = me->edit_mesh->bm; mr->edit_bmesh = me->edit_mesh; @@ -4378,6 +4379,7 @@ static void extract_task_create(TaskPool *task_pool, void mesh_buffer_cache_create_requested(MeshBatchCache *cache, MeshBufferCache mbc, Mesh *me, + const bool is_editmode, const float obmat[4][4], const bool do_final, const bool do_uvedit, @@ -4439,7 +4441,7 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache, #endif MeshRenderData *mr = mesh_render_data_create( - me, obmat, do_final, do_uvedit, iter_flag, data_flag, cd_layer_used, ts); + me, is_editmode, obmat, do_final, do_uvedit, iter_flag, data_flag, cd_layer_used, ts); mr->cache = cache; /* HACK */ mr->use_hide = use_hide; mr->use_subsurf_fdots = use_subsurf_fdots; diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 31f4bec7226..abff8911697 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -1064,6 +1064,19 @@ void DRW_mesh_batch_cache_create_requested( return; } + /* Sanity check. */ + if ((me->edit_mesh != NULL) && (ob->mode & OB_MODE_EDIT)) { + BLI_assert(me->edit_mesh->mesh_eval_final != NULL); + } + + const bool is_editmode = + (me->edit_mesh != NULL) && + (/* Simple case, the object is in edit-mode with an edit-mesh. */ + (ob->mode & OB_MODE_EDIT) || + /* This is needed so linked duplicates show updates while the user edits the mesh. + * While this is not essential, it's useful to see the edit-mode changes everywhere. */ + (me->edit_mesh->mesh_eval_final != NULL)); + DRWBatchFlag batch_requested = cache->batch_requested; cache->batch_requested = 0; @@ -1200,10 +1213,10 @@ void DRW_mesh_batch_cache_create_requested( cache->batch_ready |= batch_requested; - const bool do_cage = (me->edit_mesh && + const bool do_cage = (is_editmode && (me->edit_mesh->mesh_eval_final != me->edit_mesh->mesh_eval_cage)); - const bool do_uvcage = me->edit_mesh && !me->edit_mesh->mesh_eval_final->runtime.is_original; + const bool do_uvcage = is_editmode && !me->edit_mesh->mesh_eval_final->runtime.is_original; MeshBufferCache *mbufcache = &cache->final; @@ -1398,14 +1411,24 @@ void DRW_mesh_batch_cache_create_requested( const bool use_subsurf_fdots = scene ? modifiers_usesSubsurfFacedots((Scene *)scene, ob) : false; if (do_uvcage) { - mesh_buffer_cache_create_requested( - cache, cache->uv_cage, me, ob->obmat, false, true, false, &cache->cd_used, ts, true); + mesh_buffer_cache_create_requested(cache, + cache->uv_cage, + me, + is_editmode, + ob->obmat, + false, + true, + false, + &cache->cd_used, + ts, + true); } if (do_cage) { mesh_buffer_cache_create_requested(cache, cache->cage, me, + is_editmode, ob->obmat, false, false, @@ -1418,6 +1441,7 @@ void DRW_mesh_batch_cache_create_requested( mesh_buffer_cache_create_requested(cache, cache->final, me, + is_editmode, ob->obmat, true, false, -- cgit v1.2.3