Blender  V2.93
select_draw_utils.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2019, Blender Foundation.
17  */
18 
25 #include "BKE_editmesh.h"
26 #include "BKE_mesh.h"
27 #include "BKE_object.h"
28 
29 #include "DNA_mesh_types.h"
30 #include "DNA_scene_types.h"
31 
32 #include "ED_view3d.h"
33 
34 #include "DEG_depsgraph.h"
35 #include "DEG_depsgraph_query.h"
36 
37 #include "DRW_select_buffer.h"
38 
39 #include "draw_cache_impl.h"
40 
41 #include "select_private.h"
42 
43 /* -------------------------------------------------------------------- */
47 void select_id_object_min_max(Object *obj, float r_min[3], float r_max[3])
48 {
49  BoundBox *bb;
51  if (em) {
53  }
54  else {
55  bb = BKE_object_boundbox_get(obj);
56  }
57  copy_v3_v3(r_min, bb->vec[0]);
58  copy_v3_v3(r_max, bb->vec[6]);
59 }
60 
62 {
63  short r_select_mode = 0;
65  /* In order to sample flat colors for vertex weights / texture-paint / vertex-paint
66  * we need to be in SCE_SELECT_FACE mode so select_cache_init() correctly sets up
67  * a shgroup with select_id_flat.
68  * Note this is not working correctly for vertex-paint (yet), but has been discussed
69  * in T66645 and there is a solution by @mano-wii in P1032.
70  * So OB_MODE_VERTEX_PAINT is already included here [required for P1032 I guess]. */
71  Mesh *me_orig = DEG_get_original_object(ob)->data;
72  if (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) {
73  r_select_mode = SCE_SELECT_VERTEX;
74  }
75  else {
76  r_select_mode = SCE_SELECT_FACE;
77  }
78  }
79  else {
80  r_select_mode = scene->toolsettings->selectmode;
81  }
82 
83  return r_select_mode;
84 }
85 
86 static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, eDrawType dt)
87 {
88  if (select_mode & SCE_SELECT_FACE) {
89  if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) {
90  return true;
91  }
93  return true;
94  }
95  }
96  return false;
97 }
98 
100  Object *ob,
101  short select_mode,
102  bool draw_facedot,
103  uint initial_offset,
104  uint *r_vert_offset,
105  uint *r_edge_offset,
106  uint *r_face_offset)
107 {
108  Mesh *me = ob->data;
109  BMEditMesh *em = me->edit_mesh;
110 
112 
113  if (select_mode & SCE_SELECT_FACE) {
116  DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset);
117  DRW_shgroup_call_no_cull(face_shgrp, geom_faces, ob);
118 
119  if (draw_facedot) {
121  DRW_shgroup_call_no_cull(face_shgrp, geom_facedots, ob);
122  }
123  *r_face_offset = initial_offset + em->bm->totface;
124  }
125  else {
126  if (ob->dt >= OB_SOLID) {
127 #ifdef USE_CAGE_OCCLUSION
129 #else
130  struct GPUBatch *geom_faces = DRW_mesh_batch_cache_get_surface(me);
131 #endif
132  DRWShadingGroup *face_shgrp = stl->g_data->shgrp_face_unif;
133  DRW_shgroup_call_no_cull(face_shgrp, geom_faces, ob);
134  }
135  *r_face_offset = initial_offset;
136  }
137 
138  /* Unlike faces, only draw edges if edge select mode. */
139  if (select_mode & SCE_SELECT_EDGE) {
142  DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset);
143  DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob);
144  *r_edge_offset = *r_face_offset + em->bm->totedge;
145  }
146  else {
147  /* Note that `r_vert_offset` is calculated from `r_edge_offset`.
148  * Otherwise the first vertex is never selected, see: T53512. */
149  *r_edge_offset = *r_face_offset;
150  }
151 
152  /* Unlike faces, only verts if vert select mode. */
153  if (select_mode & SCE_SELECT_VERTEX) {
156  DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *(int *)r_edge_offset);
157  DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob);
158  *r_vert_offset = *r_edge_offset + em->bm->totvert;
159  }
160  else {
161  *r_vert_offset = *r_edge_offset;
162  }
163 }
164 
166  Object *ob,
167  short select_mode,
168  uint initial_offset,
169  uint *r_vert_offset,
170  uint *r_edge_offset,
171  uint *r_face_offset)
172 {
173  Mesh *me = ob->data;
174 
176  DRWShadingGroup *face_shgrp;
177  if (select_mode & SCE_SELECT_FACE) {
178  face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_flat);
179  DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset);
180  *r_face_offset = initial_offset + me->totpoly;
181  }
182  else {
183  /* Only draw faces to mask out verts, we don't want their selection ID's. */
184  face_shgrp = stl->g_data->shgrp_face_unif;
185  *r_face_offset = initial_offset;
186  }
187  DRW_shgroup_call_no_cull(face_shgrp, geom_faces, ob);
188 
189  if (select_mode & SCE_SELECT_EDGE) {
192  DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset);
193  DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob);
194  *r_edge_offset = *r_face_offset + me->totedge;
195  }
196  else {
197  *r_edge_offset = *r_face_offset;
198  }
199 
200  if (select_mode & SCE_SELECT_VERTEX) {
203  DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *r_edge_offset);
204  DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob);
205  *r_vert_offset = *r_edge_offset + me->totvert;
206  }
207  else {
208  *r_vert_offset = *r_edge_offset;
209  }
210 }
211 
212 void select_id_draw_object(void *vedata,
213  View3D *v3d,
214  Object *ob,
215  short select_mode,
216  uint initial_offset,
217  uint *r_vert_offset,
218  uint *r_edge_offset,
219  uint *r_face_offset)
220 {
221  SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl;
222 
223  BLI_assert(initial_offset > 0);
224 
225  switch (ob->type) {
226  case OB_MESH:
227  if (ob->mode & OB_MODE_EDIT) {
228  bool draw_facedot = check_ob_drawface_dot(select_mode, v3d, ob->dt);
230  ob,
231  select_mode,
232  draw_facedot,
233  initial_offset,
234  r_vert_offset,
235  r_edge_offset,
236  r_face_offset);
237  }
238  else {
240  stl, ob, select_mode, initial_offset, r_vert_offset, r_edge_offset, r_face_offset);
241  }
242  break;
243  case OB_CURVE:
244  case OB_SURF:
245  break;
246  }
247 }
248 
251 #undef SELECT_ENGINE
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
Definition: editmesh.c:85
struct BoundBox * BKE_editmesh_cage_boundbox_get(BMEditMesh *em)
Definition: editmesh.c:294
General operations, lookup, etc. for blender objects.
struct BoundBox * BKE_object_boundbox_get(struct Object *ob)
Definition: object.c:3817
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE void copy_v3_v3(float r[3], const float a[3])
unsigned int uint
Definition: BLI_sys_types.h:83
struct Object * DEG_get_original_object(struct Object *object)
@ ME_EDIT_PAINT_VERT_SEL
eDrawType
@ OB_SOLID
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_VERTEX_PAINT
@ OB_SURF
@ OB_MESH
@ OB_CURVE
#define SCE_SELECT_FACE
#define SCE_SELECT_VERTEX
#define SCE_SELECT_EDGE
@ V3D_OVERLAY_EDIT_FACE_DOT
#define DRW_shgroup_call_no_cull(shgroup, geom, ob)
Definition: DRW_render.h:433
#define XRAY_FLAG_ENABLED(v3d)
Definition: ED_view3d.h:709
GPUBatch
Definition: GPU_batch.h:93
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.c:2276
Scene scene
struct GPUBatch * DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me)
struct GPUBatch * DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me)
struct GPUBatch * DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me)
struct GPUBatch * DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me)
struct GPUBatch * DRW_mesh_batch_cache_get_surface(struct Mesh *me)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, eDrawType dt)
short select_id_get_object_select_mode(Scene *scene, Object *ob)
static void draw_select_id_edit_mesh(SELECTID_StorageList *stl, Object *ob, short select_mode, bool draw_facedot, uint initial_offset, uint *r_vert_offset, uint *r_edge_offset, uint *r_face_offset)
void select_id_object_min_max(Object *obj, float r_min[3], float r_max[3])
void select_id_draw_object(void *vedata, View3D *v3d, Object *ob, short select_mode, uint initial_offset, uint *r_vert_offset, uint *r_edge_offset, uint *r_face_offset)
static void draw_select_id_mesh(SELECTID_StorageList *stl, Object *ob, short select_mode, uint initial_offset, uint *r_vert_offset, uint *r_edge_offset, uint *r_face_offset)
struct BMesh * bm
Definition: BKE_editmesh.h:52
int totvert
Definition: bmesh_class.h:297
int totedge
Definition: bmesh_class.h:297
int totface
Definition: bmesh_class.h:297
float vec[8][3]
struct BMEditMesh * edit_mesh
int totedge
char editflag
int totvert
int totpoly
void * data
DRWShadingGroup * shgrp_face_unif
DRWShadingGroup * shgrp_edge
DRWShadingGroup * shgrp_face_flat
DRWShadingGroup * shgrp_vert
struct SELECTID_PrivateData * g_data
struct ToolSettings * toolsettings
View3DOverlay overlay