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