Blender V5.0
keyframes_draw.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors, Joshua Leung. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9/* System includes ----------------------------------------------------- */
10
11#include <cfloat>
12
13#include "MEM_guardedalloc.h"
14
15#include "BKE_grease_pencil.hh"
16#include "BKE_library.hh"
17
18#include "BLI_listbase.h"
19#include "BLI_math_vector.h"
20#include "BLI_rect.h"
21
22#include "DNA_anim_types.h"
25#include "DNA_mask_types.h"
26
27#include "GPU_immediate.hh"
28#include "GPU_shader_shared.hh"
29#include "GPU_state.hh"
30
31#include "UI_interface.hh"
32#include "UI_resources.hh"
33#include "UI_view2d.hh"
34
35#include "ED_anim_api.hh"
36#include "ED_keyframes_draw.hh"
38
39#include "ANIM_action.hh"
40
41using namespace blender;
42
43/* *************************** Keyframe Drawing *************************** */
44
45void draw_keyframe_shape(const float x,
46 const float y,
47 float size,
48 const bool sel,
49 const eBezTriple_KeyframeType key_type,
50 const eKeyframeShapeDrawOpts mode,
51 const float alpha,
52 const KeyframeShaderBindings *sh_bindings,
53 const short handle_type,
54 const short extreme_type)
55{
56 bool draw_fill = ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH);
57 bool draw_outline = ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH);
58
59 BLI_assert(draw_fill || draw_outline);
60
61 /* Adjust size of keyframe shape according to type of keyframe. */
62 switch (key_type) {
64 break;
65
67 size *= 0.85f;
68 break;
69
71 size *= 0.925f;
72 break;
73
75 size *= 1.2f;
76 break;
77
79 size *= 0.8f;
80 break;
81
83 size *= 0.75;
84 break;
85 }
86
87 uchar fill_col[4];
88 uchar outline_col[4];
89 uint flags = 0;
90
91 /* draw! */
92 if (draw_fill) {
93 /* get interior colors from theme (for selected and unselected only) */
94 switch (key_type) {
97 break;
100 break;
103 break;
106 break;
109 break;
112 break;
113 }
114
115 /* For effects like graying out protected/muted channels. The theme RNA/UI doesn't allow users
116 * to set the alpha. */
117 fill_col[3] = 255.0f * alpha;
118
119 if (!draw_outline) {
120 /* force outline color to match */
121 outline_col[0] = fill_col[0];
122 outline_col[1] = fill_col[1];
123 outline_col[2] = fill_col[2];
124 outline_col[3] = fill_col[3];
125 }
126 }
127
128 if (draw_outline) {
129 /* exterior - black frame */
131 outline_col[3] *= alpha;
132
133 if (!draw_fill) {
134 /* fill color needs to be (outline.rgb, 0) */
135 fill_col[0] = outline_col[0];
136 fill_col[1] = outline_col[1];
137 fill_col[2] = outline_col[2];
138 fill_col[3] = 0;
139 }
140
141 /* Handle type to outline shape. */
142 switch (handle_type) {
145 break; /* circle */
148 break; /* circle with dot */
151 break; /* square */
154 break; /* clipped diamond */
155
157 default:
158 flags = GPU_KEYFRAME_SHAPE_DIAMOND; /* diamond */
159 }
160
161 /* Extreme type to arrow-like shading. */
162 if (extreme_type & KEYFRAME_EXTREME_MAX) {
164 }
165 if (extreme_type & KEYFRAME_EXTREME_MIN) {
167 }
168 if (extreme_type & GPU_KEYFRAME_SHAPE_ARROW_END_MIXED) {
169 flags |= 0x400;
170 }
171 }
172
173 immAttr1f(sh_bindings->size_id, size);
174 immAttr4ubv(sh_bindings->color_id, fill_col);
175 immAttr4ubv(sh_bindings->outline_color_id, outline_col);
176 immAttr1u(sh_bindings->flags_id, flags);
177 immVertex2f(sh_bindings->pos_id, x, y);
178}
179
180/* Common attributes shared between the draw calls. */
182 float alpha;
186 float ipo_size;
189 float sel_color[4];
190 float unsel_color[4];
191 float sel_mhcol[4];
192 float unsel_mhcol[4];
193 float ipo_color[4];
195
196 /* Show interpolation and handle type? */
198};
199
201 View2D *v2d,
202 float yscale_fac,
203 bool channel_locked,
204 eSAction_Flag saction_flag)
205{
206 /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
207 /* TODO: allow this opacity factor to be themed? */
208 ctx->alpha = channel_locked ? 0.25f : 1.0f;
209
210 ctx->icon_size = U.widget_unit * 0.5f * yscale_fac;
211 ctx->half_icon_size = 0.5f * ctx->icon_size;
212 ctx->smaller_size = 0.35f * ctx->icon_size;
213 ctx->ipo_size = 0.1f * ctx->icon_size;
214 ctx->gpencil_size = ctx->smaller_size * 0.8f;
216
217 ctx->show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0;
218
222
223 ctx->sel_color[3] *= ctx->alpha;
224 ctx->unsel_color[3] *= ctx->alpha;
225 ctx->ipo_color[3] *= ctx->alpha;
226
227 copy_v4_v4(ctx->sel_mhcol, ctx->sel_color);
228 ctx->sel_mhcol[3] *= 0.8f;
230 ctx->unsel_mhcol[3] *= 0.8f;
232 ctx->ipo_color_mix[3] *= 0.5f;
233}
234
236 const ActKeyColumn *ab,
237 float ypos)
238{
240 float size = 1.0f;
241 switch (ab->next->key_type) {
246 size *= 0.5f;
247 break;
249 size *= 0.8f;
250 break;
252 break;
253 }
254
255 rctf box;
256 box.xmin = ab->cfra;
257 box.xmax = min_ff(ab->next->cfra - (ctx->screenspace_margin * size), ab->next->cfra);
258 box.ymin = ypos - ctx->gpencil_size;
259 box.ymax = ypos + ctx->gpencil_size;
260
262 &box, true, 0.25f * float(UI_UNIT_X), (ab->block.sel) ? ctx->sel_mhcol : ctx->unsel_mhcol);
263}
264
266 const ActKeyColumn *ab,
267 float ypos)
268{
269 rctf box;
270 box.xmin = ab->cfra;
271 box.xmax = ab->next->cfra;
272 box.ymin = ypos - ctx->smaller_size;
273 box.ymax = ypos + ctx->smaller_size;
274
275 UI_draw_roundbox_4fv(&box, true, 3.0f, (ab->block.sel) ? ctx->sel_mhcol : ctx->unsel_mhcol);
276}
277
279 const ActKeyColumn *ab,
280 float ypos)
281{
282 rctf box;
283 box.xmin = ab->cfra;
284 box.xmax = ab->next->cfra;
285 box.ymin = ypos - ctx->half_icon_size;
286 box.ymax = ypos + ctx->half_icon_size;
287
288 UI_draw_roundbox_4fv(&box, true, 3.0f, (ab->block.sel) ? ctx->sel_color : ctx->unsel_color);
289}
290
292 const ActKeyColumn *ab,
293 float ypos)
294{
295 rctf box;
296 box.xmin = ab->cfra;
297 box.xmax = ab->next->cfra;
298 box.ymin = ypos - ctx->ipo_size;
299 box.ymax = ypos + ctx->ipo_size;
300
302 true,
303 3.0f,
305 ctx->ipo_color);
306}
307
308static void draw_keylist_block(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos)
309{
310 /* Draw grease pencil bars between keyframes. */
311 if ((ab->next != nullptr) && (ab->block.flag & ACTKEYBLOCK_FLAG_GPENCIL)) {
312 draw_keylist_block_gpencil(ctx, ab, ypos);
313 }
314 else {
315 /* Draw other types. */
317
318 int valid_hold = actkeyblock_get_valid_hold(ab);
319 if (valid_hold != 0) {
320 if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
321 /* draw "moving hold" long-keyframe block - slightly smaller */
322 draw_keylist_block_moving_hold(ctx, ab, ypos);
323 }
324 else {
325 /* draw standard long-keyframe block */
326 draw_keylist_block_standard(ctx, ab, ypos);
327 }
328 }
329 if (ctx->show_ipo && actkeyblock_is_valid(ab) &&
331 {
332 /* draw an interpolation line */
334 }
335 }
336}
337
339 const ActKeyColumn *keys,
340 const int key_len,
341 float ypos)
342{
343 for (int i = 0; i < key_len; i++) {
344 const ActKeyColumn *ab = &keys[i];
345 draw_keylist_block(ctx, ab, ypos);
346 }
347}
348
349static bool draw_keylist_is_visible_key(const View2D *v2d, const ActKeyColumn *ak)
350{
351 return IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax);
352}
353
355 View2D *v2d,
356 const KeyframeShaderBindings *sh_bindings,
357 const ActKeyColumn *keys,
358 const int key_len,
359 float ypos,
360 eSAction_Flag saction_flag)
361{
362 short handle_type = KEYFRAME_HANDLE_NONE, extreme_type = KEYFRAME_EXTREME_NONE;
363
364 for (int i = 0; i < key_len; i++) {
365 const ActKeyColumn *ak = &keys[i];
366 if (draw_keylist_is_visible_key(v2d, ak)) {
367 if (ctx->show_ipo) {
368 handle_type = ak->handle_type;
369 }
370 if (saction_flag & SACTION_SHOW_EXTREMES) {
371 extreme_type = ak->extreme_type;
372 }
373
375 ypos,
376 ctx->icon_size,
377 (ak->sel & SELECT),
380 ctx->alpha,
381 sh_bindings,
382 handle_type,
383 extreme_type);
384 }
385 }
386}
387
388/* *************************** Drawing Stack *************************** */
404
409
411 float ypos;
414
415 /* Currently only used for F-Curve channels, because some should be nla
416 * remapped but not others. All other channel types ignore this, as it's clear
417 * from the type whether they should be nla remapped or not. */
419
420 /* TODO: check which of these can be put into a `union`: */
425 ID *animated_id; /* The ID that adt (below) belongs to. */
436};
437
439{
440 switch (elem->type) {
442 summary_to_keylist(elem->ac, elem->keylist, elem->saction_flag, range);
443 break;
444 }
445 case ChannelType::SCENE: {
446 scene_to_keylist(elem->ads, elem->sce, elem->keylist, elem->saction_flag, range);
447 break;
448 }
449 case ChannelType::OBJECT: {
450 ob_to_keylist(elem->ads, elem->ob, elem->keylist, elem->saction_flag, range);
451 break;
452 }
453 case ChannelType::FCURVE: {
455 elem->adt, elem->fcu, elem->keylist, elem->saction_flag, range, elem->use_nla_remapping);
456 break;
457 }
459 /* This is only called for action summaries in the Dope-sheet, *not* the
460 * Action Editor. Therefore despite the name `ACTION_LAYERED`, this is
461 * only used to show a *single slot* of the action: the slot used by the
462 * ID the action is listed under.
463 *
464 * Thus we use the same function as the `ChannelType::ACTION_SLOT` case
465 * below because in practice the only distinction between these cases is
466 * where they get the slot from. In this case, we get it from `elem`'s
467 * ADT. */
468 BLI_assert(elem->act);
469 BLI_assert(elem->adt);
471 elem->animated_id,
472 elem->act->wrap(),
473 elem->adt->slot_handle,
474 elem->keylist,
475 elem->saction_flag,
476 range);
477 break;
478 }
480 BLI_assert(elem->act);
481 BLI_assert(elem->action_slot);
483 elem->animated_id,
484 elem->act->wrap(),
485 elem->action_slot->handle,
486 elem->keylist,
487 elem->saction_flag,
488 range);
489 break;
490 }
492 action_to_keylist(elem->adt, elem->act, elem->keylist, elem->saction_flag, range);
493 break;
494 }
496 action_group_to_keylist(elem->adt, elem->agrp, elem->keylist, elem->saction_flag, range);
497 break;
498 }
501 elem->adt, elem->grease_pencil_layer, elem->keylist, elem->saction_flag);
502 break;
503 }
506 elem->adt, elem->grease_pencil_layer_group, elem->keylist, elem->saction_flag);
507 break;
508 }
510 if (elem->ac->datatype != ANIMCONT_GPENCIL && elem->adt) {
511 action_to_keylist(elem->adt, elem->adt->action, elem->keylist, elem->saction_flag, range);
512 }
514 elem->adt, elem->grease_pencil, elem->keylist, elem->saction_flag, false);
515 break;
516 }
518 gpl_to_keylist(elem->ads, elem->gpl, elem->keylist);
519 break;
520 }
522 mask_to_keylist(elem->ads, elem->masklay, elem->keylist);
523 break;
524 }
525 }
526}
527
529{
531 channel_ui_data_init(&ctx, v2d, elem->yscale_fac, elem->channel_locked, elem->saction_flag);
532
533 const int key_len = ED_keylist_array_len(elem->keylist);
534 const ActKeyColumn *keys = ED_keylist_array(elem->keylist);
535 draw_keylist_blocks(&ctx, keys, key_len, elem->ypos);
536}
537
539 View2D *v2d,
540 const KeyframeShaderBindings *sh_bindings)
541{
543 channel_ui_data_init(&ctx, v2d, elem->yscale_fac, elem->channel_locked, elem->saction_flag);
544
545 const int key_len = ED_keylist_array_len(elem->keylist);
546 const ActKeyColumn *keys = ED_keylist_array(elem->keylist);
547 draw_keylist_keys(&ctx, v2d, sh_bindings, keys, key_len, elem->ypos, elem->saction_flag);
548}
549
554
557 ListBase /*ChannelListElement*/ channels;
558};
559
564
566{
567 LISTBASE_FOREACH (ChannelListElement *, elem, &channel_list->channels) {
568 build_channel_keylist(elem, range);
570 }
571}
572
573static void channel_list_draw_blocks(ChannelDrawList *channel_list, View2D *v2d)
574{
575 LISTBASE_FOREACH (ChannelListElement *, elem, &channel_list->channels) {
576 draw_channel_blocks(elem, v2d);
577 }
578}
579
580static int channel_visible_key_len(const View2D *v2d, const ListBase * /*ActKeyColumn*/ keys)
581{
582 /* count keys */
583 uint len = 0;
584
585 LISTBASE_FOREACH (ActKeyColumn *, ak, keys) {
586 /* Optimization: if keyframe doesn't appear within 5 units (screenspace)
587 * in visible area, don't draw.
588 * This might give some improvements,
589 * since we current have to flip between view/region matrices.
590 */
591 if (draw_keylist_is_visible_key(v2d, ak)) {
592 len++;
593 }
594 }
595 return len;
596}
597
598static int channel_list_visible_key_len(const ChannelDrawList *channel_list, const View2D *v2d)
599{
600 uint len = 0;
601 LISTBASE_FOREACH (ChannelListElement *, elem, &channel_list->channels) {
602 const ListBase *keys = ED_keylist_listbase(elem->keylist);
603 len += channel_visible_key_len(v2d, keys);
604 }
605 return len;
606}
607
608static void channel_list_draw_keys(ChannelDrawList *channel_list, View2D *v2d)
609{
610 const int visible_key_len = channel_list_visible_key_len(channel_list, v2d);
611 if (visible_key_len == 0) {
612 return;
613 }
614
616
618 KeyframeShaderBindings sh_bindings;
619
620 sh_bindings.pos_id = GPU_vertformat_attr_add(
621 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
622 sh_bindings.size_id = GPU_vertformat_attr_add(
623 format, "size", blender::gpu::VertAttrType::SFLOAT_32);
624 sh_bindings.color_id = GPU_vertformat_attr_add(
625 format, "color", blender::gpu::VertAttrType::UNORM_8_8_8_8);
627 format, "outlineColor", blender::gpu::VertAttrType::UNORM_8_8_8_8);
628 sh_bindings.flags_id = GPU_vertformat_attr_add(
629 format, "flags", blender::gpu::VertAttrType::UINT_32);
630
633 immUniform1f("outline_scale", 1.0f);
634 immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
635 immBegin(GPU_PRIM_POINTS, visible_key_len);
636
637 LISTBASE_FOREACH (ChannelListElement *, elem, &channel_list->channels) {
638 draw_channel_keys(elem, v2d, &sh_bindings);
639 }
640
641 immEnd();
644
646}
647
648static void channel_list_draw(ChannelDrawList *channel_list, View2D *v2d)
649{
650 channel_list_draw_blocks(channel_list, v2d);
651 channel_list_draw_keys(channel_list, v2d);
652}
653
655{
656 channel_list_build_keylists(channel_list, {v2d->cur.xmin, v2d->cur.xmax});
657 channel_list_draw(channel_list, v2d);
658}
659
661{
662 LISTBASE_FOREACH (ChannelListElement *, elem, &channel_list->channels) {
663 ED_keylist_free(elem->keylist);
664 }
665 BLI_freelistN(&channel_list->channels);
666 MEM_freeN(channel_list);
667}
668
670 ChannelType elem_type,
671 float ypos,
672 float yscale_fac,
673 eSAction_Flag saction_flag)
674{
676 BLI_addtail(&channel_list->channels, draw_elem);
677 draw_elem->type = elem_type;
678 draw_elem->keylist = ED_keylist_create();
679 draw_elem->ypos = ypos;
680 draw_elem->yscale_fac = yscale_fac;
681 draw_elem->saction_flag = saction_flag;
682 return draw_elem;
683}
684
685/* *************************** Channel Drawing Functions *************************** */
686
688 bAnimContext *ac,
689 float ypos,
690 float yscale_fac,
691 int saction_flag)
692{
693 saction_flag &= ~SACTION_SHOW_EXTREMES;
695 channel_list, ChannelType::SUMMARY, ypos, yscale_fac, eSAction_Flag(saction_flag));
696 draw_elem->ac = ac;
697}
698
700 bDopeSheet *ads,
701 Scene *sce,
702 float ypos,
703 float yscale_fac,
704 int saction_flag)
705{
706 saction_flag &= ~SACTION_SHOW_EXTREMES;
708 channel_list, ChannelType::SCENE, ypos, yscale_fac, eSAction_Flag(saction_flag));
709 draw_elem->ads = ads;
710 draw_elem->sce = sce;
711}
712
714 bDopeSheet *ads,
715 Object *ob,
716 float ypos,
717 float yscale_fac,
718 int saction_flag)
719{
720 saction_flag &= ~SACTION_SHOW_EXTREMES;
722 channel_list, ChannelType::OBJECT, ypos, yscale_fac, eSAction_Flag(saction_flag));
723 draw_elem->ads = ads;
724 draw_elem->ob = ob;
725}
726
728 bAnimListElem *ale,
729 FCurve *fcu,
730 float ypos,
731 float yscale_fac,
732 int saction_flag)
733{
734 const bool locked = (fcu->flag & FCURVE_PROTECTED) ||
735 ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
736 ((ale->adt && ale->adt->action) &&
737 (!ID_IS_EDITABLE(ale->adt->action) ||
739
741 channel_list, ChannelType::FCURVE, ypos, yscale_fac, eSAction_Flag(saction_flag));
742 draw_elem->animated_id = ale->id;
743 draw_elem->adt = ale->adt;
744 draw_elem->fcu = fcu;
745 draw_elem->channel_locked = locked;
747}
748
750 bAnimListElem *ale,
751 bActionGroup *agrp,
752 float ypos,
753 float yscale_fac,
754 int saction_flag)
755{
756 bool locked = (agrp->flag & AGRP_PROTECTED) ||
757 ((ale->adt && ale->adt->action) &&
759
761 channel_list, ChannelType::ACTION_GROUP, ypos, yscale_fac, eSAction_Flag(saction_flag));
762 draw_elem->animated_id = ale->id;
763 draw_elem->adt = ale->adt;
764 draw_elem->agrp = agrp;
765 draw_elem->channel_locked = locked;
766}
767
769 bAnimContext *ac,
770 bAnimListElem *ale,
771 bAction *action,
772 const float ypos,
773 const float yscale_fac,
774 int saction_flag)
775{
776 BLI_assert(action);
777 BLI_assert(action->wrap().is_action_layered());
778
779 const bool locked = (!ID_IS_EDITABLE(action) || ID_IS_OVERRIDE_LIBRARY(action));
780 saction_flag &= ~SACTION_SHOW_EXTREMES;
781
783 channel_list, ChannelType::ACTION_LAYERED, ypos, yscale_fac, eSAction_Flag(saction_flag));
784 draw_elem->ac = ac;
785 draw_elem->animated_id = ale->id;
786 draw_elem->adt = ale->adt;
787 draw_elem->act = action;
788 draw_elem->channel_locked = locked;
789}
790
792 bAnimContext *ac,
793 bAnimListElem *ale,
794 animrig::Action &action,
795 animrig::Slot &slot,
796 const float ypos,
797 const float yscale_fac,
798 int saction_flag)
799{
800 const bool locked = (ID_IS_LINKED(&action) || ID_IS_OVERRIDE_LIBRARY(&action));
801 saction_flag &= ~SACTION_SHOW_EXTREMES;
802
804 channel_list, ChannelType::ACTION_SLOT, ypos, yscale_fac, eSAction_Flag(saction_flag));
805 draw_elem->ac = ac;
806 draw_elem->animated_id = ale->id;
807 draw_elem->adt = ale->adt;
808 draw_elem->act = &action;
809 draw_elem->action_slot = &slot;
810 draw_elem->channel_locked = locked;
811}
812
814 bAnimListElem *ale,
815 bAction *act,
816 float ypos,
817 float yscale_fac,
818 int saction_flag)
819{
820 BLI_assert(!act || act->wrap().is_action_legacy());
821
822 const bool locked = (act && (!ID_IS_EDITABLE(act) || ID_IS_OVERRIDE_LIBRARY(act)));
823 saction_flag &= ~SACTION_SHOW_EXTREMES;
824
826 channel_list, ChannelType::ACTION_LEGACY, ypos, yscale_fac, eSAction_Flag(saction_flag));
827 draw_elem->animated_id = ale->id;
828 draw_elem->adt = ale->adt;
829 draw_elem->act = act;
830 draw_elem->channel_locked = locked;
831}
832
834 bAnimContext *ac,
835 bAnimListElem *ale,
836 const GreasePencil *grease_pencil,
837 const float ypos,
838 const float yscale_fac,
839 int saction_flag)
840{
841 ChannelListElement *draw_elem = channel_list_add_element(channel_list,
843 ypos,
844 yscale_fac,
845 eSAction_Flag(saction_flag));
846 /* GreasePencil properties can be animated via an Action, so the GP-related
847 * animation data is not limited to GP drawings. */
848 draw_elem->animated_id = ale->id;
849 draw_elem->adt = ale->adt;
850 draw_elem->act = ale->adt ? ale->adt->action : nullptr;
851 draw_elem->grease_pencil = grease_pencil;
852 draw_elem->ac = ac;
853}
854
856 bDopeSheet *ads,
857 const GreasePencilLayer *layer,
858 const float ypos,
859 const float yscale_fac,
860 int saction_flag)
861{
862 ChannelListElement *draw_elem = channel_list_add_element(channel_list,
864 ypos,
865 yscale_fac,
866 eSAction_Flag(saction_flag));
867 draw_elem->ads = ads;
868 draw_elem->grease_pencil_layer = layer;
869 draw_elem->channel_locked = layer->wrap().is_locked();
870}
871
873 bDopeSheet *ads,
874 const GreasePencilLayerTreeGroup *layer_group,
875 const float ypos,
876 const float yscale_fac,
877 int saction_flag)
878{
879 ChannelListElement *draw_elem = channel_list_add_element(channel_list,
881 ypos,
882 yscale_fac,
883 eSAction_Flag(saction_flag));
884 draw_elem->ads = ads;
885 draw_elem->grease_pencil_layer_group = layer_group;
886 draw_elem->channel_locked = layer_group->wrap().is_locked();
887}
888
890 bDopeSheet *ads,
891 bGPDlayer *gpl,
892 float ypos,
893 float yscale_fac,
894 int saction_flag)
895{
896 bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0;
897 ChannelListElement *draw_elem = channel_list_add_element(channel_list,
899 ypos,
900 yscale_fac,
901 eSAction_Flag(saction_flag));
902 draw_elem->ads = ads;
903 draw_elem->gpl = gpl;
904 draw_elem->channel_locked = locked;
905}
906
908 bDopeSheet *ads,
909 MaskLayer *masklay,
910 float ypos,
911 float yscale_fac,
912 int saction_flag)
913{
914 bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0;
916 channel_list, ChannelType::MASK_LAYER, ypos, yscale_fac, eSAction_Flag(saction_flag));
917 draw_elem->ads = ads;
918 draw_elem->masklay = masklay;
919 draw_elem->channel_locked = locked;
920}
Functions and classes to work with Actions.
Low-level operations for grease pencil.
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
MINLINE float min_ff(float a, float b)
MINLINE void copy_v4_v4(float r[4], const float a[4])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
unsigned char uchar
unsigned int uint
#define ELEM(...)
#define IN_RANGE_INCL(a, b, c)
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:705
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
@ AGRP_PROTECTED
eSAction_Flag
@ SACTION_SHOW_INTERPOLATION
@ SACTION_SHOW_EXTREMES
@ FCURVE_PROTECTED
eBezTriple_KeyframeType
@ BEZT_KEYTYPE_EXTREME
@ BEZT_KEYTYPE_JITTER
@ BEZT_KEYTYPE_BREAKDOWN
@ BEZT_KEYTYPE_MOVEHOLD
@ BEZT_KEYTYPE_GENERATED
@ BEZT_KEYTYPE_KEYFRAME
@ MASK_LAYERFLAG_LOCKED
@ ANIMCONT_GPENCIL
@ ACTKEYBLOCK_FLAG_GPENCIL
@ ACTKEYBLOCK_FLAG_NON_BEZIER
@ ACTKEYBLOCK_FLAG_STATIC_HOLD
eKeyframeShapeDrawOpts
@ KEYFRAME_SHAPE_INSIDE
@ KEYFRAME_SHAPE_BOTH
@ KEYFRAME_SHAPE_FRAME
@ KEYFRAME_HANDLE_VECTOR
@ KEYFRAME_HANDLE_FREE
@ KEYFRAME_HANDLE_AUTO_CLAMP
@ KEYFRAME_HANDLE_NONE
@ KEYFRAME_HANDLE_AUTO
@ KEYFRAME_HANDLE_ALIGNED
@ KEYFRAME_EXTREME_MAX
@ KEYFRAME_EXTREME_NONE
@ KEYFRAME_EXTREME_MIN
void immEnd()
void immUnbindProgram()
void immBindBuiltinProgram(GPUBuiltinShader shader_id)
void immUniform2f(const char *name, float x, float y)
void immAttr4ubv(uint attr_id, const unsigned char data[4])
void immVertex2f(uint attr_id, float x, float y)
void immAttr1f(uint attr_id, float x)
void immAttr1u(uint attr_id, uint x)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat()
void immBegin(GPUPrimType, uint vertex_len)
@ GPU_PRIM_POINTS
@ GPU_SHADER_KEYFRAME_SHAPE
@ GPU_KEYFRAME_SHAPE_INNER_DOT
@ GPU_KEYFRAME_SHAPE_CIRCLE
@ GPU_KEYFRAME_SHAPE_SQUARE
@ GPU_KEYFRAME_SHAPE_ARROW_END_MIXED
@ GPU_KEYFRAME_SHAPE_DIAMOND
@ GPU_KEYFRAME_SHAPE_ARROW_END_MAX
@ GPU_KEYFRAME_SHAPE_ARROW_END_MIN
@ GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL
void GPU_program_point_size(bool enable)
Definition gpu_state.cc:180
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
void GPU_blend(GPUBlend blend)
Definition gpu_state.cc:42
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
Read Guarded memory(de)allocation.
void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float col[4])
void UI_draw_roundbox_corner_set(int type)
@ UI_CNR_BOTTOM_RIGHT
@ UI_CNR_TOP_RIGHT
@ UI_CNR_NONE
#define UI_UNIT_X
@ TH_KEYTYPE_GENERATED
@ TH_KEYBORDER_SELECT
@ TH_KEYTYPE_BREAKDOWN
@ TH_KEYTYPE_KEYFRAME
@ TH_DOPESHEET_IPOLINE
@ TH_KEYBORDER
@ TH_KEYTYPE_JITTER
@ TH_KEYTYPE_EXTREME
@ TH_KEYTYPE_KEYFRAME_SELECT
@ TH_KEYTYPE_MOVEHOLD
@ TH_KEYTYPE_BREAKDOWN_SELECT
@ TH_KEYTYPE_EXTREME_SELECT
@ TH_KEYTYPE_MOVEHOLD_SELECT
@ TH_KEYTYPE_JITTER_SELECT
@ TH_LONGKEY_SELECT
@ TH_KEYTYPE_GENERATED_SELECT
@ TH_LONGKEY
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
void UI_GetThemeColor4fv(int colorid, float col[4])
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
float UI_view2d_scale_get_x(const View2D *v2d)
Definition view2d.cc:1921
bool ANIM_nla_mapping_allowed(const bAnimListElem *ale)
Definition anim_draw.cc:274
#define U
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
nullptr float
#define SELECT
static void draw_keylist_block_standard(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos)
static void channel_ui_data_init(DrawKeylistUIData *ctx, View2D *v2d, float yscale_fac, bool channel_locked, eSAction_Flag saction_flag)
void ED_add_fcurve_channel(ChannelDrawList *channel_list, bAnimListElem *ale, FCurve *fcu, float ypos, float yscale_fac, int saction_flag)
static void prepare_channel_for_drawing(ChannelListElement *elem)
void ED_add_grease_pencil_layer_legacy_channel(ChannelDrawList *channel_list, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag)
static void draw_keylist_block_gpencil(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos)
ChannelType
ChannelDrawList * ED_channel_draw_list_create()
void ED_add_action_channel(ChannelDrawList *channel_list, bAnimListElem *ale, bAction *act, float ypos, float yscale_fac, int saction_flag)
void ED_add_grease_pencil_cels_channel(ChannelDrawList *channel_list, bDopeSheet *ads, const GreasePencilLayer *layer, const float ypos, const float yscale_fac, int saction_flag)
void ED_add_action_group_channel(ChannelDrawList *channel_list, bAnimListElem *ale, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag)
static void channel_list_draw_blocks(ChannelDrawList *channel_list, View2D *v2d)
void ED_add_scene_channel(ChannelDrawList *channel_list, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag)
void ED_channel_list_flush(ChannelDrawList *channel_list, View2D *v2d)
static int channel_list_visible_key_len(const ChannelDrawList *channel_list, const View2D *v2d)
void ED_add_grease_pencil_datablock_channel(ChannelDrawList *channel_list, bAnimContext *ac, bAnimListElem *ale, const GreasePencil *grease_pencil, const float ypos, const float yscale_fac, int saction_flag)
void ED_add_grease_pencil_layer_group_channel(ChannelDrawList *channel_list, bDopeSheet *ads, const GreasePencilLayerTreeGroup *layer_group, const float ypos, const float yscale_fac, int saction_flag)
static void draw_channel_keys(ChannelListElement *elem, View2D *v2d, const KeyframeShaderBindings *sh_bindings)
static void channel_list_build_keylists(ChannelDrawList *channel_list, blender::float2 range)
static void draw_keylist_block_interpolation_line(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos)
static void draw_channel_blocks(ChannelListElement *elem, View2D *v2d)
static void draw_keylist_block(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos)
static void channel_list_draw_keys(ChannelDrawList *channel_list, View2D *v2d)
static void channel_list_draw(ChannelDrawList *channel_list, View2D *v2d)
void draw_keyframe_shape(const float x, const float y, float size, const bool sel, const eBezTriple_KeyframeType key_type, const eKeyframeShapeDrawOpts mode, const float alpha, const KeyframeShaderBindings *sh_bindings, const short handle_type, const short extreme_type)
void ED_channel_list_free(ChannelDrawList *channel_list)
static void draw_keylist_block_moving_hold(const DrawKeylistUIData *ctx, const ActKeyColumn *ab, float ypos)
static bool draw_keylist_is_visible_key(const View2D *v2d, const ActKeyColumn *ak)
void ED_add_mask_layer_channel(ChannelDrawList *channel_list, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac, int saction_flag)
void ED_add_summary_channel(ChannelDrawList *channel_list, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag)
static ChannelListElement * channel_list_add_element(ChannelDrawList *channel_list, ChannelType elem_type, float ypos, float yscale_fac, eSAction_Flag saction_flag)
void ED_add_object_channel(ChannelDrawList *channel_list, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag)
void ED_add_action_slot_channel(ChannelDrawList *channel_list, bAnimContext *ac, bAnimListElem *ale, animrig::Action &action, animrig::Slot &slot, const float ypos, const float yscale_fac, int saction_flag)
static int channel_visible_key_len(const View2D *v2d, const ListBase *keys)
static void build_channel_keylist(ChannelListElement *elem, blender::float2 range)
void ED_add_action_layered_channel(ChannelDrawList *channel_list, bAnimContext *ac, bAnimListElem *ale, bAction *action, const float ypos, const float yscale_fac, int saction_flag)
static void draw_keylist_keys(const DrawKeylistUIData *ctx, View2D *v2d, const KeyframeShaderBindings *sh_bindings, const ActKeyColumn *keys, const int key_len, float ypos, eSAction_Flag saction_flag)
static void draw_keylist_blocks(const DrawKeylistUIData *ctx, const ActKeyColumn *keys, const int key_len, float ypos)
void mask_to_keylist(bDopeSheet *, MaskLayer *masklay, AnimKeylist *keylist)
bool actkeyblock_is_valid(const ActKeyColumn *ac)
void action_slot_summary_to_keylist(bAnimContext *ac, ID *animated_id, animrig::Action &action, const animrig::slot_handle_t slot_handle, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, AnimKeylist *keylist, const int saction_flag, blender::float2 range, const bool use_nla_remapping)
void scene_to_keylist(bDopeSheet *ads, Scene *sce, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
void ob_to_keylist(bDopeSheet *ads, Object *ob, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
void grease_pencil_data_block_to_keylist(AnimData *adt, const GreasePencil *grease_pencil, AnimKeylist *keylist, const int saction_flag, const bool active_layer_only)
void ED_keylist_prepare_for_direct_access(AnimKeylist *keylist)
void summary_to_keylist(bAnimContext *ac, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
AnimKeylist * ED_keylist_create()
int actkeyblock_get_valid_hold(const ActKeyColumn *ac)
void ED_keylist_free(AnimKeylist *keylist)
int64_t ED_keylist_array_len(const AnimKeylist *keylist)
const ListBase * ED_keylist_listbase(const AnimKeylist *keylist)
void grease_pencil_layer_group_to_keylist(AnimData *adt, const GreasePencilLayerTreeGroup *layer_group, AnimKeylist *keylist, const int saction_flag)
void action_to_keylist(AnimData *adt, bAction *dna_action, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
void grease_pencil_cels_to_keylist(AnimData *, const GreasePencilLayer *gpl, AnimKeylist *keylist, int)
void gpl_to_keylist(bDopeSheet *, bGPDlayer *gpl, AnimKeylist *keylist)
void action_group_to_keylist(AnimData *adt, bActionGroup *agrp, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
const ActKeyColumn * ED_keylist_array(const AnimKeylist *keylist)
format
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
VecBase< float, 2 > float2
eBezTriple_KeyframeType key_type
ActKeyColumn * next
ActKeyBlockInfo block
bAction * action
int32_t slot_handle
AnimKeylist * keylist
const GreasePencilLayer * grease_pencil_layer
bActionGroup * agrp
ChannelListElement * prev
const GreasePencilLayerTreeGroup * grease_pencil_layer_group
animrig::Slot * action_slot
ChannelListElement * next
const GreasePencil * grease_pencil
eSAction_Flag saction_flag
bActionGroup * grp
Definition DNA_ID.h:414
eAnimCont_Types datatype
AnimData * adt
float xmax
float xmin
float ymax
float ymin
i
Definition text_draw.cc:230
uint len