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