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