b38cbde741027d5e9d03f81594476e777501bb6f
[blender-staging.git] / source / blender / editors / animation / keyframes_edit.c
1 /**
2  * $Id: 
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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_arithb.h"
36
37 #include "DNA_anim_types.h"
38 #include "DNA_action_types.h"
39 #include "DNA_constraint_types.h"
40 #include "DNA_curve_types.h"
41 #include "DNA_ipo_types.h" // XXX to be phased out
42 #include "DNA_key_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_scene_types.h"
46
47 #include "BKE_action.h"
48 #include "BKE_fcurve.h"
49 #include "BKE_key.h"
50 #include "BKE_utildefines.h"
51
52 #include "ED_anim_api.h"
53 #include "ED_keyframes_edit.h"
54 #include "ED_markers.h"
55
56 /* This file defines an API and set of callback-operators for non-destructive editing of keyframe data.
57  *
58  * Two API functions are defined for actually performing the operations on the data:
59  *                      ipo_keys_bezier_loop() and icu_keys_bezier_loop()
60  * which take the data they operate on, a few callbacks defining what operations to perform.
61  *
62  * As operators which work on keyframes usually apply the same operation on all BezTriples in 
63  * every channel, the code has been optimised providing a set of functions which will get the 
64  * appropriate bezier-modify function to set. These functions (ANIM_editkeyframes_*) will need
65  * to be called before getting any channels.
66  * 
67  * A set of 'validation' callbacks are provided for checking if a BezTriple should be operated on.
68  * These should only be used when using a 'general' BezTriple editor (i.e. selection setters which 
69  * don't check existing selection status).
70  * 
71  * - Joshua Leung, Dec 2008
72  */
73
74 /* ************************************************************************** */
75 /* IPO Editing Loops - Exposed API */
76
77 /* --------------------------- Base Functions ------------------------------------ */
78
79 /* This function is used to loop over BezTriples in the given IpoCurve, applying a given 
80  * operation on them, and optionally applies an IPO-curve validate function afterwards.
81  */
82 short ANIM_icu_keys_bezier_loop(BeztEditData *bed, IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) 
83 {
84     BezTriple *bezt;
85         int b;
86         
87         /* if function to apply to bezier curves is set, then loop through executing it on beztriples */
88     if (bezt_cb) {
89                 /* if there's a validation func, include that check in the loop 
90                  * (this is should be more efficient than checking for it in every loop)
91                  */
92                 if (bezt_ok) {
93                         for (b=0, bezt=icu->bezt; b < icu->totvert; b++, bezt++) {
94                                 /* Only operate on this BezTriple if it fullfills the criteria of the validation func */
95                                 if (bezt_ok(bed, bezt)) {
96                                         /* Exit with return-code '1' if function returns positive
97                                          * This is useful if finding if some BezTriple satisfies a condition.
98                                          */
99                                 if (bezt_cb(bed, bezt)) return 1;
100                                 }
101                         }
102                 }
103                 else {
104                         for (b=0, bezt=icu->bezt; b < icu->totvert; b++, bezt++) {
105                                 /* Exit with return-code '1' if function returns positive
106                                  * This is useful if finding if some BezTriple satisfies a condition.
107                                  */
108                         if (bezt_cb(bed, bezt)) return 1;
109                         }
110                 }
111     }
112
113     /* if ipocurve_function has been specified then execute it */
114     if (icu_cb)
115         icu_cb(icu);
116         
117         /* done */      
118     return 0;
119 }
120
121 /* This function is used to loop over the IPO curves in the given IPO (and subsequently the keyframes in them) */
122 short ANIM_ipo_keys_bezier_loop(BeztEditData *bed, Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
123 {
124     IpoCurve *icu;
125         
126         /* Sanity check */
127         if (ipo == NULL)
128                 return 0;
129         
130     /* Loop through each curve in the Ipo */
131     for (icu= ipo->curve.first; icu; icu=icu->next) {
132         if (ANIM_icu_keys_bezier_loop(bed, icu, bezt_ok, bezt_cb, icu_cb))
133             return 1;
134     }
135
136     return 0;
137 }
138
139 /* -------------------------------- Further Abstracted ----------------------------- */
140
141 /* This function is used to loop over the keyframe data in an Action Group */
142 static short agrp_keys_bezier_loop(BeztEditData *bed, bActionGroup *agrp, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
143 {
144         bActionChannel *achan;
145         bConstraintChannel *conchan;
146         
147         /* only iterate over the action-channels and their sub-channels that are in this group */
148         for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
149                 if (ANIM_ipo_keys_bezier_loop(bed, achan->ipo, bezt_ok, bezt_cb, icu_cb))
150                         return 1;
151                 
152                 for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
153                         if (ANIM_ipo_keys_bezier_loop(bed, conchan->ipo, bezt_ok, bezt_cb, icu_cb))
154                                 return 1;
155                 }
156         }
157         
158         return 0;
159 }
160
161 /* This function is used to loop over the keyframe data in an Action Group */
162 static short act_keys_bezier_loop(BeztEditData *bed, bAction *act, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
163 {
164         bActionChannel *achan;
165         bConstraintChannel *conchan;
166         
167         for (achan= act->chanbase.first; achan; achan= achan->next) {
168                 if (ANIM_ipo_keys_bezier_loop(bed, achan->ipo, bezt_ok, bezt_cb, icu_cb))
169                         return 1;
170                 
171                 for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
172                         if (ANIM_ipo_keys_bezier_loop(bed, conchan->ipo, bezt_ok, bezt_cb, icu_cb))
173                                 return 1;
174                 }
175         }
176         
177         return 0;
178 }
179
180 /* --- */
181
182
183 /* This function is used to apply operation to all keyframes, regardless of the type */
184 short ANIM_animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
185 {
186         /* sanity checks */
187         if (ale == NULL)
188                 return 0;
189         
190         /* method to use depends on the type of keyframe data */
191         switch (ale->datatype) {
192                 /* direct keyframe data (these loops are exposed) */
193                 case ALE_ICU: /* ipo-curve */
194                         return ANIM_icu_keys_bezier_loop(bed, ale->key_data, bezt_ok, bezt_cb, icu_cb);
195                 case ALE_IPO: /* ipo */
196                         return ANIM_ipo_keys_bezier_loop(bed, ale->key_data, bezt_ok, bezt_cb, icu_cb);
197                 
198                 /* indirect 'summaries' (these are not exposed directly) 
199                  * NOTE: must keep this code in sync with the drawing code and also the filtering code!
200                  */
201                 case ALE_GROUP: /* action group */
202                         return agrp_keys_bezier_loop(bed, (bActionGroup *)ale->data, bezt_ok, bezt_cb, icu_cb);
203                 case ALE_ACT: /* action */
204                         return act_keys_bezier_loop(bed, (bAction *)ale->data, bezt_ok, bezt_cb, icu_cb);
205         }
206         
207         return 0;
208 }
209
210 /* ************************************************************************** */
211 /* Keyframe Integrity Tools */
212
213 /* Rearrange keyframes if some are out of order */
214 // used to be recalc_*_ipos() where * was object or action
215 void ANIM_editkeyframes_refresh(bAnimContext *ac)
216 {
217         ListBase anim_data = {NULL, NULL};
218         bAnimListElem *ale;
219         int filter;
220         
221         /* filter animation data */
222         filter= ANIMFILTER_ONLYFCU; 
223         ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
224         
225         /* loop over ipo-curves that are likely to have been edited, and check them */
226         for (ale= anim_data.first; ale; ale= ale->next) {
227                 FCurve *fcu= ale->key_data;
228                 
229                 /* make sure keyframes in IPO-curve are all in order, and handles are in valid positions */
230                 sort_time_fcurve(fcu);
231                 testhandles_fcurve(fcu);
232         }
233         
234         /* free temp data */
235         BLI_freelistN(&anim_data);
236 }
237
238 /* ************************************************************************** */
239 /* BezTriple Validation Callbacks */
240
241 static short ok_bezier_frame(BeztEditData *bed, BezTriple *bezt)
242 {
243         /* frame is stored in f1 property (this float accuracy check may need to be dropped?) */
244         return IS_EQ(bezt->vec[1][0], bed->f1);
245 }
246
247 static short ok_bezier_framerange(BeztEditData *bed, BezTriple *bezt)
248 {
249         /* frame range is stored in float properties */
250         return ((bezt->vec[1][0] > bed->f1) && (bezt->vec[1][0] < bed->f2));
251 }
252
253 static short ok_bezier_selected(BeztEditData *bed, BezTriple *bezt)
254 {
255         /* this macro checks all beztriple handles for selection... */
256         return BEZSELECTED(bezt);
257 }
258
259 static short ok_bezier_value(BeztEditData *bed, BezTriple *bezt)
260 {
261         /* value is stored in f1 property 
262          *      - this float accuracy check may need to be dropped?
263          *      - should value be stored in f2 instead so that we won't have conflicts when using f1 for frames too?
264          */
265         return IS_EQ(bezt->vec[1][1], bed->f1);
266 }
267
268
269 BeztEditFunc ANIM_editkeyframes_ok(short mode)
270 {
271         /* eEditKeyframes_Validate */
272         switch (mode) {
273                 case BEZT_OK_FRAME: /* only if bezt falls on the right frame (float) */
274                         return ok_bezier_frame;
275                 case BEZT_OK_FRAMERANGE: /* only if bezt falls within the specified frame range (floats) */
276                         return ok_bezier_framerange;
277                 case BEZT_OK_SELECTED:  /* only if bezt is selected */
278                         return ok_bezier_selected;
279                 case BEZT_OK_VALUE: /* only if bezt value matches (float) */
280                         return ok_bezier_value;
281                 default: /* nothing was ok */
282                         return NULL;
283         }
284 }
285
286 /* ******************************************* */
287 /* Transform */
288
289 static short snap_bezier_nearest(BeztEditData *bed, BezTriple *bezt)
290 {
291         if (bezt->f2 & SELECT)
292                 bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
293         return 0;
294 }
295
296 static short snap_bezier_nearestsec(BeztEditData *bed, BezTriple *bezt)
297 {
298         const Scene *scene= bed->scene;
299         const float secf = (float)FPS;
300         
301         if (bezt->f2 & SELECT)
302                 bezt->vec[1][0]= ((float)floor(bezt->vec[1][0]/secf + 0.5f) * secf);
303         return 0;
304 }
305
306 static short snap_bezier_cframe(BeztEditData *bed, BezTriple *bezt)
307 {
308         const Scene *scene= bed->scene;
309         if (bezt->f2 & SELECT)
310                 bezt->vec[1][0]= (float)CFRA;
311         return 0;
312 }
313
314 static short snap_bezier_nearmarker(BeztEditData *bed, BezTriple *bezt)
315 {
316         //if (bezt->f2 & SELECT)
317         //      bezt->vec[1][0]= (float)find_nearest_marker_time(bezt->vec[1][0]);  // XXX missing function!
318         return 0;
319 }
320
321 // calchandles_ipocurve
322 BeztEditFunc ANIM_editkeyframes_snap(short type)
323 {
324         /* eEditKeyframes_Snap */
325         switch (type) {
326                 case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */
327                         return snap_bezier_nearest;
328                 case SNAP_KEYS_CURFRAME: /* snap to current frame */
329                         return snap_bezier_cframe;
330                 case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */
331                         return snap_bezier_nearmarker;
332                 case SNAP_KEYS_NEARSEC: /* snap to nearest second */
333                         return snap_bezier_nearestsec;
334                 default: /* just in case */
335                         return snap_bezier_nearest;
336         }
337 }
338
339 /* --------- */
340
341 static short mirror_bezier_cframe(BeztEditData *bed, BezTriple *bezt)
342 {
343         const Scene *scene= bed->scene;
344         float diff;
345         
346         if (bezt->f2 & SELECT) {
347                 diff= ((float)CFRA - bezt->vec[1][0]);
348                 bezt->vec[1][0]= ((float)CFRA + diff);
349         }
350         
351         return 0;
352 }
353
354 static short mirror_bezier_yaxis(BeztEditData *bed, BezTriple *bezt)
355 {
356         float diff;
357         
358         if (bezt->f2 & SELECT) {
359                 diff= (0.0f - bezt->vec[1][0]);
360                 bezt->vec[1][0]= (0.0f + diff);
361         }
362         
363         return 0;
364 }
365
366 static short mirror_bezier_xaxis(BeztEditData *bed, BezTriple *bezt)
367 {
368         float diff;
369         
370         if (bezt->f2 & SELECT) {
371                 diff= (0.0f - bezt->vec[1][1]);
372                 bezt->vec[1][1]= (0.0f + diff);
373         }
374         
375         return 0;
376 }
377
378 static short mirror_bezier_marker(BeztEditData *bed, BezTriple *bezt)
379 {
380         /* mirroring time stored in f1 */
381         if (bezt->f2 & SELECT) {
382                 const float diff= (bed->f1 - bezt->vec[1][0]);
383                 bezt->vec[1][0]= (bed->f1 + diff);
384         }
385         
386         return 0;
387 }
388
389 /* Note: for markers case, need to set global vars (eww...) */
390 // calchandles_ipocurve
391 BeztEditFunc ANIM_editkeyframes_mirror(short type)
392 {
393         switch (type) {
394                 case MIRROR_KEYS_CURFRAME: /* mirror over current frame */
395                         return mirror_bezier_cframe;
396                 case MIRROR_KEYS_YAXIS: /* mirror over frame 0 */
397                         return mirror_bezier_yaxis;
398                 case MIRROR_KEYS_XAXIS: /* mirror over value 0 */
399                         return mirror_bezier_xaxis;
400                 case MIRROR_KEYS_MARKER: /* mirror over marker */
401                         return mirror_bezier_marker; 
402                 default: /* just in case */
403                         return mirror_bezier_yaxis;
404                         break;
405         }
406 }
407
408 /* ******************************************* */
409 /* Settings */
410
411 /* Sets the selected bezier handles to type 'auto' */
412 static short set_bezier_auto(BeztEditData *bed, BezTriple *bezt) 
413 {
414         if((bezt->f1  & SELECT) || (bezt->f3 & SELECT)) {
415                 if (bezt->f1 & SELECT) bezt->h1= 1; /* the secret code for auto */
416                 if (bezt->f3 & SELECT) bezt->h2= 1;
417                 
418                 /* if the handles are not of the same type, set them
419                  * to type free
420                  */
421                 if (bezt->h1 != bezt->h2) {
422                         if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE;
423                         if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE;
424                 }
425         }
426         return 0;
427 }
428
429 /* Sets the selected bezier handles to type 'vector'  */
430 static short set_bezier_vector(BeztEditData *bed, BezTriple *bezt) 
431 {
432         if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
433                 if (bezt->f1 & SELECT) bezt->h1= HD_VECT;
434                 if (bezt->f3 & SELECT) bezt->h2= HD_VECT;
435                 
436                 /* if the handles are not of the same type, set them
437                  * to type free
438                  */
439                 if (bezt->h1 != bezt->h2) {
440                         if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE;
441                         if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE;
442                 }
443         }
444         return 0;
445 }
446
447 /* Queries if the handle should be set to 'free' or 'align' */
448 static short bezier_isfree(BeztEditData *bed, BezTriple *bezt) 
449 {
450         if ((bezt->f1 & SELECT) && (bezt->h1)) return 1;
451         if ((bezt->f3 & SELECT) && (bezt->h2)) return 1;
452         return 0;
453 }
454
455 /* Sets selected bezier handles to type 'align' */
456 static short set_bezier_align(BeztEditData *bed, BezTriple *bezt) 
457 {       
458         if (bezt->f1 & SELECT) bezt->h1= HD_ALIGN;
459         if (bezt->f3 & SELECT) bezt->h2= HD_ALIGN;
460         return 0;
461 }
462
463 /* Sets selected bezier handles to type 'free'  */
464 static short set_bezier_free(BeztEditData *bed, BezTriple *bezt) 
465 {
466         if (bezt->f1 & SELECT) bezt->h1= HD_FREE;
467         if (bezt->f3 & SELECT) bezt->h2= HD_FREE;
468         return 0;
469 }
470
471 /* Set all Bezier Handles to a single type */
472 // calchandles_ipocurve
473 BeztEditFunc ANIM_editkeyframes_handles(short code)
474 {
475         switch (code) {
476                 case HD_AUTO: /* auto */
477                         return set_bezier_auto;
478                 case HD_VECT: /* vector */
479                         return set_bezier_vector;
480                 case HD_FREE: /* free */
481                         return set_bezier_free;
482                 case HD_ALIGN: /* align */
483                         return set_bezier_align;
484                 
485                 default: /* free or align? */
486                         return bezier_isfree;
487         }
488 }
489
490 /* ------- */
491
492 /* IPO-curve sanity callback - the name of this is a bit unwieldy, by is best to keep this in style... */
493 // was called set_ipocurve_mixed()
494 void ANIM_editkeyframes_ipocurve_ipotype(IpoCurve *icu)
495 {
496         /* Sets the type of the IPO curve to mixed, as some (selected)
497          * keyframes were set to other interpolation types
498          */
499         icu->ipo= IPO_MIXED;
500         
501         /* recalculate handles, as some changes may have occurred */
502         //calchandles_ipocurve(icu);    // XXX
503 }
504
505 static short set_bezt_constant(BeztEditData *bed, BezTriple *bezt) 
506 {
507         if (bezt->f2 & SELECT) 
508                 bezt->ipo= IPO_CONST;
509         return 0;
510 }
511
512 static short set_bezt_linear(BeztEditData *bed, BezTriple *bezt) 
513 {
514         if (bezt->f2 & SELECT) 
515                 bezt->ipo= IPO_LIN;
516         return 0;
517 }
518
519 static short set_bezt_bezier(BeztEditData *bed, BezTriple *bezt) 
520 {
521         if (bezt->f2 & SELECT) 
522                 bezt->ipo= IPO_BEZ;
523         return 0;
524 }
525
526 /* Set the interpolation type of the selected BezTriples in each IPO curve to the specified one */
527 // ANIM_editkeyframes_ipocurve_ipotype() !
528 BeztEditFunc ANIM_editkeyframes_ipo(short code)
529 {
530         switch (code) {
531                 case IPO_CONST: /* constant */
532                         return set_bezt_constant;
533                 case IPO_LIN: /* linear */      
534                         return set_bezt_linear;
535                 default: /* bezier */
536                         return set_bezt_bezier;
537         }
538 }
539
540 // XXX will we keep this?
541 void setexprap_ipoloop(Ipo *ipo, short code)
542 {
543         IpoCurve *icu;
544         
545         /* Loop through each curve in the Ipo */
546         for (icu=ipo->curve.first; icu; icu=icu->next)
547                 icu->extrap= code;
548 }
549
550 /* ******************************************* */
551 /* Selection */
552
553 static short select_bezier_add(BeztEditData *bed, BezTriple *bezt) 
554 {
555         /* Select the bezier triple */
556         BEZ_SEL(bezt);
557         return 0;
558 }
559
560 static short select_bezier_subtract(BeztEditData *bed, BezTriple *bezt) 
561 {
562         /* Deselect the bezier triple */
563         BEZ_DESEL(bezt);
564         return 0;
565 }
566
567 static short select_bezier_invert(BeztEditData *bed, BezTriple *bezt) 
568 {
569         /* Invert the selection for the bezier triple */
570         bezt->f2 ^= SELECT;
571         if (bezt->f2 & SELECT) {
572                 bezt->f1 |= SELECT;
573                 bezt->f3 |= SELECT;
574         }
575         else {
576                 bezt->f1 &= ~SELECT;
577                 bezt->f3 &= ~SELECT;
578         }
579         return 0;
580 }
581
582 // NULL
583 BeztEditFunc ANIM_editkeyframes_select(short selectmode)
584 {
585         switch (selectmode) {
586                 case SELECT_ADD: /* add */
587                         return select_bezier_add;
588                 case SELECT_SUBTRACT: /* subtract */
589                         return select_bezier_subtract;
590                 case SELECT_INVERT: /* invert */
591                         return select_bezier_invert;
592                 default: /* replace (need to clear all, then add) */
593                         return select_bezier_add;
594         }
595 }
596
597
598 short is_ipo_key_selected(Ipo *ipo)
599 {
600         IpoCurve *icu;
601         BezTriple *bezt;
602         int i;
603         
604         if (ipo == NULL)
605                 return 0;
606         
607         for (icu=ipo->curve.first; icu; icu=icu->next) {
608                 for (i=0, bezt=icu->bezt; i<icu->totvert; i++, bezt++) {
609                         if (BEZSELECTED(bezt))
610                                 return 1;
611                 }
612         }
613         
614         return 0;
615 }
616
617 // XXX although this is still needed, it should be removed!
618 void set_ipo_key_selection(Ipo *ipo, short sel)
619 {
620         IpoCurve *icu;
621         BezTriple *bezt;
622         int i;
623         
624         if (ipo == NULL)
625                 return;
626         
627         for (icu=ipo->curve.first; icu; icu=icu->next) {
628                 for (i=0, bezt=icu->bezt; i<icu->totvert; i++, bezt++) {
629                         if (sel == 2) {
630                                 BEZ_INVSEL(bezt);
631                         }
632                         else if (sel == 1) {
633                                 BEZ_SEL(bezt);
634                         }
635                         else {
636                                 BEZ_DESEL(bezt);
637                         }
638                 }
639         }
640 }
641
642 // XXX port this over to the new system!
643 // err... this is this still used?
644 int fullselect_ipo_keys(Ipo *ipo)
645 {
646         IpoCurve *icu;
647         int tvtot = 0;
648         int i;
649         
650         if (!ipo)
651                 return tvtot;
652         
653         for (icu=ipo->curve.first; icu; icu=icu->next) {
654                 for (i=0; i<icu->totvert; i++) {
655                         if (icu->bezt[i].f2 & SELECT) {
656                                 tvtot+=3;
657                                 icu->bezt[i].f1 |= SELECT;
658                                 icu->bezt[i].f3 |= SELECT;
659                         }
660                 }
661         }
662         
663         return tvtot;
664 }
665