3109ae6c553d01eebdb176c2133658d53c8ba7d6
[blender.git] / source / blender / editors / animation / keyframes_general.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edanimation
22  */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <math.h>
27 #include <float.h>
28
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_blenlib.h"
32 #include "BLI_utildefines.h"
33 #include "BLI_string_utils.h"
34
35 #include "DNA_anim_types.h"
36 #include "DNA_object_types.h"
37 #include "DNA_scene_types.h"
38
39 #include "BKE_action.h"
40 #include "BKE_fcurve.h"
41 #include "BKE_report.h"
42 #include "BKE_main.h"
43 #include "BKE_deform.h"
44
45 #include "RNA_access.h"
46 #include "RNA_enum_types.h"
47
48 #include "ED_anim_api.h"
49 #include "ED_keyframing.h"
50 #include "ED_keyframes_edit.h"
51
52 /* This file contains code for various keyframe-editing tools which are 'destructive'
53  * (i.e. they will modify the order of the keyframes, and change the size of the array).
54  * While some of these tools may eventually be moved out into blenkernel, for now, it is
55  * fine to have these calls here.
56  *
57  * There are also a few tools here which cannot be easily coded for in the other system (yet).
58  * These may also be moved around at some point, but for now, they are best added here.
59  *
60  * - Joshua Leung, Dec 2008
61  */
62
63 /* **************************************************** */
64
65 /**
66  * Only delete the nominated keyframe from provided F-Curve.
67  * Not recommended to be used many times successively. For that
68  * there is #delete_fcurve_keys().
69  */
70 void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc)
71 {
72   /* sanity check */
73   if (fcu == NULL)
74     return;
75
76   /* verify the index:
77    * 1) cannot be greater than the number of available keyframes
78    * 2) negative indices are for specifying a value from the end of the array
79    */
80   if (abs(index) >= fcu->totvert)
81     return;
82   else if (index < 0)
83     index += fcu->totvert;
84
85   /* Delete this keyframe */
86   memmove(
87       &fcu->bezt[index], &fcu->bezt[index + 1], sizeof(BezTriple) * (fcu->totvert - index - 1));
88   fcu->totvert--;
89
90   if (fcu->totvert == 0) {
91     if (fcu->bezt)
92       MEM_freeN(fcu->bezt);
93     fcu->bezt = NULL;
94   }
95
96   /* recalc handles - only if it won't cause problems */
97   if (do_recalc)
98     calchandles_fcurve(fcu);
99 }
100
101 /* Delete selected keyframes in given F-Curve */
102 bool delete_fcurve_keys(FCurve *fcu)
103 {
104   int i;
105   bool changed = false;
106
107   if (fcu->bezt == NULL) /* ignore baked curves */
108     return false;
109
110   /* Delete selected BezTriples */
111   for (i = 0; i < fcu->totvert; i++) {
112     if (fcu->bezt[i].f2 & SELECT) {
113       memmove(&fcu->bezt[i], &fcu->bezt[i + 1], sizeof(BezTriple) * (fcu->totvert - i - 1));
114       fcu->totvert--;
115       i--;
116       changed = true;
117     }
118   }
119
120   /* Free the array of BezTriples if there are not keyframes */
121   if (fcu->totvert == 0)
122     clear_fcurve_keys(fcu);
123
124   return changed;
125 }
126
127 void clear_fcurve_keys(FCurve *fcu)
128 {
129   if (fcu->bezt)
130     MEM_freeN(fcu->bezt);
131   fcu->bezt = NULL;
132
133   fcu->totvert = 0;
134 }
135
136 /* ---------------- */
137
138 /* duplicate selected keyframes for the given F-Curve */
139 void duplicate_fcurve_keys(FCurve *fcu)
140 {
141   BezTriple *newbezt;
142   int i;
143
144   /* this can only work when there is an F-Curve, and also when there are some BezTriples */
145   if (ELEM(NULL, fcu, fcu->bezt))
146     return;
147
148   for (i = 0; i < fcu->totvert; i++) {
149     /* If a key is selected */
150     if (fcu->bezt[i].f2 & SELECT) {
151       /* Expand the list */
152       newbezt = MEM_callocN(sizeof(BezTriple) * (fcu->totvert + 1), "beztriple");
153
154       memcpy(newbezt, fcu->bezt, sizeof(BezTriple) * (i + 1));
155       memcpy(newbezt + i + 1, fcu->bezt + i, sizeof(BezTriple));
156       memcpy(newbezt + i + 2, fcu->bezt + i + 1, sizeof(BezTriple) * (fcu->totvert - (i + 1)));
157       fcu->totvert++;
158
159       /* reassign pointers... (free old, and add new) */
160       MEM_freeN(fcu->bezt);
161       fcu->bezt = newbezt;
162
163       /* Unselect the current key */
164       BEZT_DESEL_ALL(&fcu->bezt[i]);
165       i++;
166
167       /* Select the copied key */
168       BEZT_SEL_ALL(&fcu->bezt[i]);
169     }
170   }
171 }
172
173 /* **************************************************** */
174 /* Various Tools */
175
176 /**
177  * Basic F-Curve 'cleanup' function that removes 'double points' and unnecessary keyframes on
178  * linear-segments only optionally clears up curve if one keyframe with default value remains.
179  */
180 void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault)
181 {
182   FCurve *fcu = (FCurve *)ale->key_data;
183   BezTriple *old_bezts, *bezt, *beztn;
184   BezTriple *lastb;
185   int totCount, i;
186
187   /* check if any points  */
188   if ((fcu == NULL) || (fcu->bezt == NULL) || (fcu->totvert == 0) ||
189       (!cleardefault && fcu->totvert == 1)) {
190     return;
191   }
192
193   /* make a copy of the old BezTriples, and clear F-Curve */
194   old_bezts = fcu->bezt;
195   totCount = fcu->totvert;
196   fcu->bezt = NULL;
197   fcu->totvert = 0;
198
199   /* now insert first keyframe, as it should be ok */
200   bezt = old_bezts;
201   insert_bezt_fcurve(fcu, bezt, 0);
202   if (!(bezt->f2 & SELECT)) {
203     lastb = fcu->bezt;
204     lastb->f1 = lastb->f2 = lastb->f3 = 0;
205   }
206
207   /* Loop through BezTriples, comparing them. Skip any that do
208    * not fit the criteria for "ok" points.
209    */
210   for (i = 1; i < totCount; i++) {
211     float prev[2], cur[2], next[2];
212
213     /* get BezTriples and their values */
214     if (i < (totCount - 1)) {
215       beztn = (old_bezts + (i + 1));
216       next[0] = beztn->vec[1][0];
217       next[1] = beztn->vec[1][1];
218     }
219     else {
220       beztn = NULL;
221       next[0] = next[1] = 0.0f;
222     }
223     lastb = (fcu->bezt + (fcu->totvert - 1));
224     bezt = (old_bezts + i);
225
226     /* get references for quicker access */
227     prev[0] = lastb->vec[1][0];
228     prev[1] = lastb->vec[1][1];
229     cur[0] = bezt->vec[1][0];
230     cur[1] = bezt->vec[1][1];
231
232     if (!(bezt->f2 & SELECT)) {
233       insert_bezt_fcurve(fcu, bezt, 0);
234       lastb = (fcu->bezt + (fcu->totvert - 1));
235       lastb->f1 = lastb->f2 = lastb->f3 = 0;
236       continue;
237     }
238
239     /* check if current bezt occurs at same time as last ok */
240     if (IS_EQT(cur[0], prev[0], thresh)) {
241       /* If there is a next beztriple, and if occurs at the same time, only insert
242        * if there is a considerable distance between the points, and also if the
243        * current is further away than the next one is to the previous.
244        */
245       if (beztn && (IS_EQT(cur[0], next[0], thresh)) && (IS_EQT(next[1], prev[1], thresh) == 0)) {
246         /* only add if current is further away from previous */
247         if (cur[1] > next[1]) {
248           if (IS_EQT(cur[1], prev[1], thresh) == 0) {
249             /* add new keyframe */
250             insert_bezt_fcurve(fcu, bezt, 0);
251           }
252         }
253       }
254       else {
255         /* only add if values are a considerable distance apart */
256         if (IS_EQT(cur[1], prev[1], thresh) == 0) {
257           /* add new keyframe */
258           insert_bezt_fcurve(fcu, bezt, 0);
259         }
260       }
261     }
262     else {
263       /* checks required are dependent on whether this is last keyframe or not */
264       if (beztn) {
265         /* does current have same value as previous and next? */
266         if (IS_EQT(cur[1], prev[1], thresh) == 0) {
267           /* add new keyframe */
268           insert_bezt_fcurve(fcu, bezt, 0);
269         }
270         else if (IS_EQT(cur[1], next[1], thresh) == 0) {
271           /* add new keyframe */
272           insert_bezt_fcurve(fcu, bezt, 0);
273         }
274       }
275       else {
276         /* add if value doesn't equal that of previous */
277         if (IS_EQT(cur[1], prev[1], thresh) == 0) {
278           /* add new keyframe */
279           insert_bezt_fcurve(fcu, bezt, 0);
280         }
281       }
282     }
283   }
284
285   /* now free the memory used by the old BezTriples */
286   if (old_bezts)
287     MEM_freeN(old_bezts);
288
289   /* final step, if there is just one key in fcurve, check if it's
290    * the default value and if is, remove fcurve completely. */
291   if (cleardefault && fcu->totvert == 1) {
292     float default_value = 0.0f;
293     PointerRNA id_ptr, ptr;
294     PropertyRNA *prop;
295     RNA_id_pointer_create(ale->id, &id_ptr);
296
297     /* get property to read from, and get value as appropriate */
298     if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
299       if (RNA_property_type(prop) == PROP_FLOAT)
300         default_value = RNA_property_float_get_default_index(&ptr, prop, fcu->array_index);
301     }
302
303     if (fcu->bezt->vec[1][1] == default_value) {
304       clear_fcurve_keys(fcu);
305
306       /* check if curve is really unused and if it is, return signal for deletion */
307       if ((list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0) &&
308           (fcu->driver == NULL)) {
309         AnimData *adt = ale->adt;
310         ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
311         ale->key_data = NULL;
312       }
313     }
314   }
315 }
316
317 /* ---------------- */
318
319 /* temp struct used for smooth_fcurve */
320 typedef struct tSmooth_Bezt {
321   float *h1, *h2, *h3; /* bezt->vec[0,1,2][1] */
322   float y1, y2, y3;    /* averaged before/new/after y-values */
323 } tSmooth_Bezt;
324
325 /* Use a weighted moving-means method to reduce intensity of fluctuations */
326 // TODO: introduce scaling factor for weighting falloff
327 void smooth_fcurve(FCurve *fcu)
328 {
329   BezTriple *bezt;
330   int i, x, totSel = 0;
331
332   if (fcu->bezt == NULL) {
333     return;
334   }
335
336   /* first loop through - count how many verts are selected */
337   bezt = fcu->bezt;
338   for (i = 0; i < fcu->totvert; i++, bezt++) {
339     if (BEZT_ISSEL_ANY(bezt))
340       totSel++;
341   }
342
343   /* if any points were selected, allocate tSmooth_Bezt points to work on */
344   if (totSel >= 3) {
345     tSmooth_Bezt *tarray, *tsb;
346
347     /* allocate memory in one go */
348     tsb = tarray = MEM_callocN(totSel * sizeof(tSmooth_Bezt), "tSmooth_Bezt Array");
349
350     /* populate tarray with data of selected points */
351     bezt = fcu->bezt;
352     for (i = 0, x = 0; (i < fcu->totvert) && (x < totSel); i++, bezt++) {
353       if (BEZT_ISSEL_ANY(bezt)) {
354         /* tsb simply needs pointer to vec, and index */
355         tsb->h1 = &bezt->vec[0][1];
356         tsb->h2 = &bezt->vec[1][1];
357         tsb->h3 = &bezt->vec[2][1];
358
359         /* advance to the next tsb to populate */
360         if (x < totSel - 1)
361           tsb++;
362         else
363           break;
364       }
365     }
366
367     /* calculate the new smoothed F-Curve's with weighted averages:
368      * - this is done with two passes to avoid progressive corruption errors
369      * - uses 5 points for each operation (which stores in the relevant handles)
370      * -   previous: w/a ratio = 3:5:2:1:1
371      * -   next: w/a ratio = 1:1:2:5:3
372      */
373
374     /* round 1: calculate smoothing deltas and new values */
375     tsb = tarray;
376     for (i = 0; i < totSel; i++, tsb++) {
377       /* Don't touch end points (otherwise, curves slowly explode,
378        * as we don't have enough data there). */
379       if (ELEM(i, 0, (totSel - 1)) == 0) {
380         const tSmooth_Bezt *tP1 = tsb - 1;
381         const tSmooth_Bezt *tP2 = (i - 2 > 0) ? (tsb - 2) : (NULL);
382         const tSmooth_Bezt *tN1 = tsb + 1;
383         const tSmooth_Bezt *tN2 = (i + 2 < totSel) ? (tsb + 2) : (NULL);
384
385         const float p1 = *tP1->h2;
386         const float p2 = (tP2) ? (*tP2->h2) : (*tP1->h2);
387         const float c1 = *tsb->h2;
388         const float n1 = *tN1->h2;
389         const float n2 = (tN2) ? (*tN2->h2) : (*tN1->h2);
390
391         /* calculate previous and next, then new position by averaging these */
392         tsb->y1 = (3 * p2 + 5 * p1 + 2 * c1 + n1 + n2) / 12;
393         tsb->y3 = (p2 + p1 + 2 * c1 + 5 * n1 + 3 * n2) / 12;
394
395         tsb->y2 = (tsb->y1 + tsb->y3) / 2;
396       }
397     }
398
399     /* round 2: apply new values */
400     tsb = tarray;
401     for (i = 0; i < totSel; i++, tsb++) {
402       /* don't touch end points, as their values weren't touched above */
403       if (ELEM(i, 0, (totSel - 1)) == 0) {
404         /* y2 takes the average of the 2 points */
405         *tsb->h2 = tsb->y2;
406
407         /* handles are weighted between their original values and the averaged values */
408         *tsb->h1 = ((*tsb->h1) * 0.7f) + (tsb->y1 * 0.3f);
409         *tsb->h3 = ((*tsb->h3) * 0.7f) + (tsb->y3 * 0.3f);
410       }
411     }
412
413     /* free memory required for tarray */
414     MEM_freeN(tarray);
415   }
416
417   /* recalculate handles */
418   calchandles_fcurve(fcu);
419 }
420
421 /* ---------------- */
422
423 /* little cache for values... */
424 typedef struct TempFrameValCache {
425   float frame, val;
426 } TempFrameValCache;
427
428 /* Evaluates the curves between each selected keyframe on each frame, and keys the value  */
429 void sample_fcurve(FCurve *fcu)
430 {
431   BezTriple *bezt, *start = NULL, *end = NULL;
432   TempFrameValCache *value_cache, *fp;
433   int sfra, range;
434   int i, n;
435
436   if (fcu->bezt == NULL) /* ignore baked */
437     return;
438
439   /* find selected keyframes... once pair has been found, add keyframes  */
440   for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
441     /* check if selected, and which end this is */
442     if (BEZT_ISSEL_ANY(bezt)) {
443       if (start) {
444         /* If next bezt is also selected, don't start sampling yet,
445          * but instead wait for that one to reconsider, to avoid
446          * changing the curve when sampling consecutive segments
447          * (T53229)
448          */
449         if (i < fcu->totvert - 1) {
450           BezTriple *next = &fcu->bezt[i + 1];
451           if (BEZT_ISSEL_ANY(next)) {
452             continue;
453           }
454         }
455
456         /* set end */
457         end = bezt;
458
459         /* cache values then add keyframes using these values, as adding
460          * keyframes while sampling will affect the outcome...
461          * - only start sampling+adding from index=1, so that we don't overwrite original keyframe
462          */
463         range = (int)(ceil(end->vec[1][0] - start->vec[1][0]));
464         sfra = (int)(floor(start->vec[1][0]));
465
466         if (range) {
467           value_cache = MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache");
468
469           /* sample values */
470           for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
471             fp->frame = (float)(sfra + n);
472             fp->val = evaluate_fcurve(fcu, fp->frame);
473           }
474
475           /* add keyframes with these, tagging as 'breakdowns' */
476           for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
477             insert_vert_fcurve(fcu, fp->frame, fp->val, BEZT_KEYTYPE_BREAKDOWN, 1);
478           }
479
480           /* free temp cache */
481           MEM_freeN(value_cache);
482
483           /* as we added keyframes, we need to compensate so that bezt is at the right place */
484           bezt = fcu->bezt + i + range - 1;
485           i += (range - 1);
486         }
487
488         /* the current selection island has ended, so start again from scratch */
489         start = NULL;
490         end = NULL;
491       }
492       else {
493         /* just set start keyframe */
494         start = bezt;
495         end = NULL;
496       }
497     }
498   }
499
500   /* recalculate channel's handles? */
501   calchandles_fcurve(fcu);
502 }
503
504 /* **************************************************** */
505 /* Copy/Paste Tools:
506  * - The copy/paste buffer currently stores a set of temporary F-Curves containing only the
507  *   keyframes that were selected in each of the original F-Curves.
508  * - All pasted frames are offset by the same amount.
509  *   This is calculated as the difference in the times of the current frame and the
510  *   'first keyframe' (i.e. the earliest one in all channels).
511  * - The earliest frame is calculated per copy operation.
512  */
513
514 /* globals for copy/paste data (like for other copy/paste buffers) */
515 static ListBase animcopybuf = {NULL, NULL};
516 static float animcopy_firstframe = 999999999.0f;
517 static float animcopy_lastframe = -999999999.0f;
518 static float animcopy_cfra = 0.0;
519
520 /* datatype for use in copy/paste buffer */
521 typedef struct tAnimCopybufItem {
522   struct tAnimCopybufItem *next, *prev;
523
524   ID *id;            /* ID which owns the curve */
525   bActionGroup *grp; /* Action Group */
526   char *rna_path;    /* RNA-Path */
527   int array_index;   /* array index */
528
529   int totvert;     /* number of keyframes stored for this channel */
530   BezTriple *bezt; /* keyframes in buffer */
531
532   short id_type; /* Result of GS(id->name)*/
533   bool is_bone;  /* special flag for armature bones */
534 } tAnimCopybufItem;
535
536 /* This function frees any MEM_calloc'ed copy/paste buffer data */
537 void ANIM_fcurves_copybuf_free(void)
538 {
539   tAnimCopybufItem *aci, *acn;
540
541   /* free each buffer element */
542   for (aci = animcopybuf.first; aci; aci = acn) {
543     acn = aci->next;
544
545     /* free keyframes */
546     if (aci->bezt)
547       MEM_freeN(aci->bezt);
548
549     /* free RNA-path */
550     if (aci->rna_path)
551       MEM_freeN(aci->rna_path);
552
553     /* free ourself */
554     BLI_freelinkN(&animcopybuf, aci);
555   }
556
557   /* restore initial state */
558   BLI_listbase_clear(&animcopybuf);
559   animcopy_firstframe = 999999999.0f;
560   animcopy_lastframe = -999999999.0f;
561 }
562
563 /* ------------------- */
564
565 /* This function adds data to the keyframes copy/paste buffer, freeing existing data first */
566 short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
567 {
568   bAnimListElem *ale;
569   Scene *scene = ac->scene;
570
571   /* clear buffer first */
572   ANIM_fcurves_copybuf_free();
573
574   /* assume that each of these is an F-Curve */
575   for (ale = anim_data->first; ale; ale = ale->next) {
576     FCurve *fcu = (FCurve *)ale->key_data;
577     tAnimCopybufItem *aci;
578     BezTriple *bezt, *nbezt, *newbuf;
579     int i;
580
581     /* firstly, check if F-Curve has any selected keyframes
582      * - skip if no selected keyframes found (so no need to create unnecessary copy-buffer data)
583      * - this check should also eliminate any problems associated with using sample-data
584      */
585     if (ANIM_fcurve_keyframes_loop(
586             NULL, fcu, NULL, ANIM_editkeyframes_ok(BEZT_OK_SELECTED), NULL) == 0)
587       continue;
588
589     /* init copybuf item info */
590     aci = MEM_callocN(sizeof(tAnimCopybufItem), "AnimCopybufItem");
591     aci->id = ale->id;
592     aci->id_type = GS(ale->id->name);
593     aci->grp = fcu->grp;
594     aci->rna_path = MEM_dupallocN(fcu->rna_path);
595     aci->array_index = fcu->array_index;
596
597     /* Detect if this is a bone. We do that here rather than during pasting because ID pointers
598      * will get invalidated if we undo.
599      * Storing the relevant information here helps avoiding crashes if we undo-repaste. */
600     if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) {
601       Object *ob = (Object *)aci->id;
602       bPoseChannel *pchan;
603       char *bone_name;
604
605       bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones[");
606       pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
607       if (pchan) {
608         aci->is_bone = true;
609       }
610       if (bone_name)
611         MEM_freeN(bone_name);
612     }
613
614     BLI_addtail(&animcopybuf, aci);
615
616     /* add selected keyframes to buffer */
617     /* TODO: currently, we resize array every time we add a new vert -
618      * this works ok as long as it is assumed only a few keys are copied */
619     for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
620       if (BEZT_ISSEL_ANY(bezt)) {
621         /* add to buffer */
622         newbuf = MEM_callocN(sizeof(BezTriple) * (aci->totvert + 1), "copybuf beztriple");
623
624         /* assume that since we are just re-sizing the array, just copy all existing data across */
625         if (aci->bezt)
626           memcpy(newbuf, aci->bezt, sizeof(BezTriple) * (aci->totvert));
627
628         /* copy current beztriple across too */
629         nbezt = &newbuf[aci->totvert];
630         *nbezt = *bezt;
631
632         /* ensure copy buffer is selected so pasted keys are selected */
633         BEZT_SEL_ALL(nbezt);
634
635         /* free old array and set the new */
636         if (aci->bezt)
637           MEM_freeN(aci->bezt);
638         aci->bezt = newbuf;
639         aci->totvert++;
640
641         /* check if this is the earliest frame encountered so far */
642         if (bezt->vec[1][0] < animcopy_firstframe)
643           animcopy_firstframe = bezt->vec[1][0];
644         if (bezt->vec[1][0] > animcopy_lastframe)
645           animcopy_lastframe = bezt->vec[1][0];
646       }
647     }
648   }
649
650   /* check if anything ended up in the buffer */
651   if (ELEM(NULL, animcopybuf.first, animcopybuf.last))
652     return -1;
653
654   /* in case 'relative' paste method is used */
655   animcopy_cfra = CFRA;
656
657   /* everything went fine */
658   return 0;
659 }
660
661 static void flip_names(tAnimCopybufItem *aci, char **name)
662 {
663   if (aci->is_bone) {
664     char *str_start;
665     if ((str_start = strstr(aci->rna_path, "pose.bones["))) {
666       /* ninja coding, try to change the name */
667       char bname_new[MAX_VGROUP_NAME];
668       char *str_iter, *str_end;
669       int length, prefix_l, postfix_l;
670
671       str_start += 12;
672       prefix_l = str_start - aci->rna_path;
673
674       str_end = strchr(str_start, '\"');
675
676       length = str_end - str_start;
677       postfix_l = strlen(str_end);
678
679       /* more ninja stuff, temporary substitute with NULL terminator */
680       str_start[length] = 0;
681       BLI_string_flip_side_name(bname_new, str_start, false, sizeof(bname_new));
682       str_start[length] = '\"';
683
684       str_iter = *name = MEM_mallocN(sizeof(char) * (prefix_l + postfix_l + length + 1),
685                                      "flipped_path");
686
687       BLI_strncpy(str_iter, aci->rna_path, prefix_l + 1);
688       str_iter += prefix_l;
689       BLI_strncpy(str_iter, bname_new, length + 1);
690       str_iter += length;
691       BLI_strncpy(str_iter, str_end, postfix_l + 1);
692       str_iter[postfix_l] = '\0';
693     }
694   }
695 }
696
697 /* ------------------- */
698
699 /* most strict method: exact matches only */
700 static tAnimCopybufItem *pastebuf_match_path_full(FCurve *fcu,
701                                                   const short from_single,
702                                                   const short to_simple,
703                                                   bool flip)
704 {
705   tAnimCopybufItem *aci;
706
707   for (aci = animcopybuf.first; aci; aci = aci->next) {
708     if (to_simple || (aci->rna_path && fcu->rna_path)) {
709       if (!to_simple && flip && aci->is_bone && fcu->rna_path) {
710         if ((from_single) || (aci->array_index == fcu->array_index)) {
711           char *name = NULL;
712           flip_names(aci, &name);
713           if (STREQ(name, fcu->rna_path)) {
714             MEM_freeN(name);
715             break;
716           }
717           MEM_freeN(name);
718         }
719       }
720       else if (to_simple || STREQ(aci->rna_path, fcu->rna_path)) {
721         if ((from_single) || (aci->array_index == fcu->array_index)) {
722           break;
723         }
724       }
725     }
726   }
727
728   return aci;
729 }
730
731 /* medium match strictness: path match only (i.e. ignore ID) */
732 static tAnimCopybufItem *pastebuf_match_path_property(Main *bmain,
733                                                       FCurve *fcu,
734                                                       const short from_single,
735                                                       const short UNUSED(to_simple))
736 {
737   tAnimCopybufItem *aci;
738
739   for (aci = animcopybuf.first; aci; aci = aci->next) {
740     /* check that paths exist */
741     if (aci->rna_path && fcu->rna_path) {
742       /* find the property of the fcurve and compare against the end of the tAnimCopybufItem
743        * more involved since it needs to do path lookups.
744        * This is not 100% reliable since the user could be editing the curves on a path that wont
745        * resolve, or a bone could be renamed after copying for eg. but in normal copy & paste
746        * this should work out ok.
747        */
748       if (BLI_findindex(which_libbase(bmain, aci->id_type), aci->id) == -1) {
749         /* pedantic but the ID could have been removed, and beats crashing! */
750         printf("paste_animedit_keys: error ID has been removed!\n");
751       }
752       else {
753         PointerRNA id_ptr, rptr;
754         PropertyRNA *prop;
755
756         RNA_id_pointer_create(aci->id, &id_ptr);
757
758         if (RNA_path_resolve_property(&id_ptr, aci->rna_path, &rptr, &prop)) {
759           const char *identifier = RNA_property_identifier(prop);
760           int len_id = strlen(identifier);
761           int len_path = strlen(fcu->rna_path);
762           if (len_id <= len_path) {
763             /* note, paths which end with "] will fail with this test - Animated ID Props */
764             if (STREQ(identifier, fcu->rna_path + (len_path - len_id))) {
765               if ((from_single) || (aci->array_index == fcu->array_index))
766                 break;
767             }
768           }
769         }
770         else {
771           printf("paste_animedit_keys: failed to resolve path id:%s, '%s'!\n",
772                  aci->id->name,
773                  aci->rna_path);
774         }
775       }
776     }
777   }
778
779   return aci;
780 }
781
782 /* least strict matching heuristic: indices only */
783 static tAnimCopybufItem *pastebuf_match_index_only(FCurve *fcu,
784                                                    const short from_single,
785                                                    const short UNUSED(to_simple))
786 {
787   tAnimCopybufItem *aci;
788
789   for (aci = animcopybuf.first; aci; aci = aci->next) {
790     /* check that paths exist */
791     if ((from_single) || (aci->array_index == fcu->array_index)) {
792       break;
793     }
794   }
795
796   return aci;
797 }
798
799 /* ................ */
800
801 static void do_curve_mirror_flippping(tAnimCopybufItem *aci, BezTriple *bezt)
802 {
803   if (aci->is_bone) {
804     const size_t slength = strlen(aci->rna_path);
805     bool flip = false;
806     if (BLI_strn_endswith(aci->rna_path, "location", slength) && aci->array_index == 0)
807       flip = true;
808     else if (BLI_strn_endswith(aci->rna_path, "rotation_quaternion", slength) &&
809              ELEM(aci->array_index, 2, 3))
810       flip = true;
811     else if (BLI_strn_endswith(aci->rna_path, "rotation_euler", slength) &&
812              ELEM(aci->array_index, 1, 2))
813       flip = true;
814     else if (BLI_strn_endswith(aci->rna_path, "rotation_axis_angle", slength) &&
815              ELEM(aci->array_index, 2, 3))
816       flip = true;
817
818     if (flip) {
819       bezt->vec[0][1] = -bezt->vec[0][1];
820       bezt->vec[1][1] = -bezt->vec[1][1];
821       bezt->vec[2][1] = -bezt->vec[2][1];
822     }
823   }
824 }
825
826 /* helper for paste_animedit_keys() - performs the actual pasting */
827 static void paste_animedit_keys_fcurve(
828     FCurve *fcu, tAnimCopybufItem *aci, float offset, const eKeyMergeMode merge_mode, bool flip)
829 {
830   BezTriple *bezt;
831   int i;
832
833   /* First de-select existing FCurve's keyframes */
834   for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
835     BEZT_DESEL_ALL(bezt);
836   }
837
838   /* mix mode with existing data */
839   switch (merge_mode) {
840     case KEYFRAME_PASTE_MERGE_MIX:
841       /* do-nothing */
842       break;
843
844     case KEYFRAME_PASTE_MERGE_OVER:
845       /* remove all keys */
846       clear_fcurve_keys(fcu);
847       break;
848
849     case KEYFRAME_PASTE_MERGE_OVER_RANGE:
850     case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL: {
851       float f_min;
852       float f_max;
853
854       if (merge_mode == KEYFRAME_PASTE_MERGE_OVER_RANGE) {
855         f_min = aci->bezt[0].vec[1][0] + offset;
856         f_max = aci->bezt[aci->totvert - 1].vec[1][0] + offset;
857       }
858       else { /* Entire Range */
859         f_min = animcopy_firstframe + offset;
860         f_max = animcopy_lastframe + offset;
861       }
862
863       /* remove keys in range */
864       if (f_min < f_max) {
865         /* select verts in range for removal */
866         for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
867           if ((f_min < bezt[0].vec[1][0]) && (bezt[0].vec[1][0] < f_max)) {
868             bezt->f2 |= SELECT;
869           }
870         }
871
872         /* remove frames in the range */
873         delete_fcurve_keys(fcu);
874       }
875       break;
876     }
877   }
878
879   /* just start pasting, with the first keyframe on the current frame, and so on */
880   for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) {
881     /* temporarily apply offset to src beztriple while copying */
882     if (flip)
883       do_curve_mirror_flippping(aci, bezt);
884
885     bezt->vec[0][0] += offset;
886     bezt->vec[1][0] += offset;
887     bezt->vec[2][0] += offset;
888
889     /* insert the keyframe
890      * NOTE: we do not want to inherit handles from existing keyframes in this case!
891      */
892
893     insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL);
894
895     /* un-apply offset from src beztriple after copying */
896     bezt->vec[0][0] -= offset;
897     bezt->vec[1][0] -= offset;
898     bezt->vec[2][0] -= offset;
899
900     if (flip)
901       do_curve_mirror_flippping(aci, bezt);
902   }
903
904   /* recalculate F-Curve's handles? */
905   calchandles_fcurve(fcu);
906 }
907
908 /* ------------------- */
909
910 const EnumPropertyItem rna_enum_keyframe_paste_offset_items[] = {
911     {KEYFRAME_PASTE_OFFSET_CFRA_START,
912      "START",
913      0,
914      "Frame Start",
915      "Paste keys starting at current frame"},
916     {KEYFRAME_PASTE_OFFSET_CFRA_END, "END", 0, "Frame End", "Paste keys ending at current frame"},
917     {KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE,
918      "RELATIVE",
919      0,
920      "Frame Relative",
921      "Paste keys relative to the current frame when copying"},
922     {KEYFRAME_PASTE_OFFSET_NONE, "NONE", 0, "No Offset", "Paste keys from original time"},
923     {0, NULL, 0, NULL, NULL},
924 };
925
926 const EnumPropertyItem rna_enum_keyframe_paste_merge_items[] = {
927     {KEYFRAME_PASTE_MERGE_MIX, "MIX", 0, "Mix", "Overlay existing with new keys"},
928     {KEYFRAME_PASTE_MERGE_OVER, "OVER_ALL", 0, "Overwrite All", "Replace all keys"},
929     {KEYFRAME_PASTE_MERGE_OVER_RANGE,
930      "OVER_RANGE",
931      0,
932      "Overwrite Range",
933      "Overwrite keys in pasted range"},
934     {KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL,
935      "OVER_RANGE_ALL",
936      0,
937      "Overwrite Entire Range",
938      "Overwrite keys in pasted range, using the range of all copied keys"},
939     {0, NULL, 0, NULL, NULL},
940 };
941
942 /**
943  * This function pastes data from the keyframes copy/paste buffer
944  *
945  * \return Status code is whether the method FAILED to do anything
946  */
947 short paste_animedit_keys(bAnimContext *ac,
948                           ListBase *anim_data,
949                           const eKeyPasteOffset offset_mode,
950                           const eKeyMergeMode merge_mode,
951                           bool flip)
952 {
953   bAnimListElem *ale;
954
955   const Scene *scene = (ac->scene);
956
957   const bool from_single = BLI_listbase_is_single(&animcopybuf);
958   const bool to_simple = BLI_listbase_is_single(anim_data);
959
960   float offset = 0.0f;
961   int pass;
962
963   /* check if buffer is empty */
964   if (BLI_listbase_is_empty(&animcopybuf)) {
965     BKE_report(ac->reports, RPT_ERROR, "No animation data in buffer to paste");
966     return -1;
967   }
968
969   if (BLI_listbase_is_empty(anim_data)) {
970     BKE_report(ac->reports, RPT_ERROR, "No selected F-Curves to paste into");
971     return -1;
972   }
973
974   /* methods of offset */
975   switch (offset_mode) {
976     case KEYFRAME_PASTE_OFFSET_CFRA_START:
977       offset = (float)(CFRA - animcopy_firstframe);
978       break;
979     case KEYFRAME_PASTE_OFFSET_CFRA_END:
980       offset = (float)(CFRA - animcopy_lastframe);
981       break;
982     case KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE:
983       offset = (float)(CFRA - animcopy_cfra);
984       break;
985     case KEYFRAME_PASTE_OFFSET_NONE:
986       offset = 0.0f;
987       break;
988   }
989
990   if (from_single && to_simple) {
991     /* 1:1 match, no tricky checking, just paste */
992     FCurve *fcu;
993     tAnimCopybufItem *aci;
994
995     ale = anim_data->first;
996     fcu = (FCurve *)ale->data; /* destination F-Curve */
997     aci = animcopybuf.first;
998
999     paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, false);
1000     ale->update |= ANIM_UPDATE_DEFAULT;
1001   }
1002   else {
1003     /* from selected channels
1004      * This "passes" system aims to try to find "matching" channels to paste keyframes
1005      * into with increasingly loose matching heuristics. The process finishes when at least
1006      * one F-Curve has been pasted into.
1007      */
1008     for (pass = 0; pass < 3; pass++) {
1009       unsigned int totmatch = 0;
1010
1011       for (ale = anim_data->first; ale; ale = ale->next) {
1012         /* Find buffer item to paste from:
1013          * - If names don't matter (i.e. only 1 channel in buffer), don't check id/group
1014          * - If names do matter, only check if id-type is ok for now
1015          *   (group check is not that important).
1016          * - Most importantly, rna-paths should match (array indices are unimportant for now)
1017          */
1018         AnimData *adt = ANIM_nla_mapping_get(ac, ale);
1019         FCurve *fcu = (FCurve *)ale->data; /* destination F-Curve */
1020         tAnimCopybufItem *aci = NULL;
1021
1022         switch (pass) {
1023           case 0:
1024             /* most strict, must be exact path match data_path & index */
1025             aci = pastebuf_match_path_full(fcu, from_single, to_simple, flip);
1026             break;
1027
1028           case 1:
1029             /* less strict, just compare property names */
1030             aci = pastebuf_match_path_property(ac->bmain, fcu, from_single, to_simple);
1031             break;
1032
1033           case 2:
1034             /* Comparing properties gave no results, so just do index comparisons */
1035             aci = pastebuf_match_index_only(fcu, from_single, to_simple);
1036             break;
1037         }
1038
1039         /* copy the relevant data from the matching buffer curve */
1040         if (aci) {
1041           totmatch++;
1042
1043           if (adt) {
1044             ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
1045             paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
1046             ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
1047           }
1048           else {
1049             paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
1050           }
1051         }
1052
1053         ale->update |= ANIM_UPDATE_DEFAULT;
1054       }
1055
1056       /* don't continue if some fcurves were pasted */
1057       if (totmatch)
1058         break;
1059     }
1060   }
1061
1062   ANIM_animdata_update(ac, anim_data);
1063
1064   return 0;
1065 }
1066
1067 /* **************************************************** */