Blender V5.0
draw_cache.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 "DNA_curve_types.h"
10#include "DNA_curves_types.h"
12#include "DNA_lattice_types.h"
13#include "DNA_mesh_types.h"
14#include "DNA_modifier_types.h"
15#include "DNA_object_types.h"
16#include "DNA_particle_types.h"
18#include "DNA_scene_types.h"
19#include "DNA_volume_types.h"
20
21#include "BLI_ghash.h"
22#include "BLI_listbase.h"
23#include "BLI_string.h"
24#include "BLI_utildefines.h"
25
26#include "BKE_attribute.hh"
27#include "BKE_context.hh"
28#include "BKE_mesh_wrapper.hh"
29#include "BKE_object.hh"
31
32#include "DRW_render.hh"
33#include "GPU_batch.hh"
34#include "GPU_batch_utils.hh"
35#include "GPU_capabilities.hh"
36
37#include "draw_cache.hh"
38#include "draw_cache_impl.hh"
40
41/* -------------------------------------------------------------------- */
44
45#define VCLASS_LIGHT_AREA_SHAPE (1 << 0)
46#define VCLASS_LIGHT_SPOT_SHAPE (1 << 1)
47#define VCLASS_LIGHT_SPOT_BLEND (1 << 2)
48#define VCLASS_LIGHT_SPOT_CONE (1 << 3)
49#define VCLASS_LIGHT_DIST (1 << 4)
50
51#define VCLASS_CAMERA_FRAME (1 << 5)
52#define VCLASS_CAMERA_DIST (1 << 6)
53#define VCLASS_CAMERA_VOLUME (1 << 7)
54
55#define VCLASS_SCREENSPACE (1 << 8)
56#define VCLASS_SCREENALIGNED (1 << 9)
57
58#define VCLASS_EMPTY_SCALED (1 << 10)
59#define VCLASS_EMPTY_AXES (1 << 11)
60#define VCLASS_EMPTY_AXES_NAME (1 << 12)
61#define VCLASS_EMPTY_AXES_SHADOW (1 << 13)
62#define VCLASS_EMPTY_SIZE (1 << 14)
63
65
66/* -------------------------------------------------------------------- */
69
70namespace blender::draw {
71
72void DRW_vertbuf_create_wiredata(gpu::VertBuf *vbo, const int vert_len)
73{
75 gpu::VertAttrType::SFLOAT_32);
77 GPU_vertbuf_data_alloc(*vbo, vert_len);
78 vbo->data<float>().fill(1.0f);
79}
80
82
83/* -------------------------------------------------------------------- */
90
92{
93 switch (ob->type) {
94 case OB_MESH:
96 /* TODO: should match #DRW_cache_object_surface_get. */
97 default:
98 return nullptr;
99 }
100}
101
102gpu::Batch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
103{
104 switch (ob->type) {
105 case OB_MESH:
106 return DRW_cache_mesh_edge_detection_get(ob, r_is_manifold);
107 default:
108 return nullptr;
109 }
110}
111
113{
114 switch (ob->type) {
115 case OB_MESH:
117 case OB_POINTCLOUD:
119 case OB_VOLUME:
121 case OB_GREASE_PENCIL:
123 default:
124 return nullptr;
125 }
126}
127
129{
130 switch (ob->type) {
131 case OB_MESH:
133 default:
134 return nullptr;
135 }
136}
137
139{
140 switch (ob->type) {
141 case OB_MESH:
143 default:
144 return nullptr;
145 }
146}
147
149 const Span<const GPUMaterial *> materials)
150{
151 switch (ob->type) {
152 case OB_MESH:
153 return DRW_cache_mesh_surface_shaded_get(ob, materials);
154 default:
155 return {};
156 }
157}
158
160
161/* -------------------------------------------------------------------- */
164
170
176
182
188
189gpu::Batch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
190{
191 BLI_assert(ob->type == OB_MESH);
193 r_is_manifold);
194}
195
201
208
214
222
229
236
243
249
255
261
267
274
276
277/* -------------------------------------------------------------------- */
280
287
294
301
309
317
319
320/* -------------------------------------------------------------------- */
323
330
332
333/* -------------------------------------------------------------------- */
336
343
345
346/* -------------------------------------------------------------------- */
349
357
358gpu::Batch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight)
359{
360 BLI_assert(ob->type == OB_LATTICE);
361
363 int actdef = -1;
364
365 if (use_weight && !BLI_listbase_is_empty(&lt.vertex_group_names) && lt.editlatt &&
366 lt.editlatt->latt->dvert)
367 {
368 actdef = lt.vertex_group_active_index - 1;
369 }
370
371 return DRW_lattice_batch_cache_get_all_edges(&lt, use_weight, actdef);
372}
373
381
383
384/* -------------------------------------------------------------------- */
387
395
397
398/* -------------------------------------------------------------------- */
401
407
414
416
417/* -------------------------------------------------------------------- */
420
422{
423 return DRW_particles_batch_cache_get_hair(object, psys, md);
424}
425
427{
428 return DRW_particles_batch_cache_get_dots(object, psys);
429}
430
432 ParticleSystem *psys,
433 PTCacheEdit *edit,
434 bool use_weight)
435{
436 return DRW_particles_batch_cache_get_edit_strands(object, psys, edit, use_weight);
437}
438
440 ParticleSystem *psys,
441 PTCacheEdit *edit)
442{
443 return DRW_particles_batch_cache_get_edit_inner_points(object, psys, edit);
444}
445
447 ParticleSystem *psys,
448 PTCacheEdit *edit)
449{
450 return DRW_particles_batch_cache_get_edit_tip_points(object, psys, edit);
451}
452
454
455/* -------------------------------------------------------------------- */
458
488
490{
491 const DRWContext *draw_ctx = DRW_context_get();
492 const Scene *scene = draw_ctx->scene;
494 draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
495 const bool is_paint_mode = ELEM(
497
498 const bool use_hide = ((ob->type == OB_MESH) &&
499 ((is_paint_mode && (ob == draw_ctx->obact) &&
501 ((mode == CTX_MODE_EDIT_MESH) && (ob->mode == OB_MODE_EDIT))));
502
503 switch (ob->type) {
504 case OB_MESH:
506 *ob,
508 *scene,
509 is_paint_mode,
510 use_hide);
511 break;
512 case OB_CURVES_LEGACY:
513 case OB_FONT:
514 case OB_SURF:
516 break;
517 case OB_CURVES:
519 break;
520 case OB_POINTCLOUD:
522 break;
523 /* TODO: all cases. */
524 default:
525 break;
526 }
527}
528
530{
531 /* NOTE: Logic here is duplicated from #drw_batch_cache_generate_requested. */
532
533 const DRWContext *draw_ctx = DRW_context_get();
534 const Scene *scene = draw_ctx->scene;
536 draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
537 const bool is_paint_mode = ELEM(
539
540 const bool use_hide = ((ob->type == OB_MESH) &&
541 ((is_paint_mode && (ob == draw_ctx->obact) &&
543 ((mode == CTX_MODE_EDIT_MESH) && (ob->mode == OB_MODE_EDIT))));
544
546 /* Try getting the mesh first and if that fails, try getting the curve data.
547 * If the curves are surfaces or have certain modifiers applied to them,
548 * they will have mesh data of the final result. */
549 if (mesh != nullptr) {
551 task_graph, *ob, DRW_mesh_get_for_drawing(*mesh), *scene, is_paint_mode, use_hide);
552 }
553 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
555 }
556}
557
559{
560 DRWContext &draw_ctx = drw_get();
561 if (draw_ctx.delayed_extraction == nullptr) {
562 draw_ctx.delayed_extraction = BLI_gset_ptr_new(__func__);
563 }
564 BLI_gset_add(draw_ctx.delayed_extraction, ob);
565}
566
568{
569 switch (ob->type) {
570 case OB_MESH:
572 break;
573 case OB_CURVES:
575 break;
576 case OB_POINTCLOUD:
578 ctime);
579 break;
580 default:
581 break;
582 }
583}
584
586
588 const char *base_name,
589 const bke::AttrType data_type,
590 const StringRef layer_name,
591 bool is_active_render,
592 bool is_active_layer)
593{
594 char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
595 GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
596
597 /* Attribute layer name. */
598 SNPRINTF(attr_name, "%s%s", base_name, attr_safe_name);
600
601 /* Auto layer name. */
602 SNPRINTF(attr_name, "a%s", attr_safe_name);
604
605 /* Active render layer name. */
606 if (is_active_render) {
607 GPU_vertformat_alias_add(format, data_type == bke::AttrType::Float2 ? "a" : base_name);
608 }
609
610 /* Active display layer name. */
611 if (is_active_layer) {
612 SNPRINTF(attr_name, "a%s", base_name);
614 }
615}
616
617} // namespace blender::draw
eContextObjectMode
@ CTX_MODE_PAINT_TEXTURE
@ CTX_MODE_SCULPT
@ CTX_MODE_EDIT_MESH
@ CTX_MODE_PAINT_VERTEX
@ CTX_MODE_PAINT_WEIGHT
enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, eObjectMode object_mode)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh_no_subsurf_unchecked(const Object *object)
#define BLI_assert(a)
Definition BLI_assert.h:46
GSet * BLI_gset_ptr_new(const char *info)
bool BLI_gset_add(GSet *gs, void *key)
Definition BLI_ghash.cc:966
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:604
#define ELEM(...)
@ OB_MODE_EDIT
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
T & DRW_object_get_data_for_drawing(const Object &object)
Mesh & DRW_mesh_get_for_drawing(Mesh &mesh)
#define GPU_vertbuf_init_with_format(verts, format)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertformat_alias_add(GPUVertFormat *, blender::StringRef alias)
GPUVertFormat GPU_vertformat_from_attribute(blender::StringRef name, blender::gpu::VertAttrType type)
void GPU_vertformat_safe_attr_name(blender::StringRef attr_name, char *r_safe_name, uint max_len)
static constexpr int GPU_MAX_SAFE_ATTR_NAME
MutableSpan< T > data()
const DRWContext * DRW_context_get()
bool DRW_object_use_hide_faces(const Object *ob)
DRWContext & drw_get()
format
void DRW_mesh_batch_cache_validate(Mesh &mesh)
gpu::Batch * DRW_cache_particles_get_edit_inner_points(Object *object, ParticleSystem *psys, PTCacheEdit *edit)
blender::gpu::Batch * DRW_lattice_batch_cache_get_all_verts(Lattice *lt)
void DRW_curves_batch_cache_validate(Curves *curves)
blender::gpu::Batch * DRW_mesh_batch_cache_get_loose_edges(Mesh &mesh)
void DRW_grease_pencil_batch_cache_validate(GreasePencil *grease_pencil)
gpu::Batch * DRW_cache_text_edge_wire_get(Object *ob)
void DRW_lattice_batch_cache_validate(Lattice *lt)
blender::gpu::Batch * DRW_mesh_batch_cache_get_surface_texpaint_single(Object &object, Mesh &mesh)
void DRW_vertbuf_create_wiredata(gpu::VertBuf *vbo, const int vert_len)
Definition draw_cache.cc:72
gpu::Batch * DRW_cache_mesh_all_verts_get(Object *ob)
blender::gpu::Batch * DRW_lattice_batch_cache_get_all_edges(Lattice *lt, bool use_weight, int actdef)
blender::gpu::Batch * DRW_particles_batch_cache_get_edit_inner_points(Object *object, ParticleSystem *psys, PTCacheEdit *edit)
blender::gpu::Batch * DRW_curve_batch_cache_get_wire_edge(Curve *cu)
blender::gpu::Batch * DRW_lattice_batch_cache_get_edit_verts(Lattice *lt)
blender::gpu::Batch * DRW_curve_batch_cache_get_edit_verts(Curve *cu)
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
blender::gpu::Batch * DRW_particles_batch_cache_get_edit_tip_points(Object *object, ParticleSystem *psys, PTCacheEdit *edit)
gpu::Batch * DRW_cache_mesh_paint_overlay_edges_get(Object *ob)
Span< gpu::Batch * > DRW_cache_mesh_surface_texpaint_get(Object *ob)
gpu::Batch * DRW_cache_curve_edge_wire_viewer_attribute_get(Object *ob)
gpu::Batch * DRW_cache_mesh_surface_sculptcolors_get(Object *ob)
gpu::Batch * DRW_cache_object_face_wireframe_get(const Scene *scene, Object *ob)
blender::gpu::Batch * DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh &mesh)
blender::gpu::Batch * DRW_volume_batch_cache_get_selection_surface(Volume *volume)
void drw_batch_cache_generate_requested_evaluated_mesh_or_curve(Object *ob, TaskGraph &task_graph)
gpu::Batch * DRW_cache_grease_pencil_face_wireframe_get(const Scene *scene, Object *ob)
gpu::Batch * DRW_cache_mesh_surface_vertpaint_get(Object *ob)
blender::gpu::Batch * DRW_curve_batch_cache_get_edit_edges(Curve *cu)
void DRW_curve_batch_cache_validate(Curve *cu)
blender::gpu::Batch * DRW_mesh_batch_cache_get_surface(Mesh &mesh)
blender::gpu::Batch * DRW_particles_batch_cache_get_edit_strands(Object *object, ParticleSystem *psys, PTCacheEdit *edit, bool use_weight)
gpu::Batch * DRW_cache_mesh_loose_edges_get(Object *ob)
void drw_batch_cache_validate(Object *ob)
blender::gpu::Batch * DRW_mesh_batch_cache_get_surface_weights(Mesh &mesh)
blender::gpu::Batch * DRW_particles_batch_cache_get_dots(Object *object, ParticleSystem *psys)
Span< gpu::Batch * > DRW_mesh_batch_cache_get_surface_shaded(Object &object, Mesh &mesh, Span< const GPUMaterial * > materials)
gpu::Batch * DRW_cache_mesh_face_wireframe_get(Object *ob)
gpu::Batch * DRW_cache_object_all_edges_get(Object *ob)
Definition draw_cache.cc:91
void DRW_curve_batch_cache_create_requested(Object *ob, const Scene *scene)
blender::gpu::Batch * DRW_mesh_batch_cache_get_surface_vertpaint(Object &object, Mesh &mesh)
blender::gpu::Batch * DRW_mesh_batch_cache_get_wireframes_face(Mesh &mesh)
blender::gpu::Batch * DRW_mesh_batch_cache_get_surface_sculpt(Object &object, Mesh &mesh)
blender::gpu::Batch * DRW_mesh_batch_cache_get_all_edges(Mesh &mesh)
blender::gpu::Batch * DRW_mesh_batch_cache_get_paint_overlay_verts(Mesh &mesh)
blender::gpu::Batch * DRW_mesh_batch_cache_get_edge_detection(Mesh &mesh, bool *r_is_manifold)
void DRW_mesh_batch_cache_free_old(Mesh *mesh, int ctime)
blender::gpu::Batch * DRW_pointcloud_batch_cache_get_dots(Object *ob)
gpu::Batch * DRW_cache_object_surface_get(Object *ob)
void DRW_cdlayer_attr_aliases_add(GPUVertFormat *format, const char *base_name, bke::AttrType data_type, blender::StringRef layer_name, bool is_active_render, bool is_active_layer)
blender::gpu::Batch * DRW_curve_batch_cache_get_normal_edge(Curve *cu)
gpu::Batch * DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
void DRW_volume_batch_cache_validate(Volume *volume)
Span< gpu::Batch * > DRW_mesh_batch_cache_get_surface_texpaint(Object &object, Mesh &mesh)
gpu::Batch * DRW_cache_lattice_wire_get(Object *ob, bool use_weight)
void DRW_pointcloud_batch_cache_free_old(PointCloud *pointcloud, int ctime)
gpu::Batch * DRW_cache_mesh_paint_overlay_verts_get(Object *ob)
blender::gpu::Batch * DRW_volume_batch_cache_get_wireframes_face(Volume *volume)
gpu::Batch * DRW_cache_mesh_surface_viewer_attribute_get(Object *ob)
Span< gpu::Batch * > DRW_cache_mesh_surface_shaded_get(Object *ob, const Span< const GPUMaterial * > materials)
void drw_batch_cache_generate_requested(Object *ob, TaskGraph &task_graph)
blender::gpu::Batch * DRW_pointcloud_batch_cache_get_edit_dots(PointCloud *pointcloud)
void DRW_pointcloud_batch_cache_create_requested(Object *ob)
void DRW_pointcloud_batch_cache_validate(PointCloud *pointcloud)
void drw_batch_cache_generate_requested_delayed(Object *ob)
gpu::Batch * DRW_cache_curve_edge_overlay_get(Object *ob)
blender::gpu::Batch * DRW_mesh_batch_cache_get_paint_overlay_surface(Mesh &mesh)
blender::gpu::Batch * DRW_mesh_batch_cache_get_surface_viewer_attribute(Mesh &mesh)
gpu::Batch * DRW_cache_curve_edge_wire_get(Object *ob)
gpu::Batch * DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph, Object &ob, Mesh &mesh, const Scene &scene, bool is_paint_mode, bool use_hide)
gpu::Batch * DRW_cache_lattice_verts_get(Object *ob)
gpu::Batch * DRW_cache_curve_edge_normal_get(Object *ob)
gpu::Batch * DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
gpu::Batch * DRW_cache_particles_get_edit_tip_points(Object *object, ParticleSystem *psys, PTCacheEdit *edit)
gpu::Batch * DRW_cache_lattice_vert_overlay_get(Object *ob)
gpu::Batch * DRW_cache_pointcloud_vert_overlay_get(Object *ob)
gpu::Batch * DRW_cache_mesh_surface_weights_get(Object *ob)
gpu::Batch * DRW_cache_mesh_paint_overlay_surface_get(Object *ob)
gpu::Batch * DRW_cache_particles_get_hair(Object *object, ParticleSystem *psys, ModifierData *md)
Span< gpu::Batch * > DRW_cache_object_surface_material_get(Object *ob, const Span< const GPUMaterial * > materials)
blender::gpu::Batch * DRW_particles_batch_cache_get_hair(Object *object, ParticleSystem *psys, ModifierData *md)
gpu::Batch * DRW_cache_surf_edge_wire_get(Object *ob)
gpu::Batch * DRW_cache_object_loose_edges_get(Object *ob)
gpu::Batch * DRW_cache_volume_selection_surface_get(Object *ob)
void DRW_batch_cache_free_old(Object *ob, int ctime)
gpu::Batch * DRW_cache_volume_face_wireframe_get(Object *ob)
gpu::Batch * DRW_cache_curve_vert_overlay_get(Object *ob)
blender::gpu::Batch * DRW_mesh_batch_cache_get_paint_overlay_edges(Mesh &mesh)
gpu::Batch * DRW_cache_mesh_surface_get(Object *ob)
gpu::Batch * DRW_cache_mesh_all_edges_get(Object *ob)
gpu::Batch * DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
blender::gpu::Batch * DRW_mesh_batch_cache_get_all_verts(Mesh &mesh)
blender::gpu::Batch * DRW_curve_batch_cache_get_wire_edge_viewer_attribute(Curve *cu)
void DRW_curves_batch_cache_create_requested(Object *ob)
gpu::Batch * DRW_cache_particles_get_edit_strands(Object *object, ParticleSystem *psys, PTCacheEdit *edit, bool use_weight)
gpu::Batch * DRW_cache_mesh_surface_mesh_analysis_get(Object *ob)
Object * object_edit
GSet * delayed_extraction
Object * obact
Scene * scene
eObjectMode object_mode
struct Lattice * latt
ListBase vertex_group_names
struct MDeformVert * dvert
int vertex_group_active_index
struct EditLatt * editlatt