diff options
author | mano-wii <germano.costa@ig.com.br> | 2019-05-16 02:26:33 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-05-16 02:36:15 +0300 |
commit | 8a6414ed46f669ede106b3ffbe48f74b47718e11 (patch) | |
tree | 2aec66bbcc3d42acd2f09ea4ef215c3993300f7d /source/blender/draw/intern | |
parent | 989d8543853c422fb555411bfd8fffc46d9a070b (diff) |
Fix T54686: objects don't occlude each other for edit-mesh select
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 206 |
1 files changed, 205 insertions, 1 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 355046ae277..ca283e3a83a 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -34,6 +34,7 @@ #include "BKE_anim.h" #include "BKE_colortools.h" #include "BKE_curve.h" +#include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_gpencil.h" #include "BKE_lattice.h" @@ -2615,6 +2616,12 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph, DRW_opengl_context_disable(); } +/** See #DRW_shgroup_world_clip_planes_from_rv3d. */ +static void draw_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4]) +{ + GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]); +} + /** * Clears the Depth Buffer and draws only the specified object. */ @@ -2658,7 +2665,7 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object) GPU_SHADER_CFG_DEFAULT; GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg); if (world_clip_planes != NULL) { - GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]); + draw_world_clip_planes_from_rv3d(batch, world_clip_planes); } GPU_batch_draw(batch); @@ -2678,6 +2685,203 @@ void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object) DRW_opengl_context_disable(); } +static void draw_mesh_verts(GPUBatch *batch, int offset, const float world_clip_planes[6][4]) +{ + GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE)); + + const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : + GPU_SHADER_CFG_DEFAULT; + GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg); + GPU_batch_uniform_1ui(batch, "offset", offset); + if (world_clip_planes != NULL) { + draw_world_clip_planes_from_rv3d(batch, world_clip_planes); + } + GPU_batch_draw(batch); +} + +static void draw_mesh_edges(GPUBatch *batch, int offset, const float world_clip_planes[6][4]) +{ + GPU_line_width(1.0f); + glProvokingVertex(GL_FIRST_VERTEX_CONVENTION); + + const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : + GPU_SHADER_CFG_DEFAULT; + GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg); + GPU_batch_uniform_1ui(batch, "offset", offset); + if (world_clip_planes != NULL) { + draw_world_clip_planes_from_rv3d(batch, world_clip_planes); + } + GPU_batch_draw(batch); + + glProvokingVertex(GL_LAST_VERTEX_CONVENTION); +} + +/* two options, facecolors or black */ +static void draw_mesh_face(GPUBatch *batch, + int offset, + const bool use_select, + const float world_clip_planes[6][4]) +{ + if (use_select) { + const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : + GPU_SHADER_CFG_DEFAULT; + GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg); + GPU_batch_uniform_1ui(batch, "offset", offset); + if (world_clip_planes != NULL) { + draw_world_clip_planes_from_rv3d(batch, world_clip_planes); + } + GPU_batch_draw(batch); + } + else { + const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : + GPU_SHADER_CFG_DEFAULT; + GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_UNIFORM_SELECT_ID, sh_cfg); + GPU_batch_uniform_1ui(batch, "id", 0); + if (world_clip_planes != NULL) { + draw_world_clip_planes_from_rv3d(batch, world_clip_planes); + } + GPU_batch_draw(batch); + } +} + +static void draw_mesh_face_dot(GPUBatch *batch, int offset, const float world_clip_planes[6][4]) +{ + const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : + GPU_SHADER_CFG_DEFAULT; + GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_FLAT_SELECT_ID, sh_cfg); + GPU_batch_uniform_1ui(batch, "offset", offset); + if (world_clip_planes != NULL) { + draw_world_clip_planes_from_rv3d(batch, world_clip_planes); + } + GPU_batch_draw(batch); +} + +void DRW_draw_select_id_object(Scene *scene, + RegionView3D *rv3d, + Object *ob, + short select_mode, + bool draw_facedot, + uint initial_offset, + uint *r_vert_offset, + uint *r_edge_offset, + uint *r_face_offset) +{ + ToolSettings *ts = scene->toolsettings; + if (select_mode == -1) { + select_mode = ts->selectmode; + } + + GPU_matrix_mul(ob->obmat); + GPU_depth_test(true); + + const float(*world_clip_planes)[4] = NULL; + if (rv3d->rflag & RV3D_CLIPPING) { + ED_view3d_clipping_local(rv3d, ob->obmat); + world_clip_planes = rv3d->clip_local; + } + + initial_offset += 1; + + switch (ob->type) { + case OB_MESH: + if (ob->mode & OB_MODE_EDIT) { + Mesh *me = ob->data; + BMEditMesh *em = me->edit_mesh; + const bool use_faceselect = (select_mode & SCE_SELECT_FACE) != 0; + + DRW_mesh_batch_cache_validate(me); + + BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); + + GPUBatch *geom_faces, *geom_edges, *geom_verts, *geom_facedots; + geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me); + if (select_mode & SCE_SELECT_EDGE) { + geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me); + } + if (select_mode & SCE_SELECT_VERTEX) { + geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); + } + if (draw_facedot) { + geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me); + } + DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true); + + draw_mesh_face(geom_faces, initial_offset, use_faceselect, world_clip_planes); + + if (use_faceselect && draw_facedot) { + draw_mesh_face_dot(geom_facedots, initial_offset, world_clip_planes); + } + + if (select_mode & SCE_SELECT_FACE) { + *r_face_offset = initial_offset + em->bm->totface; + } + else { + *r_face_offset = initial_offset; + } + + ED_view3d_polygon_offset(rv3d, 1.0); + + /* Unlike faces, only draw edges if edge select mode. */ + if (select_mode & SCE_SELECT_EDGE) { + draw_mesh_edges(geom_edges, *r_face_offset, world_clip_planes); + *r_edge_offset = *r_face_offset + em->bm->totedge; + } + else { + /* Note that `r_vert_offset` is calculated from `r_edge_offset`. + * Otherwise the first vertex is never selected, see: T53512. */ + *r_edge_offset = *r_face_offset; + } + + ED_view3d_polygon_offset(rv3d, 1.1); + + /* Unlike faces, only verts if vert select mode. */ + if (select_mode & SCE_SELECT_VERTEX) { + draw_mesh_verts(geom_verts, *r_edge_offset, world_clip_planes); + *r_vert_offset = *r_edge_offset + em->bm->totvert; + } + else { + *r_vert_offset = *r_edge_offset; + } + + ED_view3d_polygon_offset(rv3d, 0.0); + } + else { + Mesh *me_orig = DEG_get_original_object(ob)->data; + Mesh *me_eval = ob->data; + + DRW_mesh_batch_cache_validate(me_eval); + GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me_eval); + if ((me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) && + /* Currently vertex select supports weight paint and vertex paint. */ + ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT))) { + + GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me_eval); + DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, true); + + /* Only draw faces to mask out verts, we don't want their selection ID's. */ + draw_mesh_face(geom_faces, 0, false, world_clip_planes); + draw_mesh_verts(geom_verts, 1, world_clip_planes); + + *r_vert_offset = me_eval->totvert + 1; + } + else { + const bool use_hide = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL); + DRW_mesh_batch_cache_create_requested(ob, me_eval, NULL, false, use_hide); + + draw_mesh_face(geom_faces, initial_offset, true, world_clip_planes); + + *r_face_offset = initial_offset + me_eval->totface; + } + } + break; + case OB_CURVE: + case OB_SURF: + break; + } + + GPU_matrix_set(rv3d->viewmat); +} + /* Set an opengl context to be used with shaders that draw on U32 colors. */ void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear) { |