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