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