From becf20e29f606cff01d2e6595572b86e734a01d4 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Wed, 29 Jul 2015 16:18:33 +0200 Subject: [PATCH] Fix T45605 crash with editmode selection on solidify modifier. Looks like derivedmesh draw code always assumed a mesh is available. Make sure that if we use a bmesh, a flag is used to control that. --- source/blender/blenkernel/BKE_DerivedMesh.h | 1 + .../blender/blenkernel/intern/cdderivedmesh.c | 24 ++++++++++++++++--- .../blender/editors/space_view3d/drawobject.c | 4 ++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 32baa452b4b..6b331980df5 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -151,6 +151,7 @@ typedef enum DMDrawFlag { DM_DRAW_USE_TEXPAINT_UV = (1 << 3), DM_DRAW_SKIP_HIDDEN = (1 << 4), DM_DRAW_SKIP_SELECT = (1 << 5), + DM_DRAW_SELECT_USE_EDITMODE = (1 << 6) } DMDrawFlag; typedef enum DMForeachFlag { diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 6a766037c8b..b5ff4f6ee5f 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -654,9 +654,15 @@ static void cdDM_drawMappedFaces( /* if we do selection, fill the selection buffer color */ if (G.f & G_BACKBUFSEL) { if (!(flag & DM_DRAW_SKIP_SELECT)) { - Mesh *me = userData; + Mesh *me = NULL; + BMesh *bm = NULL; unsigned int *fi_map; + if (flag & DM_DRAW_SELECT_USE_EDITMODE) + bm = userData; + else + me = userData; + findex_buffer = GPU_buffer_alloc(dm->drawObject->tot_loop_verts * sizeof(int), false); fi_map = GPU_buffer_lock(findex_buffer, GPU_BINDING_ARRAY); @@ -664,10 +670,22 @@ static void cdDM_drawMappedFaces( for (i = 0; i < totpoly; i++, mpoly++) { int selcol = 0xFFFFFFFF; const int orig = (index_mp_to_orig) ? index_mp_to_orig[i] : i; + bool is_hidden; - if ((orig != ORIGINDEX_NONE) && (!useHide || !(me->mpoly[orig].flag & ME_HIDE))) { - WM_framebuffer_index_get(orig + 1, &selcol); + if (useHide) { + if (flag & DM_DRAW_SELECT_USE_EDITMODE) { + BMFace *efa = BM_face_at_index(bm, orig); + is_hidden = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) != 0; + } + else { + is_hidden = (me->mpoly[orig].flag & ME_HIDE) != 0; + } + + if ((orig != ORIGINDEX_NONE) && !is_hidden) + WM_framebuffer_index_get(orig + 1, &selcol); } + else if (orig != ORIGINDEX_NONE) + WM_framebuffer_index_get(orig + 1, &selcol); for (j = 0; j < mpoly->totloop; j++) fi_map[start_element++] = selcol; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index fee68057646..f03b008762f 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -8445,7 +8445,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, cpack(0); if (use_faceselect) { - dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_HIDDEN); + dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_HIDDEN | DM_DRAW_SELECT_USE_EDITMODE); if (check_ob_drawface_dot(scene, v3d, ob->dt)) { glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE)); @@ -8457,7 +8457,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, } else { - dm->drawMappedFaces(dm, bbs_mesh_mask__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_SELECT | DM_DRAW_SKIP_HIDDEN); + dm->drawMappedFaces(dm, bbs_mesh_mask__setSolidDrawOptions, NULL, NULL, em->bm, DM_DRAW_SKIP_SELECT | DM_DRAW_SKIP_HIDDEN | DM_DRAW_SELECT_USE_EDITMODE); } }