5c348f16c06966dd7e0c9cdee373fc53e43a12b4
[blender-staging.git] / source / blender / editors / animation / keyframes_draw.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
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.
10  *
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.
15  *
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.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Joshua Leung (full recode)
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /* System includes ----------------------------------------------------- */
31
32 #include <math.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <float.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_math.h"
41 #include "BLI_dlrbTree.h"
42
43 #include "DNA_anim_types.h"
44 #include "DNA_armature_types.h"
45 #include "DNA_camera_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_scene_types.h"
48 #include "DNA_key_types.h"
49 #include "DNA_lamp_types.h"
50 #include "DNA_mesh_types.h"
51 #include "DNA_material_types.h"
52 #include "DNA_meta_types.h"
53 #include "DNA_node_types.h"
54 #include "DNA_particle_types.h"
55 #include "DNA_world_types.h"
56 #include "DNA_gpencil_types.h"
57
58 #include "BKE_action.h"
59 #include "BKE_depsgraph.h"
60 #include "BKE_fcurve.h"
61 #include "BKE_key.h"
62 #include "BKE_material.h"
63 #include "BKE_object.h"
64 #include "BKE_global.h"         // XXX remove me!
65 #include "BKE_context.h"
66 #include "BKE_utildefines.h"
67
68 #include "BIF_gl.h"
69 #include "BIF_glutil.h"
70
71 #include "UI_resources.h"
72 #include "UI_view2d.h"
73
74 #include "ED_anim_api.h"
75 #include "ED_keyframes_draw.h"
76
77 /* *************************** Keyframe Processing *************************** */
78
79 /* ActKeyColumns (Keyframe Columns) ------------------------------------------ */
80
81 /* Comparator callback used for ActKeyColumns and cframe float-value pointer */
82 // NOTE: this is exported to other modules that use the ActKeyColumns for finding keyframes
83 short compare_ak_cfraPtr (void *node, void *data)
84 {
85         ActKeyColumn *ak= (ActKeyColumn *)node;
86         float *cframe= data;
87         
88         if (*cframe < ak->cfra)
89                 return -1;
90         else if (*cframe > ak->cfra)
91                 return 1;
92         else
93                 return 0;
94 }
95
96 /* --------------- */
97
98 /* Comparator callback used for ActKeyColumns and BezTriple */
99 static short compare_ak_bezt (void *node, void *data)
100 {
101         ActKeyColumn *ak= (ActKeyColumn *)node;
102         BezTriple *bezt= (BezTriple *)data;
103         
104         if (bezt->vec[1][0] < ak->cfra)
105                 return -1;
106         else if (bezt->vec[1][0] > ak->cfra)
107                 return 1;
108         else
109                 return 0;
110 }
111
112 /* New node callback used for building ActKeyColumns from BezTriples */
113 static DLRBT_Node *nalloc_ak_bezt (void *data)
114 {
115         ActKeyColumn *ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
116         BezTriple *bezt= (BezTriple *)data;
117         
118         /* store settings based on state of BezTriple */
119         ak->cfra= bezt->vec[1][0];
120         ak->sel= BEZSELECTED(bezt) ? SELECT : 0;
121         ak->key_type= BEZKEYTYPE(bezt); 
122         
123         /* set 'modified', since this is used to identify long keyframes */
124         ak->modified = 1;
125         
126         return (DLRBT_Node *)ak;
127 }
128
129 /* Node updater callback used for building ActKeyColumns from BezTriples */
130 static void nupdate_ak_bezt (void *node, void *data)
131 {
132         ActKeyColumn *ak= (ActKeyColumn *)node;
133         BezTriple *bezt= (BezTriple *)data;
134         
135         /* set selection status and 'touched' status */
136         if (BEZSELECTED(bezt)) ak->sel = SELECT;
137         ak->modified += 1;
138         
139         /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
140         if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
141                 ak->key_type= BEZT_KEYTYPE_KEYFRAME;
142 }
143
144 /* --------------- */
145
146 /* Add the given BezTriple to the given 'list' of Keyframes */
147 static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTriple *bezt)
148 {
149         if ELEM(NULL, keys, bezt) 
150                 return;
151         else
152                 BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
153 }
154
155 /* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */
156
157 /* maximum size of default buffer for BezTriple columns */
158 #define MAX_ABK_BUFSIZE         4
159
160 /* BezTriple Container Node */
161 // NOTE: only used internally while building Long Keyframes for now, but may be useful externally?
162 typedef struct ActBeztColumn {
163         /* Tree Node interface ---------------- */
164                 /* ListBase linkage */
165         struct ActBeztColumn *next, *prev;
166         
167                 /* sorting-tree linkage */
168         struct ActBeztColumn *left, *right;     /* 'children' of this node, less than and greater than it (respectively) */
169         struct ActBeztColumn *parent;           /* parent of this node in the tree */
170         char tree_col;                                          /* DLRB_BLACK or DLRB_RED */
171         char pad;
172         
173         /* BezTriple Store -------------------- */
174         short numBezts;                                         /* number of BezTriples on this frame */
175         float cfra;                                                     /* frame that the BezTriples occur on */
176         
177         BezTriple *bezts[MAX_ABK_BUFSIZE];      /* buffer of pointers to BezTriples on the same frame */
178         //BezTriple **bezts_extra;                      /* secondary buffer of pointers if need be */
179 } ActBeztColumn;
180
181 /* --------------- */
182
183 /* Comparator callback used for ActBeztColumns and BezTriple */
184 static short compare_abk_bezt (void *node, void *data)
185 {
186         ActBeztColumn *abk= (ActBeztColumn *)node;
187         BezTriple *bezt= (BezTriple *)data;
188         
189         if (bezt->vec[1][0] < abk->cfra)
190                 return -1;
191         else if (bezt->vec[1][0] > abk->cfra)
192                 return 1;
193         else
194                 return 0;
195 }
196
197 /* New node callback used for building ActBeztColumns from BezTriples */
198 static DLRBT_Node *nalloc_abk_bezt (void *data)
199 {
200         ActBeztColumn *abk= MEM_callocN(sizeof(ActBeztColumn), "ActKeyColumn");
201         BezTriple *bezt= (BezTriple *)data;
202         
203         /* store the BeztTriple in the buffer, and keep track of its frame number */
204         abk->cfra= bezt->vec[1][0];
205         abk->bezts[abk->numBezts++]= bezt;
206         
207         return (DLRBT_Node *)abk;
208 }
209
210 /* Node updater callback used for building ActBeztColumns from BezTriples */
211 static void nupdate_abk_bezt (void *node, void *data)
212 {
213         ActBeztColumn *abk= (ActBeztColumn *)node;
214         BezTriple *bezt= (BezTriple *)data;
215         
216         /* just add the BezTriple to the buffer if there's space, or allocate a new one */
217         if (abk->numBezts >= MAX_ABK_BUFSIZE) {
218                 // TODO: need to allocate new array to cater...
219                 //bezts_extra= MEM_callocN(...);
220                 if(G.f & G_DEBUG)
221                         printf("FIXME: nupdate_abk_bezt() missing case for too many overlapping BezTriples \n");
222         }
223         else {
224                 /* just store an extra one */
225                 abk->bezts[abk->numBezts++]= bezt;
226         }
227 }
228
229 /* --------------- */
230
231 /* Return the BezTriple in the given ActBeztColumn that matches the requested value */
232 static BezTriple *abk_get_bezt_with_value (ActBeztColumn *abk, float value)
233 {
234         BezTriple *bezt;
235         int i;
236         
237         /* sanity checks */
238         if (abk == NULL)
239                 return NULL;
240         
241         /* look over each BezTriple in this container */
242         for (i = 0; i < abk->numBezts; i++) {           
243                 /* only do exact match for now... */
244                 if (/*i >= MAX_ABK_BUFSIZE*/0) {
245                         // TODO: this case needs special handling
246                 }
247                 else {
248                         /* just use the default buffer */
249                         bezt= abk->bezts[i];
250                         
251                         if (bezt->vec[1][1] == value)
252                                 return bezt;
253                 }
254         }
255         
256         return NULL;
257 }
258
259 /* ActKeyBlocks (Long Keyframes) ------------------------------------------ */
260
261 /* Create a ActKeyColumn for a pair of BezTriples */
262 static ActKeyBlock *bezts_to_new_actkeyblock(BezTriple *prev, BezTriple *beztn)
263 {
264         ActKeyBlock *ab= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock");
265         
266         ab->start= prev->vec[1][0];
267         ab->end= beztn->vec[1][0];
268         ab->val= beztn->vec[1][1];
269         
270         ab->sel= (BEZSELECTED(prev) || BEZSELECTED(beztn)) ? SELECT : 0;
271         ab->modified = 1;
272         
273         return ab;
274 }
275
276 static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, DLRBT_Tree *beztTree, BezTriple *beztn)
277 {
278         ActKeyBlock *new_ab= NULL;
279         ActBeztColumn *abk;
280         BezTriple *prev;
281         
282         /* get the BezTriple immediately before the given one which has the same value */
283                 /* the keyframes immediately before the ones containing the specified keyframe */
284         abk= (ActBeztColumn *)BLI_dlrbTree_search_prev(beztTree, compare_abk_bezt, beztn);
285                 /* if applicable, the BezTriple with the same value */
286         prev= (abk) ? abk_get_bezt_with_value(abk, beztn->vec[1][1]) : NULL;
287         
288         /* check if block needed - same value(s)?
289          *      -> firstly, handles must have same central value as each other
290          *      -> secondly, handles which control that section of the curve must be constant
291          */
292         if ((!prev) || (!beztn)) return;
293         if (IS_EQ(beztn->vec[1][1], prev->vec[1][1])==0) return;
294         if (IS_EQ(beztn->vec[1][1], beztn->vec[0][1])==0) return;
295         if (IS_EQ(prev->vec[1][1], prev->vec[2][1])==0) return;
296         
297         
298         /* if there are no blocks already, just add as root */
299         if (blocks->root == NULL) {
300                 /* just add this as the root, then call the tree-balancing functions to validate */
301                 new_ab= bezts_to_new_actkeyblock(prev, beztn);
302                 blocks->root= (DLRBT_Node *)new_ab;
303         }
304         else {
305                 ActKeyBlock *ab, *abp=NULL, *abn=NULL;
306                 
307                 /* try to find a keyblock that starts on the previous beztriple, and add a new one if none start there
308                  * Note: we can't search from end to try to optimise this as it causes errors there's
309                  *              an A ___ B |---| B situation
310                  */
311                 // FIXME: here there is a bug where we are trying to get the summary for the following channels
312                 //              A|--------------|A ______________ B|--------------|B
313                 //              A|------------------------------------------------|A
314                 //              A|----|A|---|A|-----------------------------------|A
315                 for (ab= blocks->root; ab; abp= ab, ab= abn) {
316                         /* check if this is a match, or whether we go left or right */
317                         if (ab->start == prev->vec[1][0]) {
318                                 /* set selection status and 'touched' status */
319                                 if (BEZSELECTED(beztn)) ab->sel = SELECT;
320                                 ab->modified += 1;
321                                 
322                                 /* done... no need to insert */
323                                 return;
324                         }
325                         else {
326                                 ActKeyBlock **abnp= NULL; 
327                                 
328                                 /* check if go left or right, but if not available, add new node */
329                                 if (ab->start < prev->vec[1][0]) 
330                                         abnp= &ab->right;
331                                 else
332                                         abnp= &ab->left;
333                                         
334                                 /* if this does not exist, add a new node, otherwise continue... */
335                                 if (*abnp == NULL) {
336                                         /* add a new node representing this, and attach it to the relevant place */
337                                         new_ab= bezts_to_new_actkeyblock(prev, beztn);
338                                         new_ab->parent= ab;
339                                         *abnp= new_ab;
340                                         break;
341                                 }
342                                 else
343                                         abn= *abnp;
344                         }
345                 }
346         }
347         
348         /* now, balance the tree taking into account this newly added node */
349         BLI_dlrbTree_insert(blocks, (DLRBT_Node *)new_ab);
350 }
351
352 /* --------- */
353
354 /* Handle the 'touched' status of ActKeyColumn tree nodes */
355 static void set_touched_actkeycolumn (ActKeyColumn *ak)
356 {
357         /* sanity check */
358         if (ak == NULL)
359                 return;
360                 
361         /* deal with self first */
362         if (ak->modified) {
363                 ak->modified= 0;
364                 ak->totcurve++;
365         }
366         
367         /* children */
368         set_touched_actkeycolumn(ak->left);
369         set_touched_actkeycolumn(ak->right);
370 }
371
372 /* Handle the 'touched' status of ActKeyBlock tree nodes */
373 static void set_touched_actkeyblock (ActKeyBlock *ab)
374 {
375         /* sanity check */
376         if (ab == NULL)
377                 return;
378                 
379         /* deal with self first */
380         if (ab->modified) {
381                 ab->modified= 0;
382                 ab->totcurve++;
383         }
384         
385         /* children */
386         set_touched_actkeyblock(ab->left);
387         set_touched_actkeyblock(ab->right);
388 }
389
390 /* *************************** Keyframe Drawing *************************** */
391
392 /* coordinates for diamond shape */
393 static const float _unit_diamond_shape[4][2] = {
394         {0.0f, 1.0f},   /* top vert */
395         {1.0f, 0.0f},   /* mid-right */
396         {0.0f, -1.0f},  /* bottom vert */
397         {-1.0f, 0.0f}   /* mid-left */
398 }; 
399
400 /* draw a simple diamond shape with OpenGL */
401 void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode)
402 {
403         static GLuint displist1=0;
404         static GLuint displist2=0;
405         
406         /* initialise 2 display lists for diamond shape - one empty, one filled */
407         if (displist1 == 0) {
408                 displist1= glGenLists(1);
409                         glNewList(displist1, GL_COMPILE);
410                         
411                         glBegin(GL_LINE_LOOP);
412                                 glVertex2fv(_unit_diamond_shape[0]);
413                                 glVertex2fv(_unit_diamond_shape[1]);
414                                 glVertex2fv(_unit_diamond_shape[2]);
415                                 glVertex2fv(_unit_diamond_shape[3]);
416                         glEnd();
417                 glEndList();
418         }
419         if (displist2 == 0) {
420                 displist2= glGenLists(1);
421                         glNewList(displist2, GL_COMPILE);
422                         
423                         glBegin(GL_QUADS);
424                                 glVertex2fv(_unit_diamond_shape[0]);
425                                 glVertex2fv(_unit_diamond_shape[1]);
426                                 glVertex2fv(_unit_diamond_shape[2]);
427                                 glVertex2fv(_unit_diamond_shape[3]);
428                         glEnd();
429                 glEndList();
430         }
431         
432         /* tweak size of keyframe shape according to type of keyframe 
433          *      - 'proper' keyframes have key_type=0, so get drawn at full size
434          */
435         hsize -= 0.5f*key_type;
436         
437         /* adjust view transform before starting */
438         glTranslatef(x, y, 0.0f);
439         glScalef(1.0f/xscale*hsize, hsize, 1.0f);
440         
441         /* anti-aliased lines for more consistent appearance */
442         glEnable(GL_LINE_SMOOTH);
443         
444         /* draw! */
445         if ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH) {
446                 /* interior - hardcoded colors (for selected and unselected only) */
447                 switch (key_type) {
448                         case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames for now */
449                         {
450                                 if (sel) glColor3f(0.33f, 0.75f, 0.93f);
451                                 else glColor3f(0.70f, 0.86f, 0.91f);
452                         }
453                                 break;
454                                 
455                         case BEZT_KEYTYPE_EXTREME: /* redish frames for now */
456                         {
457                                 if (sel) glColor3f(95.0f, 0.5f, 0.5f);
458                                 else glColor3f(0.91f, 0.70f, 0.80f);
459                         }
460                                 break;
461                                 
462                         case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */
463                         default:
464                         {
465                                 if (sel) UI_ThemeColorShade(TH_STRIP_SELECT, 50);
466                                 else glColor3f(0.91f, 0.91f, 0.91f);
467                         }
468                                 break;
469                 }
470                 
471                 glCallList(displist2);
472         }
473         
474         if ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH) {
475                 /* exterior - black frame */
476                 glColor3ub(0, 0, 0);
477                 
478                 glCallList(displist1);
479         }
480         
481         glDisable(GL_LINE_SMOOTH);
482         
483         /* restore view transform */
484         glScalef(xscale/hsize, 1.0f/hsize, 1.0);
485         glTranslatef(-x, -y, 0.0f);
486 }
487
488 static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos)
489 {
490         ActKeyColumn *ak;
491         ActKeyBlock *ab;
492         float xscale;
493         
494         glEnable(GL_BLEND);
495         
496         /* get View2D scaling factor */
497         UI_view2d_getscale(v2d, &xscale, NULL);
498         
499         /* draw keyblocks */
500         if (blocks) {
501                 for (ab= blocks->first; ab; ab= ab->next) {
502                         short startCurves, endCurves, totCurves;
503                         
504                         /* find out how many curves occur at each keyframe */
505                         ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->start);
506                         startCurves = (ak)? ak->totcurve: 0;
507                         
508                         ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->end);
509                         endCurves = (ak)? ak->totcurve: 0;
510                         
511                         /* only draw keyblock if it appears in at all of the keyframes at lowest end */
512                         if (!startCurves && !endCurves) 
513                                 continue;
514                         else
515                                 totCurves = (startCurves>endCurves)? endCurves: startCurves;
516                                 
517                         if (ab->totcurve >= totCurves) {
518                                 /* draw block */
519                                 if (ab->sel)
520                                         UI_ThemeColor4(TH_STRIP_SELECT);
521                                 else
522                                         UI_ThemeColor4(TH_STRIP);
523                                 
524                                 glRectf(ab->start, ypos-5, ab->end, ypos+5);
525                         }
526                 }
527         }
528         
529         /* draw keys */
530         if (keys) {
531                 for (ak= keys->first; ak; ak= ak->next) {
532                         /* optimisation: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw 
533                          *      - this might give some improvements, since we current have to flip between view/region matrices
534                          */
535                         if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0)
536                                 continue;
537                         
538                         /* draw using OpenGL - uglier but faster */
539                         // NOTE1: a previous version of this didn't work nice for some intel cards
540                         // NOTE2: if we wanted to go back to icons, these are  icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3;
541                         draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH);
542                 }       
543         }
544         
545         glDisable(GL_BLEND);
546 }
547
548 /* *************************** Channel Drawing Funcs *************************** */
549
550 void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos)
551 {
552         DLRBT_Tree keys, blocks;
553         
554         BLI_dlrbTree_init(&keys);
555         BLI_dlrbTree_init(&blocks);
556         
557                 summary_to_keylist(ac, &keys, &blocks);
558         
559         BLI_dlrbTree_linkedlist_sync(&keys);
560         BLI_dlrbTree_linkedlist_sync(&blocks);
561         
562                 draw_keylist(v2d, &keys, &blocks, ypos);
563         
564         BLI_dlrbTree_free(&keys);
565         BLI_dlrbTree_free(&blocks);
566 }
567
568 void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos)
569 {
570         DLRBT_Tree keys, blocks;
571         
572         BLI_dlrbTree_init(&keys);
573         BLI_dlrbTree_init(&blocks);
574         
575                 scene_to_keylist(ads, sce, &keys, &blocks);
576         
577         BLI_dlrbTree_linkedlist_sync(&keys);
578         BLI_dlrbTree_linkedlist_sync(&blocks);
579         
580                 draw_keylist(v2d, &keys, &blocks, ypos);
581         
582         BLI_dlrbTree_free(&keys);
583         BLI_dlrbTree_free(&blocks);
584 }
585
586 void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos)
587 {
588         DLRBT_Tree keys, blocks;
589         
590         BLI_dlrbTree_init(&keys);
591         BLI_dlrbTree_init(&blocks);
592         
593                 ob_to_keylist(ads, ob, &keys, &blocks);
594         
595         BLI_dlrbTree_linkedlist_sync(&keys);
596         BLI_dlrbTree_linkedlist_sync(&blocks);
597         
598                 draw_keylist(v2d, &keys, &blocks, ypos);
599         
600         BLI_dlrbTree_free(&keys);
601         BLI_dlrbTree_free(&blocks);
602 }
603
604 void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos)
605 {
606         DLRBT_Tree keys, blocks;
607         
608         BLI_dlrbTree_init(&keys);
609         BLI_dlrbTree_init(&blocks);
610         
611                 fcurve_to_keylist(adt, fcu, &keys, &blocks);
612         
613         BLI_dlrbTree_linkedlist_sync(&keys);
614         BLI_dlrbTree_linkedlist_sync(&blocks);
615         
616                 draw_keylist(v2d, &keys, &blocks, ypos);
617         
618         BLI_dlrbTree_free(&keys);
619         BLI_dlrbTree_free(&blocks);
620 }
621
622 void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos)
623 {
624         DLRBT_Tree keys, blocks;
625         
626         BLI_dlrbTree_init(&keys);
627         BLI_dlrbTree_init(&blocks);
628         
629                 agroup_to_keylist(adt, agrp, &keys, &blocks);
630         
631         BLI_dlrbTree_linkedlist_sync(&keys);
632         BLI_dlrbTree_linkedlist_sync(&blocks);
633         
634                 draw_keylist(v2d, &keys, &blocks, ypos);
635         
636         BLI_dlrbTree_free(&keys);
637         BLI_dlrbTree_free(&blocks);
638 }
639
640 void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
641 {
642         DLRBT_Tree keys, blocks;
643         
644         BLI_dlrbTree_init(&keys);
645         BLI_dlrbTree_init(&blocks);
646         
647                 action_to_keylist(adt, act, &keys, &blocks);
648         
649         BLI_dlrbTree_linkedlist_sync(&keys);
650         BLI_dlrbTree_linkedlist_sync(&blocks);
651         
652                 draw_keylist(v2d, &keys, &blocks, ypos);
653         
654         BLI_dlrbTree_free(&keys);
655         BLI_dlrbTree_free(&blocks);
656 }
657
658 void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos)
659 {
660         DLRBT_Tree keys;
661         
662         BLI_dlrbTree_init(&keys);
663         
664                 gpl_to_keylist(ads, gpl, &keys, NULL);
665         
666         BLI_dlrbTree_linkedlist_sync(&keys);
667         
668                 draw_keylist(v2d, &keys, NULL, ypos);
669         
670         BLI_dlrbTree_free(&keys);
671 }
672
673 /* *************************** Keyframe List Conversions *************************** */
674
675 void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks)
676 {
677         if (ac) {
678                 ListBase anim_data = {NULL, NULL};
679                 bAnimListElem *ale;
680                 int filter;
681                 
682                 /* get F-Curves to take keyframes from */
683                 filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
684                 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
685                 
686                 /* loop through each F-Curve, grabbing the keyframes */
687                 for (ale= anim_data.first; ale; ale= ale->next)
688                         fcurve_to_keylist(ale->adt, ale->data, keys, blocks);
689                 
690                 BLI_freelistN(&anim_data);
691         }
692 }
693
694 void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree *blocks)
695 {
696         if (sce) {
697                 AnimData *adt;
698                 int filterflag;
699                 
700                 /* get filterflag */
701                 if (ads)
702                         filterflag= ads->filterflag;
703                 else
704                         filterflag= 0;
705                         
706                 /* scene animdata */
707                 if ((sce->adt) && !(filterflag & ADS_FILTER_NOSCE)) {
708                         adt= sce->adt;
709                         
710                         if (adt->action) 
711                                 action_to_keylist(adt, adt->action, keys, blocks);
712                 }
713                 
714                 /* world animdata */
715                 if ((sce->world) && (sce->world->adt) && !(filterflag & ADS_FILTER_NOWOR)) {
716                         adt= sce->world->adt;
717                         
718                         if (adt->action) 
719                                 action_to_keylist(adt, adt->action, keys, blocks);
720                 }
721                 
722                 /* nodetree animdata */
723                 if ((sce->nodetree) && (sce->nodetree->adt) && !(filterflag & ADS_FILTER_NONTREE)) {
724                         adt= sce->nodetree->adt;
725                         
726                         if (adt->action) 
727                                 action_to_keylist(adt, adt->action, keys, blocks);
728                 }
729         }
730 }
731
732 void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *blocks)
733 {
734         Key *key= ob_get_key(ob);
735         int filterflag= (ads)? ads->filterflag : 0;
736         
737         /* sanity check */
738         if (ob == NULL)
739                 return;
740                 
741         /* Add action keyframes */
742         if (ob->adt && ob->adt->action)
743                 action_to_keylist(ob->adt, ob->adt->action, keys, blocks);
744         
745         /* Add shapekey keyframes (only if dopesheet allows, if it is available) */
746         if ((key && key->adt && key->adt->action) && !(filterflag & ADS_FILTER_NOSHAPEKEYS))
747                 action_to_keylist(key->adt, key->adt->action, keys, blocks);
748         
749         /* Add material keyframes */
750         if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) {
751                 int a;
752                 
753                 for (a=1; a <= ob->totcol; a++) {
754                         Material *ma= give_current_material(ob, a);
755                         
756                         /* there might not be a material */
757                         if (ELEM(NULL, ma, ma->adt)) 
758                                 continue;
759                         
760                         /* add material's data */
761                         action_to_keylist(ma->adt, ma->adt->action, keys, blocks);
762                 }
763         }
764         
765         /* Add object data keyframes */
766         switch (ob->type) {
767                 case OB_CAMERA: /* ------- Camera ------------ */
768                 {
769                         Camera *ca= (Camera *)ob->data;
770                         
771                         if ((ca->adt) && !(filterflag & ADS_FILTER_NOCAM)) 
772                                 action_to_keylist(ca->adt, ca->adt->action, keys, blocks);
773                 }
774                         break;
775                 case OB_LAMP: /* ---------- Lamp ----------- */
776                 {
777                         Lamp *la= (Lamp *)ob->data;
778                         
779                         if ((la->adt) && !(filterflag & ADS_FILTER_NOLAM)) 
780                                 action_to_keylist(la->adt, la->adt->action, keys, blocks);
781                 }
782                         break;
783                 case OB_CURVE: /* ------- Curve ---------- */
784                 case OB_SURF: /* ------- Nurbs Surface ---------- */
785                 case OB_FONT: /* ------- Text Curve ---------- */
786                 {
787                         Curve *cu= (Curve *)ob->data;
788                         
789                         if ((cu->adt) && !(filterflag & ADS_FILTER_NOCUR)) 
790                                 action_to_keylist(cu->adt, cu->adt->action, keys, blocks);
791                 }
792                         break;
793                 case OB_MBALL: /* ------- MetaBall ---------- */
794                 {
795                         MetaBall *mb= (MetaBall *)ob->data;
796                         
797                         if ((mb->adt) && !(filterflag & ADS_FILTER_NOMBA)) 
798                                 action_to_keylist(mb->adt, mb->adt->action, keys, blocks);
799                 }
800                         break;
801                 case OB_ARMATURE: /* ------- Armature ---------- */
802                 {
803                         bArmature *arm= (bArmature *)ob->data;
804                         
805                         if ((arm->adt) && !(filterflag & ADS_FILTER_NOARM)) 
806                                 action_to_keylist(arm->adt, arm->adt->action, keys, blocks);
807                 }
808                         break;
809                 case OB_MESH: /* ------- Mesh ---------- */
810                 {
811                         Mesh *me= (Mesh *)ob->data;
812                         
813                         if ((me->adt) && !(filterflag & ADS_FILTER_NOMESH)) 
814                                 action_to_keylist(me->adt, me->adt->action, keys, blocks);
815                 }
816                         break;
817         }
818         
819         /* Add Particle System Keyframes */
820         if ((ob->particlesystem.first) && !(filterflag & ADS_FILTER_NOPART)) {
821                 ParticleSystem *psys = ob->particlesystem.first;
822                 
823                 for(; psys; psys=psys->next) {
824                         if (ELEM(NULL, psys->part, psys->part->adt))
825                                 continue;
826                         else
827                                 action_to_keylist(psys->part->adt, psys->part->adt->action, keys, blocks);
828                 }
829         }
830 }
831
832 void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree *blocks)
833 {
834         DLRBT_Tree *beztTree = NULL;
835         BezTriple *bezt;
836         int v;
837         
838         if (fcu && fcu->totvert && fcu->bezt) {
839                 /* apply NLA-mapping (if applicable) */
840                 if (adt)        
841                         ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
842                 
843                 /* if getting long keyframes too, grab the BezTriples in a BST for 
844                  * accelerated searching...
845                  */
846                 if (blocks) {
847                         /* init new tree */
848                         beztTree= BLI_dlrbTree_new();
849                         
850                         /* populate tree with the BezTriples */
851                         for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++)
852                                 BLI_dlrbTree_add(beztTree, compare_abk_bezt, nalloc_abk_bezt, nupdate_abk_bezt, bezt);
853                         
854                         /* make sure that it is suitable for linked-list searching too */
855                         BLI_dlrbTree_linkedlist_sync(beztTree);
856                 }
857                 
858                 /* loop through beztriples, making ActKeysColumns and ActKeyBlocks */
859                 for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++) {
860                         add_bezt_to_keycolumns_list(keys, bezt);
861                         if (blocks) add_bezt_to_keyblocks_list(blocks, beztTree, bezt);
862                 }
863                 
864                 /* update the number of curves that elements have appeared in  */
865                 if (keys)
866                         set_touched_actkeycolumn(keys->root);
867                 if (blocks)
868                         set_touched_actkeyblock(blocks->root);
869                         
870                 /* free temp data for building long keyframes */
871                 if (blocks && beztTree) {
872                         BLI_dlrbTree_free(beztTree);
873                         MEM_freeN(beztTree);
874                 }
875                 
876                 /* unapply NLA-mapping if applicable */
877                 if (adt)
878                         ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
879         }
880 }
881
882 void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, DLRBT_Tree *blocks)
883 {
884         FCurve *fcu;
885
886         if (agrp) {
887                 /* loop through F-Curves */
888                 for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) {
889                         fcurve_to_keylist(adt, fcu, keys, blocks);
890                 }
891         }
892 }
893
894 void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree *blocks)
895 {
896         FCurve *fcu;
897
898         if (act) {
899                 /* loop through F-Curves */
900                 for (fcu= act->curves.first; fcu; fcu= fcu->next) {
901                         fcurve_to_keylist(adt, fcu, keys, blocks);
902                 }
903         }
904 }
905
906
907 void gpl_to_keylist(bDopeSheet *ads, bGPDlayer *gpl, DLRBT_Tree *keys, DLRBT_Tree *blocks)
908 {
909         bGPDframe *gpf;
910         ActKeyColumn *ak;
911         
912         if (gpl && keys) {
913                 /* loop over frames, converting directly to 'keyframes' (should be in order too) */
914                 for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
915                         ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
916                         BLI_addtail((ListBase *)keys, ak);
917                         
918                         ak->cfra= (float)gpf->framenum;
919                         ak->modified = 1;
920                         ak->key_type= 0; 
921                         
922                         if (gpf->flag & GP_FRAME_SELECT)
923                                 ak->sel = SELECT;
924                         else
925                                 ak->sel = 0;
926                 }
927         }
928 }
929