Blender V4.3
select_draw_utils.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "BKE_editmesh.hh"
12#include "BKE_mesh.hh"
13#include "BKE_object.hh"
14
15#include "DNA_mesh_types.h"
16#include "DNA_scene_types.h"
17
18#include "ED_view3d.hh"
19
20#include "DEG_depsgraph.hh"
22
23#include "DRW_select_buffer.hh"
24
25#include "draw_cache_impl.hh"
26
27#include "select_private.hh"
28
29/* -------------------------------------------------------------------- */
34{
35 short r_select_mode = 0;
37 /* In order to sample flat colors for vertex weights / texture-paint / vertex-paint
38 * we need to be in SCE_SELECT_FACE mode so select_cache_init() correctly sets up
39 * a shgroup with select_id_flat.
40 * Note this is not working correctly for vertex-paint (yet), but has been discussed
41 * in #66645 and there is a solution by @mano-wii in P1032.
42 * So OB_MODE_VERTEX_PAINT is already included here [required for P1032 I guess]. */
43 Mesh *me_orig = static_cast<Mesh *>(DEG_get_original_object(ob)->data);
44 if (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) {
45 r_select_mode = SCE_SELECT_VERTEX;
46 }
47 else {
48 r_select_mode = SCE_SELECT_FACE;
49 }
50 }
51 else {
52 r_select_mode = scene->toolsettings->selectmode;
53 }
54
55 return r_select_mode;
56}
57
58static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, eDrawType dt)
59{
60 if (select_mode & SCE_SELECT_FACE) {
61 if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) {
62 return true;
63 }
65 return true;
66 }
67 }
68 return false;
69}
70
72 Object *ob,
73 short select_mode,
74 bool draw_facedot,
75 uint initial_offset,
76 uint *r_vert_offset,
77 uint *r_edge_offset,
78 uint *r_face_offset)
79{
80 using namespace blender::draw;
81 Mesh &mesh = *static_cast<Mesh *>(ob->data);
82 BMEditMesh *em = mesh.runtime->edit_mesh.get();
83
85
86 if (select_mode & SCE_SELECT_FACE) {
87 blender::gpu::Batch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(mesh);
89 DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset);
90 DRW_shgroup_call_no_cull(face_shgrp, geom_faces, ob);
91
92 if (draw_facedot) {
93 blender::gpu::Batch *geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(mesh);
94 DRW_shgroup_call_no_cull(face_shgrp, geom_facedots, ob);
95 }
96 *r_face_offset = initial_offset + em->bm->totface;
97 }
98 else {
99 if (ob->dt >= OB_SOLID) {
100#ifdef USE_CAGE_OCCLUSION
101 blender::gpu::Batch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(mesh);
102#else
103 struct blender::gpu::Batch *geom_faces = DRW_mesh_batch_cache_get_surface(mesh);
104#endif
105 DRWShadingGroup *face_shgrp = stl->g_data->shgrp_face_unif;
106 DRW_shgroup_call_no_cull(face_shgrp, geom_faces, ob);
107 }
108 *r_face_offset = initial_offset;
109 }
110
111 /* Unlike faces, only draw edges if edge select mode. */
112 if (select_mode & SCE_SELECT_EDGE) {
113 blender::gpu::Batch *geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(mesh);
115 DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset);
116 DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob);
117 *r_edge_offset = *r_face_offset + em->bm->totedge;
118 }
119 else {
120 /* Note that `r_vert_offset` is calculated from `r_edge_offset`.
121 * Otherwise the first vertex is never selected, see: #53512. */
122 *r_edge_offset = *r_face_offset;
123 }
124
125 /* Unlike faces, only verts if vert select mode. */
126 if (select_mode & SCE_SELECT_VERTEX) {
127 blender::gpu::Batch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(mesh);
129 DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *(int *)r_edge_offset);
130 DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob);
131 *r_vert_offset = *r_edge_offset + em->bm->totvert;
132 }
133 else {
134 *r_vert_offset = *r_edge_offset;
135 }
136}
137
139 Object *ob,
140 short select_mode,
141 uint initial_offset,
142 uint *r_vert_offset,
143 uint *r_edge_offset,
144 uint *r_face_offset)
145{
146 using namespace blender::draw;
147 Mesh &mesh = *static_cast<Mesh *>(ob->data);
148
149 blender::gpu::Batch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(mesh);
150 DRWShadingGroup *face_shgrp;
151 if (select_mode & SCE_SELECT_FACE) {
153 DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset);
154 *r_face_offset = initial_offset + mesh.faces_num;
155 }
156 else {
157 /* Only draw faces to mask out verts, we don't want their selection ID's. */
158 face_shgrp = stl->g_data->shgrp_face_unif;
159 *r_face_offset = initial_offset;
160 }
161 DRW_shgroup_call_no_cull(face_shgrp, geom_faces, ob);
162
163 if (select_mode & SCE_SELECT_EDGE) {
164 blender::gpu::Batch *geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(mesh);
166 DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset);
167 DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob);
168 *r_edge_offset = *r_face_offset + mesh.edges_num;
169 }
170 else {
171 *r_edge_offset = *r_face_offset;
172 }
173
174 if (select_mode & SCE_SELECT_VERTEX) {
175 blender::gpu::Batch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(mesh);
177 DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *r_edge_offset);
178 DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob);
179 *r_vert_offset = *r_edge_offset + mesh.verts_num;
180 }
181 else {
182 *r_vert_offset = *r_edge_offset;
183 }
184}
185
186void select_id_draw_object(void *vedata,
187 View3D *v3d,
188 Object *ob,
189 short select_mode,
190 uint initial_offset,
191 uint *r_vert_offset,
192 uint *r_edge_offset,
193 uint *r_face_offset)
194{
195 SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl;
196
197 BLI_assert(initial_offset > 0);
198
199 switch (ob->type) {
200 case OB_MESH:
201 if (ob->mode & OB_MODE_EDIT) {
202 bool draw_facedot = check_ob_drawface_dot(select_mode, v3d, eDrawType(ob->dt));
204 ob,
205 select_mode,
206 draw_facedot,
207 initial_offset,
208 r_vert_offset,
209 r_edge_offset,
210 r_face_offset);
211 }
212 else {
214 stl, ob, select_mode, initial_offset, r_vert_offset, r_edge_offset, r_face_offset);
215 }
216 break;
217 case OB_CURVES_LEGACY:
218 case OB_SURF:
219 break;
220 }
221}
222
225#undef SELECT_ENGINE
General operations, lookup, etc. for blender objects.
#define BLI_assert(a)
Definition BLI_assert.h:50
unsigned int uint
Object * DEG_get_original_object(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_CURVES_LEGACY
@ SCE_SELECT_FACE
@ SCE_SELECT_VERTEX
@ SCE_SELECT_EDGE
@ V3D_OVERLAY_EDIT_FACE_DOT
#define DRW_shgroup_call_no_cull(shgroup, geom, ob)
#define XRAY_FLAG_ENABLED(v3d)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
#define BM_FACE
#define BM_EDGE
#define BM_VERT
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
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_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)
int totvert
int totedge
int totface
char editflag
DRWShadingGroup * shgrp_face_unif
DRWShadingGroup * shgrp_edge
DRWShadingGroup * shgrp_face_flat
DRWShadingGroup * shgrp_vert
struct SELECTID_PrivateData * g_data
View3DOverlay overlay