Blender V5.0
overlay_grease_pencil.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include "BLI_bounds.hh"
12#include "BLI_math_matrix.h"
13#include "BLI_math_matrix.hh"
14
15#include "BKE_curves.hh"
16#include "BKE_grease_pencil.hh"
17#include "BKE_material.hh"
18#include "BKE_object.hh"
19
20#include "DNA_material_types.h"
21
22#include "ED_grease_pencil.hh"
23
24#include "draw_cache.hh"
25#include "draw_manager_text.hh"
26
27#include "overlay_base.hh"
28
29namespace blender::draw::overlay {
30
36 private:
37 PassSimple edit_grease_pencil_ps_ = {"GPencil Edit"};
38 PassSimple::Sub *edit_handles_ = nullptr;
39 PassSimple::Sub *edit_points_ = nullptr;
40 PassSimple::Sub *edit_lines_ = nullptr;
41
42 PassSimple grid_ps_ = {"GPencil Grid"};
43
44 bool show_handles_ = false;
45 bool show_points_ = false;
46 bool show_lines_ = false;
47 bool show_grid_ = false;
48 bool show_weight_ = false;
49 bool show_material_name_ = false;
50
51 /* TODO(fclem): This is quite wasteful and expensive, prefer in shader Z modification like the
52 * retopology offset. */
53 View view_edit_cage_ = {"view_edit_cage"};
54 View::OffsetData offset_data_;
55
56 public:
57 void begin_sync(Resources &res, const State &state) final
58 {
59 enabled_ = state.is_space_v3d();
60
61 res.depth_planes.clear();
62 res.depth_planes_count = 0;
63
64 if (!enabled_) {
65 return;
66 }
67
68 offset_data_ = state.offset_data_get();
69
70 const View3D *v3d = state.v3d;
71 const ToolSettings *ts = state.scene->toolsettings;
72
73 show_material_name_ = (v3d->gp_flag & V3D_GP_SHOW_MATERIAL_NAME) && state.show_text;
74 const bool show_lines = (v3d->gp_flag & V3D_GP_SHOW_EDIT_LINES);
75 const bool show_direction = (v3d->gp_flag & V3D_GP_SHOW_STROKE_DIRECTION);
76
77 show_handles_ = show_points_ = show_lines_ = show_weight_ = false;
78
79 switch (state.object_mode) {
81 /* Draw mode. */
82 break;
84 /* Vertex paint mode. */
85 show_points_ = ts->gpencil_selectmode_vertex &
87 show_lines_ = show_lines && ts->gpencil_selectmode_vertex;
88 break;
89 case OB_MODE_EDIT:
90 /* Edit mode. */
91 show_points_ = ELEM(
93 show_lines_ = show_lines;
94 show_handles_ = show_points_;
95 break;
97 /* Weight paint mode. */
98 show_points_ = true;
99 show_lines_ = show_lines;
100 show_weight_ = true;
101 break;
103 /* Sculpt mode. */
104 show_points_ = ts->gpencil_selectmode_sculpt &
106 show_lines_ = show_lines && ts->gpencil_selectmode_sculpt;
107 break;
108 default:
109 /* Not a Grease Pencil mode. */
110 break;
111 }
112
113 edit_handles_ = nullptr;
114 edit_points_ = nullptr;
115 edit_lines_ = nullptr;
116
117 {
118 auto &pass = edit_grease_pencil_ps_;
119 pass.init();
120 pass.bind_ubo(OVERLAY_GLOBALS_SLOT, &res.globals_buf);
121 pass.bind_ubo(DRW_CLIPPING_UBO_SLOT, &res.clip_planes_buf);
124 state.clipping_plane_count);
125
126 const int handle_display = show_handles_ ? int(state.overlay.handle_display) :
128
129 if (show_handles_) {
130 auto &sub = pass.sub("Handles");
131 sub.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA, state.clipping_plane_count);
132 sub.shader_set(res.shaders->curve_edit_handles.get());
133 sub.push_constant("show_curve_handles", handle_display != int(CURVE_HANDLE_NONE));
134 sub.push_constant("curve_handle_display", handle_display);
135 edit_handles_ = ⊂
136 }
137
138 if (show_points_) {
139 auto &sub = pass.sub("Points");
140 sub.shader_set(res.shaders->curve_edit_points.get());
141 sub.bind_texture("weight_tx", &res.weight_ramp_tx);
142 sub.push_constant("use_weight", show_weight_);
143 sub.push_constant("use_grease_pencil", true);
144 sub.push_constant("do_stroke_endpoints", show_direction);
145 sub.push_constant("curve_handle_display", handle_display);
146 edit_points_ = ⊂
147 }
148
149 if (show_lines_) {
150 auto &sub = pass.sub("Lines");
151 sub.shader_set(res.shaders->curve_edit_line.get());
152 sub.bind_texture("weight_tx", &res.weight_ramp_tx);
153 sub.push_constant("use_weight", show_weight_);
154 sub.push_constant("use_grease_pencil", true);
155 edit_lines_ = ⊂
156 }
157 }
158
159 const bool is_depth_projection_mode = ts->gpencil_v3d_align &
161 show_grid_ = (v3d->gp_flag & V3D_GP_SHOW_GRID) && !is_depth_projection_mode;
162
163 {
164 const bool grid_xray = (v3d->gp_flag & V3D_GP_SHOW_GRID_XRAY);
165 DRWState depth_write_state = (grid_xray) ? DRW_STATE_DEPTH_ALWAYS :
167 auto &pass = grid_ps_;
168 pass.init();
169 pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA | depth_write_state,
170 state.clipping_plane_count);
171 if (show_grid_) {
172 const float4 col_grid(float3(state.overlay.gpencil_grid_color),
173 state.overlay.gpencil_grid_opacity);
174 pass.shader_set(res.shaders->grid_grease_pencil.get());
175 pass.bind_ubo(OVERLAY_GLOBALS_SLOT, &res.globals_buf);
176 pass.bind_ubo(DRW_CLIPPING_UBO_SLOT, &res.clip_planes_buf);
177 pass.push_constant("color", col_grid);
178 }
179 }
180 }
181
183 const ObjectRef &ob_ref,
184 Resources &res,
185 const State &state) final
186 {
187 if (!enabled_) {
188 return;
189 }
190
191 Object *ob = ob_ref.object;
192
193 if (show_handles_) {
194 gpu::Batch *geom = DRW_cache_grease_pencil_edit_handles_get(state.scene, ob);
195 if (geom) {
196 edit_handles_->draw_expand(geom, GPU_PRIM_TRIS, 8, 1, manager.unique_handle(ob_ref));
197 }
198 }
199 if (show_points_) {
200 gpu::Batch *geom = show_weight_ ?
203 if (geom) {
204 edit_points_->draw(geom, manager.unique_handle(ob_ref));
205 }
206 }
207 if (show_lines_) {
208 gpu::Batch *geom = show_weight_ ? DRW_cache_grease_pencil_weight_lines_get(state.scene, ob) :
210 if (geom) {
211 edit_lines_->draw(geom, manager.unique_handle(ob_ref));
212 }
213 }
214
215 if (show_material_name_) {
216 draw_material_names(ob_ref, state, res);
217 }
218 }
219
221 const ObjectRef &ob_ref,
222 Resources &res,
223 const State &state)
224 {
225 /* Reuse same logic as edit mode. */
226 edit_object_sync(manager, ob_ref, res, state);
227 }
228
230 const ObjectRef &ob_ref,
231 Resources &res,
232 const State &state)
233 {
234 /* Reuse same logic as edit mode. */
235 edit_object_sync(manager, ob_ref, res, state);
236 }
237
238 void object_sync(Manager & /*manager*/,
239 const ObjectRef &ob_ref,
240 Resources & /*res*/,
241 const State &state) final
242 {
243 if (!enabled_) {
244 return;
245 }
246
247 if (ob_ref.object != state.object_active) {
248 /* Only display for the active object. */
249 return;
250 }
251
252 if (show_grid_) {
253 const int grid_lines = state.v3d->overlay.gpencil_grid_subdivisions;
254 const int line_count = grid_lines * 4 + 2;
255
256 const float3 grid_offset = float3(float2(state.v3d->overlay.gpencil_grid_offset), 0.0f);
257 const float3 grid_scale = float3(float2(state.v3d->overlay.gpencil_grid_scale), 0.0f);
258 const float4x4 transform_mat = math::from_loc_scale<float4x4>(grid_offset, grid_scale);
259
260 const float4x4 grid_mat = grid_matrix_get(*ob_ref.object, state.scene) * transform_mat;
261
262 grid_ps_.push_constant("axis_x", grid_mat.x_axis());
263 grid_ps_.push_constant("axis_y", grid_mat.y_axis());
264 grid_ps_.push_constant("origin", grid_mat.location());
265 grid_ps_.push_constant("half_line_count", line_count / 2);
266 grid_ps_.draw_procedural(GPU_PRIM_LINES, 1, line_count * 2);
267 }
268 }
269
270 static void compute_depth_planes(Manager &manager,
271 View &view,
272 Resources &res,
273 const State & /*state*/)
274 {
275 for (auto i : IndexRange(res.depth_planes_count)) {
277 const float4x4 &object_to_world =
278 manager.matrix_buf.current().get_or_resize(plane.handle.resource_index()).model;
279 plane.plane = GreasePencil::depth_plane_get(object_to_world, plane.bounds, view);
280 }
281 }
282
283 void draw_line(Framebuffer &framebuffer, Manager &manager, View &view) final
284 {
285 if (!enabled_) {
286 return;
287 }
288
289 GPU_framebuffer_bind(framebuffer);
290 manager.submit(grid_ps_, view);
291 }
292
293 void draw_color_only(Framebuffer &framebuffer, Manager &manager, View &view) final
294 {
295 if (!enabled_) {
296 return;
297 }
298
299 view_edit_cage_.sync(view.viewmat(), offset_data_.winmat_polygon_offset(view.winmat(), 0.5f));
300
301 GPU_framebuffer_bind(framebuffer);
302 manager.submit(edit_grease_pencil_ps_, view_edit_cage_);
303 }
304
306 PassMain::Sub &pass,
307 const Scene *scene,
308 Object *ob,
309 ResourceHandleRange res_handle,
311 {
312 using namespace blender;
313 using namespace blender::ed::greasepencil;
315
316 const bool is_stroke_order_3d = (grease_pencil.flag & GREASE_PENCIL_STROKE_ORDER_3D) != 0;
317
318 if (is_stroke_order_3d) {
319 pass.push_constant("gp_depth_plane", float4(0.0f));
320 }
321 else {
322 int64_t index = res.depth_planes.append_and_get_index({});
323 res.depth_planes_count++;
324
325 GreasePencilDepthPlane &plane = res.depth_planes[index];
326 plane.bounds = BKE_object_boundbox_get(ob).value_or(blender::Bounds(float3(0)));
327 plane.handle = res_handle;
328
329 pass.push_constant("gp_depth_plane", &plane.plane);
330 }
331
332 int t_offset = 0;
333 const Vector<DrawingInfo> drawings = retrieve_visible_drawings(*scene, grease_pencil, true);
334 for (const DrawingInfo info : drawings) {
335
338
339 pass.push_constant("gp_stroke_order3d", is_stroke_order_3d);
340 pass.bind_texture("gp_pos_tx", position_tx);
341 pass.bind_texture("gp_col_tx", color_tx);
342
343 const bke::CurvesGeometry &curves = info.drawing.strokes();
344 const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
345 const bke::AttributeAccessor attributes = curves.attributes();
346 const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
347 "material_index", bke::AttrDomain::Curve, 0);
348 const VArray<bool> cyclic = *attributes.lookup_or_default<bool>(
349 "cyclic", bke::AttrDomain::Curve, false);
350
351 IndexMaskMemory memory;
353 *ob, info.drawing, memory);
354
355 visible_strokes.foreach_index([&](const int stroke_i) {
356 const IndexRange points = points_by_curve[stroke_i];
357 const int material_index = stroke_materials[stroke_i];
358 MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, material_index + 1);
359
360 const bool hide_onion = info.onion_id != 0;
361 const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
362
363 const int num_stroke_triangles = (points.size() >= 3) ? (points.size() - 2) : 0;
364 const int num_stroke_vertices = (points.size() +
365 int(cyclic[stroke_i] && (points.size() >= 3)));
366
367 if (hide_material || hide_onion) {
368 t_offset += num_stroke_triangles;
369 t_offset += num_stroke_vertices * 2;
370 return;
371 }
372
373 blender::gpu::Batch *geom = draw::DRW_cache_grease_pencil_get(scene, ob);
374
375 const bool show_stroke = (gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0;
376 const bool show_fill = (points.size() >= 3) &&
377 (gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0;
378
379 if (show_fill) {
380 int v_first = t_offset * 3;
381 int v_count = num_stroke_triangles * 3;
382 pass.draw(geom, 1, v_count, v_first, res_handle, select_id.get());
383 }
384
385 t_offset += num_stroke_triangles;
386
387 if (show_stroke) {
388 int v_first = t_offset * 3;
389 int v_count = num_stroke_vertices * 2 * 3;
390 pass.draw(geom, 1, v_count, v_first, res_handle, select_id.get());
391 }
392 t_offset += num_stroke_vertices * 2;
393 });
394 }
395 }
396
397 private:
398 /* Returns the normal plane in NDC space. */
399 static float4 depth_plane_get(const float4x4 &object_to_world,
401 const View &view)
402 {
403 using namespace blender::math;
404
405 /* Find the normal most likely to represent the grease pencil object. */
406 /* TODO: This does not work quite well if you use
407 * strokes not aligned with the object axes. Maybe we could try to
408 * compute the minimum axis of all strokes. But this would be more
409 * computationally heavy and should go into the GPData evaluation. */
410 float3 center = bounds.center();
411 float3 size = bounds.size();
412 /* Avoid division by 0.0 later. */
413 size += 1e-8f;
414
415 /* Convert Bbox unit space to object space. */
416 float4x4 bbox_to_object = from_loc_scale<float4x4>(center, size * 0.5f);
417 float4x4 bbox_to_world = object_to_world * bbox_to_object;
418
419 float3 bbox_center = bbox_to_world.location();
420 float3 view_vector = (view.is_persp()) ? (view.location() - bbox_center) : view.forward();
421
422 float3x3 world_to_bbox = invert(float3x3(bbox_to_world));
423
424 /* Normalize the vector in BBox space. */
425 float3 local_plane_direction = normalize(transform_direction(world_to_bbox, view_vector));
426 /* `bbox_to_world_normal` is a "normal" matrix. It transforms BBox space normals to world. */
427 float3x3 bbox_to_world_normal = transpose(world_to_bbox);
428 float3 plane_direction = normalize(
429 transform_direction(bbox_to_world_normal, local_plane_direction));
430
431 return float4(plane_direction, -dot(plane_direction, bbox_center));
432 }
433
434 float4x4 grid_matrix_get(const Object &object, const Scene *scene)
435 {
436 const ToolSettings *ts = scene->toolsettings;
437
438 const ::GreasePencil &grease_pencil = DRW_object_get_data_for_drawing<::GreasePencil>(object);
439 const blender::bke::greasepencil::Layer *active_layer = grease_pencil.get_active_layer();
440
441 float4x4 mat = object.object_to_world();
442 if (active_layer && ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR) {
443 mat = active_layer->to_world_space(object);
444 }
445 const View3DCursor *cursor = &scene->cursor;
446
447 /* Set the grid in the selected axis */
448 switch (ts->gp_sculpt.lock_axis) {
449 case GP_LOCKAXIS_X:
450 std::swap(mat[0], mat[2]);
451 break;
452 case GP_LOCKAXIS_Y:
453 std::swap(mat[1], mat[2]);
454 break;
455 case GP_LOCKAXIS_Z:
456 /* Default. */
457 break;
458 case GP_LOCKAXIS_CURSOR: {
459 mat = float4x4(cursor->matrix<float3x3>());
460 break;
461 }
462 case GP_LOCKAXIS_VIEW:
463 /* view aligned */
464 /* TODO(fclem): Global access. */
466 break;
467 }
468
469 mat *= 2.0f;
470
472 mat.location() = cursor->location;
473 }
474 else if (active_layer) {
475 mat.location() = active_layer->to_world_space(object).location();
476 }
477 else {
478 mat.location() = object.object_to_world().location();
479 }
480 return mat;
481 }
482
483 void draw_material_names(const ObjectRef &ob_ref, const State &state, Resources &res)
484 {
485 Object &object = *ob_ref.object;
486
487 uchar4 color;
488 UI_GetThemeColor4ubv(res.object_wire_theme_id(ob_ref, state), color);
489
491
492 Vector<ed::greasepencil::DrawingInfo> drawings = ed::greasepencil::retrieve_visible_drawings(
493 *state.scene, grease_pencil, false);
494 if (drawings.is_empty()) {
495 return;
496 }
497
498 for (const ed::greasepencil::DrawingInfo &info : drawings) {
499 const bke::greasepencil::Drawing &drawing = info.drawing;
500
501 const bke::CurvesGeometry strokes = drawing.strokes();
502 const OffsetIndices<int> points_by_curve = strokes.points_by_curve();
503 const bke::AttrDomain domain = show_points_ ? bke::AttrDomain::Point :
505 const VArray<bool> selections = *strokes.attributes().lookup_or_default<bool>(
506 ".selection", domain, true);
507 const VArray<int> materials = *strokes.attributes().lookup_or_default<int>(
508 "material_index", bke::AttrDomain::Curve, 0);
509 const Span<float3> positions = strokes.positions();
510
511 auto show_stroke_name = [&](const int stroke_i) {
512 if (show_points_) {
513 for (const int point_i : points_by_curve[stroke_i]) {
514 if (selections[point_i]) {
515 return true;
516 }
517 }
518 return false;
519 }
520 return selections[stroke_i];
521 };
522
523 for (const int stroke_i : strokes.curves_range()) {
524 if (!show_stroke_name(stroke_i)) {
525 continue;
526 }
527 const int point_i = points_by_curve[stroke_i].first();
528 const float3 fpt = math::transform_point(object.object_to_world(), positions[point_i]);
529 if (Material *ma = BKE_object_material_get_eval(&object, materials[stroke_i] + 1)) {
531 fpt,
532 ma->id.name + 2,
533 strlen(ma->id.name + 2),
534 10,
535 0,
537 color);
538 }
539 }
540 }
541 }
542};
543
544} // namespace blender::draw::overlay
Low-level operations for curves.
Low-level operations for grease pencil.
General operations, lookup, etc. for materials.
MaterialGPencilStyle * BKE_gpencil_material_settings(Object *ob, short act)
Material * BKE_object_material_get_eval(Object *ob, short act)
General operations, lookup, etc. for blender objects.
std::optional< blender::Bounds< blender::float3 > > BKE_object_boundbox_get(const Object *ob)
#define ELEM(...)
struct GreasePencil GreasePencil
@ GREASE_PENCIL_STROKE_ORDER_3D
struct Material Material
@ GP_MATERIAL_HIDE
@ GP_MATERIAL_STROKE_SHOW
@ GP_MATERIAL_FILL_SHOW
@ OB_MODE_VERTEX_GREASE_PENCIL
@ OB_MODE_EDIT
@ OB_MODE_PAINT_GREASE_PENCIL
@ OB_MODE_SCULPT_GREASE_PENCIL
@ OB_MODE_WEIGHT_GREASE_PENCIL
struct Object Object
@ 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_GP_SHOW_MATERIAL_NAME
@ V3D_GP_SHOW_GRID_XRAY
@ V3D_GP_SHOW_STROKE_DIRECTION
@ V3D_GP_SHOW_EDIT_LINES
@ V3D_GP_SHOW_GRID
@ CURVE_HANDLE_NONE
T & DRW_object_get_data_for_drawing(const Object &object)
static AppView * view
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
@ GPU_PRIM_LINES
@ GPU_PRIM_TRIS
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
bool is_empty() const
constexpr int64_t size() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
OffsetIndices< int > points_by_curve() const
IndexRange curves_range() const
Span< float3 > positions() const
AttributeAccessor attributes() const
const bke::CurvesGeometry & strokes() const
float4x4 to_world_space(const Object &object) const
SwapChain< ObjectMatricesBuf, 2 > matrix_buf
static View & default_get()
Definition draw_view.cc:317
const float4x4 & viewinv(int view_id=0) const
Definition draw_view.hh:142
void bind_texture(const char *name, gpu::Texture *texture, GPUSamplerState state=sampler_auto)
void draw(gpu::Batch *batch, uint instance_len=-1, uint vertex_len=-1, uint vertex_first=-1, ResourceIndexRange res_index={}, uint custom_id=0)
Definition draw_pass.hh:893
void push_constant(const char *name, const float &data)
detail::PassBase< command::DrawCommandBuf > Sub
Definition draw_pass.hh:499
void sculpt_object_sync(Manager &manager, const ObjectRef &ob_ref, Resources &res, const State &state)
void draw_line(Framebuffer &framebuffer, Manager &manager, View &view) final
void draw_color_only(Framebuffer &framebuffer, Manager &manager, View &view) final
void begin_sync(Resources &res, const State &state) final
void object_sync(Manager &, const ObjectRef &ob_ref, Resources &, const State &state) final
void edit_object_sync(Manager &manager, const ObjectRef &ob_ref, Resources &res, const State &state) final
void paint_object_sync(Manager &manager, const ObjectRef &ob_ref, Resources &res, const State &state)
static void compute_depth_planes(Manager &manager, View &view, Resources &res, const State &)
static void draw_grease_pencil(Resources &res, PassMain::Sub &pass, const Scene *scene, Object *ob, ResourceHandleRange res_handle, select::ID select_id=select::SelectMap::select_invalid_id())
void foreach_index(Fn &&fn) const
#define DRW_CLIPPING_UBO_SLOT
#define OVERLAY_GLOBALS_SLOT
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
VecBase< float, D > normalize(VecOp< float, D >) RET
MatBase< R, C > transpose(MatBase< C, R >) RET
static ulong state[N]
gpu::Batch * DRW_cache_grease_pencil_get(const Scene *scene, Object *ob)
detail::Pass< command::DrawCommandBuf > PassSimple
gpu::Batch * DRW_cache_grease_pencil_edit_handles_get(const Scene *scene, Object *ob)
gpu::VertBuf * DRW_cache_grease_pencil_position_buffer_get(const Scene *scene, Object *ob)
gpu::Batch * DRW_cache_grease_pencil_edit_lines_get(const Scene *scene, Object *ob)
gpu::Batch * DRW_cache_grease_pencil_weight_lines_get(const Scene *scene, Object *ob)
gpu::Batch * DRW_cache_grease_pencil_edit_points_get(const Scene *scene, Object *ob)
gpu::Batch * DRW_cache_grease_pencil_weight_points_get(const Scene *scene, Object *ob)
gpu::VertBuf * DRW_cache_grease_pencil_color_buffer_get(const Scene *scene, Object *ob)
Vector< DrawingInfo > retrieve_visible_drawings(const Scene &scene, const GreasePencil &grease_pencil, const bool do_onion_skinning)
IndexMask retrieve_visible_strokes(Object &object, const bke::greasepencil::Drawing &drawing, IndexMaskMemory &memory)
MatT from_loc_scale(const typename MatT::loc_type &location, const VecBase< typename MatT::base_type, ScaleDim > &scale)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
CartesianBasis invert(const CartesianBasis &basis)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
MatBase< float, 4, 4 > float4x4
blender::VecBase< uint8_t, 4 > uchar4
VecBase< float, 4 > float4
VecBase< float, 2 > float2
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
struct ToolSettings * toolsettings
View3DCursor cursor
char gpencil_selectmode_vertex
char gpencil_selectmode_sculpt
struct GP_Sculpt_Settings gp_sculpt
detail::SubPassVector< GreasePencilDepthPlane, 16 > depth_planes
i
Definition text_draw.cc:230