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