[Bf-blender-cvs] [8a6414ed46f] master: Fix T54686: objects don't occlude each other for edit-mesh select

mano-wii noreply at git.blender.org
Thu May 16 01:37:18 CEST 2019


Commit: 8a6414ed46f669ede106b3ffbe48f74b47718e11
Author: mano-wii
Date:   Thu May 16 09:26:33 2019 +1000
Branches: master
https://developer.blender.org/rB8a6414ed46f669ede106b3ffbe48f74b47718e11

Fix T54686: objects don't occlude each other for edit-mesh select

===================================================================

M	source/blender/draw/DRW_engine.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/include/ED_mesh.h
M	source/blender/editors/mesh/CMakeLists.txt
M	source/blender/editors/mesh/editface.c
M	source/blender/editors/mesh/editmesh_loopcut.c
M	source/blender/editors/mesh/editmesh_select.c
M	source/blender/editors/mesh/meshtools.c
M	source/blender/editors/sculpt_paint/paint_utils.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/editors/space_view3d/view3d_draw_legacy.c
M	source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
M	source/blender/editors/space_view3d/view3d_intern.h
M	source/blender/editors/space_view3d/view3d_select.c

===================================================================

diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index cb75a965ef7..5919e100ddd 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -38,6 +38,7 @@ struct IDProperty;
 struct Main;
 struct Material;
 struct Object;
+struct RegionView3D;
 struct RenderEngine;
 struct RenderEngineType;
 struct Scene;
@@ -135,6 +136,15 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
 void DRW_draw_depth_object(struct ARegion *ar,
                            struct GPUViewport *viewport,
                            struct Object *object);
+void DRW_draw_select_id_object(struct Scene *scene,
+                               struct RegionView3D *rv3d,
+                               struct Object *ob,
+                               short select_mode,
+                               bool draw_facedot,
+                               uint initial_offset,
+                               uint *r_vert_offset,
+                               uint *r_edge_offset,
+                               uint *r_face_offset);
 
 void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
 void DRW_framebuffer_select_id_release(struct ARegion *ar);
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_CU

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list