Blender V4.3
overlay_grease_pencil.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "DRW_render.hh"
10
11#include "draw_manager_text.hh"
12
13#include "ED_grease_pencil.hh"
14
15#include "BKE_attribute.hh"
16#include "BKE_curves.hh"
17#include "BKE_grease_pencil.hh"
18
20
21#include "overlay_private.hh"
22
24
25static void is_selection_visible(bool &r_show_points, bool &r_show_lines)
26{
27 using namespace blender;
28
29 const DRWContextState *draw_ctx = DRW_context_state_get();
30 const ToolSettings *ts = draw_ctx->scene->toolsettings;
31 const bool in_sculpt_mode = (draw_ctx->object_mode & OB_MODE_SCULPT_GREASE_PENCIL) != 0;
32 const bool in_weight_mode = (draw_ctx->object_mode & OB_MODE_WEIGHT_GREASE_PENCIL) != 0;
33 const bool in_vertex_mode = (draw_ctx->object_mode & OB_MODE_VERTEX_GREASE_PENCIL) != 0;
34 const bool flag_show_lines = (draw_ctx->v3d->gp_flag & V3D_GP_SHOW_EDIT_LINES) != 0;
35
36 if (in_weight_mode) {
37 /* Always display points in weight mode. */
38 r_show_points = true;
39 r_show_lines = flag_show_lines;
40 return;
41 }
42
43 if (in_sculpt_mode) {
44 /* Sculpt selection modes are flags and can be disabled individually. */
45 static constexpr int sculpt_point_modes = GP_SCULPT_MASK_SELECTMODE_POINT |
47 r_show_points = (ts->gpencil_selectmode_sculpt & sculpt_point_modes) != 0;
48 r_show_lines = flag_show_lines && (ts->gpencil_selectmode_sculpt != 0);
49 return;
50 }
51
52 if (in_vertex_mode) {
53 /* Vertex selection modes are flags and can be disabled individually. */
54 static constexpr int vertex_point_modes = GP_VERTEX_MASK_SELECTMODE_POINT |
56 r_show_points = (ts->gpencil_selectmode_vertex & vertex_point_modes) != 0;
57 r_show_lines = flag_show_lines && (ts->gpencil_selectmode_vertex != 0);
58 return;
59 }
60
61 /* Edit selection modes are exclusive. */
63 r_show_lines = flag_show_lines;
64}
65
67 const int mat_nr,
68 const blender::float3 position)
69{
70 Material *ma = BKE_object_material_get_eval(&object, mat_nr + 1);
71 const DRWContextState *draw_ctx = DRW_context_state_get();
72 ViewLayer *view_layer = draw_ctx->view_layer;
73
74 int theme_id = DRW_object_wire_theme_get(&object, view_layer, nullptr);
75 uchar color[4];
76 UI_GetThemeColor4ubv(theme_id, color);
77
78 const float3 fpt = blender::math::transform_point(object.object_to_world(), position);
79
82 fpt,
83 ma->id.name + 2,
84 strlen(ma->id.name + 2),
85 10,
86 0,
88 color);
89}
90
92{
93 using namespace blender;
94
95 const DRWContextState *draw_ctx = DRW_context_state_get();
96
97 bool show_points = false;
98 bool show_lines = false;
99 is_selection_visible(show_points, show_lines);
100
101 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
102
104 *draw_ctx->scene, grease_pencil, false);
105 if (drawings.is_empty()) {
106 return;
107 }
108
109 for (const ed::greasepencil::DrawingInfo &info : drawings) {
110 const bke::greasepencil::Drawing &drawing = info.drawing;
111
112 const bke::CurvesGeometry strokes = drawing.strokes();
113 const OffsetIndices<int> points_by_curve = strokes.points_by_curve();
115 const VArray<bool> selections = *strokes.attributes().lookup_or_default<bool>(
116 ".selection", domain, true);
117 const VArray<int> materials = *strokes.attributes().lookup_or_default<int>(
118 "material_index", bke::AttrDomain::Curve, 0);
119 const Span<float3> positions = strokes.positions();
120
121 auto show_stroke_name = [&](const int stroke_i) {
122 if (show_points) {
123 for (const int point_i : points_by_curve[stroke_i]) {
124 if (selections[point_i]) {
125 return true;
126 }
127 }
128 return false;
129 }
130 return selections[stroke_i];
131 };
132
133 for (const int stroke_i : strokes.curves_range()) {
134 const int point_i = points_by_curve[stroke_i].first();
135 if (show_stroke_name(stroke_i)) {
136 overlay_grease_pencil_draw_stroke_color_name(*ob, materials[stroke_i], positions[point_i]);
137 }
138 }
139 }
140}
141
143{
144 using namespace blender;
145 OVERLAY_PassList *psl = vedata->psl;
146 OVERLAY_PrivateData *pd = vedata->stl->pd;
147 const DRWContextState *draw_ctx = DRW_context_state_get();
148 const bool use_weight = (draw_ctx->object_mode & OB_MODE_WEIGHT_GREASE_PENCIL) != 0;
149 View3D *v3d = draw_ctx->v3d;
150
151 GPUShader *sh;
152 DRWShadingGroup *grp;
153
157
158 bool show_points = false;
159 bool show_lines = false;
160 is_selection_visible(show_points, show_lines);
161
162 if (show_lines) {
165 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
166 DRW_shgroup_uniform_bool_copy(grp, "useWeight", use_weight);
167 DRW_shgroup_uniform_bool_copy(grp, "useGreasePencil", true);
168 DRW_shgroup_uniform_texture(grp, "weightTex", G_draw.weight_ramp);
169 }
170 else {
171 pd->edit_grease_pencil_wires_grp = nullptr;
172 }
173
174 if (show_points) {
177 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
178 DRW_shgroup_uniform_bool_copy(grp, "useWeight", use_weight);
179 DRW_shgroup_uniform_bool_copy(grp, "useGreasePencil", true);
180 DRW_shgroup_uniform_texture(grp, "weightTex", G_draw.weight_ramp);
181 const bool show_direction = (v3d->gp_flag & V3D_GP_SHOW_STROKE_DIRECTION) != 0;
182 DRW_shgroup_uniform_bool_copy(grp, "doStrokeEndpoints", show_direction);
183 }
184 else {
185 pd->edit_grease_pencil_points_grp = nullptr;
186 }
187}
188
190{
191 using namespace blender;
192 OVERLAY_PassList *psl = vedata->psl;
193 const DRWContextState *draw_ctx = DRW_context_state_get();
194 Scene *scene = draw_ctx->scene;
195 ToolSettings *ts = scene->toolsettings;
196 const View3D *v3d = draw_ctx->v3d;
197
198 GPUShader *sh;
199 DRWShadingGroup *grp;
200
201 /* Default: Display nothing. */
202 psl->grease_pencil_canvas_ps = nullptr;
203
204 Object *ob = draw_ctx->obact;
205 const bool show_overlays = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
206 const bool show_grid = (v3d->gp_flag & V3D_GP_SHOW_GRID) != 0 &&
207 ((ts->gpencil_v3d_align &
209 const bool grid_xray = (v3d->gp_flag & V3D_GP_SHOW_GRID_XRAY);
210
211 if (!ob || (ob->type != OB_GREASE_PENCIL) || !show_grid || !show_overlays) {
212 return;
213 }
214 const float3 base_color = float3(v3d->overlay.gpencil_grid_color);
215 const float4 col_grid = float4(base_color, v3d->overlay.gpencil_grid_opacity);
216
217 float4x4 mat = ob->object_to_world();
218
219 const GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
220 if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR && grease_pencil.has_active_layer()) {
221 const bke::greasepencil::Layer &layer = *grease_pencil.get_active_layer();
222 mat = layer.to_world_space(*ob);
223 }
224 const View3DCursor *cursor = &scene->cursor;
225
226 /* Set the grid in the selected axis */
227 switch (ts->gp_sculpt.lock_axis) {
228 case GP_LOCKAXIS_X:
229 std::swap(mat[0], mat[2]);
230 break;
231 case GP_LOCKAXIS_Y:
232 std::swap(mat[1], mat[2]);
233 break;
234 case GP_LOCKAXIS_Z:
235 /* Default. */
236 break;
237 case GP_LOCKAXIS_CURSOR: {
238 mat = float4x4(cursor->matrix<float3x3>());
239 break;
240 }
241 case GP_LOCKAXIS_VIEW:
242 /* view aligned */
243 DRW_view_viewmat_get(nullptr, mat.ptr(), true);
244 break;
245 }
246
248 mat.location() = cursor->location;
249 }
250
251 /* Note: This is here to match the legacy size. */
252 mat.view<3, 3>() *= 2.0f;
253
254 /* Local transform of the grid from the overlay settings. */
255 const float3 offset = float3(
257 const float3 scale = float3(
259 const float4x4 local_transform = math::from_loc_scale<float4x4>(offset, scale);
260 mat = mat * local_transform;
261
262 const int gridlines = v3d->overlay.gpencil_grid_subdivisions;
263 const int line_count = gridlines * 4 + 2;
264
267
269
272 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
273 DRW_shgroup_uniform_vec4_copy(grp, "color", col_grid);
274 DRW_shgroup_uniform_vec3_copy(grp, "xAxis", mat[0]);
275 DRW_shgroup_uniform_vec3_copy(grp, "yAxis", mat[1]);
276 DRW_shgroup_uniform_vec3_copy(grp, "origin", mat[3]);
277 DRW_shgroup_uniform_int_copy(grp, "halfLineCount", line_count / 2);
278 DRW_shgroup_call_procedural_lines(grp, nullptr, line_count);
279}
280
282{
283 using namespace blender::draw;
284 OVERLAY_PrivateData *pd = vedata->stl->pd;
285 const DRWContextState *draw_ctx = DRW_context_state_get();
286
288 if (lines_grp) {
289 blender::gpu::Batch *geom_lines = DRW_cache_grease_pencil_edit_lines_get(draw_ctx->scene, ob);
290 if (geom_lines) {
291 DRW_shgroup_call_no_cull(lines_grp, geom_lines, ob);
292 }
293 }
294
296 if (points_grp) {
297 blender::gpu::Batch *geom_points = DRW_cache_grease_pencil_edit_points_get(draw_ctx->scene,
298 ob);
299 if (geom_points) {
300 DRW_shgroup_call_no_cull(points_grp, geom_points, ob);
301 }
302 }
303
304 View3D *v3d = draw_ctx->v3d;
305 /* Don't show object extras in set's. */
306 if ((ob->base_flag & (BASE_FROM_SET | BASE_FROM_DUPLI)) == 0) {
309 }
310 }
311}
312
314{
315 using namespace blender::draw;
316 OVERLAY_PrivateData *pd = vedata->stl->pd;
317 const DRWContextState *draw_ctx = DRW_context_state_get();
318
320 if (lines_grp) {
321 blender::gpu::Batch *geom_lines = DRW_cache_grease_pencil_edit_lines_get(draw_ctx->scene, ob);
322 if (geom_lines) {
323 DRW_shgroup_call_no_cull(lines_grp, geom_lines, ob);
324 }
325 }
326
328 if (points_grp) {
329 blender::gpu::Batch *geom_points = DRW_cache_grease_pencil_edit_points_get(draw_ctx->scene,
330 ob);
331 if (geom_points) {
332 DRW_shgroup_call_no_cull(points_grp, geom_points, ob);
333 }
334 }
335}
336
338{
339 using namespace blender::draw;
340 OVERLAY_PrivateData *pd = vedata->stl->pd;
341 const DRWContextState *draw_ctx = DRW_context_state_get();
342
344 if (lines_grp) {
345 blender::gpu::Batch *geom_lines = DRW_cache_grease_pencil_weight_lines_get(draw_ctx->scene,
346 ob);
347 if (geom_lines) {
348 DRW_shgroup_call_no_cull(lines_grp, geom_lines, ob);
349 }
350 }
351
353 if (points_grp) {
354 blender::gpu::Batch *geom_points = DRW_cache_grease_pencil_weight_points_get(draw_ctx->scene,
355 ob);
356 if (geom_points) {
357 DRW_shgroup_call_no_cull(points_grp, geom_points, ob);
358 }
359 }
360}
361
363{
364 using namespace blender::draw;
365 OVERLAY_PrivateData *pd = vedata->stl->pd;
366 const DRWContextState *draw_ctx = DRW_context_state_get();
367
369 if (lines_grp) {
370 blender::gpu::Batch *geom_lines = DRW_cache_grease_pencil_edit_lines_get(draw_ctx->scene, ob);
371 if (geom_lines) {
372 DRW_shgroup_call_no_cull(lines_grp, geom_lines, ob);
373 }
374 }
375
377 if (points_grp) {
378 blender::gpu::Batch *geom_points = DRW_cache_grease_pencil_edit_points_get(draw_ctx->scene,
379 ob);
380 if (geom_points) {
381 DRW_shgroup_call_no_cull(points_grp, geom_points, ob);
382 }
383 }
384}
385
387{
388 OVERLAY_PassList *psl = vedata->psl;
389
390 if (psl->grease_pencil_canvas_ps) {
392 }
393}
394
396{
397 OVERLAY_PassList *psl = vedata->psl;
398
399 if (psl->edit_grease_pencil_ps) {
401 }
402}
Low-level operations for curves.
Low-level operations for grease pencil.
struct Material * BKE_object_material_get_eval(struct Object *ob, short act)
unsigned char uchar
#define ELEM(...)
@ BASE_FROM_DUPLI
@ BASE_FROM_SET
@ OB_MODE_VERTEX_GREASE_PENCIL
@ OB_MODE_SCULPT_GREASE_PENCIL
@ OB_MODE_WEIGHT_GREASE_PENCIL
@ OB_GREASE_PENCIL
@ GP_LOCKAXIS_X
@ GP_LOCKAXIS_VIEW
@ GP_LOCKAXIS_Y
@ GP_LOCKAXIS_Z
@ GP_LOCKAXIS_CURSOR
@ GP_SELECTMODE_POINT
@ GP_SELECTMODE_SEGMENT
@ GP_SCULPT_MASK_SELECTMODE_POINT
@ GP_SCULPT_MASK_SELECTMODE_SEGMENT
@ GP_VERTEX_MASK_SELECTMODE_SEGMENT
@ GP_VERTEX_MASK_SELECTMODE_POINT
@ GP_PROJECT_DEPTH_VIEW
@ GP_PROJECT_CURSOR
@ GP_PROJECT_DEPTH_STROKE
@ V3D_HIDE_OVERLAYS
@ V3D_GP_SHOW_MATERIAL_NAME
@ V3D_GP_SHOW_GRID_XRAY
@ V3D_GP_SHOW_STROKE_DIRECTION
@ V3D_GP_SHOW_EDIT_LINES
@ V3D_GP_SHOW_GRID
#define DRW_shgroup_call_no_cull(shgroup, geom, ob)
#define DRW_PASS_CREATE(pass, state)
#define DRW_shgroup_uniform_block(shgroup, name, ubo)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
struct GPUShader GPUShader
bool is_empty() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
OffsetIndices< int > points_by_curve() const
IndexRange curves_range() const
Span< float3 > positions() const
const bke::CurvesGeometry & strokes() const
float4x4 to_world_space(const Object &object) const
int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color)
DRW_Global G_draw
bool DRW_state_show_text()
DRWTextStore * DRW_text_cache_ensure()
const DRWContextState * DRW_context_state_get()
DRWShadingGroup * DRW_shgroup_create(GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_shgroup_uniform_vec3_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
void DRW_shgroup_call_procedural_lines(DRWShadingGroup *shgroup, const Object *ob, uint line_count)
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_draw_pass(DRWPass *pass)
void DRW_text_cache_add(DRWTextStore *dt, const float co[3], const char *str, const int str_len, short xoffs, short yoffs, short flag, const uchar col[4], const bool shadow, const bool align_center)
@ DRW_TEXT_CACHE_GLOBALSPACE
@ DRW_TEXT_CACHE_STRING_PTR
DRWState
Definition draw_state.hh:25
@ DRW_STATE_BLEND_ALPHA
Definition draw_state.hh:55
@ DRW_STATE_WRITE_DEPTH
Definition draw_state.hh:29
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition draw_state.hh:38
@ DRW_STATE_DEPTH_ALWAYS
Definition draw_state.hh:36
static ulong state[N]
blender::gpu::Batch * DRW_cache_grease_pencil_edit_lines_get(const Scene *scene, Object *ob)
blender::gpu::Batch * DRW_cache_grease_pencil_weight_lines_get(const Scene *scene, Object *ob)
blender::gpu::Batch * DRW_cache_grease_pencil_edit_points_get(const Scene *scene, Object *ob)
blender::gpu::Batch * DRW_cache_grease_pencil_weight_points_get(const Scene *scene, Object *ob)
Vector< DrawingInfo > retrieve_visible_drawings(const Scene &scene, const GreasePencil &grease_pencil, const bool do_onion_skinning)
MatT from_loc_scale(const typename MatT::loc_type &location, const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< float, 3 > float3
void OVERLAY_edit_grease_pencil_draw(OVERLAY_Data *vedata)
void OVERLAY_weight_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_vertex_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_edit_grease_pencil_cache_init(OVERLAY_Data *vedata)
static void overlay_grease_pencil_draw_stroke_color_name(Object &object, const int mat_nr, const blender::float3 position)
static void is_selection_visible(bool &r_show_points, bool &r_show_lines)
void OVERLAY_grease_pencil_cache_init(OVERLAY_Data *vedata)
void OVERLAY_edit_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
void OVERLAY_grease_pencil_draw(OVERLAY_Data *vedata)
void OVERLAY_sculpt_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
static void OVERLAY_grease_pencil_material_names(Object *ob)
GPUShader * OVERLAY_shader_edit_particle_point()
GPUShader * OVERLAY_shader_edit_particle_strand()
GPUShader * OVERLAY_shader_gpencil_canvas()
ViewLayer * view_layer
eObjectMode object_mode
char name[66]
Definition DNA_ID.h:425
OVERLAY_PassList * psl
OVERLAY_StorageList * stl
DRWPass * grease_pencil_canvas_ps
DRWPass * edit_grease_pencil_ps
DRWShadingGroup * edit_grease_pencil_wires_grp
DRWShadingGroup * edit_grease_pencil_points_grp
OVERLAY_PrivateData * pd
short base_flag
struct ToolSettings * toolsettings
View3DCursor cursor
char gpencil_selectmode_vertex
char gpencil_selectmode_sculpt
struct GP_Sculpt_Settings gp_sculpt
float gpencil_grid_color[3]
float gpencil_grid_scale[2]
float gpencil_grid_offset[2]
View3DOverlay overlay
const c_style_mat & ptr() const
const MatView< T, ViewNumCol, ViewNumRow, NumCol, NumRow, SrcStartCol, SrcStartRow, Alignment > view() const
MatBase< float, 3, 3 > float3x3