Blender V4.3
draw_cache_impl_curve.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2017 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "MEM_guardedalloc.h"
12
13#include "BLI_array.hh"
14#include "BLI_color.hh"
15#include "BLI_listbase.h"
16#include "BLI_math_rotation.h"
17#include "BLI_math_vector.h"
19#include "BLI_span.hh"
20#include "BLI_utildefines.h"
21
22#include "DNA_curve_types.h"
23
24#include "BKE_curve.hh"
25#include "BKE_curves.hh"
26#include "BKE_displist.h"
27#include "BKE_geometry_set.hh"
28#include "BKE_object_types.hh"
29#include "BKE_vfont.hh"
30
31#include "GPU_batch.hh"
32#include "GPU_capabilities.hh"
33#include "GPU_material.hh"
34#include "GPU_texture.hh"
35
36#include "UI_resources.hh"
37
38#include "DRW_render.hh"
39
40#include "draw_cache_inline.hh"
41
42#include "draw_cache_impl.hh" /* own include */
43
44namespace blender::draw {
45
46/* See: edit_curve_point_vert.glsl for duplicate includes. */
47#define SELECT 1
48#define ACTIVE_NURB (1 << 2)
49#define BEZIER_HANDLE (1 << 3)
50#define EVEN_U_BIT (1 << 4) /* Alternate this bit for every U vert. */
51#define COLOR_SHIFT 5
52
53/* Used as values of `color_id` in `edit_curve_overlay_handle_geom.glsl` */
54enum {
56
58};
59
67static void curve_batch_cache_clear(Curve *cu);
68
69/* ---------------------------------------------------------------------- */
70/* Curve Interface, direct access to basic data. */
71
73 int *r_vert_len,
74 int *r_edge_len)
75{
76 BLI_assert(r_vert_len || r_edge_len);
77 int vert_len = 0;
78 int edge_len = 0;
79 LISTBASE_FOREACH (Nurb *, nu, lb) {
80 if (nu->bezt) {
81 vert_len += nu->pntsu * 3;
82 /* 2x handles per point. */
83 edge_len += 2 * nu->pntsu;
84 }
85 else if (nu->bp) {
86 vert_len += nu->pntsu * nu->pntsv;
87 /* segments between points */
88 edge_len += (nu->pntsu - 1) * nu->pntsv;
89 edge_len += (nu->pntsv - 1) * nu->pntsu;
90 }
91 }
92 if (r_vert_len) {
93 *r_vert_len = vert_len;
94 }
95 if (r_edge_len) {
96 *r_edge_len = edge_len;
97 }
98}
99
101 int *r_curve_len,
102 int *r_vert_len,
103 int *r_edge_len)
104{
105 const OffsetIndices points_by_curve = curves.evaluated_points_by_curve();
106 const VArray<bool> cyclic = curves.cyclic();
107
108 *r_curve_len = curves.curves_num();
109 *r_vert_len = points_by_curve.total_size();
110 *r_edge_len = 0;
111 for (const int i : curves.curves_range()) {
112 *r_edge_len += bke::curves::segments_num(points_by_curve[i].size(), cyclic[i]);
113 }
114}
115
116static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_curve_cache)
117{
118 int normal_len = 0;
119 const BevList *bl;
120 const Nurb *nu;
121 for (bl = (const BevList *)ob_curve_cache->bev.first, nu = (const Nurb *)lb->first; nu && bl;
122 bl = bl->next, nu = nu->next)
123 {
124 int nr = bl->nr;
125 int skip = nu->resolu / 16;
126#if 0
127 while (nr-- > 0) { /* accounts for empty bevel lists */
128 normal_len += 1;
129 nr -= skip;
130 }
131#else
132 /* Same as loop above */
133 normal_len += (nr / (skip + 1)) + ((nr % (skip + 1)) != 0);
134#endif
135 }
136 return normal_len;
137}
138
139/* ---------------------------------------------------------------------- */
140/* Curve Interface, indirect, partially cached access to complex data. */
141
143 int types;
144
145 struct {
149
150 struct {
152 int vert_len;
153 int edge_len;
155
156 /* edit mode normal's */
157 struct {
158 /* 'edge_len == len * 2'
159 * 'vert_len == len * 3' */
160 int len;
162
163 struct {
166
167 /* borrow from 'Object' */
169
170 /* Owned by the evaluated object's geometry set (#geometry_set_eval). */
172
173 /* borrow from 'Curve' */
175
176 /* edit, index in nurb list */
177 int actnu;
178 /* edit, index in active nurb (BPoint or BezTriple) */
180};
181
182enum {
183 /* Wire center-line */
185 /* Edit-mode verts and optionally handles */
187 /* Edit-mode normals */
189 /* Geometry */
191 /* Text */
193};
194
199 CurveCache *ob_curve_cache,
200 const int types)
201{
202 CurveRenderData *rdata = (CurveRenderData *)MEM_callocN(sizeof(*rdata), __func__);
203 rdata->types = types;
204 ListBase *nurbs;
205
206 rdata->actnu = cu->actnu;
207 rdata->actvert = cu->actvert;
208
209 rdata->ob_curve_cache = ob_curve_cache;
210
211 rdata->curve_eval = cu->curve_eval;
212
213 if (types & CU_DATATYPE_WIRE) {
214 if (rdata->curve_eval != nullptr) {
216 &rdata->wire.curve_len,
217 &rdata->wire.vert_len,
218 &rdata->wire.edge_len);
219 }
220 }
221
222 if (cu->editnurb) {
223 EditNurb *editnurb = cu->editnurb;
224 nurbs = &editnurb->nurbs;
225
226 if (types & CU_DATATYPE_OVERLAY) {
228 nurbs, &rdata->overlay.vert_len, &rdata->overlay.edge_len);
229
230 rdata->actnu = cu->actnu;
231 rdata->actvert = cu->actvert;
232 }
233 if (types & CU_DATATYPE_NORMAL) {
235 }
236 }
237 else {
238 nurbs = &cu->nurb;
239 }
240
241 rdata->nurbs = nurbs;
242
243 rdata->text.edit_font = cu->editfont;
244
245 return rdata;
246}
247
249{
250#if 0
251 if (rdata->loose_verts) {
252 MEM_freeN(rdata->loose_verts);
253 }
254#endif
255 MEM_freeN(rdata);
256}
257
259{
261 return rdata->overlay.vert_len;
262}
263
265{
267 return rdata->overlay.edge_len;
268}
269
271{
273 return rdata->wire.vert_len;
274}
275
277{
279 return rdata->wire.edge_len;
280}
281
283{
285 return rdata->wire.curve_len;
286}
287
289{
291 return rdata->normal.len;
292}
293
294/* ---------------------------------------------------------------------- */
295/* Curve gpu::Batch Cache */
296
298 struct {
302
303 struct {
305 /* Edit points (beztriples and bpoints) */
309
310 struct {
312 /* Edit mode */
316
317 struct {
318 gpu::Batch *curves;
320 /* control handles and vertices */
321 gpu::Batch *edit_edges;
322 gpu::Batch *edit_verts;
323 gpu::Batch *edit_normals;
325
326 /* settings to determine if cache is invalid */
329};
330
331/* gpu::Batch cache management. */
332
334{
336
337 if (cache == nullptr) {
338 return false;
339 }
340
341 if (cache->is_dirty) {
342 return false;
343 }
344
345 if (cache->is_editmode != ((cu->editnurb != nullptr) || (cu->editfont != nullptr))) {
346 return false;
347 }
348
349 if (cache->is_editmode) {
350 if (cu->editfont) {
351 /* TODO */
352 }
353 }
354
355 return true;
356}
357
359{
361
362 if (!cache) {
363 cache = (CurveBatchCache *)MEM_callocN(sizeof(*cache), __func__);
364 cu->batch_cache = cache;
365 }
366 else {
367 memset(cache, 0, sizeof(*cache));
368 }
369
370#if 0
371 ListBase *nurbs;
372 if (cu->editnurb) {
373 EditNurb *editnurb = cu->editnurb;
374 nurbs = &editnurb->nurbs;
375 }
376 else {
377 nurbs = &cu->nurb;
378 }
379#endif
380
381 cache->is_editmode = (cu->editnurb != nullptr) || (cu->editfont != nullptr);
382
383 cache->is_dirty = false;
384}
385
393
398
400{
402 if (cache == nullptr) {
403 return;
404 }
405 switch (mode) {
407 cache->is_dirty = true;
408 break;
411
414 break;
415 default:
416 BLI_assert(0);
417 }
418}
419
421{
423 if (!cache) {
424 return;
425 }
426
427 for (int i = 0; i < sizeof(cache->ordered) / sizeof(void *); i++) {
428 gpu::VertBuf **vbo = (gpu::VertBuf **)&cache->ordered;
430 }
431 for (int i = 0; i < sizeof(cache->edit) / sizeof(void *); i++) {
432 gpu::VertBuf **vbo = (gpu::VertBuf **)&cache->edit;
434 }
435 for (int i = 0; i < sizeof(cache->ibo) / sizeof(void *); i++) {
436 gpu::IndexBuf **ibo = (gpu::IndexBuf **)&cache->ibo;
438 }
439 for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); i++) {
440 gpu::Batch **batch = (gpu::Batch **)&cache->batch;
442 }
443}
444
450
451/* -------------------------------------------------------------------- */
455/* gpu::Batch cache usage. */
456static void curve_create_curves_pos(CurveRenderData *rdata, gpu::VertBuf *vbo_curves_pos)
457{
458 if (rdata->curve_eval == nullptr) {
459 return;
460 }
461
462 static GPUVertFormat format = {0};
463 static struct {
464 uint pos;
465 } attr_id;
466 if (format.attr_len == 0) {
468 }
469
470 const int vert_len = curve_render_data_wire_verts_len_get(rdata);
471 GPU_vertbuf_init_with_format(*vbo_curves_pos, format);
472 GPU_vertbuf_data_alloc(*vbo_curves_pos, vert_len);
473
474 const bke::CurvesGeometry &curves = rdata->curve_eval->geometry.wrap();
475 const Span<float3> positions = curves.evaluated_positions();
476 GPU_vertbuf_attr_fill(vbo_curves_pos, attr_id.pos, positions.data());
477}
478
480{
481 if (rdata->curve_eval == nullptr) {
482 return;
483 }
484
485 static GPUVertFormat format = {0};
486 if (format.attr_len == 0) {
488 }
489
490 const int vert_len = curve_render_data_wire_verts_len_get(rdata);
492 GPU_vertbuf_data_alloc(vbo_attr, vert_len);
493
494 const bke::CurvesGeometry &curves = rdata->curve_eval->geometry.wrap();
495 curves.ensure_can_interpolate_to_evaluated();
496 const VArraySpan colors = *curves.attributes().lookup<ColorGeometry4f>(".viewer",
498 curves.interpolate_to_evaluated(colors, vbo_attr.data<ColorGeometry4f>());
499}
500
501static void curve_create_curves_lines(CurveRenderData *rdata, gpu::IndexBuf *ibo_curve_lines)
502{
503 if (rdata->curve_eval == nullptr) {
504 return;
505 }
506
507 const int vert_len = curve_render_data_wire_verts_len_get(rdata);
508 const int edge_len = curve_render_data_wire_edges_len_get(rdata);
509 const int curve_len = curve_render_data_wire_curve_len_get(rdata);
510 /* Count the last vertex or each strip and the primitive restart. */
511 const int index_len = edge_len + curve_len * 2;
512
514 GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len);
515
516 const bke::CurvesGeometry &curves = rdata->curve_eval->geometry.wrap();
517 const OffsetIndices points_by_curve = curves.evaluated_points_by_curve();
518 const VArray<bool> cyclic = curves.cyclic();
519
520 for (const int i : curves.curves_range()) {
521 const IndexRange points = points_by_curve[i];
522 if (cyclic[i] && points.size() > 1) {
523 GPU_indexbuf_add_generic_vert(&elb, points.last());
524 }
525 for (const int i_point : points) {
526 GPU_indexbuf_add_generic_vert(&elb, i_point);
527 }
529 }
530
531 GPU_indexbuf_build_in_place(&elb, ibo_curve_lines);
532}
533
535 gpu::VertBuf &vbo_curves_nor,
536 const Scene *scene)
537{
538 const bool do_hq_normals = (scene->r.perf_flag & SCE_PERF_HQ_NORMALS) != 0 ||
540
541 static GPUVertFormat format = {0};
542 static GPUVertFormat format_hq = {0};
543 static struct {
544 uint pos, nor, tan, rad;
545 uint pos_hq, nor_hq, tan_hq, rad_hq;
546 } attr_id;
547 if (format.attr_len == 0) {
548 /* initialize vertex formats */
555
556 attr_id.pos_hq = GPU_vertformat_attr_add(&format_hq, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
557 attr_id.rad_hq = GPU_vertformat_attr_add(&format_hq, "rad", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
559 &format_hq, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
561 &format_hq, "tan", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
562 }
563
564 const GPUVertFormat &format_ptr = do_hq_normals ? format_hq : format;
565
566 int verts_len_capacity = curve_render_data_normal_len_get(rdata) * 2;
567 int vbo_len_used = 0;
568
569 GPU_vertbuf_init_with_format(vbo_curves_nor, format_ptr);
570 GPU_vertbuf_data_alloc(vbo_curves_nor, verts_len_capacity);
571
572 const BevList *bl;
573 const Nurb *nu;
574
575 const uint pos_id = do_hq_normals ? attr_id.pos_hq : attr_id.pos;
576 const uint nor_id = do_hq_normals ? attr_id.nor_hq : attr_id.nor;
577 const uint tan_id = do_hq_normals ? attr_id.tan_hq : attr_id.tan;
578 const uint rad_id = do_hq_normals ? attr_id.rad_hq : attr_id.rad;
579
580 for (bl = (const BevList *)rdata->ob_curve_cache->bev.first,
581 nu = (const Nurb *)rdata->nurbs->first;
582 nu && bl;
583 bl = bl->next, nu = nu->next)
584 {
585 const BevPoint *bevp = bl->bevpoints;
586 int nr = bl->nr;
587 int skip = nu->resolu / 16;
588
589 while (nr-- > 0) { /* accounts for empty bevel lists */
590 float nor[3] = {1.0f, 0.0f, 0.0f};
591 mul_qt_v3(bevp->quat, nor);
592
593 GPUNormal pnor;
594 GPUNormal ptan;
595 GPU_normal_convert_v3(&pnor, nor, do_hq_normals);
596 GPU_normal_convert_v3(&ptan, bevp->dir, do_hq_normals);
597 /* Only set attributes for one vertex. */
598 GPU_vertbuf_attr_set(&vbo_curves_nor, pos_id, vbo_len_used, bevp->vec);
599 GPU_vertbuf_attr_set(&vbo_curves_nor, rad_id, vbo_len_used, &bevp->radius);
600 GPU_vertbuf_attr_set(&vbo_curves_nor, nor_id, vbo_len_used, &pnor);
601 GPU_vertbuf_attr_set(&vbo_curves_nor, tan_id, vbo_len_used, &ptan);
602 vbo_len_used++;
603
604 /* Skip the other vertex (it does not need to be offsetted). */
605 GPU_vertbuf_attr_set(&vbo_curves_nor, attr_id.pos, vbo_len_used, bevp->vec);
606 vbo_len_used++;
607
608 bevp += skip + 1;
609 nr -= skip;
610 }
611 }
612 BLI_assert(vbo_len_used == verts_len_capacity);
613}
614
617 uint8_t col_id,
618 int v_idx,
619 int nu_id,
620 bool handle_point,
621 const bool handle_selected)
622{
623 uint8_t vflag = 0;
625 SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert && nu_id == rdata->actnu), VFLAG_VERT_ACTIVE);
626 SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB);
627 SET_FLAG_FROM_TEST(vflag, handle_point, BEZIER_HANDLE);
629 /* Setting flags that overlap with will cause the color id not to work properly. */
630 BLI_assert((vflag >> COLOR_SHIFT) == 0);
631 /* handle color id */
632 vflag |= col_id << COLOR_SHIFT;
633 return vflag;
634}
635
636static uint8_t bpoint_vflag_get(CurveRenderData *rdata, uint8_t flag, int v_idx, int nu_id, int u)
637{
638 uint8_t vflag = 0;
640 SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert && nu_id == rdata->actnu), VFLAG_VERT_ACTIVE);
641 SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB);
642 SET_FLAG_FROM_TEST(vflag, ((u % 2) == 0), EVEN_U_BIT);
643 /* Setting flags that overlap with will cause the color id not to work properly. */
644 BLI_assert((vflag >> COLOR_SHIFT) == 0);
646 return vflag;
647}
648
650 gpu::VertBuf *vbo_pos,
651 gpu::VertBuf *vbo_data,
652 gpu::IndexBuf *ibo_edit_verts_points,
653 gpu::IndexBuf *ibo_edit_lines)
654{
655 static GPUVertFormat format_pos = {0};
656 static GPUVertFormat format_data = {0};
657 static struct {
658 uint pos, data;
659 } attr_id;
660 if (format_pos.attr_len == 0) {
661 /* initialize vertex formats */
662 attr_id.pos = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
663 attr_id.data = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U32, 1, GPU_FETCH_INT);
664 }
665
666 int verts_len_capacity = curve_render_data_overlay_verts_len_get(rdata);
667 int edges_len_capacity = curve_render_data_overlay_edges_len_get(rdata) * 2;
668 int vbo_len_used = 0;
669
670#define DRW_TEST_ASSIGN_VBO(v) (v = (DRW_vbo_requested(v) ? (v) : nullptr))
671#define DRW_TEST_ASSIGN_IBO(v) (v = (DRW_ibo_requested(v) ? (v) : nullptr))
672
673 if (DRW_TEST_ASSIGN_VBO(vbo_pos)) {
674 GPU_vertbuf_init_with_format(*vbo_pos, format_pos);
675 GPU_vertbuf_data_alloc(*vbo_pos, verts_len_capacity);
676 }
677 if (DRW_TEST_ASSIGN_VBO(vbo_data)) {
678 GPU_vertbuf_init_with_format(*vbo_data, format_data);
679 GPU_vertbuf_data_alloc(*vbo_data, verts_len_capacity);
680 }
681
682 GPUIndexBufBuilder elb_verts, *elbp_verts = nullptr;
683 GPUIndexBufBuilder elb_lines, *elbp_lines = nullptr;
684 if (DRW_TEST_ASSIGN_IBO(ibo_edit_verts_points)) {
685 elbp_verts = &elb_verts;
686 GPU_indexbuf_init(elbp_verts, GPU_PRIM_POINTS, verts_len_capacity, verts_len_capacity);
687 }
688 if (DRW_TEST_ASSIGN_IBO(ibo_edit_lines)) {
689 elbp_lines = &elb_lines;
690 GPU_indexbuf_init(elbp_lines, GPU_PRIM_LINES, edges_len_capacity, verts_len_capacity);
691 }
692
693#undef DRW_TEST_ASSIGN_VBO
694#undef DRW_TEST_ASSIGN_IBO
695
696 int nu_id = 0;
697 for (Nurb *nu = (Nurb *)rdata->nurbs->first; nu; nu = nu->next, nu_id++) {
698 const BezTriple *bezt = nu->bezt;
699 const BPoint *bp = nu->bp;
700
701 if (bezt) {
702 for (int a = 0; a < nu->pntsu; a++, bezt++) {
703 if (bezt->hide != 0) {
704 continue;
705 }
706 const bool handle_selected = BEZT_ISSEL_ANY(bezt);
707
708 if (elbp_verts) {
709 GPU_indexbuf_add_point_vert(elbp_verts, vbo_len_used + 0);
710 GPU_indexbuf_add_point_vert(elbp_verts, vbo_len_used + 1);
711 GPU_indexbuf_add_point_vert(elbp_verts, vbo_len_used + 2);
712 }
713 if (elbp_lines) {
714 GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used + 1, vbo_len_used + 0);
715 GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used + 1, vbo_len_used + 2);
716 }
717 if (vbo_data) {
718 const uint32_t vflag[3] = {
719 beztriple_vflag_get(rdata, bezt->f1, bezt->h1, a, nu_id, true, handle_selected),
720 beztriple_vflag_get(rdata, bezt->f2, bezt->h1, a, nu_id, false, handle_selected),
721 beztriple_vflag_get(rdata, bezt->f3, bezt->h2, a, nu_id, true, handle_selected),
722 };
723 for (int j = 0; j < 3; j++) {
724 GPU_vertbuf_attr_set(vbo_data, attr_id.data, vbo_len_used + j, &vflag[j]);
725 }
726 }
727 if (vbo_pos) {
728 for (int j = 0; j < 3; j++) {
729 GPU_vertbuf_attr_set(vbo_pos, attr_id.pos, vbo_len_used + j, bezt->vec[j]);
730 }
731 }
732 vbo_len_used += 3;
733 }
734 }
735 else if (bp) {
736 int pt_len = nu->pntsu * nu->pntsv;
737 for (int a = 0; a < pt_len; a++, bp++, vbo_len_used += 1) {
738 if (bp->hide != 0) {
739 continue;
740 }
741 int u = (a % nu->pntsu);
742 int v = (a / nu->pntsu);
743 /* Use indexed rendering for bezier.
744 * Specify all points and use indices to hide/show. */
745 if (elbp_verts) {
746 GPU_indexbuf_add_point_vert(elbp_verts, vbo_len_used);
747 }
748 if (elbp_lines) {
749 const BPoint *bp_next_u = (u < (nu->pntsu - 1)) ? &nu->bp[a + 1] : nullptr;
750 const BPoint *bp_next_v = (v < (nu->pntsv - 1)) ? &nu->bp[a + nu->pntsu] : nullptr;
751 if (bp_next_u && (bp_next_u->hide == false)) {
752 GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used, vbo_len_used + 1);
753 }
754 if (bp_next_v && (bp_next_v->hide == false)) {
755 GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used, vbo_len_used + nu->pntsu);
756 }
757 }
758 if (vbo_data) {
759 uint32_t vflag = bpoint_vflag_get(rdata, bp->f1, a, nu_id, u);
760 GPU_vertbuf_attr_set(vbo_data, attr_id.data, vbo_len_used, &vflag);
761 }
762 if (vbo_pos) {
763 GPU_vertbuf_attr_set(vbo_pos, attr_id.pos, vbo_len_used, bp->vec);
764 }
765 }
766 }
767 }
768
769 /* Resize & Finish */
770 if (elbp_verts != nullptr) {
771 GPU_indexbuf_build_in_place(elbp_verts, ibo_edit_verts_points);
772 }
773 if (elbp_lines != nullptr) {
774 GPU_indexbuf_build_in_place(elbp_lines, ibo_edit_lines);
775 }
776 if (vbo_len_used != verts_len_capacity) {
777 if (vbo_pos != nullptr) {
778 GPU_vertbuf_data_resize(*vbo_pos, vbo_len_used);
779 }
780 if (vbo_data != nullptr) {
781 GPU_vertbuf_data_resize(*vbo_data, vbo_len_used);
782 }
783 }
784}
785
788/* -------------------------------------------------------------------- */
793{
795 return DRW_batch_request(&cache->batch.curves);
796}
797
803
809
815
821
823{
824 return max_ii(1, cu->totcol);
825}
826
829/* -------------------------------------------------------------------- */
834{
836
837 Curve *cu = (Curve *)ob->data;
839
840 /* Init batches and request VBOs & IBOs */
844 }
849 }
850
851 /* Edit mode */
854 DRW_vbo_request(cache->batch.edit_edges, &cache->edit.pos);
855 DRW_vbo_request(cache->batch.edit_edges, &cache->edit.data);
856 }
859 DRW_vbo_request(cache->batch.edit_verts, &cache->edit.pos);
860 DRW_vbo_request(cache->batch.edit_verts, &cache->edit.data);
861 }
864 }
865
866#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
867 printf("-- %s %s --\n", __func__, ob->id.name + 2);
868#endif
869
870 /* Generate MeshRenderData flags */
871 int mr_flag = 0;
876
882
883#ifdef DRW_DEBUG_MESH_CACHE_REQUEST
884 printf(" mr_flag %d\n\n", mr_flag);
885#endif
886
887 CurveRenderData *rdata = curve_render_data_create(cu, ob->runtime->curve_cache, mr_flag);
888
889 /* Generate VBOs */
892 }
895 }
896 if (DRW_ibo_requested(cache->ibo.curves_lines)) {
898 }
899 if (DRW_vbo_requested(cache->edit.pos) || DRW_vbo_requested(cache->edit.data) ||
901 {
903 rdata, cache->edit.pos, cache->edit.data, cache->ibo.edit_verts, cache->ibo.edit_lines);
904 }
905 if (DRW_vbo_requested(cache->edit.curves_nor)) {
906 curve_create_edit_curves_nor(rdata, *cache->edit.curves_nor, scene);
907 }
908
910
911#ifndef NDEBUG
912 /* Make sure all requested batches have been setup. */
913 for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); i++) {
914 BLI_assert(!DRW_batch_requested(((gpu::Batch **)&cache->batch)[i], (GPUPrimType)0));
915 }
916#endif
917}
918
921} // namespace blender::draw
@ BKE_CURVE_BATCH_DIRTY_SELECT
Definition BKE_curve.hh:376
@ BKE_CURVE_BATCH_DIRTY_ALL
Definition BKE_curve.hh:375
Low-level operations for curves.
display list (or rather multi purpose list) stuff.
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
MINLINE int max_ii(int a, int b)
void mul_qt_v3(const float q[4], float r[3])
unsigned int uint
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define BEZT_ISSEL_ANY(bezt)
@ OB_SURF
@ OB_FONT
@ OB_CURVES_LEGACY
@ SCE_PERF_HQ_NORMALS
#define GPU_BATCH_DISCARD_SAFE(batch)
Definition GPU_batch.hh:205
bool GPU_use_hq_normals_workaround()
#define GPU_INDEXBUF_DISCARD_SAFE(elem)
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *)
void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder *, uint v)
void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder *, uint v1, uint v2)
void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *, uint v)
void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, blender::gpu::IndexBuf *)
void GPU_indexbuf_init_ex(GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len)
GPUPrimType
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_LINE_STRIP
void GPU_vertbuf_data_resize(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertbuf_attr_fill(blender::gpu::VertBuf *, uint a_idx, const void *data)
void GPU_vertbuf_attr_set(blender::gpu::VertBuf *, uint a_idx, uint v_idx, const void *data)
#define GPU_vertbuf_init_with_format(verts, format)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
@ GPU_FETCH_INT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
BLI_INLINE void GPU_normal_convert_v3(GPUNormal *gpu_normal, const float data[3], const bool do_hq_normals)
@ GPU_COMP_I10
@ GPU_COMP_F32
@ GPU_COMP_U32
@ GPU_COMP_I16
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ TH_HANDLE_FREE
@ TH_HANDLE_AUTOCLAMP
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
MutableSpan< T > data()
#define printf
#define SELECT
#define DRW_TEST_ASSIGN_VBO(v)
#define EVEN_U_BIT
#define DRW_TEST_ASSIGN_IBO(v)
#define COLOR_SHIFT
#define BEZIER_HANDLE
#define ACTIVE_NURB
bool DRW_batch_requested(blender::gpu::Batch *batch, GPUPrimType prim_type)
#define DRW_ADD_FLAG_FROM_IBO_REQUEST(flag, ibo, value)
#define DRW_ADD_FLAG_FROM_VBO_REQUEST(flag, vbo, value)
blender::gpu::Batch * DRW_batch_request(blender::gpu::Batch **batch)
void DRW_vbo_request(blender::gpu::Batch *batch, blender::gpu::VertBuf **vbo)
bool DRW_vbo_requested(blender::gpu::VertBuf *vbo)
void DRW_ibo_request(blender::gpu::Batch *batch, blender::gpu::IndexBuf **ibo)
bool DRW_ibo_requested(blender::gpu::IndexBuf *ibo)
struct @620::@622 batch
struct @620::@623 attr_id
format
static char ** types
Definition makesdna.cc:71
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
int segments_num(const int points_num, const bool cyclic)
static void curve_batch_cache_init(Curve *cu)
static void curve_create_curves_lines(CurveRenderData *rdata, gpu::IndexBuf *ibo_curve_lines)
static uint8_t beztriple_vflag_get(CurveRenderData *rdata, uint8_t flag, uint8_t col_id, int v_idx, int nu_id, bool handle_point, const bool handle_selected)
blender::gpu::Batch * DRW_curve_batch_cache_get_wire_edge(Curve *cu)
blender::gpu::Batch * DRW_curve_batch_cache_get_edit_verts(Curve *cu)
static int curve_render_data_wire_verts_len_get(const CurveRenderData *rdata)
static int curve_render_data_normal_len_get(const CurveRenderData *rdata)
blender::gpu::Batch * DRW_curve_batch_cache_get_edit_edges(Curve *cu)
void DRW_curve_batch_cache_validate(Curve *cu)
static void curve_create_curves_pos(CurveRenderData *rdata, gpu::VertBuf *vbo_curves_pos)
void DRW_curve_batch_cache_create_requested(Object *ob, const Scene *scene)
static int curve_render_data_overlay_edges_len_get(const CurveRenderData *rdata)
blender::gpu::Batch * DRW_curve_batch_cache_get_normal_edge(Curve *cu)
static void curve_render_overlay_verts_edges_len_get(ListBase *lb, int *r_vert_len, int *r_edge_len)
static int curve_render_data_overlay_verts_len_get(const CurveRenderData *rdata)
static void curve_batch_cache_clear(Curve *cu)
void DRW_curve_batch_cache_free(Curve *cu)
int DRW_curve_material_count_get(const Curve *cu)
static CurveRenderData * curve_render_data_create(Curve *cu, CurveCache *ob_curve_cache, const int types)
static void curve_create_edit_data_and_handles(CurveRenderData *rdata, gpu::VertBuf *vbo_pos, gpu::VertBuf *vbo_data, gpu::IndexBuf *ibo_edit_verts_points, gpu::IndexBuf *ibo_edit_lines)
static void curve_render_data_free(CurveRenderData *rdata)
static void curve_create_edit_curves_nor(CurveRenderData *rdata, gpu::VertBuf &vbo_curves_nor, const Scene *scene)
static void curve_eval_render_wire_verts_edges_len_get(const bke::CurvesGeometry &curves, int *r_curve_len, int *r_vert_len, int *r_edge_len)
static CurveBatchCache * curve_batch_cache_get(Curve *cu)
static int curve_render_data_wire_edges_len_get(const CurveRenderData *rdata)
static void curve_create_attribute(CurveRenderData *rdata, gpu::VertBuf &vbo_attr)
static bool curve_batch_cache_valid(Curve *cu)
static uint8_t bpoint_vflag_get(CurveRenderData *rdata, uint8_t flag, int v_idx, int nu_id, int u)
static int curve_render_data_wire_curve_len_get(const CurveRenderData *rdata)
blender::gpu::Batch * DRW_curve_batch_cache_get_wire_edge_viewer_attribute(Curve *cu)
static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_curve_cache)
void DRW_curve_batch_cache_dirty_tag(Curve *cu, int mode)
T tan(const AngleRadianBase< T > &a)
Frequency::GEOMETRY nor[]
unsigned int uint32_t
Definition stdint.h:80
unsigned char uint8_t
Definition stdint.h:78
struct BevList * next
BevPoint * bevpoints
float dir[3]
float quat[4]
float vec[3]
float vec[3][3]
ListBase bev
Definition BKE_curve.hh:38
short totcol
void * batch_cache
const struct Curves * curve_eval
struct EditFont * editfont
EditNurb * editnurb
ListBase nurb
CurvesGeometry geometry
ListBase nurbs
char name[66]
Definition DNA_ID.h:425
void * first
struct Nurb * next
short resolu
ObjectRuntimeHandle * runtime
struct blender::draw::CurveBatchCache::@258 edit
struct blender::draw::CurveBatchCache::@260 batch
struct blender::draw::CurveBatchCache::@259 ibo
struct blender::draw::CurveBatchCache::@257 ordered
struct blender::draw::CurveRenderData::@254 wire
struct blender::draw::CurveRenderData::@253 overlay
struct blender::draw::CurveRenderData::@256 text
struct blender::draw::CurveRenderData::@255 normal
uint8_t flag
Definition wm_window.cc:138