Merging with trunk up to r38631.
[blender.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 /** \file blender/editors/animation/keyframes_draw.c
31  *  \ingroup edanimation
32  */
33
34
35 /* System includes ----------------------------------------------------- */
36
37 #include <math.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <float.h>
41
42 #include "MEM_guardedalloc.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_math.h"
46 #include "BLI_dlrbTree.h"
47 #include "BLI_utildefines.h"
48
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"
64
65 #include "BKE_key.h"
66 #include "BKE_material.h"
67 #include "BKE_global.h"         // XXX remove me!
68
69
70 #include "BIF_gl.h"
71
72 #include "UI_resources.h"
73 #include "UI_view2d.h"
74
75 #include "ED_anim_api.h"
76 #include "ED_keyframes_draw.h"
77
78 /* *************************** Keyframe Processing *************************** */
79
80 /* ActKeyColumns (Keyframe Columns) ------------------------------------------ */
81
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)
85 {
86         ActKeyColumn *ak= (ActKeyColumn *)node;
87         float *cframe= data;
88         
89         if (*cframe < ak->cfra)
90                 return -1;
91         else if (*cframe > ak->cfra)
92                 return 1;
93         else
94                 return 0;
95 }
96
97 /* --------------- */
98
99 /* Comparator callback used for ActKeyColumns and BezTriple */
100 static short compare_ak_bezt (void *node, void *data)
101 {
102         ActKeyColumn *ak= (ActKeyColumn *)node;
103         BezTriple *bezt= (BezTriple *)data;
104         
105         if (bezt->vec[1][0] < ak->cfra)
106                 return -1;
107         else if (bezt->vec[1][0] > ak->cfra)
108                 return 1;
109         else
110                 return 0;
111 }
112
113 /* New node callback used for building ActKeyColumns from BezTriples */
114 static DLRBT_Node *nalloc_ak_bezt (void *data)
115 {
116         ActKeyColumn *ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
117         BezTriple *bezt= (BezTriple *)data;
118         
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); 
123         
124         /* set 'modified', since this is used to identify long keyframes */
125         ak->modified = 1;
126         
127         return (DLRBT_Node *)ak;
128 }
129
130 /* Node updater callback used for building ActKeyColumns from BezTriples */
131 static void nupdate_ak_bezt (void *node, void *data)
132 {
133         ActKeyColumn *ak= (ActKeyColumn *)node;
134         BezTriple *bezt= (BezTriple *)data;
135         
136         /* set selection status and 'touched' status */
137         if (BEZSELECTED(bezt)) ak->sel = SELECT;
138         ak->modified += 1;
139         
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;
143 }
144
145 /* ......... */
146
147 /* Comparator callback used for ActKeyColumns and GPencil frame */
148 static short compare_ak_gpframe (void *node, void *data)
149 {
150         ActKeyColumn *ak= (ActKeyColumn *)node;
151         bGPDframe *gpf= (bGPDframe *)data;
152         
153         if (gpf->framenum < ak->cfra)
154                 return -1;
155         else if (gpf->framenum > ak->cfra)
156                 return 1;
157         else
158                 return 0;
159 }
160
161 /* New node callback used for building ActKeyColumns from GPencil frames */
162 static DLRBT_Node *nalloc_ak_gpframe (void *data)
163 {
164         ActKeyColumn *ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
165         bGPDframe *gpf= (bGPDframe *)data;
166         
167         /* store settings based on state of BezTriple */
168         ak->cfra= gpf->framenum;
169         ak->sel= (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
170         
171         /* set 'modified', since this is used to identify long keyframes */
172         ak->modified = 1;
173         
174         return (DLRBT_Node *)ak;
175 }
176
177 /* Node updater callback used for building ActKeyColumns from GPencil frames */
178 static void nupdate_ak_gpframe (void *node, void *data)
179 {
180         ActKeyColumn *ak= (ActKeyColumn *)node;
181         bGPDframe *gpf= (bGPDframe *)data;
182         
183         /* set selection status and 'touched' status */
184         if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT;
185         ak->modified += 1;
186 }
187
188 /* --------------- */
189
190 /* Add the given BezTriple to the given 'list' of Keyframes */
191 static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTriple *bezt)
192 {
193         if ELEM(NULL, keys, bezt) 
194                 return;
195         else
196                 BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
197 }
198
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)
201 {
202         if ELEM(NULL, keys, gpf) 
203                 return;
204         else
205                 BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
206 }
207
208 /* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */
209
210 /* maximum size of default buffer for BezTriple columns */
211 #define MAX_ABK_BUFSIZE         4
212
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;
219         
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 */
224         char pad;
225         
226         /* BezTriple Store -------------------- */
227         short numBezts;                                         /* number of BezTriples on this frame */
228         float cfra;                                                     /* frame that the BezTriples occur on */
229         
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 */
232 } ActBeztColumn;
233
234 /* --------------- */
235
236 /* Comparator callback used for ActBeztColumns and BezTriple */
237 static short compare_abk_bezt (void *node, void *data)
238 {
239         ActBeztColumn *abk= (ActBeztColumn *)node;
240         BezTriple *bezt= (BezTriple *)data;
241         
242         if (bezt->vec[1][0] < abk->cfra)
243                 return -1;
244         else if (bezt->vec[1][0] > abk->cfra)
245                 return 1;
246         else
247                 return 0;
248 }
249
250 /* New node callback used for building ActBeztColumns from BezTriples */
251 static DLRBT_Node *nalloc_abk_bezt (void *data)
252 {
253         ActBeztColumn *abk= MEM_callocN(sizeof(ActBeztColumn), "ActKeyColumn");
254         BezTriple *bezt= (BezTriple *)data;
255         
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;
259         
260         return (DLRBT_Node *)abk;
261 }
262
263 /* Node updater callback used for building ActBeztColumns from BezTriples */
264 static void nupdate_abk_bezt (void *node, void *data)
265 {
266         ActBeztColumn *abk= (ActBeztColumn *)node;
267         BezTriple *bezt= (BezTriple *)data;
268         
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(...);
273                 if(G.f & G_DEBUG)
274                         printf("FIXME: nupdate_abk_bezt() missing case for too many overlapping BezTriples \n");
275         }
276         else {
277                 /* just store an extra one */
278                 abk->bezts[abk->numBezts++]= bezt;
279         }
280 }
281
282 /* --------------- */
283
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)
286 {
287         BezTriple *bezt;
288         int i;
289         
290         /* sanity checks */
291         if (abk == NULL)
292                 return NULL;
293         
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
299                 }
300                 else {
301                         /* just use the default buffer */
302                         bezt= abk->bezts[i];
303                         
304                         if (bezt->vec[1][1] == value)
305                                 return bezt;
306                 }
307         }
308         
309         return NULL;
310 }
311
312 /* ActKeyBlocks (Long Keyframes) ------------------------------------------ */
313
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)
317 {
318         ActKeyBlock *ab= (ActKeyBlock *)node;
319         float *cframe= data;
320         
321         if (*cframe < ab->start)
322                 return -1;
323         else if (*cframe > ab->start)
324                 return 1;
325         else
326                 return 0;
327 }
328
329 /* --------------- */
330
331 /* Create a ActKeyColumn for a pair of BezTriples */
332 static ActKeyBlock *bezts_to_new_actkeyblock(BezTriple *prev, BezTriple *beztn)
333 {
334         ActKeyBlock *ab= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock");
335         
336         ab->start= prev->vec[1][0];
337         ab->end= beztn->vec[1][0];
338         ab->val= beztn->vec[1][1];
339         
340         ab->sel= (BEZSELECTED(prev) || BEZSELECTED(beztn)) ? SELECT : 0;
341         ab->modified = 1;
342         
343         return ab;
344 }
345
346 static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, DLRBT_Tree *beztTree, BezTriple *beztn)
347 {
348         ActKeyBlock *new_ab= NULL;
349         ActBeztColumn *abk;
350         BezTriple *prev;
351         
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;
357         
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
361          */
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;
366         
367         
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;
373         }
374         else {
375                 ActKeyBlock *ab, *abn=NULL;
376                 
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
380                  */
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; 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;
390                                 ab->modified += 1;
391                                 
392                                 /* done... no need to insert */
393                                 return;
394                         }
395                         else {
396                                 ActKeyBlock **abnp= NULL; 
397                                 
398                                 /* check if go left or right, but if not available, add new node */
399                                 if (ab->start < prev->vec[1][0]) 
400                                         abnp= &ab->right;
401                                 else
402                                         abnp= &ab->left;
403                                         
404                                 /* if this does not exist, add a new node, otherwise continue... */
405                                 if (*abnp == NULL) {
406                                         /* add a new node representing this, and attach it to the relevant place */
407                                         new_ab= bezts_to_new_actkeyblock(prev, beztn);
408                                         new_ab->parent= ab;
409                                         *abnp= new_ab;
410                                         break;
411                                 }
412                                 else
413                                         abn= *abnp;
414                         }
415                 }
416         }
417         
418         /* now, balance the tree taking into account this newly added node */
419         BLI_dlrbTree_insert(blocks, (DLRBT_Node *)new_ab);
420 }
421
422 /* --------- */
423
424 /* Handle the 'touched' status of ActKeyColumn tree nodes */
425 static void set_touched_actkeycolumn (ActKeyColumn *ak)
426 {
427         /* sanity check */
428         if (ak == NULL)
429                 return;
430                 
431         /* deal with self first */
432         if (ak->modified) {
433                 ak->modified= 0;
434                 ak->totcurve++;
435         }
436         
437         /* children */
438         set_touched_actkeycolumn(ak->left);
439         set_touched_actkeycolumn(ak->right);
440 }
441
442 /* Handle the 'touched' status of ActKeyBlock tree nodes */
443 static void set_touched_actkeyblock (ActKeyBlock *ab)
444 {
445         /* sanity check */
446         if (ab == NULL)
447                 return;
448                 
449         /* deal with self first */
450         if (ab->modified) {
451                 ab->modified= 0;
452                 ab->totcurve++;
453         }
454         
455         /* children */
456         set_touched_actkeyblock(ab->left);
457         set_touched_actkeyblock(ab->right);
458 }
459
460 /* --------- */
461
462 /* Checks if ActKeyBlock should exist... */
463 short actkeyblock_is_valid (ActKeyBlock *ab, DLRBT_Tree *keys)
464 {
465         ActKeyColumn *ak;
466         short startCurves, endCurves, totCurves;
467         
468         /* check that block is valid */
469         if (ab == NULL)
470                 return 0;
471         
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;
475         
476         ak= (ActKeyColumn *)BLI_dlrbTree_search_exact(keys, compare_ak_cfraPtr, &ab->end);
477         endCurves = (ak)? ak->totcurve: 0;
478         
479         /* only draw keyblock if it appears in at all of the keyframes at lowest end */
480         if (!startCurves && !endCurves) 
481                 return 0;
482         
483         totCurves = (startCurves>endCurves)? endCurves: startCurves;
484         return (ab->totcurve >= totCurves);
485 }
486
487 /* *************************** Keyframe Drawing *************************** */
488
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 */
495 }; 
496
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)
499 {
500         static GLuint displist1=0;
501         static GLuint displist2=0;
502         
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);
507                         
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]);
513                         glEnd();
514                 glEndList();
515         }
516         if (displist2 == 0) {
517                 displist2= glGenLists(1);
518                         glNewList(displist2, GL_COMPILE);
519                         
520                         glBegin(GL_QUADS);
521                                 glVertex2fv(_unit_diamond_shape[0]);
522                                 glVertex2fv(_unit_diamond_shape[1]);
523                                 glVertex2fv(_unit_diamond_shape[2]);
524                                 glVertex2fv(_unit_diamond_shape[3]);
525                         glEnd();
526                 glEndList();
527         }
528         
529         /* tweak size of keyframe shape according to type of keyframe 
530          *      - 'proper' keyframes have key_type=0, so get drawn at full size
531          */
532         hsize -= 0.5f*key_type;
533         
534         /* adjust view transform before starting */
535         glTranslatef(x, y, 0.0f);
536         glScalef(1.0f/xscale*hsize, hsize, 1.0f);
537         
538         /* anti-aliased lines for more consistent appearance */
539         glEnable(GL_LINE_SMOOTH);
540         
541         /* draw! */
542         if ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH) {
543                 /* interior - hardcoded colors (for selected and unselected only) */
544                 switch (key_type) {
545                         case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames for now */
546                         {
547                                 if (sel) glColor4f(0.33f, 0.75f, 0.93f, alpha);
548                                 else glColor4f(0.70f, 0.86f, 0.91f, alpha);
549                         }
550                                 break;
551                                 
552                         case BEZT_KEYTYPE_EXTREME: /* redish frames for now */
553                         {
554                                 if (sel) glColor4f(0.95f, 0.5f, 0.5f, alpha);
555                                 else glColor4f(0.91f, 0.70f, 0.80f, alpha);
556                         }
557                                 break;
558                                 
559                         case BEZT_KEYTYPE_JITTER: /* greenish frames for now? */
560                         {
561                                 if (sel) glColor4f(0.38f, 0.75f, 0.26f, alpha);
562                                 else glColor4f(0.58f, 0.90f, 0.46f, alpha);
563                         }
564                                 break;
565                                 
566                         case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */
567                         default:
568                         {
569                                 if (sel) UI_ThemeColorShadeAlpha(TH_STRIP_SELECT, 50, -255*(1.0f-alpha));
570                                 else glColor4f(0.91f, 0.91f, 0.91f, alpha);
571                         }
572                                 break;
573                 }
574                 
575                 glCallList(displist2);
576         }
577         
578         if ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH) {
579                 /* exterior - black frame */
580                 glColor4f(0.0f, 0.0f, 0.0f, alpha);
581                 
582                 glCallList(displist1);
583         }
584         
585         glDisable(GL_LINE_SMOOTH);
586         
587         /* restore view transform */
588         glScalef(xscale/hsize, 1.0f/hsize, 1.0);
589         glTranslatef(-x, -y, 0.0f);
590 }
591
592 static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, short channelLocked)
593 {
594         ActKeyColumn *ak;
595         ActKeyBlock *ab;
596         float xscale;
597         
598         glEnable(GL_BLEND);
599         
600         /* get View2D scaling factor */
601         UI_view2d_getscale(v2d, &xscale, NULL);
602         
603         /* draw keyblocks */
604         if (blocks) {
605                 for (ab= blocks->first; ab; ab= ab->next) {
606                         if (actkeyblock_is_valid(ab, keys)) {
607                                 /* draw block */
608                                 if (ab->sel)
609                                         UI_ThemeColor4(TH_STRIP_SELECT);
610                                 else
611                                         UI_ThemeColor4(TH_STRIP);
612                                 
613                                 glRectf(ab->start, ypos-5, ab->end, ypos+5);
614                         }
615                 }
616         }
617         
618         /* draw keys */
619         if (keys) {
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;
623                 
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
627                          */
628                         if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0)
629                                 continue;
630                         
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);
635                 }       
636         }
637         
638         glDisable(GL_BLEND);
639 }
640
641 /* *************************** Channel Drawing Funcs *************************** */
642
643 void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos)
644 {
645         DLRBT_Tree keys, blocks;
646         
647         BLI_dlrbTree_init(&keys);
648         BLI_dlrbTree_init(&blocks);
649         
650                 summary_to_keylist(ac, &keys, &blocks);
651         
652         BLI_dlrbTree_linkedlist_sync(&keys);
653         BLI_dlrbTree_linkedlist_sync(&blocks);
654         
655                 draw_keylist(v2d, &keys, &blocks, ypos, 0);
656         
657         BLI_dlrbTree_free(&keys);
658         BLI_dlrbTree_free(&blocks);
659 }
660
661 void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos)
662 {
663         DLRBT_Tree keys, blocks;
664         
665         BLI_dlrbTree_init(&keys);
666         BLI_dlrbTree_init(&blocks);
667         
668                 scene_to_keylist(ads, sce, &keys, &blocks);
669         
670         BLI_dlrbTree_linkedlist_sync(&keys);
671         BLI_dlrbTree_linkedlist_sync(&blocks);
672         
673                 draw_keylist(v2d, &keys, &blocks, ypos, 0);
674         
675         BLI_dlrbTree_free(&keys);
676         BLI_dlrbTree_free(&blocks);
677 }
678
679 void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos)
680 {
681         DLRBT_Tree keys, blocks;
682         
683         BLI_dlrbTree_init(&keys);
684         BLI_dlrbTree_init(&blocks);
685         
686                 ob_to_keylist(ads, ob, &keys, &blocks);
687         
688         BLI_dlrbTree_linkedlist_sync(&keys);
689         BLI_dlrbTree_linkedlist_sync(&blocks);
690         
691                 draw_keylist(v2d, &keys, &blocks, ypos, 0);
692         
693         BLI_dlrbTree_free(&keys);
694         BLI_dlrbTree_free(&blocks);
695 }
696
697 void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos)
698 {
699         DLRBT_Tree keys, blocks;
700         
701         BLI_dlrbTree_init(&keys);
702         BLI_dlrbTree_init(&blocks);
703         
704                 fcurve_to_keylist(adt, fcu, &keys, &blocks);
705         
706         BLI_dlrbTree_linkedlist_sync(&keys);
707         BLI_dlrbTree_linkedlist_sync(&blocks);
708         
709                 draw_keylist(v2d, &keys, &blocks, ypos, (fcu->flag & FCURVE_PROTECTED));
710         
711         BLI_dlrbTree_free(&keys);
712         BLI_dlrbTree_free(&blocks);
713 }
714
715 void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos)
716 {
717         DLRBT_Tree keys, blocks;
718         
719         BLI_dlrbTree_init(&keys);
720         BLI_dlrbTree_init(&blocks);
721         
722                 agroup_to_keylist(adt, agrp, &keys, &blocks);
723         
724         BLI_dlrbTree_linkedlist_sync(&keys);
725         BLI_dlrbTree_linkedlist_sync(&blocks);
726         
727                 draw_keylist(v2d, &keys, &blocks, ypos, (agrp->flag & AGRP_PROTECTED));
728         
729         BLI_dlrbTree_free(&keys);
730         BLI_dlrbTree_free(&blocks);
731 }
732
733 void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
734 {
735         DLRBT_Tree keys, blocks;
736         
737         BLI_dlrbTree_init(&keys);
738         BLI_dlrbTree_init(&blocks);
739         
740                 action_to_keylist(adt, act, &keys, &blocks);
741         
742         BLI_dlrbTree_linkedlist_sync(&keys);
743         BLI_dlrbTree_linkedlist_sync(&blocks);
744         
745                 draw_keylist(v2d, &keys, &blocks, ypos, 0);
746         
747         BLI_dlrbTree_free(&keys);
748         BLI_dlrbTree_free(&blocks);
749 }
750
751 void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos)
752 {
753         DLRBT_Tree keys;
754         
755         BLI_dlrbTree_init(&keys);
756         
757                 gpl_to_keylist(ads, gpl, &keys);
758         
759         BLI_dlrbTree_linkedlist_sync(&keys);
760         
761                 draw_keylist(v2d, &keys, NULL, ypos, (gpl->flag & GP_LAYER_LOCKED));
762         
763         BLI_dlrbTree_free(&keys);
764 }
765
766 /* *************************** Keyframe List Conversions *************************** */
767
768 void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks)
769 {
770         if (ac) {
771                 ListBase anim_data = {NULL, NULL};
772                 bAnimListElem *ale;
773                 int filter;
774                 
775                 /* get F-Curves to take keyframes from */
776                 filter= ANIMFILTER_DATA_VISIBLE; // curves only
777                 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
778                 
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);
782                 
783                 BLI_freelistN(&anim_data);
784         }
785 }
786
787 void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree *blocks)
788 {
789         bAnimContext ac = {NULL};
790         ListBase anim_data = {NULL, NULL};
791         bAnimListElem *ale;
792         int filter;
793         
794         bAnimListElem dummychan = {0};
795         
796         if (sce == NULL)
797                 return;
798         
799         /* create a dummy wrapper data to work with */
800         dummychan.type = ANIMTYPE_SCENE;
801         dummychan.data = sce;
802         dummychan.id = &sce->id;
803         dummychan.adt = sce->adt;
804         
805         ac.ads = ads;
806         ac.data = &dummychan;
807         ac.datatype = ANIMCONT_CHANNEL;
808         
809         /* get F-Curves to take keyframes from */
810         filter= ANIMFILTER_DATA_VISIBLE; // curves only
811         ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
812         
813         /* loop through each F-Curve, grabbing the keyframes */
814         for (ale= anim_data.first; ale; ale= ale->next)
815                 fcurve_to_keylist(ale->adt, ale->data, keys, blocks);
816         
817         BLI_freelistN(&anim_data);
818 }
819
820 void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *blocks)
821 {       
822         bAnimContext ac = {NULL};
823         ListBase anim_data = {NULL, NULL};
824         bAnimListElem *ale;
825         int filter;
826         
827         bAnimListElem dummychan = {0};
828         Base dummybase = {0};
829         
830         if (ob == NULL)
831                 return;
832         
833         /* create a dummy wrapper data to work with */
834         dummybase.object = ob;
835         
836         dummychan.type = ANIMTYPE_OBJECT;
837         dummychan.data = &dummybase;
838         dummychan.id = &ob->id;
839         dummychan.adt = ob->adt;
840         
841         ac.ads = ads;
842         ac.data = &dummychan;
843         ac.datatype = ANIMCONT_CHANNEL;
844         
845         /* get F-Curves to take keyframes from */
846         filter= ANIMFILTER_DATA_VISIBLE; // curves only
847         ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
848         
849         /* loop through each F-Curve, grabbing the keyframes */
850         for (ale= anim_data.first; ale; ale= ale->next)
851                 fcurve_to_keylist(ale->adt, ale->data, keys, blocks);
852         
853         BLI_freelistN(&anim_data);
854 }
855
856 void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree *blocks)
857 {
858         DLRBT_Tree *beztTree = NULL;
859         BezTriple *bezt;
860         unsigned int v;
861
862         if (fcu && fcu->totvert && fcu->bezt) {
863                 /* apply NLA-mapping (if applicable) */
864                 if (adt)        
865                         ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
866                 
867                 /* if getting long keyframes too, grab the BezTriples in a BST for 
868                  * accelerated searching...
869                  */
870                 if (blocks) {
871                         /* init new tree */
872                         beztTree= BLI_dlrbTree_new();
873                         
874                         /* populate tree with the BezTriples */
875                         for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++)
876                                 BLI_dlrbTree_add(beztTree, compare_abk_bezt, nalloc_abk_bezt, nupdate_abk_bezt, bezt);
877                         
878                         /* make sure that it is suitable for linked-list searching too */
879                         BLI_dlrbTree_linkedlist_sync(beztTree);
880                 }
881                 
882                 /* loop through beztriples, making ActKeysColumns and ActKeyBlocks */
883                 for (v=0, bezt=fcu->bezt; v < fcu->totvert; v++, bezt++) {
884                         add_bezt_to_keycolumns_list(keys, bezt);
885                         if (blocks) add_bezt_to_keyblocks_list(blocks, beztTree, bezt);
886                 }
887                 
888                 /* update the number of curves that elements have appeared in  */
889                 if (keys)
890                         set_touched_actkeycolumn(keys->root);
891                 if (blocks)
892                         set_touched_actkeyblock(blocks->root);
893                         
894                 /* free temp data for building long keyframes */
895                 if (blocks && beztTree) {
896                         BLI_dlrbTree_free(beztTree);
897                         MEM_freeN(beztTree);
898                 }
899                 
900                 /* unapply NLA-mapping if applicable */
901                 if (adt)
902                         ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
903         }
904 }
905
906 void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, DLRBT_Tree *blocks)
907 {
908         FCurve *fcu;
909
910         if (agrp) {
911                 /* loop through F-Curves */
912                 for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) {
913                         fcurve_to_keylist(adt, fcu, keys, blocks);
914                 }
915         }
916 }
917
918 void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree *blocks)
919 {
920         FCurve *fcu;
921
922         if (act) {
923                 /* loop through F-Curves */
924                 for (fcu= act->curves.first; fcu; fcu= fcu->next) {
925                         fcurve_to_keylist(adt, fcu, keys, blocks);
926                 }
927         }
928 }
929
930
931 void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
932 {
933         bGPDframe *gpf;
934         
935         if (gpl && keys) {
936                 /* although the frames should already be in an ordered list, they are not suitable for displaying yet */
937                 for (gpf= gpl->frames.first; gpf; gpf= gpf->next)
938                         add_gpframe_to_keycolumns_list(keys, gpf);
939         }
940 }
941