remove unused includes
[blender-staging.git] / source / blender / editors / animation / keyframes_edit.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) 2008 Blender Foundation
21  *
22  * Contributor(s): Joshua Leung
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <math.h>
30 #include <float.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_blenlib.h"
35 #include "BLI_math.h"
36
37 #include "DNA_anim_types.h"
38 #include "DNA_armature_types.h"
39 #include "DNA_camera_types.h"
40 #include "DNA_key_types.h"
41 #include "DNA_lamp_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_material_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_meta_types.h"
46 #include "DNA_node_types.h"
47 #include "DNA_particle_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_world_types.h"
50
51 #include "BKE_fcurve.h"
52 #include "BKE_key.h"
53 #include "BKE_material.h"
54 #include "BKE_utildefines.h"
55
56 #include "ED_anim_api.h"
57 #include "ED_keyframes_edit.h"
58 #include "ED_markers.h"
59
60 /* This file defines an API and set of callback-operators for non-destructive editing of keyframe data.
61  *
62  * Two API functions are defined for actually performing the operations on the data:
63  *                      ANIM_fcurve_keyframes_loop()
64  * which take the data they operate on, a few callbacks defining what operations to perform.
65  *
66  * As operators which work on keyframes usually apply the same operation on all BezTriples in 
67  * every channel, the code has been optimised providing a set of functions which will get the 
68  * appropriate bezier-modify function to set. These functions (ANIM_editkeyframes_*) will need
69  * to be called before getting any channels.
70  * 
71  * A set of 'validation' callbacks are provided for checking if a BezTriple should be operated on.
72  * These should only be used when using a 'general' BezTriple editor (i.e. selection setters which 
73  * don't check existing selection status).
74  * 
75  * - Joshua Leung, Dec 2008
76  */
77
78 /* ************************************************************************** */
79 /* Keyframe Editing Loops - Exposed API */
80
81 /* --------------------------- Base Functions ------------------------------------ */
82
83 /* This function is used to loop over BezTriples in the given F-Curve, applying a given 
84  * operation on them, and optionally applies an F-Curve validation function afterwards.
85  */
86 // TODO: make this function work on samples too...
87 short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb) 
88 {
89         BezTriple *bezt;
90         short ok = 0;
91         int i;
92
93         /* sanity check */
94         if (ELEM(NULL, fcu, fcu->bezt))
95                 return 0;
96
97         /* set the F-Curve into the editdata so that it can be accessed */
98         if (ked) {
99                 ked->fcu= fcu;
100                 ked->curIndex= 0;
101                 ked->curflags= ok;
102         }
103
104         /* if function to apply to bezier curves is set, then loop through executing it on beztriples */
105         if (key_cb) {
106                 /* if there's a validation func, include that check in the loop 
107                  * (this is should be more efficient than checking for it in every loop)
108                  */
109                 if (key_ok) {
110                         for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) {
111                                 if (ked) {
112                                         /* advance the index, and reset the ok flags (to not influence the result) */
113                                         ked->curIndex= i;
114                                         ked->curflags= 0;
115                                 }
116                                 
117                                 /* Only operate on this BezTriple if it fullfills the criteria of the validation func */
118                                 if ( (ok = key_ok(ked, bezt)) ) {
119                                         if (ked) ked->curflags= ok;
120                                         
121                                         /* Exit with return-code '1' if function returns positive
122                                          * This is useful if finding if some BezTriple satisfies a condition.
123                                          */
124                                         if (key_cb(ked, bezt)) return 1;
125                                 }
126                         }
127                 }
128                 else {
129                         for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) {
130                                 if (ked) ked->curIndex= i;
131                                 
132                                 /* Exit with return-code '1' if function returns positive
133                                 * This is useful if finding if some BezTriple satisfies a condition.
134                                 */
135                                 if (key_cb(ked, bezt)) return 1;
136                         }
137                 }
138         }
139         
140         /* unset the F-Curve from the editdata now that it's done */
141         if (ked) {
142                 ked->fcu= NULL;
143                 ked->curIndex= 0;
144                 ked->curflags= 0;
145         }
146
147         /* if fcu_cb (F-Curve post-editing callback) has been specified then execute it */
148         if (fcu_cb)
149                 fcu_cb(fcu);
150         
151         /* done */      
152         return 0;
153 }
154
155 /* -------------------------------- Further Abstracted (Not Exposed Directly) ----------------------------- */
156
157 /* This function is used to loop over the keyframe data in an Action Group */
158 static short agrp_keyframes_loop(KeyframeEditData *ked, bActionGroup *agrp, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
159 {
160         FCurve *fcu;
161         
162         /* sanity check */
163         if (agrp == NULL)
164                 return 0;
165         
166         /* only iterate over the F-Curves that are in this group */
167         for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) {
168                 if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
169                         return 1;
170         }
171         
172         return 0;
173 }
174
175 /* This function is used to loop over the keyframe data in an Action */
176 static short act_keyframes_loop(KeyframeEditData *ked, bAction *act, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
177 {
178         FCurve *fcu;
179         
180         /* sanity check */
181         if (act == NULL)
182                 return 0;
183         
184         /* just loop through all F-Curves */
185         for (fcu= act->curves.first; fcu; fcu= fcu->next) {
186                 if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
187                         return 1;
188         }
189         
190         return 0;
191 }
192
193 /* This function is used to loop over the keyframe data of an AnimData block */
194 static short adt_keyframes_loop(KeyframeEditData *ked, AnimData *adt, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag)
195 {
196         /* sanity check */
197         if (adt == NULL)
198                 return 0;
199         
200         /* drivers or actions? */
201         if (filterflag & ADS_FILTER_ONLYDRIVERS) {
202                 FCurve *fcu;
203                 
204                 /* just loop through all F-Curves acting as Drivers */
205                 for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
206                         if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
207                                 return 1;
208                 }
209         }
210         else if (adt->action) {
211                 /* call the function for actions */
212                 if (act_keyframes_loop(ked, adt->action, key_ok, key_cb, fcu_cb))
213                         return 1;
214         }
215         
216         return 0;
217 }
218
219 /* This function is used to loop over the keyframe data in an Object */
220 static short ob_keyframes_loop(KeyframeEditData *ked, Object *ob, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag)
221 {
222         Key *key= ob_get_key(ob);
223         
224         /* sanity check */
225         if (ob == NULL)
226                 return 0;
227         
228         /* firstly, Object's own AnimData */
229         if (ob->adt) {
230                 if (adt_keyframes_loop(ked, ob->adt, key_ok, key_cb, fcu_cb, filterflag))
231                         return 1;
232         }
233         
234         /* shapekeys */
235         if ((key && key->adt) && !(filterflag & ADS_FILTER_NOSHAPEKEYS)) {
236                 if (adt_keyframes_loop(ked, key->adt, key_ok, key_cb, fcu_cb, filterflag))
237                         return 1;
238         }
239                 
240         /* Add material keyframes */
241         if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) {
242                 int a;
243                 
244                 for (a=1; a <= ob->totcol; a++) {
245                         Material *ma= give_current_material(ob, a);
246                         
247                         /* there might not be a material */
248                         if (ELEM(NULL, ma, ma->adt)) 
249                                 continue;
250                         
251                         /* add material's data */
252                         if (adt_keyframes_loop(ked, ma->adt, key_ok, key_cb, fcu_cb, filterflag))
253                                 return 1;
254                 }
255         }
256         
257         /* Add object data keyframes */
258         switch (ob->type) {
259                 case OB_CAMERA: /* ------- Camera ------------ */
260                 {
261                         Camera *ca= (Camera *)ob->data;
262                         
263                         if ((ca->adt) && !(filterflag & ADS_FILTER_NOCAM)) {
264                                 if (adt_keyframes_loop(ked, ca->adt, key_ok, key_cb, fcu_cb, filterflag))
265                                         return 1;
266                         }
267                 }
268                         break;
269                 case OB_LAMP: /* ---------- Lamp ----------- */
270                 {
271                         Lamp *la= (Lamp *)ob->data;
272                         
273                         if ((la->adt) && !(filterflag & ADS_FILTER_NOLAM)) {
274                                 if (adt_keyframes_loop(ked, la->adt, key_ok, key_cb, fcu_cb, filterflag))
275                                         return 1;
276                         }
277                 }
278                         break;
279                 case OB_CURVE: /* ------- Curve ---------- */
280                 case OB_SURF: /* ------- Nurbs Surface ---------- */
281                 case OB_FONT: /* ------- Text Curve ---------- */
282                 {
283                         Curve *cu= (Curve *)ob->data;
284                         
285                         if ((cu->adt) && !(filterflag & ADS_FILTER_NOCUR)) {
286                                 if (adt_keyframes_loop(ked, cu->adt, key_ok, key_cb, fcu_cb, filterflag))
287                                         return 1;
288                         }
289                 }
290                         break;
291                 case OB_MBALL: /* ------- MetaBall ---------- */
292                 {
293                         MetaBall *mb= (MetaBall *)ob->data;
294                         
295                         if ((mb->adt) && !(filterflag & ADS_FILTER_NOMBA)) {
296                                 if (adt_keyframes_loop(ked, mb->adt, key_ok, key_cb, fcu_cb, filterflag))
297                                         return 1;
298                         }
299                 }
300                         break;
301                 case OB_ARMATURE: /* ------- Armature ---------- */
302                 {
303                         bArmature *arm= (bArmature *)ob->data;
304                         
305                         if ((arm->adt) && !(filterflag & ADS_FILTER_NOARM)) {
306                                 if (adt_keyframes_loop(ked, arm->adt, key_ok, key_cb, fcu_cb, filterflag))
307                                         return 1;
308                         }
309                 }
310                         break;
311                 case OB_MESH: /* ------- Mesh ---------- */
312                 {
313                         Mesh *me= (Mesh *)ob->data;
314                         
315                         if ((me->adt) && !(filterflag & ADS_FILTER_NOMESH)) {
316                                 if (adt_keyframes_loop(ked, me->adt, key_ok, key_cb, fcu_cb, filterflag))
317                                         return 1;
318                         }
319                 }
320                         break;
321         }
322         
323         /* Add Particle System Keyframes */
324         if ((ob->particlesystem.first) && !(filterflag & ADS_FILTER_NOPART)) {
325                 ParticleSystem *psys = ob->particlesystem.first;
326                 
327                 for(; psys; psys=psys->next) {
328                         if (ELEM(NULL, psys->part, psys->part->adt))
329                                 continue;
330                                 
331                         if (adt_keyframes_loop(ked, psys->part->adt, key_ok, key_cb, fcu_cb, filterflag))
332                                 return 1;
333                 }
334         }
335         
336         return 0;
337 }
338
339 /* This function is used to loop over the keyframe data in a Scene */
340 static short scene_keyframes_loop(KeyframeEditData *ked, Scene *sce, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag)
341 {
342         World *wo= (sce) ? sce->world : NULL;
343         bNodeTree *ntree= (sce) ? sce->nodetree : NULL;
344         
345         /* sanity check */
346         if (sce == NULL)
347                 return 0;
348         
349         /* Scene's own animation */
350         if (sce->adt) {
351                 if (adt_keyframes_loop(ked, sce->adt, key_ok, key_cb, fcu_cb, filterflag))
352                         return 1;
353         }
354         
355         /* World */
356         if (wo && wo->adt) {
357                 if (adt_keyframes_loop(ked, wo->adt, key_ok, key_cb, fcu_cb, filterflag))
358                         return 1;
359         }
360         
361         /* NodeTree */
362         if (ntree && ntree->adt) {
363                 if (adt_keyframes_loop(ked, ntree->adt, key_ok, key_cb, fcu_cb, filterflag))
364                         return 1;
365         }
366         
367         
368         return 0;
369 }
370
371 /* This function is used to loop over the keyframe data in a DopeSheet summary */
372 static short summary_keyframes_loop(KeyframeEditData *ked, bAnimContext *ac, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag)
373 {
374         ListBase anim_data = {NULL, NULL};
375         bAnimListElem *ale;
376         int filter, ret_code=0;
377         
378         /* sanity check */
379         if (ac == NULL)
380                 return 0;
381         
382         /* get F-Curves to take keyframes from */
383         filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
384         ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
385         
386         /* loop through each F-Curve, working on the keyframes until the first curve aborts */
387         for (ale= anim_data.first; ale; ale= ale->next) {
388                 ret_code= ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb);
389                 
390                 if (ret_code)
391                         break;
392         }
393         
394         BLI_freelistN(&anim_data);
395         
396         return ret_code;
397 }
398
399 /* --- */
400
401 /* This function is used to apply operation to all keyframes, regardless of the type */
402 short ANIM_animchannel_keyframes_loop(KeyframeEditData *ked, bAnimListElem *ale, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag)
403 {
404         /* sanity checks */
405         if (ale == NULL)
406                 return 0;
407         
408         /* method to use depends on the type of keyframe data */
409         switch (ale->datatype) {
410                 /* direct keyframe data (these loops are exposed) */
411                 case ALE_FCURVE: /* F-Curve */
412                         return ANIM_fcurve_keyframes_loop(ked, ale->key_data, key_ok, key_cb, fcu_cb);
413                 
414                 /* indirect 'summaries' (these are not exposed directly) 
415                  * NOTE: must keep this code in sync with the drawing code and also the filtering code!
416                  */
417                 case ALE_GROUP: /* action group */
418                         return agrp_keyframes_loop(ked, (bActionGroup *)ale->data, key_ok, key_cb, fcu_cb);
419                 case ALE_ACT: /* action */
420                         return act_keyframes_loop(ked, (bAction *)ale->key_data, key_ok, key_cb, fcu_cb);
421                         
422                 case ALE_OB: /* object */
423                         return ob_keyframes_loop(ked, (Object *)ale->key_data, key_ok, key_cb, fcu_cb, filterflag);
424                 case ALE_SCE: /* scene */
425                         return scene_keyframes_loop(ked, (Scene *)ale->data, key_ok, key_cb, fcu_cb, filterflag);
426                 case ALE_ALL: /* 'all' (DopeSheet summary) */
427                         return summary_keyframes_loop(ked, (bAnimContext *)ale->data, key_ok, key_cb, fcu_cb, filterflag);
428         }
429         
430         return 0;
431 }
432
433 /* This function is used to apply operation to all keyframes, regardless of the type without needed an AnimListElem wrapper */
434 short ANIM_animchanneldata_keyframes_loop(KeyframeEditData *ked, void *data, int keytype, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb, int filterflag)
435 {
436         /* sanity checks */
437         if (data == NULL)
438                 return 0;
439         
440         /* method to use depends on the type of keyframe data */
441         switch (keytype) {
442                 /* direct keyframe data (these loops are exposed) */
443                 case ALE_FCURVE: /* F-Curve */
444                         return ANIM_fcurve_keyframes_loop(ked, data, key_ok, key_cb, fcu_cb);
445                 
446                 /* indirect 'summaries' (these are not exposed directly) 
447                  * NOTE: must keep this code in sync with the drawing code and also the filtering code!
448                  */
449                 case ALE_GROUP: /* action group */
450                         return agrp_keyframes_loop(ked, (bActionGroup *)data, key_ok, key_cb, fcu_cb);
451                 case ALE_ACT: /* action */
452                         return act_keyframes_loop(ked, (bAction *)data, key_ok, key_cb, fcu_cb);
453                         
454                 case ALE_OB: /* object */
455                         return ob_keyframes_loop(ked, (Object *)data, key_ok, key_cb, fcu_cb, filterflag);
456                 case ALE_SCE: /* scene */
457                         return scene_keyframes_loop(ked, (Scene *)data, key_ok, key_cb, fcu_cb, filterflag);
458                 case ALE_ALL: /* 'all' (DopeSheet summary) */
459                         return summary_keyframes_loop(ked, (bAnimContext *)data, key_ok, key_cb, fcu_cb, filterflag);
460         }
461         
462         return 0;
463 }
464
465 /* ************************************************************************** */
466 /* Keyframe Integrity Tools */
467
468 /* Rearrange keyframes if some are out of order */
469 // used to be recalc_*_ipos() where * was object or action
470 void ANIM_editkeyframes_refresh(bAnimContext *ac)
471 {
472         ListBase anim_data = {NULL, NULL};
473         bAnimListElem *ale;
474         int filter;
475         
476         /* filter animation data */
477         filter= ANIMFILTER_CURVESONLY; 
478         ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
479         
480         /* loop over F-Curves that are likely to have been edited, and check them */
481         for (ale= anim_data.first; ale; ale= ale->next) {
482                 FCurve *fcu= ale->key_data;
483                 
484                 /* make sure keyframes in F-Curve are all in order, and handles are in valid positions */
485                 sort_time_fcurve(fcu);
486                 testhandles_fcurve(fcu);
487         }
488         
489         /* free temp data */
490         BLI_freelistN(&anim_data);
491 }
492
493 /* ************************************************************************** */
494 /* BezTriple Validation Callbacks */
495
496 /* ------------------------ */
497 /* Some macros to make this easier... */
498
499 /* run the given check on the 3 handles 
500  *      - check should be a macro, which takes the handle index as its single arg, which it substitutes later
501  *      - requires that a var, of type short, is named 'ok', and has been initialised ot 0
502  */
503 #define KEYFRAME_OK_CHECKS(check) \
504         { \
505                 if (check(1)) \
506                         ok |= KEYFRAME_OK_KEY; \
507                  \
508                 if (ked && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) { \
509                         if (check(0)) \
510                                 ok |= KEYFRAME_OK_H1; \
511                         if (check(2)) \
512                                 ok |= KEYFRAME_OK_H2; \
513                 } \
514         }       
515  
516 /* ------------------------ */
517  
518 static short ok_bezier_frame(KeyframeEditData *ked, BezTriple *bezt)
519 {
520         short ok = 0;
521         
522         /* frame is stored in f1 property (this float accuracy check may need to be dropped?) */
523         #define KEY_CHECK_OK(_index) IS_EQ(bezt->vec[_index][0], ked->f1)
524                 KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
525         #undef KEY_CHECK_OK
526         
527         /* return ok flags */
528         return ok;
529 }
530
531 static short ok_bezier_framerange(KeyframeEditData *ked, BezTriple *bezt)
532 {
533         short ok = 0;
534         
535         /* frame range is stored in float properties */
536         #define KEY_CHECK_OK(_index) ((bezt->vec[_index][0] > ked->f1) && (bezt->vec[_index][0] < ked->f2))
537                 KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
538         #undef KEY_CHECK_OK
539         
540         /* return ok flags */
541         return ok;
542 }
543
544 static short ok_bezier_selected(KeyframeEditData *ked, BezTriple *bezt)
545 {
546         /* this macro checks all beztriple handles for selection... 
547          *      only one of the verts has to be selected for this to be ok...
548          */
549         if (BEZSELECTED(bezt))
550                 return KEYFRAME_OK_ALL;
551         else
552                 return 0;
553 }
554
555 static short ok_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
556 {       
557         short ok = 0;
558         
559         /* value is stored in f1 property 
560          *      - this float accuracy check may need to be dropped?
561          *      - should value be stored in f2 instead so that we won't have conflicts when using f1 for frames too?
562          */
563         #define KEY_CHECK_OK(_index) IS_EQ(bezt->vec[_index][1], ked->f1)
564                 KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
565         #undef KEY_CHECK_OK
566         
567         /* return ok flags */
568         return ok;
569 }
570
571 static short ok_bezier_valuerange(KeyframeEditData *ked, BezTriple *bezt)
572 {
573         short ok = 0;
574         
575         /* value range is stored in float properties */
576         #define KEY_CHECK_OK(_index) ((bezt->vec[_index][1] > ked->f1) && (bezt->vec[_index][1] < ked->f2))
577                 KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
578         #undef KEY_CHECK_OK
579         
580         /* return ok flags */
581         return ok;
582 }
583
584 static short ok_bezier_region(KeyframeEditData *ked, BezTriple *bezt)
585 {
586         /* rect is stored in data property (it's of type rectf, but may not be set) */
587         if (ked->data) {
588                 short ok = 0;
589                 
590                 #define KEY_CHECK_OK(_index) BLI_in_rctf(ked->data, bezt->vec[_index][0], bezt->vec[_index][1])
591                         KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
592                 #undef KEY_CHECK_OK
593                 
594                 /* return ok flags */
595                 return ok;
596         }
597         else 
598                 return 0;
599 }
600
601
602 KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
603 {
604         /* eEditKeyframes_Validate */
605         switch (mode) {
606                 case BEZT_OK_FRAME: /* only if bezt falls on the right frame (float) */
607                         return ok_bezier_frame;
608                 case BEZT_OK_FRAMERANGE: /* only if bezt falls within the specified frame range (floats) */
609                         return ok_bezier_framerange;
610                 case BEZT_OK_SELECTED:  /* only if bezt is selected (self) */
611                         return ok_bezier_selected;
612                 case BEZT_OK_VALUE: /* only if bezt value matches (float) */
613                         return ok_bezier_value;
614                 case BEZT_OK_VALUERANGE: /* only if bezier falls within the specified value range (floats) */
615                         return ok_bezier_valuerange;
616                 case BEZT_OK_REGION: /* only if bezier falls within the specified rect (data -> rectf) */
617                         return ok_bezier_region;
618                 default: /* nothing was ok */
619                         return NULL;
620         }
621 }
622
623 /* ******************************************* */
624 /* Assorted Utility Functions */
625
626 /* helper callback for <animeditor>_cfrasnap_exec() -> used to help get the average time of all selected beztriples */
627 short bezt_calc_average(KeyframeEditData *ked, BezTriple *bezt)
628 {
629         /* only if selected */
630         if (bezt->f2 & SELECT) {
631                 /* store average time in float 1 (only do rounding at last step) */
632                 ked->f1 += bezt->vec[1][0];
633                 
634                 /* store average value in float 2 (only do rounding at last step) 
635                  *      - this isn't always needed, but some operators may also require this
636                  */
637                 ked->f2 += bezt->vec[1][1];
638                 
639                 /* increment number of items */
640                 ked->i1++;
641         }
642         
643         return 0;
644 }
645
646 /* helper callback for columnselect_<animeditor>_keys() -> populate list CfraElems with frame numbers from selected beztriples */
647 short bezt_to_cfraelem(KeyframeEditData *ked, BezTriple *bezt)
648 {
649         /* only if selected */
650         if (bezt->f2 & SELECT) {
651                 CfraElem *ce= MEM_callocN(sizeof(CfraElem), "cfraElem");
652                 BLI_addtail(&ked->list, ce);
653                 
654                 ce->cfra= bezt->vec[1][0];
655         }
656         
657         return 0;
658 }
659
660 /* used to remap times from one range to another
661  * requires:  ked->data = KeyframeEditCD_Remap  
662  */
663 void bezt_remap_times(KeyframeEditData *ked, BezTriple *bezt)
664 {
665         KeyframeEditCD_Remap *rmap= (KeyframeEditCD_Remap*)ked->data;
666         const float scale = (rmap->newMax - rmap->newMin) / (rmap->oldMax - rmap->oldMin);
667         
668         /* perform transform on all three handles unless indicated otherwise */
669         // TODO: need to include some checks for that
670         
671         bezt->vec[0][0]= scale*(bezt->vec[0][0] - rmap->oldMin) + rmap->newMin;
672         bezt->vec[1][0]= scale*(bezt->vec[1][0] - rmap->oldMin) + rmap->newMin;
673         bezt->vec[2][0]= scale*(bezt->vec[2][0] - rmap->oldMin) + rmap->newMin;
674 }
675
676 /* ******************************************* */
677 /* Transform */
678
679 /* snaps the keyframe to the nearest frame */
680 static short snap_bezier_nearest(KeyframeEditData *ked, BezTriple *bezt)
681 {
682         if (bezt->f2 & SELECT)
683                 bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
684         return 0;
685 }
686
687 /* snaps the keyframe to the neares second */
688 static short snap_bezier_nearestsec(KeyframeEditData *ked, BezTriple *bezt)
689 {
690         const Scene *scene= ked->scene;
691         const float secf = (float)FPS;
692         
693         if (bezt->f2 & SELECT)
694                 bezt->vec[1][0]= ((float)floor(bezt->vec[1][0]/secf + 0.5f) * secf);
695         return 0;
696 }
697
698 /* snaps the keyframe to the current frame */
699 static short snap_bezier_cframe(KeyframeEditData *ked, BezTriple *bezt)
700 {
701         const Scene *scene= ked->scene;
702         if (bezt->f2 & SELECT)
703                 bezt->vec[1][0]= (float)CFRA;
704         return 0;
705 }
706
707 /* snaps the keyframe time to the nearest marker's frame */
708 static short snap_bezier_nearmarker(KeyframeEditData *ked, BezTriple *bezt)
709 {
710         if (bezt->f2 & SELECT)
711                 bezt->vec[1][0]= (float)ED_markers_find_nearest_marker_time(&ked->list, bezt->vec[1][0]);
712         return 0;
713 }
714
715 /* make the handles have the same value as the key */
716 static short snap_bezier_horizontal(KeyframeEditData *ked, BezTriple *bezt)
717 {
718         if (bezt->f2 & SELECT) {
719                 bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
720                 
721                 if ((bezt->h1==HD_AUTO) || (bezt->h1==HD_VECT)) bezt->h1= HD_ALIGN;
722                 if ((bezt->h2==HD_AUTO) || (bezt->h2==HD_VECT)) bezt->h2= HD_ALIGN;
723         }
724         return 0;       
725 }
726
727 /* value to snap to is stored in the custom data -> first float value slot */
728 static short snap_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
729 {
730         if (bezt->f2 & SELECT)
731                 bezt->vec[1][1]= ked->f1;
732         return 0;
733 }
734
735 KeyframeEditFunc ANIM_editkeyframes_snap(short type)
736 {
737         /* eEditKeyframes_Snap */
738         switch (type) {
739                 case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */
740                         return snap_bezier_nearest;
741                 case SNAP_KEYS_CURFRAME: /* snap to current frame */
742                         return snap_bezier_cframe;
743                 case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */
744                         return snap_bezier_nearmarker;
745                 case SNAP_KEYS_NEARSEC: /* snap to nearest second */
746                         return snap_bezier_nearestsec;
747                 case SNAP_KEYS_HORIZONTAL: /* snap handles to same value */
748                         return snap_bezier_horizontal;
749                 case SNAP_KEYS_VALUE: /* snap to given value */
750                         return snap_bezier_value;
751                 default: /* just in case */
752                         return snap_bezier_nearest;
753         }
754 }
755
756 /* --------- */
757
758 static short mirror_bezier_cframe(KeyframeEditData *ked, BezTriple *bezt)
759 {
760         const Scene *scene= ked->scene;
761         float diff;
762         
763         if (bezt->f2 & SELECT) {
764                 diff= ((float)CFRA - bezt->vec[1][0]);
765                 bezt->vec[1][0]= ((float)CFRA + diff);
766         }
767         
768         return 0;
769 }
770
771 static short mirror_bezier_yaxis(KeyframeEditData *ked, BezTriple *bezt)
772 {
773         float diff;
774         
775         if (bezt->f2 & SELECT) {
776                 diff= (0.0f - bezt->vec[1][0]);
777                 bezt->vec[1][0]= (0.0f + diff);
778         }
779         
780         return 0;
781 }
782
783 static short mirror_bezier_xaxis(KeyframeEditData *ked, BezTriple *bezt)
784 {
785         float diff;
786         
787         if (bezt->f2 & SELECT) {
788                 diff= (0.0f - bezt->vec[1][1]);
789                 bezt->vec[1][1]= (0.0f + diff);
790         }
791         
792         return 0;
793 }
794
795 static short mirror_bezier_marker(KeyframeEditData *ked, BezTriple *bezt)
796 {
797         /* mirroring time stored in f1 */
798         if (bezt->f2 & SELECT) {
799                 const float diff= (ked->f1 - bezt->vec[1][0]);
800                 bezt->vec[1][0]= (ked->f1 + diff);
801         }
802         
803         return 0;
804 }
805
806 static short mirror_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
807 {
808         float diff;
809         
810         /* value to mirror over is stored in the custom data -> first float value slot */
811         if (bezt->f2 & SELECT) {
812                 diff= (ked->f1 - bezt->vec[1][1]);
813                 bezt->vec[1][1]= (ked->f1 + diff);
814         }
815         
816         return 0;
817 }
818
819 /* Note: for markers and 'value', the values to use must be supplied as the first float value */
820 // calchandles_fcurve
821 KeyframeEditFunc ANIM_editkeyframes_mirror(short type)
822 {
823         switch (type) {
824                 case MIRROR_KEYS_CURFRAME: /* mirror over current frame */
825                         return mirror_bezier_cframe;
826                 case MIRROR_KEYS_YAXIS: /* mirror over frame 0 */
827                         return mirror_bezier_yaxis;
828                 case MIRROR_KEYS_XAXIS: /* mirror over value 0 */
829                         return mirror_bezier_xaxis;
830                 case MIRROR_KEYS_MARKER: /* mirror over marker */
831                         return mirror_bezier_marker; 
832                 case MIRROR_KEYS_VALUE: /* mirror over given value */
833                         return mirror_bezier_value;
834                 default: /* just in case */
835                         return mirror_bezier_yaxis;
836                         break;
837         }
838 }
839
840 /* ******************************************* */
841 /* Settings */
842
843 /* Sets the selected bezier handles to type 'auto' */
844 static short set_bezier_auto(KeyframeEditData *ked, BezTriple *bezt) 
845 {
846         if((bezt->f1  & SELECT) || (bezt->f3 & SELECT)) {
847                 if (bezt->f1 & SELECT) bezt->h1= HD_AUTO; /* the secret code for auto */
848                 if (bezt->f3 & SELECT) bezt->h2= HD_AUTO;
849                 
850                 /* if the handles are not of the same type, set them
851                  * to type free
852                  */
853                 if (bezt->h1 != bezt->h2) {
854                         if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE;
855                         if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE;
856                 }
857         }
858         return 0;
859 }
860
861 /* Sets the selected bezier handles to type 'vector'  */
862 static short set_bezier_vector(KeyframeEditData *ked, BezTriple *bezt) 
863 {
864         if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
865                 if (bezt->f1 & SELECT) bezt->h1= HD_VECT;
866                 if (bezt->f3 & SELECT) bezt->h2= HD_VECT;
867                 
868                 /* if the handles are not of the same type, set them
869                  * to type free
870                  */
871                 if (bezt->h1 != bezt->h2) {
872                         if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE;
873                         if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE;
874                 }
875         }
876         return 0;
877 }
878
879 /* Queries if the handle should be set to 'free' or 'align' */
880 // NOTE: this was used for the 'toggle free/align' option
881 //              currently this isn't used, but may be restored later
882 static short bezier_isfree(KeyframeEditData *ked, BezTriple *bezt) 
883 {
884         if ((bezt->f1 & SELECT) && (bezt->h1)) return 1;
885         if ((bezt->f3 & SELECT) && (bezt->h2)) return 1;
886         return 0;
887 }
888
889 /* Sets selected bezier handles to type 'align' */
890 static short set_bezier_align(KeyframeEditData *ked, BezTriple *bezt) 
891 {       
892         if (bezt->f1 & SELECT) bezt->h1= HD_ALIGN;
893         if (bezt->f3 & SELECT) bezt->h2= HD_ALIGN;
894         return 0;
895 }
896
897 /* Sets selected bezier handles to type 'free'  */
898 static short set_bezier_free(KeyframeEditData *ked, BezTriple *bezt) 
899 {
900         if (bezt->f1 & SELECT) bezt->h1= HD_FREE;
901         if (bezt->f3 & SELECT) bezt->h2= HD_FREE;
902         return 0;
903 }
904
905 /* Set all selected Bezier Handles to a single type */
906 // calchandles_fcurve
907 KeyframeEditFunc ANIM_editkeyframes_handles(short code)
908 {
909         switch (code) {
910                 case HD_AUTO: /* auto */
911                 case HD_AUTO_ANIM: /* auto clamped */
912                         return set_bezier_auto;
913                         
914                 case HD_VECT: /* vector */
915                         return set_bezier_vector;
916                 case HD_FREE: /* free */
917                         return set_bezier_free;
918                 case HD_ALIGN: /* align */
919                         return set_bezier_align;
920                 
921                 default: /* check for toggle free or align? */
922                         return bezier_isfree;
923         }
924 }
925
926 /* ------- */
927
928 static short set_bezt_constant(KeyframeEditData *ked, BezTriple *bezt) 
929 {
930         if (bezt->f2 & SELECT) 
931                 bezt->ipo= BEZT_IPO_CONST;
932         return 0;
933 }
934
935 static short set_bezt_linear(KeyframeEditData *ked, BezTriple *bezt) 
936 {
937         if (bezt->f2 & SELECT) 
938                 bezt->ipo= BEZT_IPO_LIN;
939         return 0;
940 }
941
942 static short set_bezt_bezier(KeyframeEditData *ked, BezTriple *bezt) 
943 {
944         if (bezt->f2 & SELECT) 
945                 bezt->ipo= BEZT_IPO_BEZ;
946         return 0;
947 }
948
949 /* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
950 // ANIM_editkeyframes_ipocurve_ipotype() !
951 KeyframeEditFunc ANIM_editkeyframes_ipo(short code)
952 {
953         switch (code) {
954                 case BEZT_IPO_CONST: /* constant */
955                         return set_bezt_constant;
956                 case BEZT_IPO_LIN: /* linear */ 
957                         return set_bezt_linear;
958                 default: /* bezier */
959                         return set_bezt_bezier;
960         }
961 }
962
963 /* ------- */
964
965 static short set_keytype_keyframe(KeyframeEditData *ked, BezTriple *bezt) 
966 {
967         if (bezt->f2 & SELECT) 
968                 BEZKEYTYPE(bezt)= BEZT_KEYTYPE_KEYFRAME;
969         return 0;
970 }
971
972 static short set_keytype_breakdown(KeyframeEditData *ked, BezTriple *bezt) 
973 {
974         if (bezt->f2 & SELECT) 
975                 BEZKEYTYPE(bezt)= BEZT_KEYTYPE_BREAKDOWN;
976         return 0;
977 }
978
979 static short set_keytype_extreme(KeyframeEditData *ked, BezTriple *bezt) 
980 {
981         if (bezt->f2 & SELECT) 
982                 BEZKEYTYPE(bezt)= BEZT_KEYTYPE_EXTREME;
983         return 0;
984 }
985
986 /* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
987 KeyframeEditFunc ANIM_editkeyframes_keytype(short code)
988 {
989         switch (code) {
990                 case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */
991                         return set_keytype_breakdown;
992                         
993                 case BEZT_KEYTYPE_EXTREME: /* extreme keyframe */
994                         return set_keytype_extreme;
995                         
996                 case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */       
997                 default:
998                         return set_keytype_keyframe;
999         }
1000 }
1001
1002 /* ******************************************* */
1003 /* Selection */
1004
1005 static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt) 
1006 {
1007         /* if we've got info on what to select, use it, otherwise select all */
1008         if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
1009                 if (ked->curflags & KEYFRAME_OK_KEY)
1010                         bezt->f2 |= SELECT;
1011                 if (ked->curflags & KEYFRAME_OK_H1)
1012                         bezt->f1 |= SELECT;
1013                 if (ked->curflags & KEYFRAME_OK_H2)
1014                         bezt->f3 |= SELECT;
1015         }
1016         else {
1017                 BEZ_SEL(bezt);
1018         }
1019         
1020         return 0;
1021 }
1022
1023 static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt) 
1024 {
1025         /* if we've got info on what to deselect, use it, otherwise deselect all */
1026         if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
1027                 if (ked->curflags & KEYFRAME_OK_KEY)
1028                         bezt->f2 &= ~SELECT;
1029                 if (ked->curflags & KEYFRAME_OK_H1)
1030                         bezt->f1 &= ~SELECT;
1031                 if (ked->curflags & KEYFRAME_OK_H2)
1032                         bezt->f3 &= ~SELECT;
1033         }
1034         else {
1035                 BEZ_DESEL(bezt);
1036         }
1037         
1038         return 0;
1039 }
1040
1041 static short select_bezier_invert(KeyframeEditData *ked, BezTriple *bezt) 
1042 {
1043         /* Invert the selection for the whole bezier triple */
1044         bezt->f2 ^= SELECT;
1045         if (bezt->f2 & SELECT) {
1046                 bezt->f1 |= SELECT;
1047                 bezt->f3 |= SELECT;
1048         }
1049         else {
1050                 bezt->f1 &= ~SELECT;
1051                 bezt->f3 &= ~SELECT;
1052         }
1053         return 0;
1054 }
1055
1056 KeyframeEditFunc ANIM_editkeyframes_select(short selectmode)
1057 {
1058         switch (selectmode) {
1059                 case SELECT_ADD: /* add */
1060                         return select_bezier_add;
1061                 case SELECT_SUBTRACT: /* subtract */
1062                         return select_bezier_subtract;
1063                 case SELECT_INVERT: /* invert */
1064                         return select_bezier_invert;
1065                 default: /* replace (need to clear all, then add) */
1066                         return select_bezier_add;
1067         }
1068 }
1069
1070 /* ******************************************* */
1071 /* Selection Maps */
1072
1073 /* Selection maps are simply fancy names for char arrays that store on/off
1074  * info for whether the selection status. The main purpose for these is to
1075  * allow extra info to be tagged to the keyframes without influencing their
1076  * values or having to be removed later.
1077  */
1078
1079 /* ----------- */
1080
1081 static short selmap_build_bezier_more(KeyframeEditData *ked, BezTriple *bezt)
1082 {
1083         FCurve *fcu= ked->fcu;
1084         char *map= ked->data;
1085         int i= ked->curIndex;
1086         
1087         /* if current is selected, just make sure it stays this way */
1088         if (BEZSELECTED(bezt)) {
1089                 map[i]= 1;
1090                 return 0;
1091         }
1092         
1093         /* if previous is selected, that means that selection should extend across */
1094         if (i > 0) {
1095                 BezTriple *prev= bezt - 1;
1096                 
1097                 if (BEZSELECTED(prev)) {
1098                         map[i]= 1;
1099                         return 0;
1100                 }
1101         }
1102         
1103         /* if next is selected, that means that selection should extend across */
1104         if (i < (fcu->totvert-1)) {
1105                 BezTriple *next= bezt + 1;
1106                 
1107                 if (BEZSELECTED(next)) {
1108                         map[i]= 1;
1109                         return 0;
1110                 }
1111         }
1112         
1113         return 0;
1114 }
1115
1116 static short selmap_build_bezier_less(KeyframeEditData *ked, BezTriple *bezt)
1117 {
1118         FCurve *fcu= ked->fcu;
1119         char *map= ked->data;
1120         int i= ked->curIndex;
1121         
1122         /* if current is selected, check the left/right keyframes
1123          * since it might need to be deselected (but otherwise no)
1124          */
1125         if (BEZSELECTED(bezt)) {
1126                 /* if previous is not selected, we're on the tip of an iceberg */
1127                 if (i > 0) {
1128                         BezTriple *prev= bezt - 1;
1129                         
1130                         if (BEZSELECTED(prev) == 0)
1131                                 return 0;
1132                 }
1133                 else if (i == 0) {
1134                         /* current keyframe is selected at an endpoint, so should get deselected */
1135                         return 0;
1136                 }
1137                 
1138                 /* if next is not selected, we're on the tip of an iceberg */
1139                 if (i < (fcu->totvert-1)) {
1140                         BezTriple *next= bezt + 1;
1141                         
1142                         if (BEZSELECTED(next) == 0)
1143                                 return 0;
1144                 }
1145                 else if (i == (fcu->totvert-1)) {
1146                         /* current keyframe is selected at an endpoint, so should get deselected */
1147                         return 0;
1148                 }
1149                 
1150                 /* if we're still here, that means that keyframe should remain untouched */
1151                 map[i]= 1;
1152         }
1153         
1154         return 0;
1155 }
1156
1157 /* Get callback for building selection map */
1158 KeyframeEditFunc ANIM_editkeyframes_buildselmap(short mode)
1159 {
1160         switch (mode) {
1161                 case SELMAP_LESS: /* less */
1162                         return selmap_build_bezier_less;
1163                 
1164                 case SELMAP_MORE: /* more */
1165                 default:
1166                         return selmap_build_bezier_more;
1167         }
1168 }
1169
1170 /* ----------- */
1171
1172 /* flush selection map values to the given beztriple */
1173 short bezt_selmap_flush(KeyframeEditData *ked, BezTriple *bezt)
1174 {
1175         char *map= ked->data;
1176         short on= map[ked->curIndex];
1177         
1178         /* select or deselect based on whether the map allows it or not */
1179         if (on) {
1180                 BEZ_SEL(bezt);
1181         }
1182         else {
1183                 BEZ_DESEL(bezt);
1184         }
1185         
1186         return 0;
1187 }
1188