4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): Joshua Leung (full recode)
27 * ***** END GPL LICENSE BLOCK *****
30 /** \file blender/editors/animation/keyframes_draw.c
31 * \ingroup edanimation
35 /* System includes ----------------------------------------------------- */
42 #include "MEM_guardedalloc.h"
44 #include "BLI_blenlib.h"
46 #include "BLI_dlrbTree.h"
47 #include "BLI_utildefines.h"
49 #include "DNA_anim_types.h"
50 #include "DNA_armature_types.h"
51 #include "DNA_camera_types.h"
52 #include "DNA_object_types.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_key_types.h"
55 #include "DNA_lamp_types.h"
56 #include "DNA_lattice_types.h"
57 #include "DNA_mesh_types.h"
58 #include "DNA_material_types.h"
59 #include "DNA_meta_types.h"
60 #include "DNA_node_types.h"
61 #include "DNA_particle_types.h"
62 #include "DNA_world_types.h"
63 #include "DNA_gpencil_types.h"
66 #include "BKE_material.h"
67 #include "BKE_global.h" // XXX remove me!
72 #include "UI_resources.h"
73 #include "UI_view2d.h"
75 #include "ED_anim_api.h"
76 #include "ED_keyframes_draw.h"
78 /* *************************** Keyframe Processing *************************** */
80 /* ActKeyColumns (Keyframe Columns) ------------------------------------------ */
82 /* Comparator callback used for ActKeyColumns and cframe float-value pointer */
83 /* NOTE: this is exported to other modules that use the ActKeyColumns for finding keyframes */
84 short compare_ak_cfraPtr (void *node, void *data)
86 ActKeyColumn *ak= (ActKeyColumn *)node;
89 if (*cframe < ak->cfra)
91 else if (*cframe > ak->cfra)
99 /* Comparator callback used for ActKeyColumns and BezTriple */
100 static short compare_ak_bezt (void *node, void *data)
102 ActKeyColumn *ak= (ActKeyColumn *)node;
103 BezTriple *bezt= (BezTriple *)data;
105 if (bezt->vec[1][0] < ak->cfra)
107 else if (bezt->vec[1][0] > ak->cfra)
113 /* New node callback used for building ActKeyColumns from BezTriples */
114 static DLRBT_Node *nalloc_ak_bezt (void *data)
116 ActKeyColumn *ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
117 BezTriple *bezt= (BezTriple *)data;
119 /* store settings based on state of BezTriple */
120 ak->cfra= bezt->vec[1][0];
121 ak->sel= BEZSELECTED(bezt) ? SELECT : 0;
122 ak->key_type= BEZKEYTYPE(bezt);
124 /* set 'modified', since this is used to identify long keyframes */
127 return (DLRBT_Node *)ak;
130 /* Node updater callback used for building ActKeyColumns from BezTriples */
131 static void nupdate_ak_bezt (void *node, void *data)
133 ActKeyColumn *ak= (ActKeyColumn *)node;
134 BezTriple *bezt= (BezTriple *)data;
136 /* set selection status and 'touched' status */
137 if (BEZSELECTED(bezt)) ak->sel = SELECT;
140 /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
141 if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
142 ak->key_type= BEZT_KEYTYPE_KEYFRAME;
147 /* Comparator callback used for ActKeyColumns and GPencil frame */
148 static short compare_ak_gpframe (void *node, void *data)
150 ActKeyColumn *ak= (ActKeyColumn *)node;
151 bGPDframe *gpf= (bGPDframe *)data;
153 if (gpf->framenum < ak->cfra)
155 else if (gpf->framenum > ak->cfra)
161 /* New node callback used for building ActKeyColumns from GPencil frames */
162 static DLRBT_Node *nalloc_ak_gpframe (void *data)
164 ActKeyColumn *ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
165 bGPDframe *gpf= (bGPDframe *)data;
167 /* store settings based on state of BezTriple */
168 ak->cfra= gpf->framenum;
169 ak->sel= (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
171 /* set 'modified', since this is used to identify long keyframes */
174 return (DLRBT_Node *)ak;
177 /* Node updater callback used for building ActKeyColumns from GPencil frames */
178 static void nupdate_ak_gpframe (void *node, void *data)
180 ActKeyColumn *ak= (ActKeyColumn *)node;
181 bGPDframe *gpf= (bGPDframe *)data;
183 /* set selection status and 'touched' status */
184 if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT;
188 /* --------------- */
190 /* Add the given BezTriple to the given 'list' of Keyframes */
191 static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTriple *bezt)
193 if ELEM(NULL, keys, bezt)
196 BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
199 /* Add the given GPencil Frame to the given 'list' of Keyframes */
200 static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf)
202 if ELEM(NULL, keys, gpf)
205 BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
208 /* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */
210 /* maximum size of default buffer for BezTriple columns */
211 #define MAX_ABK_BUFSIZE 4
213 /* BezTriple Container Node */
214 // NOTE: only used internally while building Long Keyframes for now, but may be useful externally?
215 typedef struct ActBeztColumn {
216 /* Tree Node interface ---------------- */
217 /* ListBase linkage */
218 struct ActBeztColumn *next, *prev;
220 /* sorting-tree linkage */
221 struct ActBeztColumn *left, *right; /* 'children' of this node, less than and greater than it (respectively) */
222 struct ActBeztColumn *parent; /* parent of this node in the tree */
223 char tree_col; /* DLRB_BLACK or DLRB_RED */
226 /* BezTriple Store -------------------- */
227 short numBezts; /* number of BezTriples on this frame */
228 float cfra; /* frame that the BezTriples occur on */
230 BezTriple *bezts[MAX_ABK_BUFSIZE]; /* buffer of pointers to BezTriples on the same frame */
231 //BezTriple **bezts_extra; /* secondary buffer of pointers if need be */
234 /* --------------- */
236 /* Comparator callback used for ActBeztColumns and BezTriple */
237 static short compare_abk_bezt (void *node, void *data)
239 ActBeztColumn *abk= (ActBeztColumn *)node;
240 BezTriple *bezt= (BezTriple *)data;
242 if (bezt->vec[1][0] < abk->cfra)
244 else if (bezt->vec[1][0] > abk->cfra)
250 /* New node callback used for building ActBeztColumns from BezTriples */
251 static DLRBT_Node *nalloc_abk_bezt (void *data)
253 ActBeztColumn *abk= MEM_callocN(sizeof(ActBeztColumn), "ActKeyColumn");
254 BezTriple *bezt= (BezTriple *)data;
256 /* store the BeztTriple in the buffer, and keep track of its frame number */
257 abk->cfra= bezt->vec[1][0];
258 abk->bezts[abk->numBezts++]= bezt;
260 return (DLRBT_Node *)abk;
263 /* Node updater callback used for building ActBeztColumns from BezTriples */
264 static void nupdate_abk_bezt (void *node, void *data)
266 ActBeztColumn *abk= (ActBeztColumn *)node;
267 BezTriple *bezt= (BezTriple *)data;
269 /* just add the BezTriple to the buffer if there's space, or allocate a new one */
270 if (abk->numBezts >= MAX_ABK_BUFSIZE) {
271 // TODO: need to allocate new array to cater...
272 //bezts_extra= MEM_callocN(...);
274 printf("FIXME: nupdate_abk_bezt() missing case for too many overlapping BezTriples \n");
277 /* just store an extra one */
278 abk->bezts[abk->numBezts++]= bezt;
282 /* --------------- */
284 /* Return the BezTriple in the given ActBeztColumn that matches the requested value */
285 static BezTriple *abk_get_bezt_with_value (ActBeztColumn *abk, float value)
294 /* look over each BezTriple in this container */
295 for (i = 0; i < abk->numBezts; i++) {
296 /* only do exact match for now... */
297 if (/*i >= MAX_ABK_BUFSIZE*/0) {
298 // TODO: this case needs special handling
301 /* just use the default buffer */
304 if (bezt->vec[1][1] == value)
312 /* ActKeyBlocks (Long Keyframes) ------------------------------------------ */
314 /* Comparator callback used for ActKeyBlock and cframe float-value pointer */
315 /* NOTE: this is exported to other modules that use the ActKeyBlocks for finding long-keyframes */
316 short compare_ab_cfraPtr (void *node, void *data)
318 ActKeyBlock *ab= (ActKeyBlock *)node;
321 if (*cframe < ab->start)
323 else if (*cframe > ab->start)
329 /* --------------- */
331 /* Create a ActKeyColumn for a pair of BezTriples */
332 static ActKeyBlock *bezts_to_new_actkeyblock(BezTriple *prev, BezTriple *beztn)
334 ActKeyBlock *ab= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock");
336 ab->start= prev->vec[1][0];
337 ab->end= beztn->vec[1][0];
338 ab->val= beztn->vec[1][1];
340 ab->sel= (BEZSELECTED(prev) || BEZSELECTED(beztn)) ? SELECT : 0;
346 static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, DLRBT_Tree *beztTree, BezTriple *beztn)
348 ActKeyBlock *new_ab= NULL;
352 /* get the BezTriple immediately before the given one which has the same value */
353 /* the keyframes immediately before the ones containing the specified keyframe */
354 abk= (ActBeztColumn *)BLI_dlrbTree_search_prev(beztTree, compare_abk_bezt, beztn);
355 /* if applicable, the BezTriple with the same value */
356 prev= (abk) ? abk_get_bezt_with_value(abk, beztn->vec[1][1]) : NULL;
358 /* check if block needed - same value(s)?
359 * -> firstly, handles must have same central value as each other
360 * -> secondly, handles which control that section of the curve must be constant
362 if ((!prev) || (!beztn)) return;
363 if (IS_EQF(beztn->vec[1][1], prev->vec[1][1])==0) return;
364 if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1])==0) return;
365 if (IS_EQF(prev->vec[1][1], prev->vec[2][1])==0) return;
368 /* if there are no blocks already, just add as root */
369 if (blocks->root == NULL) {
370 /* just add this as the root, then call the tree-balancing functions to validate */
371 new_ab= bezts_to_new_actkeyblock(prev, beztn);
372 blocks->root= (DLRBT_Node *)new_ab;
375 ActKeyBlock *ab, *abp=NULL, *abn=NULL;
377 /* try to find a keyblock that starts on the previous beztriple, and add a new one if none start there
378 * Note: we can't search from end to try to optimise this as it causes errors there's
379 * an A ___ B |---| B situation
381 // FIXME: here there is a bug where we are trying to get the summary for the following channels
382 // A|--------------|A ______________ B|--------------|B
383 // A|------------------------------------------------|A
384 // A|----|A|---|A|-----------------------------------|A
385 for (ab= blocks->root; ab; abp= ab, ab= abn) {
386 /* check if this is a match, or whether we go left or right */
387 if (ab->start == prev->vec[1][0]) {
388 /* set selection status and 'touched' status */
389 if (BEZSELECTED(beztn)) ab->sel = SELECT;
392 /* done... no need to insert */
396 ActKeyBlock **abnp= NULL;
398 /* check if go left or right, but if not available, add new node */
399 if (ab->start < prev->vec[1][0])
404 /* if this does not exist, add a new node, otherwise continue... */
406 /* add a new node representing this, and attach it to the relevant place */
407 new_ab= bezts_to_new_actkeyblock(prev, beztn);
418 /* now, balance the tree taking into account this newly added node */
419 BLI_dlrbTree_insert(blocks, (DLRBT_Node *)new_ab);
424 /* Handle the 'touched' status of ActKeyColumn tree nodes */
425 static void set_touched_actkeycolumn (ActKeyColumn *ak)
431 /* deal with self first */
438 set_touched_actkeycolumn(ak->left);
439 set_touched_actkeycolumn(ak->right);
442 /* Handle the 'touched' status of ActKeyBlock tree nodes */
443 static void set_touched_actkeyblock (ActKeyBlock *ab)
449 /* deal with self first */
456 set_touched_actkeyblock(ab->left);
457 set_touched_actkeyblock(ab->right);
462 /* Checks if ActKeyBlock should exist... */
463 short actkeyblock_is_valid (ActKeyBlock *ab, DLRBT_Tree *keys)
466 short startCurves, endCurves, totCurves;
468 /* check that block is valid */
472 /* find out how many curves occur at each keyframe */
473 ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->start);
474 startCurves = (ak)? ak->totcurve: 0;
476 ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->end);
477 endCurves = (ak)? ak->totcurve: 0;
479 /* only draw keyblock if it appears in at all of the keyframes at lowest end */
480 if (!startCurves && !endCurves)
483 totCurves = (startCurves>endCurves)? endCurves: startCurves;
484 return (ab->totcurve >= totCurves);
487 /* *************************** Keyframe Drawing *************************** */
489 /* coordinates for diamond shape */
490 static const float _unit_diamond_shape[4][2] = {
491 {0.0f, 1.0f}, /* top vert */
492 {1.0f, 0.0f}, /* mid-right */
493 {0.0f, -1.0f}, /* bottom vert */
494 {-1.0f, 0.0f} /* mid-left */
497 /* draw a simple diamond shape with OpenGL */
498 void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode, float alpha)
500 static GLuint displist1=0;
501 static GLuint displist2=0;
503 /* initialise 2 display lists for diamond shape - one empty, one filled */
504 if (displist1 == 0) {
505 displist1= glGenLists(1);
506 glNewList(displist1, GL_COMPILE);
508 glBegin(GL_LINE_LOOP);
509 glVertex2fv(_unit_diamond_shape[0]);
510 glVertex2fv(_unit_diamond_shape[1]);
511 glVertex2fv(_unit_diamond_shape[2]);
512 glVertex2fv(_unit_diamond_shape[3]);
516 if (displist2 == 0) {
517 displist2= glGenLists(1);
518 glNewList(displist2, GL_COMPILE);
521 glVertex2fv(_unit_diamond_shape[0]);
522 glVertex2fv(_unit_diamond_shape[1]);
523 glVertex2fv(_unit_diamond_shape[2]);
524 glVertex2fv(_unit_diamond_shape[3]);
529 /* tweak size of keyframe shape according to type of keyframe
530 * - 'proper' keyframes have key_type=0, so get drawn at full size
532 hsize -= 0.5f*key_type;
534 /* adjust view transform before starting */
535 glTranslatef(x, y, 0.0f);
536 glScalef(1.0f/xscale*hsize, hsize, 1.0f);
538 /* anti-aliased lines for more consistent appearance */
539 glEnable(GL_LINE_SMOOTH);
542 if ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH) {
543 /* interior - hardcoded colors (for selected and unselected only) */
545 case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames for now */
547 if (sel) glColor4f(0.33f, 0.75f, 0.93f, alpha);
548 else glColor4f(0.70f, 0.86f, 0.91f, alpha);
552 case BEZT_KEYTYPE_EXTREME: /* redish frames for now */
554 if (sel) glColor4f(0.95f, 0.5f, 0.5f, alpha);
555 else glColor4f(0.91f, 0.70f, 0.80f, alpha);
559 case BEZT_KEYTYPE_JITTER: /* greenish frames for now? */
561 if (sel) glColor4f(0.38f, 0.75f, 0.26f, alpha);
562 else glColor4f(0.58f, 0.90f, 0.46f, alpha);
566 case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */
569 if (sel) UI_ThemeColorShadeAlpha(TH_STRIP_SELECT, 50, -255*(1.0f-alpha));
570 else glColor4f(0.91f, 0.91f, 0.91f, alpha);
575 glCallList(displist2);
578 if ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH) {
579 /* exterior - black frame */
580 glColor4f(0.0f, 0.0f, 0.0f, alpha);
582 glCallList(displist1);
585 glDisable(GL_LINE_SMOOTH);
587 /* restore view transform */
588 glScalef(xscale/hsize, 1.0f/hsize, 1.0);
589 glTranslatef(-x, -y, 0.0f);
592 static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, short channelLocked)
600 /* get View2D scaling factor */
601 UI_view2d_getscale(v2d, &xscale, NULL);
605 for (ab= blocks->first; ab; ab= ab->next) {
606 if (actkeyblock_is_valid(ab, keys)) {
609 UI_ThemeColor4(TH_STRIP_SELECT);
611 UI_ThemeColor4(TH_STRIP);
613 glRectf(ab->start, ypos-5, ab->end, ypos+5);
620 /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
621 // TODO: allow this opacity factor to be themed?
622 float kalpha = (channelLocked)? 0.35f : 1.0f;
624 for (ak= keys->first; ak; ak= ak->next) {
625 /* optimisation: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw
626 * - this might give some improvements, since we current have to flip between view/region matrices
628 if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0)
631 /* draw using OpenGL - uglier but faster */
632 // NOTE1: a previous version of this didn't work nice for some intel cards
633 // NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3;
634 draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha);
641 /* *************************** Channel Drawing Funcs *************************** */
643 void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos)
645 DLRBT_Tree keys, blocks;
647 BLI_dlrbTree_init(&keys);
648 BLI_dlrbTree_init(&blocks);
650 summary_to_keylist(ac, &keys, &blocks);
652 BLI_dlrbTree_linkedlist_sync(&keys);
653 BLI_dlrbTree_linkedlist_sync(&blocks);
655 draw_keylist(v2d, &keys, &blocks, ypos, 0);
657 BLI_dlrbTree_free(&keys);
658 BLI_dlrbTree_free(&blocks);
661 void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos)
663 DLRBT_Tree keys, blocks;
665 BLI_dlrbTree_init(&keys);
666 BLI_dlrbTree_init(&blocks);
668 scene_to_keylist(ads, sce, &keys, &blocks);
670 BLI_dlrbTree_linkedlist_sync(&keys);
671 BLI_dlrbTree_linkedlist_sync(&blocks);
673 draw_keylist(v2d, &keys, &blocks, ypos, 0);
675 BLI_dlrbTree_free(&keys);
676 BLI_dlrbTree_free(&blocks);
679 void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos)
681 DLRBT_Tree keys, blocks;
683 BLI_dlrbTree_init(&keys);
684 BLI_dlrbTree_init(&blocks);
686 ob_to_keylist(ads, ob, &keys, &blocks);
688 BLI_dlrbTree_linkedlist_sync(&keys);
689 BLI_dlrbTree_linkedlist_sync(&blocks);
691 draw_keylist(v2d, &keys, &blocks, ypos, 0);
693 BLI_dlrbTree_free(&keys);
694 BLI_dlrbTree_free(&blocks);
697 void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos)
699 DLRBT_Tree keys, blocks;
701 BLI_dlrbTree_init(&keys);
702 BLI_dlrbTree_init(&blocks);
704 fcurve_to_keylist(adt, fcu, &keys, &blocks);
706 BLI_dlrbTree_linkedlist_sync(&keys);
707 BLI_dlrbTree_linkedlist_sync(&blocks);
709 draw_keylist(v2d, &keys, &blocks, ypos, (fcu->flag & FCURVE_PROTECTED));
711 BLI_dlrbTree_free(&keys);
712 BLI_dlrbTree_free(&blocks);
715 void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos)
717 DLRBT_Tree keys, blocks;
719 BLI_dlrbTree_init(&keys);
720 BLI_dlrbTree_init(&blocks);
722 agroup_to_keylist(adt, agrp, &keys, &blocks);
724 BLI_dlrbTree_linkedlist_sync(&keys);
725 BLI_dlrbTree_linkedlist_sync(&blocks);
727 draw_keylist(v2d, &keys, &blocks, ypos, (agrp->flag & AGRP_PROTECTED));
729 BLI_dlrbTree_free(&keys);
730 BLI_dlrbTree_free(&blocks);
733 void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
735 DLRBT_Tree keys, blocks;
737 BLI_dlrbTree_init(&keys);
738 BLI_dlrbTree_init(&blocks);
740 action_to_keylist(adt, act, &keys, &blocks);
742 BLI_dlrbTree_linkedlist_sync(&keys);
743 BLI_dlrbTree_linkedlist_sync(&blocks);
745 draw_keylist(v2d, &keys, &blocks, ypos, 0);
747 BLI_dlrbTree_free(&keys);
748 BLI_dlrbTree_free(&blocks);
751 void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos)
755 BLI_dlrbTree_init(&keys);
757 gpl_to_keylist(ads, gpl, &keys);
759 BLI_dlrbTree_linkedlist_sync(&keys);
761 draw_keylist(v2d, &keys, NULL, ypos, (gpl->flag & GP_LAYER_LOCKED));
763 BLI_dlrbTree_free(&keys);
766 /* *************************** Keyframe List Conversions *************************** */
768 void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks)
771 ListBase anim_data = {NULL, NULL};
775 /* get F-Curves to take keyframes from */
776 filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
777 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
779 /* loop through each F-Curve, grabbing the keyframes */
780 for (ale= anim_data.first; ale; ale= ale->next)
781 fcurve_to_keylist(ale->adt, ale->data, keys, blocks);
783 BLI_freelistN(&anim_data);
787 void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree *blocks)
795 filterflag= ads->filterflag;
800 if ((sce->adt) && !(filterflag & ADS_FILTER_NOSCE)) {
804 action_to_keylist(adt, adt->action, keys, blocks);
808 if ((sce->world) && (sce->world->adt) && !(filterflag & ADS_FILTER_NOWOR)) {
809 adt= sce->world->adt;
812 action_to_keylist(adt, adt->action, keys, blocks);
815 /* nodetree animdata */
816 if ((sce->nodetree) && (sce->nodetree->adt) && !(filterflag & ADS_FILTER_NONTREE)) {
817 adt= sce->nodetree->adt;
820 action_to_keylist(adt, adt->action, keys, blocks);
825 void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *blocks)
827 Key *key= ob_get_key(ob);
828 int filterflag= (ads)? ads->filterflag : 0;
834 /* Add action keyframes */
835 if (ob->adt && ob->adt->action)
836 action_to_keylist(ob->adt, ob->adt->action, keys, blocks);
838 /* Add shapekey keyframes (only if dopesheet allows, if it is available) */
839 if ((key && key->adt && key->adt->action) && !(filterflag & ADS_FILTER_NOSHAPEKEYS))
840 action_to_keylist(key->adt, key->adt->action, keys, blocks);
842 /* Add material keyframes */
843 if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) {
846 for (a=1; a <= ob->totcol; a++) {
847 Material *ma= give_current_material(ob, a);
849 /* there might not be a material */
850 if (ELEM(NULL, ma, ma->adt))
853 /* add material's data */
854 action_to_keylist(ma->adt, ma->adt->action, keys, blocks);
860 /* Add object data keyframes */
862 case OB_CAMERA: /* ------- Camera ------------ */
864 Camera *ca= (Camera *)ob->data;
866 if ((ca->adt) && !(filterflag & ADS_FILTER_NOCAM))
867 action_to_keylist(ca->adt, ca->adt->action, keys, blocks);
870 case OB_LAMP: /* ---------- Lamp ----------- */
872 Lamp *la= (Lamp *)ob->data;
874 if ((la->adt) && !(filterflag & ADS_FILTER_NOLAM))
875 action_to_keylist(la->adt, la->adt->action, keys, blocks);
878 case OB_CURVE: /* ------- Curve ---------- */
879 case OB_SURF: /* ------- Nurbs Surface ---------- */
880 case OB_FONT: /* ------- Text Curve ---------- */
882 Curve *cu= (Curve *)ob->data;
884 if ((cu->adt) && !(filterflag & ADS_FILTER_NOCUR))
885 action_to_keylist(cu->adt, cu->adt->action, keys, blocks);
888 case OB_MBALL: /* ------- MetaBall ---------- */
890 MetaBall *mb= (MetaBall *)ob->data;
892 if ((mb->adt) && !(filterflag & ADS_FILTER_NOMBA))
893 action_to_keylist(mb->adt, mb->adt->action, keys, blocks);
896 case OB_ARMATURE: /* ------- Armature ---------- */
898 bArmature *arm= (bArmature *)ob->data;
900 if ((arm->adt) && !(filterflag & ADS_FILTER_NOARM))
901 action_to_keylist(arm->adt, arm->adt->action, keys, blocks);
904 case OB_MESH: /* ------- Mesh ---------- */
906 Mesh *me= (Mesh *)ob->data;
908 if ((me->adt) && !(filterflag & ADS_FILTER_NOMESH))
909 action_to_keylist(me->adt, me->adt->action, keys, blocks);
912 case OB_LATTICE: /* ------- Lattice ---------- */
914 Lattice *lt= (Lattice *)ob->data;
916 if ((lt->adt) && !(filterflag & ADS_FILTER_NOLAT))
917 action_to_keylist(lt->adt, lt->adt->action, keys, blocks);
922 /* Add Particle System Keyframes */
923 if ((ob->particlesystem.first) && !(filterflag & ADS_FILTER_NOPART)) {
924 ParticleSystem *psys = ob->particlesystem.first;
926 for(; psys; psys=psys->next) {
927 if (ELEM(NULL, psys->part, psys->part->adt))
930 action_to_keylist(psys->part->adt, psys->part->adt->action, keys, blocks);
935 void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree *blocks)
937 DLRBT_Tree *beztTree = NULL;
941 if (fcu && fcu->totvert && fcu->bezt) {
942 /* apply NLA-mapping (if applicable) */
944 ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
946 /* if getting long keyframes too, grab the BezTriples in a BST for
947 * accelerated searching...
951 beztTree= BLI_dlrbTree_new();
953 /* populate tree with the BezTriples */
954 for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++)
955 BLI_dlrbTree_add(beztTree, compare_abk_bezt, nalloc_abk_bezt, nupdate_abk_bezt, bezt);
957 /* make sure that it is suitable for linked-list searching too */
958 BLI_dlrbTree_linkedlist_sync(beztTree);
961 /* loop through beztriples, making ActKeysColumns and ActKeyBlocks */
962 for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++) {
963 add_bezt_to_keycolumns_list(keys, bezt);
964 if (blocks) add_bezt_to_keyblocks_list(blocks, beztTree, bezt);
967 /* update the number of curves that elements have appeared in */
969 set_touched_actkeycolumn(keys->root);
971 set_touched_actkeyblock(blocks->root);
973 /* free temp data for building long keyframes */
974 if (blocks && beztTree) {
975 BLI_dlrbTree_free(beztTree);
979 /* unapply NLA-mapping if applicable */
981 ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
985 void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, DLRBT_Tree *blocks)
990 /* loop through F-Curves */
991 for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) {
992 fcurve_to_keylist(adt, fcu, keys, blocks);
997 void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree *blocks)
1002 /* loop through F-Curves */
1003 for (fcu= act->curves.first; fcu; fcu= fcu->next) {
1004 fcurve_to_keylist(adt, fcu, keys, blocks);
1010 void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
1015 /* although the frames should already be in an ordered list, they are not suitable for displaying yet */
1016 for (gpf= gpl->frames.first; gpf; gpf= gpf->next)
1017 add_gpframe_to_keycolumns_list(keys, gpf);