Blender  V2.93
keyframes_draw.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
17  * All rights reserved.
18  */
19 
24 /* System includes ----------------------------------------------------- */
25 
26 #include <float.h>
27 #include <math.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_dlrbTree.h"
34 #include "BLI_listbase.h"
35 #include "BLI_math.h"
36 #include "BLI_rect.h"
37 #include "BLI_utildefines.h"
38 
39 #include "DNA_anim_types.h"
40 #include "DNA_brush_types.h"
41 #include "DNA_cachefile_types.h"
42 #include "DNA_gpencil_types.h"
43 #include "DNA_mask_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46 
47 #include "BKE_fcurve.h"
48 
49 #include "GPU_immediate.h"
50 #include "GPU_state.h"
51 
52 #include "UI_interface.h"
53 #include "UI_resources.h"
54 #include "UI_view2d.h"
55 
56 #include "ED_anim_api.h"
57 #include "ED_keyframes_draw.h"
58 
59 /* *************************** Keyframe Processing *************************** */
60 
61 /* ActKeyColumns (Keyframe Columns) ------------------------------------------ */
62 
63 BLI_INLINE bool is_cfra_eq(float a, float b)
64 {
65  return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH);
66 }
67 
68 BLI_INLINE bool is_cfra_lt(float a, float b)
69 {
70  return (b - a) > BEZT_BINARYSEARCH_THRESH;
71 }
72 
73 /* Comparator callback used for ActKeyColumns and cframe float-value pointer */
74 /* NOTE: this is exported to other modules that use the ActKeyColumns for finding keyframes */
75 short compare_ak_cfraPtr(void *node, void *data)
76 {
78  const float *cframe = data;
79  float val = *cframe;
80 
81  if (is_cfra_eq(val, ak->cfra)) {
82  return 0;
83  }
84 
85  if (val < ak->cfra) {
86  return -1;
87  }
88  return 1;
89 }
90 
91 /* --------------- */
92 
93 /* Set of references to three logically adjacent keys. */
94 typedef struct BezTripleChain {
95  /* Current keyframe. */
97 
98  /* Logical neighbors. May be NULL. */
101 
102 /* Categorize the interpolation & handle type of the keyframe. */
104 {
105  if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) {
107  }
108  if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) {
109  return KEYFRAME_HANDLE_AUTO;
110  }
111  if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
112  return KEYFRAME_HANDLE_VECTOR;
113  }
114  if (ELEM(HD_FREE, bezt->h1, bezt->h2)) {
115  return KEYFRAME_HANDLE_FREE;
116  }
118 }
119 
120 /* Determine if the keyframe is an extreme by comparing with neighbors.
121  * Ends of fixed-value sections and of the whole curve are also marked.
122  */
124 {
125  if (chain->prev == NULL && chain->next == NULL) {
126  return KEYFRAME_EXTREME_NONE;
127  }
128 
129  /* Keyframe values for the current one and neighbors. */
130  float cur_y = chain->cur->vec[1][1];
131  float prev_y = cur_y, next_y = cur_y;
132 
133  if (chain->prev && !IS_EQF(cur_y, chain->prev->vec[1][1])) {
134  prev_y = chain->prev->vec[1][1];
135  }
136  if (chain->next && !IS_EQF(cur_y, chain->next->vec[1][1])) {
137  next_y = chain->next->vec[1][1];
138  }
139 
140  /* Static hold. */
141  if (prev_y == cur_y && next_y == cur_y) {
142  return KEYFRAME_EXTREME_FLAT;
143  }
144 
145  /* Middle of an incline. */
146  if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) {
147  return KEYFRAME_EXTREME_NONE;
148  }
149 
150  /* Bezier handle values for the overshoot check. */
151  bool l_bezier = chain->prev && chain->prev->ipo == BEZT_IPO_BEZ;
152  bool r_bezier = chain->next && chain->cur->ipo == BEZT_IPO_BEZ;
153  float handle_l = l_bezier ? chain->cur->vec[0][1] : cur_y;
154  float handle_r = r_bezier ? chain->cur->vec[2][1] : cur_y;
155 
156  /* Detect extremes. One of the neighbors is allowed to be equal to current. */
157  if (prev_y < cur_y || next_y < cur_y) {
158  bool is_overshoot = (handle_l > cur_y || handle_r > cur_y);
159 
160  return KEYFRAME_EXTREME_MAX | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
161  }
162 
163  if (prev_y > cur_y || next_y > cur_y) {
164  bool is_overshoot = (handle_l < cur_y || handle_r < cur_y);
165 
166  return KEYFRAME_EXTREME_MIN | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
167  }
168 
169  return KEYFRAME_EXTREME_NONE;
170 }
171 
172 /* Comparator callback used for ActKeyColumns and BezTripleChain */
173 static short compare_ak_bezt(void *node, void *data)
174 {
175  BezTripleChain *chain = data;
176 
177  return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]);
178 }
179 
180 /* New node callback used for building ActKeyColumns from BezTripleChain */
182 {
183  ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
184  BezTripleChain *chain = data;
185  BezTriple *bezt = chain->cur;
186 
187  /* store settings based on state of BezTriple */
188  ak->cfra = bezt->vec[1][0];
189  ak->sel = BEZT_ISSEL_ANY(bezt) ? SELECT : 0;
190  ak->key_type = BEZKEYTYPE(bezt);
191  ak->handle_type = bezt_handle_type(bezt);
192  ak->extreme_type = bezt_extreme_type(chain);
193 
194  /* count keyframes in this column */
195  ak->totkey = 1;
196 
197  return (DLRBT_Node *)ak;
198 }
199 
200 /* Node updater callback used for building ActKeyColumns from BezTripleChain */
201 static void nupdate_ak_bezt(void *node, void *data)
202 {
203  ActKeyColumn *ak = node;
204  BezTripleChain *chain = data;
205  BezTriple *bezt = chain->cur;
206 
207  /* set selection status and 'touched' status */
208  if (BEZT_ISSEL_ANY(bezt)) {
209  ak->sel = SELECT;
210  }
211 
212  /* count keyframes in this column */
213  ak->totkey++;
214 
215  /* For keyframe type, 'proper' keyframes have priority over breakdowns
216  * (and other types for now). */
217  if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME) {
219  }
220 
221  /* For interpolation type, select the highest value (enum is sorted). */
222  ak->handle_type = MAX2(ak->handle_type, bezt_handle_type(bezt));
223 
224  /* For extremes, detect when combining different states. */
225  char new_extreme = bezt_extreme_type(chain);
226 
227  if (new_extreme != ak->extreme_type) {
228  /* Replace the flat status without adding mixed. */
229  if (ak->extreme_type == KEYFRAME_EXTREME_FLAT) {
230  ak->extreme_type = new_extreme;
231  }
232  else if (new_extreme != KEYFRAME_EXTREME_FLAT) {
233  ak->extreme_type |= (new_extreme | KEYFRAME_EXTREME_MIXED);
234  }
235  }
236 }
237 
238 /* ......... */
239 
240 /* Comparator callback used for ActKeyColumns and GPencil frame */
241 static short compare_ak_gpframe(void *node, void *data)
242 {
243  bGPDframe *gpf = (bGPDframe *)data;
244 
245  float frame = gpf->framenum;
246  return compare_ak_cfraPtr(node, &frame);
247 }
248 
249 /* New node callback used for building ActKeyColumns from GPencil frames */
251 {
252  ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
253  bGPDframe *gpf = (bGPDframe *)data;
254 
255  /* store settings based on state of BezTriple */
256  ak->cfra = gpf->framenum;
257  ak->sel = (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
258  ak->key_type = gpf->key_type;
259 
260  /* count keyframes in this column */
261  ak->totkey = 1;
262  /* Set as visible block. */
263  ak->totblock = 1;
264  ak->block.sel = ak->sel;
266 
267  return (DLRBT_Node *)ak;
268 }
269 
270 /* Node updater callback used for building ActKeyColumns from GPencil frames */
271 static void nupdate_ak_gpframe(void *node, void *data)
272 {
273  ActKeyColumn *ak = (ActKeyColumn *)node;
274  bGPDframe *gpf = (bGPDframe *)data;
275 
276  /* set selection status and 'touched' status */
277  if (gpf->flag & GP_FRAME_SELECT) {
278  ak->sel = SELECT;
279  }
280 
281  /* count keyframes in this column */
282  ak->totkey++;
283 
284  /* for keyframe type, 'proper' keyframes have priority over breakdowns
285  * (and other types for now). */
286  if (gpf->key_type == BEZT_KEYTYPE_KEYFRAME) {
288  }
289 }
290 
291 /* ......... */
292 
293 /* Comparator callback used for ActKeyColumns and GPencil frame */
294 static short compare_ak_masklayshape(void *node, void *data)
295 {
296  MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
297 
298  float frame = masklay_shape->frame;
299  return compare_ak_cfraPtr(node, &frame);
300 }
301 
302 /* New node callback used for building ActKeyColumns from GPencil frames */
304 {
305  ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
306  MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
307 
308  /* store settings based on state of BezTriple */
309  ak->cfra = masklay_shape->frame;
310  ak->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? SELECT : 0;
311 
312  /* count keyframes in this column */
313  ak->totkey = 1;
314 
315  return (DLRBT_Node *)ak;
316 }
317 
318 /* Node updater callback used for building ActKeyColumns from GPencil frames */
319 static void nupdate_ak_masklayshape(void *node, void *data)
320 {
321  ActKeyColumn *ak = (ActKeyColumn *)node;
322  MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
323 
324  /* set selection status and 'touched' status */
325  if (masklay_shape->flag & MASK_SHAPE_SELECT) {
326  ak->sel = SELECT;
327  }
328 
329  /* count keyframes in this column */
330  ak->totkey++;
331 }
332 
333 /* --------------- */
334 
335 /* Add the given BezTriple to the given 'list' of Keyframes */
337 {
338  if (ELEM(NULL, keys, bezt)) {
339  return;
340  }
341 
343 }
344 
345 /* Add the given GPencil Frame to the given 'list' of Keyframes */
347 {
348  if (ELEM(NULL, keys, gpf)) {
349  return;
350  }
351 
353 }
354 
355 /* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */
356 static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape)
357 {
358  if (ELEM(NULL, keys, masklay_shape)) {
359  return;
360  }
361 
362  BLI_dlrbTree_add(keys,
366  masklay_shape);
367 }
368 
369 /* ActKeyBlocks (Long Keyframes) ------------------------------------------ */
370 
371 static const ActKeyBlockInfo dummy_keyblock = {0};
372 
373 static void compute_keyblock_data(ActKeyBlockInfo *info, BezTriple *prev, BezTriple *beztn)
374 {
375  memset(info, 0, sizeof(ActKeyBlockInfo));
376 
377  if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) {
378  /* Animator tagged a "moving hold"
379  * - Previous key must also be tagged as a moving hold, otherwise
380  * we're just dealing with the first of a pair, and we don't
381  * want to be creating any phantom holds...
382  */
383  if (BEZKEYTYPE(prev) == BEZT_KEYTYPE_MOVEHOLD) {
385  }
386  }
387 
388  /* Check for same values...
389  * - Handles must have same central value as each other
390  * - Handles which control that section of the curve must be constant
391  */
392  if (IS_EQF(beztn->vec[1][1], prev->vec[1][1])) {
393  bool hold;
394 
395  /* Only check handles in case of actual bezier interpolation. */
396  if (prev->ipo == BEZT_IPO_BEZ) {
397  hold = IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) &&
398  IS_EQF(prev->vec[1][1], prev->vec[2][1]);
399  }
400  /* This interpolation type induces movement even between identical keys. */
401  else {
402  hold = !ELEM(prev->ipo, BEZT_IPO_ELASTIC);
403  }
404 
405  if (hold) {
407  }
408  }
409 
410  /* Remember non-bezier interpolation info. */
411  if (prev->ipo != BEZT_IPO_BEZ) {
413  }
414 
415  info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn);
416 }
417 
419 {
420  /* New curve and block. */
421  if (col->totcurve <= 1 && col->totblock == 0) {
422  memcpy(&col->block, block, sizeof(ActKeyBlockInfo));
423  }
424  /* Existing curve. */
425  else {
426  col->block.conflict |= (col->block.flag ^ block->flag);
427  col->block.flag |= block->flag;
428  col->block.sel |= block->sel;
429  }
430 
431  if (block->flag) {
432  col->totblock++;
433  }
434 }
435 
436 static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len)
437 {
438  ActKeyColumn *col = keys->first;
439 
440  if (bezt && bezt_len >= 2) {
441  ActKeyBlockInfo block;
442 
443  /* Find the first key column while inserting dummy blocks. */
444  for (; col != NULL && is_cfra_lt(col->cfra, bezt[0].vec[1][0]); col = col->next) {
446  }
447 
448  BLI_assert(col != NULL);
449 
450  /* Insert real blocks. */
451  for (int v = 1; col != NULL && v < bezt_len; v++, bezt++) {
452  /* Wrong order of bezier keys: resync position. */
453  if (is_cfra_lt(bezt[1].vec[1][0], bezt[0].vec[1][0])) {
454  /* Backtrack to find the right location. */
455  if (is_cfra_lt(bezt[1].vec[1][0], col->cfra)) {
457  keys, compare_ak_cfraPtr, &bezt[1].vec[1][0]);
458 
459  if (newcol != NULL) {
460  col = newcol;
461 
462  /* The previous keyblock is garbage too. */
463  if (col->prev != NULL) {
465  }
466  }
467  else {
468  BLI_assert(false);
469  }
470  }
471 
472  continue;
473  }
474 
475  /* Normal sequence */
476  BLI_assert(is_cfra_eq(col->cfra, bezt[0].vec[1][0]));
477 
478  compute_keyblock_data(&block, bezt, bezt + 1);
479 
480  for (; col != NULL && is_cfra_lt(col->cfra, bezt[1].vec[1][0]); col = col->next) {
481  add_keyblock_info(col, &block);
482  }
483 
484  BLI_assert(col != NULL);
485  }
486  }
487 
488  /* Insert dummy blocks at the end. */
489  for (; col != NULL; col = col->next) {
491  }
492 }
493 
494 /* Walk through columns and propagate blocks and totcurve.
495  *
496  * This must be called even by animation sources that don't generate
497  * keyblocks to keep the data structure consistent after adding columns.
498  */
499 static void update_keyblocks(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len)
500 {
501  /* Recompute the prev/next linked list. */
503 
504  /* Find the curve count */
505  int max_curve = 0;
506 
507  LISTBASE_FOREACH (ActKeyColumn *, col, keys) {
508  max_curve = MAX2(max_curve, col->totcurve);
509  }
510 
511  /* Propagate blocks to inserted keys */
512  ActKeyColumn *prev_ready = NULL;
513 
514  LISTBASE_FOREACH (ActKeyColumn *, col, keys) {
515  /* Pre-existing column. */
516  if (col->totcurve > 0) {
517  prev_ready = col;
518  }
519  /* Newly inserted column, so copy block data from previous. */
520  else if (prev_ready != NULL) {
521  col->totblock = prev_ready->totblock;
522  memcpy(&col->block, &prev_ready->block, sizeof(ActKeyBlockInfo));
523  }
524 
525  col->totcurve = max_curve + 1;
526  }
527 
528  /* Add blocks on top */
529  add_bezt_to_keyblocks_list(keys, bezt, bezt_len);
530 }
531 
532 /* --------- */
533 
535 {
536  return ac != NULL && ac->next != NULL && ac->totblock > 0;
537 }
538 
539 /* Checks if ActKeyBlock should exist... */
541 {
542  /* check that block is valid */
543  if (!actkeyblock_is_valid(ac)) {
544  return 0;
545  }
546 
548  return (ac->block.flag & ~ac->block.conflict) & hold_mask;
549 }
550 
551 /* *************************** Keyframe Drawing *************************** */
552 
554  float y,
555  float size,
556  bool sel,
557  short key_type,
558  short mode,
559  float alpha,
560  uint pos_id,
561  uint size_id,
562  uint color_id,
563  uint outline_color_id,
564  uint flags_id,
565  short handle_type,
566  short extreme_type)
567 {
568  bool draw_fill = ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH);
569  bool draw_outline = ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH);
570 
571  BLI_assert(draw_fill || draw_outline);
572 
573  /* tweak size of keyframe shape according to type of keyframe
574  * - 'proper' keyframes have key_type = 0, so get drawn at full size
575  */
576  switch (key_type) {
577  case BEZT_KEYTYPE_KEYFRAME: /* must be full size */
578  break;
579 
580  case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */
581  size *= 0.85f;
582  break;
583 
584  case BEZT_KEYTYPE_MOVEHOLD: /* Slightly smaller than normal keyframes
585  * (but by less than for breakdowns). */
586  size *= 0.925f;
587  break;
588 
589  case BEZT_KEYTYPE_EXTREME: /* slightly larger */
590  size *= 1.2f;
591  break;
592 
593  default:
594  size -= 0.8f * key_type;
595  }
596 
597  uchar fill_col[4];
598  uchar outline_col[4];
599  uint flags = 0;
600 
601  /* draw! */
602  if (draw_fill) {
603  /* get interior colors from theme (for selected and unselected only) */
604  switch (key_type) {
605  case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames (default theme) */
607  break;
608  case BEZT_KEYTYPE_EXTREME: /* reddish frames (default theme) */
610  break;
611  case BEZT_KEYTYPE_JITTER: /* greenish frames (default theme) */
613  break;
614  case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */
616  break;
617  case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */
618  default:
620  }
621 
622  /* NOTE: we don't use the straight alpha from the theme, or else effects such as
623  * graying out protected/muted channels doesn't work correctly!
624  */
625  fill_col[3] *= alpha;
626 
627  if (!draw_outline) {
628  /* force outline color to match */
629  outline_col[0] = fill_col[0];
630  outline_col[1] = fill_col[1];
631  outline_col[2] = fill_col[2];
632  outline_col[3] = fill_col[3];
633  }
634  }
635 
636  if (draw_outline) {
637  /* exterior - black frame */
639  outline_col[3] *= alpha;
640 
641  if (!draw_fill) {
642  /* fill color needs to be (outline.rgb, 0) */
643  fill_col[0] = outline_col[0];
644  fill_col[1] = outline_col[1];
645  fill_col[2] = outline_col[2];
646  fill_col[3] = 0;
647  }
648 
649  /* Handle type to outline shape. */
650  switch (handle_type) {
652  flags = 0x2;
653  break; /* circle */
655  flags = 0x12;
656  break; /* circle with dot */
658  flags = 0xC;
659  break; /* square */
661  flags = 0x5;
662  break; /* clipped diamond */
663 
665  default:
666  flags = 1; /* diamond */
667  }
668 
669  /* Extreme type to arrow-like shading. */
670  if (extreme_type & KEYFRAME_EXTREME_MAX) {
671  flags |= 0x100;
672  }
673  if (extreme_type & KEYFRAME_EXTREME_MIN) {
674  flags |= 0x200;
675  }
676  if (extreme_type & KEYFRAME_EXTREME_MIXED) {
677  flags |= 0x400;
678  }
679  }
680 
681  immAttr1f(size_id, size);
682  immAttr4ubv(color_id, fill_col);
683  immAttr4ubv(outline_color_id, outline_col);
684  immAttr1u(flags_id, flags);
685  immVertex2f(pos_id, x, y);
686 }
687 
688 static void draw_keylist(View2D *v2d,
689  DLRBT_Tree *keys,
690  float ypos,
691  float yscale_fac,
692  bool channelLocked,
693  int saction_flag)
694 {
695  if (keys == NULL) {
696  return;
697  }
698 
699  const float icon_sz = U.widget_unit * 0.5f * yscale_fac;
700  const float half_icon_sz = 0.5f * icon_sz;
701  const float smaller_sz = 0.35f * icon_sz;
702  const float ipo_sz = 0.1f * icon_sz;
703  const float gpencil_sz = smaller_sz * 0.8f;
704  const float screenspace_margin = (0.35f * (float)UI_UNIT_X) / UI_view2d_scale_get_x(v2d);
705 
706  /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
707  /* TODO: allow this opacity factor to be themed? */
708  float alpha = channelLocked ? 0.25f : 1.0f;
709 
710  /* Show interpolation and handle type? */
711  bool show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0;
712  /* draw keyblocks */
713  float sel_color[4], unsel_color[4];
714  float sel_mhcol[4], unsel_mhcol[4];
715  float ipo_color[4], ipo_color_mix[4];
716 
717  /* cache colors first */
719  UI_GetThemeColor4fv(TH_STRIP, unsel_color);
721 
722  sel_color[3] *= alpha;
723  unsel_color[3] *= alpha;
724  ipo_color[3] *= alpha;
725 
726  copy_v4_v4(sel_mhcol, sel_color);
727  sel_mhcol[3] *= 0.8f;
728  copy_v4_v4(unsel_mhcol, unsel_color);
729  unsel_mhcol[3] *= 0.8f;
730  copy_v4_v4(ipo_color_mix, ipo_color);
731  ipo_color_mix[3] *= 0.5f;
732 
733  LISTBASE_FOREACH (ActKeyColumn *, ab, keys) {
734  /* Draw grease pencil bars between keyframes. */
735  if ((ab->next != NULL) && (ab->block.flag & ACTKEYBLOCK_FLAG_GPENCIL)) {
737  float size = 1.0f;
738  switch (ab->next->key_type) {
741  case BEZT_KEYTYPE_JITTER:
742  size *= 0.5f;
743  break;
745  size *= 0.8f;
746  break;
747  default:
748  break;
749  }
751  &(const rctf){
752  .xmin = ab->cfra,
753  .xmax = min_ff(ab->next->cfra - (screenspace_margin * size), ab->next->cfra),
754  .ymin = ypos - gpencil_sz,
755  .ymax = ypos + gpencil_sz,
756  },
757  true,
758  0.25f * (float)UI_UNIT_X,
759  (ab->block.sel) ? sel_mhcol : unsel_mhcol);
760  }
761  else {
762  /* Draw other types. */
764 
765  int valid_hold = actkeyblock_get_valid_hold(ab);
766  if (valid_hold != 0) {
767  if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
768  /* draw "moving hold" long-keyframe block - slightly smaller */
770  &(const rctf){
771  .xmin = ab->cfra,
772  .xmax = ab->next->cfra,
773  .ymin = ypos - smaller_sz,
774  .ymax = ypos + smaller_sz,
775  },
776  true,
777  3.0f,
778  (ab->block.sel) ? sel_mhcol : unsel_mhcol);
779  }
780  else {
781  /* draw standard long-keyframe block */
783  &(const rctf){
784  .xmin = ab->cfra,
785  .xmax = ab->next->cfra,
786  .ymin = ypos - half_icon_sz,
787  .ymax = ypos + half_icon_sz,
788  },
789  true,
790  3.0f,
791  (ab->block.sel) ? sel_color : unsel_color);
792  }
793  }
794  if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
795  /* draw an interpolation line */
797  &(const rctf){
798  .xmin = ab->cfra,
799  .xmax = ab->next->cfra,
800  .ymin = ypos - ipo_sz,
801  .ymax = ypos + ipo_sz,
802  },
803  true,
804  3.0f,
805  (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
806  }
807  }
808  }
809 
811 
812  /* count keys */
813  uint key_len = 0;
814  LISTBASE_FOREACH (ActKeyColumn *, ak, keys) {
815  /* Optimization: if keyframe doesn't appear within 5 units (screenspace)
816  * in visible area, don't draw.
817  * This might give some improvements,
818  * since we current have to flip between view/region matrices.
819  */
820  if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) {
821  key_len++;
822  }
823  }
824 
825  if (key_len > 0) {
826  /* draw keys */
830  uint color_id = GPU_vertformat_attr_add(
832  uint outline_color_id = GPU_vertformat_attr_add(
833  format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
835 
838  immUniform1f("outline_scale", 1.0f);
839  immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
840  immBegin(GPU_PRIM_POINTS, key_len);
841 
842  short handle_type = KEYFRAME_HANDLE_NONE, extreme_type = KEYFRAME_EXTREME_NONE;
843 
844  LISTBASE_FOREACH (ActKeyColumn *, ak, keys) {
845  if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) {
846  if (show_ipo) {
847  handle_type = ak->handle_type;
848  }
849  if (saction_flag & SACTION_SHOW_EXTREMES) {
850  extreme_type = ak->extreme_type;
851  }
852 
853  draw_keyframe_shape(ak->cfra,
854  ypos,
855  icon_sz,
856  (ak->sel & SELECT),
857  ak->key_type,
859  alpha,
860  pos_id,
861  size_id,
862  color_id,
863  outline_color_id,
864  flags_id,
865  handle_type,
866  extreme_type);
867  }
868  }
869 
870  immEnd();
871  GPU_program_point_size(false);
873  }
874 
876 }
877 
878 /* *************************** Channel Drawing Funcs *************************** */
879 
881  View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag)
882 {
883  DLRBT_Tree keys;
884 
885  saction_flag &= ~SACTION_SHOW_EXTREMES;
886 
887  BLI_dlrbTree_init(&keys);
888 
889  summary_to_keylist(ac, &keys, saction_flag);
890 
891  draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
892 
893  BLI_dlrbTree_free(&keys);
894 }
895 
897  View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag)
898 {
899  DLRBT_Tree keys;
900 
901  saction_flag &= ~SACTION_SHOW_EXTREMES;
902 
903  BLI_dlrbTree_init(&keys);
904 
905  scene_to_keylist(ads, sce, &keys, saction_flag);
906 
907  draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
908 
909  BLI_dlrbTree_free(&keys);
910 }
911 
913  View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag)
914 {
915  DLRBT_Tree keys;
916 
917  saction_flag &= ~SACTION_SHOW_EXTREMES;
918 
919  BLI_dlrbTree_init(&keys);
920 
921  ob_to_keylist(ads, ob, &keys, saction_flag);
922 
923  draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
924 
925  BLI_dlrbTree_free(&keys);
926 }
927 
929  View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac, int saction_flag)
930 {
931  DLRBT_Tree keys;
932 
933  bool locked = (fcu->flag & FCURVE_PROTECTED) ||
934  ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
935  ((adt && adt->action) && ID_IS_LINKED(adt->action));
936 
937  BLI_dlrbTree_init(&keys);
938 
939  fcurve_to_keylist(adt, fcu, &keys, saction_flag);
940 
941  draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
942 
943  BLI_dlrbTree_free(&keys);
944 }
945 
947  View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag)
948 {
949  DLRBT_Tree keys;
950 
951  bool locked = (agrp->flag & AGRP_PROTECTED) ||
952  ((adt && adt->action) && ID_IS_LINKED(adt->action));
953 
954  BLI_dlrbTree_init(&keys);
955 
956  agroup_to_keylist(adt, agrp, &keys, saction_flag);
957 
958  draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
959 
960  BLI_dlrbTree_free(&keys);
961 }
962 
964  View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac, int saction_flag)
965 {
966  DLRBT_Tree keys;
967 
968  bool locked = (act && ID_IS_LINKED(act));
969 
970  saction_flag &= ~SACTION_SHOW_EXTREMES;
971 
972  BLI_dlrbTree_init(&keys);
973 
974  action_to_keylist(adt, act, &keys, saction_flag);
975 
976  draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
977 
978  BLI_dlrbTree_free(&keys);
979 }
980 
982  View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac, int saction_flag)
983 {
984  DLRBT_Tree keys;
985 
986  saction_flag &= ~SACTION_SHOW_EXTREMES;
987 
988  BLI_dlrbTree_init(&keys);
989 
990  gpencil_to_keylist(ads, gpd, &keys, false);
991 
992  draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
993 
994  BLI_dlrbTree_free(&keys);
995 }
996 
998  View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag)
999 {
1000  DLRBT_Tree keys;
1001 
1002  bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0;
1003 
1004  BLI_dlrbTree_init(&keys);
1005 
1006  gpl_to_keylist(ads, gpl, &keys);
1007 
1008  draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
1009 
1010  BLI_dlrbTree_free(&keys);
1011 }
1012 
1014  bDopeSheet *ads,
1015  MaskLayer *masklay,
1016  float ypos,
1017  float yscale_fac,
1018  int saction_flag)
1019 {
1020  DLRBT_Tree keys;
1021 
1022  bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0;
1023 
1024  BLI_dlrbTree_init(&keys);
1025 
1026  mask_to_keylist(ads, masklay, &keys);
1027 
1028  draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
1029 
1030  BLI_dlrbTree_free(&keys);
1031 }
1032 
1033 /* *************************** Keyframe List Conversions *************************** */
1034 
1035 void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag)
1036 {
1037  if (ac) {
1038  ListBase anim_data = {NULL, NULL};
1039  bAnimListElem *ale;
1040  int filter;
1041 
1042  /* get F-Curves to take keyframes from */
1044  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1045 
1046  /* loop through each F-Curve, grabbing the keyframes */
1047  for (ale = anim_data.first; ale; ale = ale->next) {
1048  /* Why not use all #eAnim_KeyType here?
1049  * All of the other key types are actually "summaries" themselves,
1050  * and will just end up duplicating stuff that comes up through
1051  * standard filtering of just F-Curves. Given the way that these work,
1052  * there isn't really any benefit at all from including them. - Aligorith */
1053 
1054  switch (ale->datatype) {
1055  case ALE_FCURVE:
1056  fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
1057  break;
1058  case ALE_MASKLAY:
1059  mask_to_keylist(ac->ads, ale->data, keys);
1060  break;
1061  case ALE_GPFRAME:
1062  gpl_to_keylist(ac->ads, ale->data, keys);
1063  break;
1064  default:
1065  // printf("%s: datatype %d unhandled\n", __func__, ale->datatype);
1066  break;
1067  }
1068  }
1069 
1070  ANIM_animdata_freelist(&anim_data);
1071  }
1072 }
1073 
1074 void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, int saction_flag)
1075 {
1076  bAnimContext ac = {NULL};
1077  ListBase anim_data = {NULL, NULL};
1078  bAnimListElem *ale;
1079  int filter;
1080 
1081  bAnimListElem dummychan = {NULL};
1082 
1083  if (sce == NULL) {
1084  return;
1085  }
1086 
1087  /* create a dummy wrapper data to work with */
1088  dummychan.type = ANIMTYPE_SCENE;
1089  dummychan.data = sce;
1090  dummychan.id = &sce->id;
1091  dummychan.adt = sce->adt;
1092 
1093  ac.ads = ads;
1094  ac.data = &dummychan;
1096 
1097  /* get F-Curves to take keyframes from */
1098  filter = ANIMFILTER_DATA_VISIBLE; /* curves only */
1099  ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
1100 
1101  /* loop through each F-Curve, grabbing the keyframes */
1102  for (ale = anim_data.first; ale; ale = ale->next) {
1103  fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
1104  }
1105 
1106  ANIM_animdata_freelist(&anim_data);
1107 }
1108 
1109 void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_flag)
1110 {
1111  bAnimContext ac = {NULL};
1112  ListBase anim_data = {NULL, NULL};
1113  bAnimListElem *ale;
1114  int filter;
1115 
1116  bAnimListElem dummychan = {NULL};
1117  Base dummybase = {NULL};
1118 
1119  if (ob == NULL) {
1120  return;
1121  }
1122 
1123  /* create a dummy wrapper data to work with */
1124  dummybase.object = ob;
1125 
1126  dummychan.type = ANIMTYPE_OBJECT;
1127  dummychan.data = &dummybase;
1128  dummychan.id = &ob->id;
1129  dummychan.adt = ob->adt;
1130 
1131  ac.ads = ads;
1132  ac.data = &dummychan;
1134 
1135  /* get F-Curves to take keyframes from */
1136  filter = ANIMFILTER_DATA_VISIBLE; /* curves only */
1137  ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
1138 
1139  /* loop through each F-Curve, grabbing the keyframes */
1140  for (ale = anim_data.first; ale; ale = ale->next) {
1141  fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
1142  }
1143 
1144  ANIM_animdata_freelist(&anim_data);
1145 }
1146 
1148  CacheFile *cache_file,
1149  DLRBT_Tree *keys,
1150  int saction_flag)
1151 {
1152  if (cache_file == NULL) {
1153  return;
1154  }
1155 
1156  /* create a dummy wrapper data to work with */
1157  bAnimListElem dummychan = {NULL};
1158  dummychan.type = ANIMTYPE_DSCACHEFILE;
1159  dummychan.data = cache_file;
1160  dummychan.id = &cache_file->id;
1161  dummychan.adt = cache_file->adt;
1162 
1163  bAnimContext ac = {NULL};
1164  ac.ads = ads;
1165  ac.data = &dummychan;
1167 
1168  /* get F-Curves to take keyframes from */
1169  ListBase anim_data = {NULL, NULL};
1170  int filter = ANIMFILTER_DATA_VISIBLE; /* curves only */
1171  ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
1172 
1173  /* loop through each F-Curve, grabbing the keyframes */
1174  LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
1175  fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
1176  }
1177 
1178  ANIM_animdata_freelist(&anim_data);
1179 }
1180 
1181 void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, int saction_flag)
1182 {
1183  if (fcu && fcu->totvert && fcu->bezt) {
1184  /* apply NLA-mapping (if applicable) */
1185  if (adt) {
1186  ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
1187  }
1188 
1189  /* Check if the curve is cyclic. */
1190  bool is_cyclic = BKE_fcurve_is_cyclic(fcu) && (fcu->totvert >= 2);
1191  bool do_extremes = (saction_flag & SACTION_SHOW_EXTREMES) != 0;
1192 
1193  /* loop through beztriples, making ActKeysColumns */
1194  BezTripleChain chain = {0};
1195 
1196  for (int v = 0; v < fcu->totvert; v++) {
1197  chain.cur = &fcu->bezt[v];
1198 
1199  /* Neighbor keys, accounting for being cyclic. */
1200  if (do_extremes) {
1201  chain.prev = (v > 0) ? &fcu->bezt[v - 1] : is_cyclic ? &fcu->bezt[fcu->totvert - 2] : NULL;
1202  chain.next = (v + 1 < fcu->totvert) ? &fcu->bezt[v + 1] : is_cyclic ? &fcu->bezt[1] : NULL;
1203  }
1204 
1205  add_bezt_to_keycolumns_list(keys, &chain);
1206  }
1207 
1208  /* Update keyblocks. */
1209  update_keyblocks(keys, fcu->bezt, fcu->totvert);
1210 
1211  /* unapply NLA-mapping if applicable */
1212  if (adt) {
1213  ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
1214  }
1215  }
1216 }
1217 
1218 void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, int saction_flag)
1219 {
1220  FCurve *fcu;
1221 
1222  if (agrp) {
1223  /* loop through F-Curves */
1224  for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) {
1225  fcurve_to_keylist(adt, fcu, keys, saction_flag);
1226  }
1227  }
1228 }
1229 
1230 void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, int saction_flag)
1231 {
1232  FCurve *fcu;
1233 
1234  if (act) {
1235  /* loop through F-Curves */
1236  for (fcu = act->curves.first; fcu; fcu = fcu->next) {
1237  fcurve_to_keylist(adt, fcu, keys, saction_flag);
1238  }
1239  }
1240 }
1241 
1242 void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys, const bool active)
1243 {
1244  bGPDlayer *gpl;
1245 
1246  if (gpd && keys) {
1247  /* for now, just aggregate out all the frames, but only for visible layers */
1248  for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
1249  if ((gpl->flag & GP_LAYER_HIDE) == 0) {
1250  if ((!active) || ((active) && (gpl->flag & GP_LAYER_SELECT))) {
1251  gpl_to_keylist(ads, gpl, keys);
1252  }
1253  }
1254  }
1255  }
1256 }
1257 
1259 {
1260  bGPDframe *gpf;
1261 
1262  if (gpl && keys) {
1263  /* Although the frames should already be in an ordered list,
1264  * they are not suitable for displaying yet. */
1265  for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1266  add_gpframe_to_keycolumns_list(keys, gpf);
1267  }
1268 
1269  update_keyblocks(keys, NULL, 0);
1270  }
1271 }
1272 
1274 {
1275  MaskLayerShape *masklay_shape;
1276 
1277  if (masklay && keys) {
1278  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
1279  masklay_shape = masklay_shape->next) {
1280  add_masklay_to_keycolumns_list(keys, masklay_shape);
1281  }
1282 
1283  update_keyblocks(keys, NULL, 0);
1284  }
1285 }
typedef float(TangentPoint)[2]
#define BEZT_BINARYSEARCH_THRESH
Definition: BKE_fcurve.h:181
bool BKE_fcurve_is_cyclic(struct FCurve *fcu)
Definition: fcurve.c:1267
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
void BLI_dlrbTree_init(DLRBT_Tree *tree)
Definition: DLRB_tree.c:40
DLRBT_Node * BLI_dlrbTree_add(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, DLRBT_NAlloc_FP new_cb, DLRBT_NUpdate_FP update_cb, void *data)
Definition: DLRB_tree.c:545
void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree)
Definition: DLRB_tree.c:113
DLRBT_Node * BLI_dlrbTree_search_exact(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
Definition: DLRB_tree.c:177
void BLI_dlrbTree_free(DLRBT_Tree *tree)
Definition: DLRB_tree.c:66
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
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:157
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
#define IS_EQF(a, b)
#define IN_RANGE_INCL(a, b, c)
#define IS_EQT(a, b, c)
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
@ AGRP_PROTECTED
@ SACTION_SHOW_INTERPOLATION
@ SACTION_SHOW_EXTREMES
@ FCURVE_PROTECTED
#define BEZT_ISSEL_ANY(bezt)
@ HD_AUTO_ANIM
@ HD_VECT
@ HD_FREE
@ HD_AUTO
@ BEZT_IPO_ELASTIC
@ BEZT_IPO_BEZ
@ BEZT_KEYTYPE_EXTREME
@ BEZT_KEYTYPE_JITTER
@ BEZT_KEYTYPE_BREAKDOWN
@ BEZT_KEYTYPE_MOVEHOLD
@ BEZT_KEYTYPE_KEYFRAME
@ GP_LAYER_LOCKED
@ GP_LAYER_SELECT
@ GP_LAYER_HIDE
@ GP_FRAME_SELECT
@ MASK_LAYERFLAG_LOCKED
@ MASK_SHAPE_SELECT
Object is a sort of wrapper for general info.
@ ANIMTYPE_SCENE
Definition: ED_anim_api.h:204
@ ANIMTYPE_DSCACHEFILE
Definition: ED_anim_api.h:218
@ ANIMTYPE_OBJECT
Definition: ED_anim_api.h:205
@ ALE_GPFRAME
Definition: ED_anim_api.h:259
@ ALE_FCURVE
Definition: ED_anim_api.h:258
@ ALE_MASKLAY
Definition: ED_anim_api.h:260
@ ANIMCONT_CHANNEL
Definition: ED_anim_api.h:124
#define BEZKEYTYPE(bezt)
Definition: ED_anim_api.h:789
@ ANIMFILTER_DATA_VISIBLE
Definition: ED_anim_api.h:295
@ ACTKEYBLOCK_FLAG_ANY_HOLD
@ ACTKEYBLOCK_FLAG_MOVING_HOLD
@ ACTKEYBLOCK_FLAG_GPENCIL
@ ACTKEYBLOCK_FLAG_NON_BEZIER
@ ACTKEYBLOCK_FLAG_STATIC_HOLD
@ KEYFRAME_SHAPE_INSIDE
@ KEYFRAME_SHAPE_BOTH
@ KEYFRAME_SHAPE_FRAME
eKeyframeHandleDrawOpts
@ KEYFRAME_HANDLE_VECTOR
@ KEYFRAME_HANDLE_FREE
@ KEYFRAME_HANDLE_AUTO_CLAMP
@ KEYFRAME_HANDLE_NONE
@ KEYFRAME_HANDLE_AUTO
@ KEYFRAME_HANDLE_ALIGNED
eKeyframeExtremeDrawOpts
@ KEYFRAME_EXTREME_MAX
@ KEYFRAME_EXTREME_MIXED
@ KEYFRAME_EXTREME_NONE
@ KEYFRAME_EXTREME_FLAT
@ KEYFRAME_EXTREME_MIN
void immUniform2f(const char *name, float x, float y)
void immAttr4ubv(uint attr_id, const unsigned char data[4])
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immAttr1f(uint attr_id, float x)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immAttr1u(uint attr_id, uint x)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat(void)
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
@ GPU_PRIM_POINTS
Definition: GPU_primitive.h:35
@ GPU_SHADER_KEYFRAME_DIAMOND
Definition: GPU_shader.h:162
void GPU_program_point_size(bool enable)
Definition: gpu_state.cc:191
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
@ 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)
@ GPU_COMP_F32
@ GPU_COMP_U32
@ GPU_COMP_U8
Read Guarded memory(de)allocation.
@ UI_CNR_BOTTOM_RIGHT
@ UI_CNR_TOP_RIGHT
@ UI_CNR_NONE
void UI_draw_roundbox_4fv(const struct rctf *rect, bool filled, float rad, const float col[4])
void UI_draw_roundbox_corner_set(int type)
#define UI_UNIT_X
@ TH_KEYBORDER_SELECT
Definition: UI_resources.h:169
@ TH_KEYTYPE_BREAKDOWN
Definition: UI_resources.h:161
@ TH_KEYTYPE_KEYFRAME
Definition: UI_resources.h:157
@ TH_DOPESHEET_IPOLINE
Definition: UI_resources.h:230
@ TH_KEYBORDER
Definition: UI_resources.h:168
@ TH_KEYTYPE_JITTER
Definition: UI_resources.h:163
@ TH_KEYTYPE_EXTREME
Definition: UI_resources.h:159
@ TH_KEYTYPE_KEYFRAME_SELECT
Definition: UI_resources.h:158
@ TH_KEYTYPE_MOVEHOLD
Definition: UI_resources.h:165
@ TH_KEYTYPE_BREAKDOWN_SELECT
Definition: UI_resources.h:162
@ TH_KEYTYPE_EXTREME_SELECT
Definition: UI_resources.h:160
@ TH_STRIP
Definition: UI_resources.h:154
@ TH_KEYTYPE_MOVEHOLD_SELECT
Definition: UI_resources.h:166
@ TH_KEYTYPE_JITTER_SELECT
Definition: UI_resources.h:164
@ TH_STRIP_SELECT
Definition: UI_resources.h:155
void UI_GetThemeColor4fv(int colorid, float col[4])
Definition: resources.c:1199
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
Definition: resources.c:1381
float UI_view2d_scale_get_x(const struct View2D *v2d)
void ANIM_animdata_freelist(ListBase *anim_data)
Definition: anim_deps.c:425
void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, bool only_keys)
Definition: anim_draw.c:257
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_Flags filter_mode, void *data, eAnimCont_Types datatype)
Definition: anim_filter.c:3442
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
#define SELECT
OperationNode * node
static CCL_NAMESPACE_BEGIN const double alpha
uint col
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, int saction_flag)
void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac, int saction_flag)
static DLRBT_Node * nalloc_ak_masklayshape(void *data)
static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale_fac, bool channelLocked, int saction_flag)
static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf)
static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape)
void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, int saction_flag)
void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag)
static DLRBT_Node * nalloc_ak_gpframe(void *data)
BLI_INLINE bool is_cfra_lt(float a, float b)
bool actkeyblock_is_valid(ActKeyColumn *ac)
static void update_keyblocks(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len)
void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac, int saction_flag)
static short compare_ak_gpframe(void *node, void *data)
void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac, int saction_flag)
static void nupdate_ak_gpframe(void *node, void *data)
void cachefile_to_keylist(bDopeSheet *ads, CacheFile *cache_file, DLRBT_Tree *keys, int saction_flag)
BLI_INLINE bool is_cfra_eq(float a, float b)
void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys)
short compare_ak_cfraPtr(void *node, void *data)
static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTripleChain *bezt)
static void compute_keyblock_data(ActKeyBlockInfo *info, BezTriple *prev, BezTriple *beztn)
static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt)
static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block)
static void nupdate_ak_bezt(void *node, void *data)
static const ActKeyBlockInfo dummy_keyblock
static short compare_ak_masklayshape(void *node, void *data)
void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, int saction_flag)
static DLRBT_Node * nalloc_ak_bezt(void *data)
void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag)
static void nupdate_ak_masklayshape(void *node, void *data)
static short compare_ak_bezt(void *node, void *data)
void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag)
int actkeyblock_get_valid_hold(ActKeyColumn *ac)
static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len)
void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag)
void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys, const bool active)
struct BezTripleChain BezTripleChain
void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_flag)
void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha, uint pos_id, uint size_id, uint color_id, uint outline_color_id, uint flags_id, short handle_type, short extreme_type)
void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag)
void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag)
void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac, int saction_flag)
static eKeyframeExtremeDrawOpts bezt_extreme_type(BezTripleChain *chain)
void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, int saction_flag)
format
Definition: logImageCore.h:47
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
bool active
all scheduled work for the GPU.
ActKeyBlockInfo block
struct ActKeyColumn * next
bAction * action
struct Object * object
BezTriple * cur
BezTriple * prev
BezTriple * next
float vec[3][3]
struct AnimData * adt
void * first
Definition: BLI_dlrbTree.h:66
struct FCurve * next
bActionGroup * grp
BezTriple * bezt
short flag
unsigned int totvert
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
struct MaskLayerShape * next
ListBase splines_shapes
struct AnimData * adt
struct AnimData * adt
ListBase curves
struct bDopeSheet * ads
Definition: ED_anim_api.h:92
short datatype
Definition: ED_anim_api.h:75
void * data
Definition: ED_anim_api.h:73
struct bAnimListElem * next
Definition: ED_anim_api.h:135
struct AnimData * adt
Definition: ED_anim_api.h:170
struct ID * id
Definition: ED_anim_api.h:168
struct bGPDframe * next
ListBase frames
struct bGPDlayer * prev
ListBase layers
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85