Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / animation / keyframing.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Joshua Leung (full recode)
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/animation/keyframing.c
29  *  \ingroup edanimation
30  */
31
32
33 #include <stdio.h>
34 #include <stddef.h>
35 #include <string.h>
36 #include <math.h>
37 #include <float.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_math.h"
43 #include "BLI_utildefines.h"
44
45 #include "BLT_translation.h"
46
47 #include "DNA_anim_types.h"
48 #include "DNA_armature_types.h"
49 #include "DNA_constraint_types.h"
50 #include "DNA_key_types.h"
51 #include "DNA_material_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_rigidbody_types.h"
55
56 #include "BKE_action.h"
57 #include "BKE_animsys.h"
58 #include "BKE_armature.h"
59 #include "BKE_context.h"
60 #include "BKE_fcurve.h"
61 #include "BKE_global.h"
62 #include "BKE_idcode.h"
63 #include "BKE_key.h"
64 #include "BKE_main.h"
65 #include "BKE_material.h"
66 #include "BKE_nla.h"
67 #include "BKE_report.h"
68
69 #include "DEG_depsgraph.h"
70 #include "DEG_depsgraph_build.h"
71 #include "DEG_depsgraph_query.h"
72
73 #include "ED_anim_api.h"
74 #include "ED_keyframing.h"
75 #include "ED_keyframes_edit.h"
76 #include "ED_screen.h"
77 #include "ED_object.h"
78
79 #include "UI_interface.h"
80 #include "UI_resources.h"
81
82 #include "WM_api.h"
83 #include "WM_types.h"
84
85 #include "RNA_access.h"
86 #include "RNA_define.h"
87 #include "RNA_enum_types.h"
88
89 #include "anim_intern.h"
90
91 /* ************************************************** */
92 /* Keyframing Setting Wrangling */
93
94 /* Get the active settings for keyframing settings from context (specifically the given scene) */
95 short ANIM_get_keyframing_flags(Scene *scene, short incl_mode)
96 {
97         eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
98
99         /* standard flags */
100         {
101                 /* visual keying */
102                 if (IS_AUTOKEY_FLAG(scene, AUTOMATKEY))
103                         flag |= INSERTKEY_MATRIX;
104
105                 /* only needed */
106                 if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED))
107                         flag |= INSERTKEY_NEEDED;
108
109                 /* default F-Curve color mode - RGB from XYZ indices */
110                 if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
111                         flag |= INSERTKEY_XYZ2RGB;
112         }
113
114         /* only if including settings from the autokeying mode... */
115         if (incl_mode) {
116                 /* keyframing mode - only replace existing keyframes */
117                 if (IS_AUTOKEY_MODE(scene, EDITKEYS))
118                         flag |= INSERTKEY_REPLACE;
119         }
120
121         return flag;
122 }
123
124 /* ******************************************* */
125 /* Animation Data Validation */
126
127 /* Get (or add relevant data to be able to do so) the Active Action for the given
128  * Animation Data block, given an ID block where the Animation Data should reside.
129  */
130 bAction *verify_adt_action(Main *bmain, ID *id, short add)
131 {
132         AnimData *adt;
133
134         /* init animdata if none available yet */
135         adt = BKE_animdata_from_id(id);
136         if ((adt == NULL) && (add))
137                 adt = BKE_animdata_add_id(id);
138         if (adt == NULL) {
139                 /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
140                 printf("ERROR: Couldn't add AnimData (ID = %s)\n", (id) ? (id->name) : "<None>");
141                 return NULL;
142         }
143
144         /* init action if none available yet */
145         /* TODO: need some wizardry to handle NLA stuff correct */
146         if ((adt->action == NULL) && (add)) {
147                 /* init action name from name of ID block */
148                 char actname[sizeof(id->name) - 2];
149                 BLI_snprintf(actname, sizeof(actname), "%sAction", id->name + 2);
150
151                 /* create action */
152                 adt->action = BKE_action_add(bmain, actname);
153
154                 /* set ID-type from ID-block that this is going to be assigned to
155                  * so that users can't accidentally break actions by assigning them
156                  * to the wrong places
157                  */
158                 adt->action->idroot = GS(id->name);
159
160                 /* tag depsgraph to be rebuilt to include time dependency */
161                 /* XXX: we probably should have bmain passed down, but that involves altering too many API's */
162                 DEG_relations_tag_update(bmain);
163         }
164
165         DEG_id_tag_update(&adt->action->id, DEG_TAG_COPY_ON_WRITE);
166
167         /* return the action */
168         return adt->action;
169 }
170
171 /* Get (or add relevant data to be able to do so) F-Curve from the Active Action,
172  * for the given Animation Data block. This assumes that all the destinations are valid.
173  */
174 FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr,
175                       const char rna_path[], const int array_index, short add)
176 {
177         bActionGroup *agrp;
178         FCurve *fcu;
179
180         /* sanity checks */
181         if (ELEM(NULL, act, rna_path))
182                 return NULL;
183
184         /* try to find f-curve matching for this setting
185          *      - add if not found and allowed to add one
186          *              TODO: add auto-grouping support? how this works will need to be resolved
187          */
188         fcu = list_find_fcurve(&act->curves, rna_path, array_index);
189
190         if ((fcu == NULL) && (add)) {
191                 /* use default settings to make a F-Curve */
192                 fcu = MEM_callocN(sizeof(FCurve), "FCurve");
193
194                 fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
195                 fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
196                 if (BLI_listbase_is_empty(&act->curves))
197                         fcu->flag |= FCURVE_ACTIVE;  /* first one added active */
198
199                 /* store path - make copy, and store that */
200                 fcu->rna_path = BLI_strdup(rna_path);
201                 fcu->array_index = array_index;
202
203                 /* if a group name has been provided, try to add or find a group, then add F-Curve to it */
204                 if (group) {
205                         /* try to find group */
206                         agrp = BKE_action_group_find_name(act, group);
207
208                         /* no matching groups, so add one */
209                         if (agrp == NULL) {
210                                 agrp = action_groups_add_new(act, group);
211
212                                 /* sync bone group colors if applicable */
213                                 if (ptr && (ptr->type == &RNA_PoseBone)) {
214                                         Object *ob = (Object *)ptr->id.data;
215                                         bPoseChannel *pchan = (bPoseChannel *)ptr->data;
216                                         bPose *pose = ob->pose;
217                                         bActionGroup *grp;
218
219                                         /* find bone group (if present), and use the color from that */
220                                         grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
221                                         if (grp) {
222                                                 agrp->customCol = grp->customCol;
223                                                 action_group_colors_sync(agrp, grp);
224                                         }
225                                 }
226                         }
227
228                         /* add F-Curve to group */
229                         action_groups_add_channel(act, agrp, fcu);
230                 }
231                 else {
232                         /* just add F-Curve to end of Action's list */
233                         BLI_addtail(&act->curves, fcu);
234                 }
235         }
236
237         /* return the F-Curve */
238         return fcu;
239 }
240
241 /* Helper for update_autoflags_fcurve() */
242 static void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop)
243 {
244         /* set additional flags for the F-Curve (i.e. only integer values) */
245         fcu->flag &= ~(FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES);
246         switch (RNA_property_type(prop)) {
247                 case PROP_FLOAT:
248                         /* do nothing */
249                         break;
250                 case PROP_INT:
251                         /* do integer (only 'whole' numbers) interpolation between all points */
252                         fcu->flag |= FCURVE_INT_VALUES;
253                         break;
254                 default:
255                         /* do 'discrete' (i.e. enum, boolean values which cannot take any intermediate
256                          * values at all) interpolation between all points
257                          *    - however, we must also ensure that evaluated values are only integers still
258                          */
259                         fcu->flag |= (FCURVE_DISCRETE_VALUES | FCURVE_INT_VALUES);
260                         break;
261         }
262 }
263
264 /* Update integer/discrete flags of the FCurve (used when creating/inserting keyframes,
265  * but also through RNA when editing an ID prop, see T37103).
266  */
267 void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, PointerRNA *ptr)
268 {
269         PointerRNA tmp_ptr;
270         PropertyRNA *prop;
271         int old_flag = fcu->flag;
272
273         if ((ptr->id.data == NULL) && (ptr->data == NULL)) {
274                 BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for this fcurve");
275                 return;
276         }
277
278         /* try to get property we should be affecting */
279         if (RNA_path_resolve_property(ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
280                 /* property not found... */
281                 const char *idname = (ptr->id.data) ? ((ID *)ptr->id.data)->name : TIP_("<No ID pointer>");
282
283                 BKE_reportf(reports, RPT_ERROR,
284                             "Could not update flags for this fcurve, as RNA path is invalid for the given ID "
285                             "(ID = %s, path = %s)",
286                             idname, fcu->rna_path);
287                 return;
288         }
289
290         /* update F-Curve flags */
291         update_autoflags_fcurve_direct(fcu, prop);
292
293         if (old_flag != fcu->flag) {
294                 /* Same as if keyframes had been changed */
295                 WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
296         }
297 }
298
299 /* ************************************************** */
300 /* KEYFRAME INSERTION */
301
302 /* -------------- BezTriple Insertion -------------------- */
303
304 /* This function adds a given BezTriple to an F-Curve. It will allocate
305  * memory for the array if needed, and will insert the BezTriple into a
306  * suitable place in chronological order.
307  *
308  * NOTE: any recalculate of the F-Curve that needs to be done will need to
309  *      be done by the caller.
310  */
311 int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
312 {
313         int i = 0;
314
315         /* are there already keyframes? */
316         if (fcu->bezt) {
317                 bool replace;
318                 i = binarysearch_bezt_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace);
319
320                 /* replace an existing keyframe? */
321                 if (replace) {
322                         /* sanity check: 'i' may in rare cases exceed arraylen */
323                         if ((i >= 0) && (i < fcu->totvert)) {
324                                 if (flag & INSERTKEY_OVERWRITE_FULL) {
325                                         fcu->bezt[i] = *bezt;
326                                 }
327                                 else {
328                                         /* just change the values when replacing, so as to not overwrite handles */
329                                         BezTriple *dst = (fcu->bezt + i);
330                                         float dy = bezt->vec[1][1] - dst->vec[1][1];
331
332                                         /* just apply delta value change to the handle values */
333                                         dst->vec[0][1] += dy;
334                                         dst->vec[1][1] += dy;
335                                         dst->vec[2][1] += dy;
336
337                                         dst->f1 = bezt->f1;
338                                         dst->f2 = bezt->f2;
339                                         dst->f3 = bezt->f3;
340
341                                         /* TODO: perform some other operations? */
342                                 }
343                         }
344                 }
345                 /* keyframing modes allow to not replace keyframe */
346                 else if ((flag & INSERTKEY_REPLACE) == 0) {
347                         /* insert new - if we're not restricted to replacing keyframes only */
348                         BezTriple *newb = MEM_callocN((fcu->totvert + 1) * sizeof(BezTriple), "beztriple");
349
350                         /* add the beztriples that should occur before the beztriple to be pasted (originally in fcu) */
351                         if (i > 0)
352                                 memcpy(newb, fcu->bezt, i * sizeof(BezTriple));
353
354                         /* add beztriple to paste at index i */
355                         *(newb + i) = *bezt;
356
357                         /* add the beztriples that occur after the beztriple to be pasted (originally in fcu) */
358                         if (i < fcu->totvert)
359                                 memcpy(newb + i + 1, fcu->bezt + i, (fcu->totvert - i) * sizeof(BezTriple));
360
361                         /* replace (+ free) old with new, only if necessary to do so */
362                         MEM_freeN(fcu->bezt);
363                         fcu->bezt = newb;
364
365                         fcu->totvert++;
366                 }
367         }
368         /* no keyframes already, but can only add if...
369          *      1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know
370          *      2) there are no samples on the curve
371          *              // NOTE: maybe we may want to allow this later when doing samples -> bezt conversions,
372          *              // but for now, having both is asking for trouble
373          */
374         else if ((flag & INSERTKEY_REPLACE) == 0 && (fcu->fpt == NULL)) {
375                 /* create new keyframes array */
376                 fcu->bezt = MEM_callocN(sizeof(BezTriple), "beztriple");
377                 *(fcu->bezt) = *bezt;
378                 fcu->totvert = 1;
379         }
380         /* cannot add anything */
381         else {
382                 /* return error code -1 to prevent any misunderstandings */
383                 return -1;
384         }
385
386
387         /* we need to return the index, so that some tools which do post-processing can
388          * detect where we added the BezTriple in the array
389          */
390         return i;
391 }
392
393 /**
394  * This function is a wrapper for insert_bezt_fcurve_internal(), and should be used when
395  * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet.
396  * It returns the index at which the keyframe was added.
397  *
398  * \param keyframe_type: The type of keyframe (eBezTriple_KeyframeType)
399  * \param flag: Optional flags (eInsertKeyFlags) for controlling how keys get added
400  *              and/or whether updates get done
401  */
402 int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag)
403 {
404         BezTriple beztr = {{{0}}};
405         unsigned int oldTot = fcu->totvert;
406         int a;
407
408         /* set all three points, for nicer start position
409          * NOTE: +/- 1 on vec.x for left and right handles is so that 'free' handles work ok...
410          */
411         beztr.vec[0][0] = x - 1.0f;
412         beztr.vec[0][1] = y;
413         beztr.vec[1][0] = x;
414         beztr.vec[1][1] = y;
415         beztr.vec[2][0] = x + 1.0f;
416         beztr.vec[2][1] = y;
417         beztr.f1 = beztr.f2 = beztr.f3 = SELECT;
418
419         /* set default handle types and interpolation mode */
420         if (flag & INSERTKEY_NO_USERPREF) {
421                 /* for Py-API, we want scripts to have predictable behaviour,
422                  * hence the option to not depend on the userpref defaults
423                  */
424                 beztr.h1 = beztr.h2 = HD_AUTO_ANIM;
425                 beztr.ipo = BEZT_IPO_BEZ;
426         }
427         else {
428                 /* for UI usage - defaults should come from the userprefs and/or toolsettings */
429                 beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */
430
431                 /* use default interpolation mode, with exceptions for int/discrete values */
432                 beztr.ipo = U.ipo_new;
433         }
434
435         /* interpolation type used is constrained by the type of values the curve can take */
436         if (fcu->flag & FCURVE_DISCRETE_VALUES) {
437                 beztr.ipo = BEZT_IPO_CONST;
438         }
439         else if ((beztr.ipo == BEZT_IPO_BEZ) && (fcu->flag & FCURVE_INT_VALUES)) {
440                 beztr.ipo = BEZT_IPO_LIN;
441         }
442
443         /* set keyframe type value (supplied), which should come from the scene settings in most cases */
444         BEZKEYTYPE(&beztr) = keyframe_type;
445
446         /* set default values for "easing" interpolation mode settings
447          * NOTE: Even if these modes aren't currently used, if users switch
448          *       to these later, we want these to work in a sane way out of
449          *       the box.
450          */
451         beztr.back = 1.70158f;     /* "back" easing - this value used to be used when overshoot=0, but that        */
452                                    /*                 introduced discontinuities in how the param worked           */
453
454         beztr.amplitude = 0.8f;    /* "elastic" easing - values here were hand-optimised for a default duration of */
455         beztr.period = 4.1f;       /*                    ~10 frames (typical mograph motion length)                */
456
457         /* add temp beztriple to keyframes */
458         a = insert_bezt_fcurve(fcu, &beztr, flag);
459
460         /* what if 'a' is a negative index?
461          * for now, just exit to prevent any segfaults
462          */
463         if (a < 0) return -1;
464
465         /* don't recalculate handles if fast is set
466          *      - this is a hack to make importers faster
467          *      - we may calculate twice (due to autohandle needing to be calculated twice)
468          */
469         if ((flag & INSERTKEY_FAST) == 0)
470                 calchandles_fcurve(fcu);
471
472         /* set handletype and interpolation */
473         if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) {
474                 BezTriple *bezt = (fcu->bezt + a);
475
476                 /* set interpolation from previous (if available), but only if we didn't just replace some keyframe
477                  *  - replacement is indicated by no-change in number of verts
478                  *      - when replacing, the user may have specified some interpolation that should be kept
479                  */
480                 if (fcu->totvert > oldTot) {
481                         if (a > 0)
482                                 bezt->ipo = (bezt - 1)->ipo;
483                         else if (a < fcu->totvert - 1)
484                                 bezt->ipo = (bezt + 1)->ipo;
485                 }
486
487                 /* don't recalculate handles if fast is set
488                  *      - this is a hack to make importers faster
489                  *      - we may calculate twice (due to autohandle needing to be calculated twice)
490                  */
491                 if ((flag & INSERTKEY_FAST) == 0)
492                         calchandles_fcurve(fcu);
493         }
494
495         /* return the index at which the keyframe was added */
496         return a;
497 }
498
499 /* -------------- 'Smarter' Keyframing Functions -------------------- */
500 /* return codes for new_key_needed */
501 enum {
502         KEYNEEDED_DONTADD = 0,
503         KEYNEEDED_JUSTADD,
504         KEYNEEDED_DELPREV,
505         KEYNEEDED_DELNEXT
506 } /*eKeyNeededStatus*/;
507
508 /* This helper function determines whether a new keyframe is needed */
509 /* Cases where keyframes should not be added:
510  *      1. Keyframe to be added between two keyframes with similar values
511  *      2. Keyframe to be added on frame where two keyframes are already situated
512  *      3. Keyframe lies at point that intersects the linear line between two keyframes
513  */
514 static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
515 {
516         BezTriple *bezt = NULL, *prev = NULL;
517         int totCount, i;
518         float valA = 0.0f, valB = 0.0f;
519
520         /* safety checking */
521         if (fcu == NULL) return KEYNEEDED_JUSTADD;
522         totCount = fcu->totvert;
523         if (totCount == 0) return KEYNEEDED_JUSTADD;
524
525         /* loop through checking if any are the same */
526         bezt = fcu->bezt;
527         for (i = 0; i < totCount; i++) {
528                 float prevPosi = 0.0f, prevVal = 0.0f;
529                 float beztPosi = 0.0f, beztVal = 0.0f;
530
531                 /* get current time+value */
532                 beztPosi = bezt->vec[1][0];
533                 beztVal = bezt->vec[1][1];
534
535                 if (prev) {
536                         /* there is a keyframe before the one currently being examined */
537
538                         /* get previous time+value */
539                         prevPosi = prev->vec[1][0];
540                         prevVal = prev->vec[1][1];
541
542                         /* keyframe to be added at point where there are already two similar points? */
543                         if (IS_EQF(prevPosi, cFrame) && IS_EQF(beztPosi, cFrame) && IS_EQF(beztPosi, prevPosi)) {
544                                 return KEYNEEDED_DONTADD;
545                         }
546
547                         /* keyframe between prev+current points ? */
548                         if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
549                                 /* is the value of keyframe to be added the same as keyframes on either side ? */
550                                 if (IS_EQF(prevVal, nValue) && IS_EQF(beztVal, nValue) && IS_EQF(prevVal, beztVal)) {
551                                         return KEYNEEDED_DONTADD;
552                                 }
553                                 else {
554                                         float realVal;
555
556                                         /* get real value of curve at that point */
557                                         realVal = evaluate_fcurve(fcu, cFrame);
558
559                                         /* compare whether it's the same as proposed */
560                                         if (IS_EQF(realVal, nValue))
561                                                 return KEYNEEDED_DONTADD;
562                                         else
563                                                 return KEYNEEDED_JUSTADD;
564                                 }
565                         }
566
567                         /* new keyframe before prev beztriple? */
568                         if (cFrame < prevPosi) {
569                                 /* A new keyframe will be added. However, whether the previous beztriple
570                                  * stays around or not depends on whether the values of previous/current
571                                  * beztriples and new keyframe are the same.
572                                  */
573                                 if (IS_EQF(prevVal, nValue) && IS_EQF(beztVal, nValue) && IS_EQF(prevVal, beztVal))
574                                         return KEYNEEDED_DELNEXT;
575                                 else
576                                         return KEYNEEDED_JUSTADD;
577                         }
578                 }
579                 else {
580                         /* just add a keyframe if there's only one keyframe
581                          * and the new one occurs before the existing one does.
582                          */
583                         if ((cFrame < beztPosi) && (totCount == 1))
584                                 return KEYNEEDED_JUSTADD;
585                 }
586
587                 /* continue. frame to do not yet passed (or other conditions not met) */
588                 if (i < (totCount - 1)) {
589                         prev = bezt;
590                         bezt++;
591                 }
592                 else
593                         break;
594         }
595
596         /* Frame in which to add a new-keyframe occurs after all other keys
597          * -> If there are at least two existing keyframes, then if the values of the
598          *    last two keyframes and the new-keyframe match, the last existing keyframe
599          *    gets deleted as it is no longer required.
600          * -> Otherwise, a keyframe is just added. 1.0 is added so that fake-2nd-to-last
601          *    keyframe is not equal to last keyframe.
602          */
603         bezt = (fcu->bezt + (fcu->totvert - 1));
604         valA = bezt->vec[1][1];
605
606         if (prev)
607                 valB = prev->vec[1][1];
608         else
609                 valB = bezt->vec[1][1] + 1.0f;
610
611         if (IS_EQF(valA, nValue) && IS_EQF(valA, valB))
612                 return KEYNEEDED_DELPREV;
613         else
614                 return KEYNEEDED_JUSTADD;
615 }
616
617 /* ------------------ RNA Data-Access Functions ------------------ */
618
619 /* Try to read value using RNA-properties obtained already */
620 static float setting_get_rna_value(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, int index, const bool get_evaluated)
621 {
622         PointerRNA ptr_eval = *ptr;
623         float value = 0.0f;
624
625         if (get_evaluated) {
626                 DEG_get_evaluated_rna_pointer(depsgraph, ptr, &ptr_eval);
627         }
628
629         switch (RNA_property_type(prop)) {
630                 case PROP_BOOLEAN:
631                         if (RNA_property_array_check(prop))
632                                 value = (float)RNA_property_boolean_get_index(&ptr_eval, prop, index);
633                         else
634                                 value = (float)RNA_property_boolean_get(&ptr_eval, prop);
635                         break;
636                 case PROP_INT:
637                         if (RNA_property_array_check(prop))
638                                 value = (float)RNA_property_int_get_index(&ptr_eval, prop, index);
639                         else
640                                 value = (float)RNA_property_int_get(&ptr_eval, prop);
641                         break;
642                 case PROP_FLOAT:
643                         if (RNA_property_array_check(prop))
644                                 value = RNA_property_float_get_index(&ptr_eval, prop, index);
645                         else
646                                 value = RNA_property_float_get(&ptr_eval, prop);
647                         break;
648                 case PROP_ENUM:
649                         value = (float)RNA_property_enum_get(&ptr_eval, prop);
650                         break;
651                 default:
652                         break;
653         }
654
655         return value;
656 }
657
658 /* ------------------ 'Visual' Keyframing Functions ------------------ */
659
660 /* internal status codes for visualkey_can_use */
661 enum {
662         VISUALKEY_NONE = 0,
663         VISUALKEY_LOC,
664         VISUALKEY_ROT,
665         VISUALKEY_SCA,
666 };
667
668 /* This helper function determines if visual-keyframing should be used when
669  * inserting keyframes for the given channel. As visual-keyframing only works
670  * on Object and Pose-Channel blocks, this should only get called for those
671  * blocktypes, when using "standard" keying but 'Visual Keying' option in Auto-Keying
672  * settings is on.
673  */
674 static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
675 {
676         bConstraint *con = NULL;
677         short searchtype = VISUALKEY_NONE;
678         bool has_rigidbody = false;
679         bool has_parent = false;
680         const char *identifier = NULL;
681
682         /* validate data */
683         if (ELEM(NULL, ptr, ptr->data, prop))
684                 return false;
685
686         /* get first constraint and determine type of keyframe constraints to check for
687          *  - constraints can be on either Objects or PoseChannels, so we only check if the
688          *    ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
689          *    those structs, allowing us to identify the owner of the data
690          */
691         if (ptr->type == &RNA_Object) {
692                 /* Object */
693                 Object *ob = (Object *)ptr->data;
694                 RigidBodyOb *rbo = ob->rigidbody_object;
695
696                 con = ob->constraints.first;
697                 identifier = RNA_property_identifier(prop);
698                 has_parent = (ob->parent != NULL);
699
700                 /* active rigidbody objects only, as only those are affected by sim */
701                 has_rigidbody = ((rbo) && (rbo->type == RBO_TYPE_ACTIVE));
702         }
703         else if (ptr->type == &RNA_PoseBone) {
704                 /* Pose Channel */
705                 bPoseChannel *pchan = (bPoseChannel *)ptr->data;
706
707                 con = pchan->constraints.first;
708                 identifier = RNA_property_identifier(prop);
709                 has_parent = (pchan->parent != NULL);
710         }
711
712         /* check if any data to search using */
713         if (ELEM(NULL, con, identifier) && (has_parent == false) && (has_rigidbody == false))
714                 return false;
715
716         /* location or rotation identifiers only... */
717         if (identifier == NULL) {
718                 printf("%s failed: NULL identifier\n", __func__);
719                 return false;
720         }
721         else if (strstr(identifier, "location")) {
722                 searchtype = VISUALKEY_LOC;
723         }
724         else if (strstr(identifier, "rotation")) {
725                 searchtype = VISUALKEY_ROT;
726         }
727         else if (strstr(identifier, "scale")) {
728                 searchtype = VISUALKEY_SCA;
729         }
730         else {
731                 printf("%s failed: identifier - '%s'\n", __func__, identifier);
732                 return false;
733         }
734
735
736         /* only search if a searchtype and initial constraint are available */
737         if (searchtype) {
738                 /* parent or rigidbody are always matching */
739                 if (has_parent || has_rigidbody)
740                         return true;
741
742                 /* constraints */
743                 for (; con; con = con->next) {
744                         /* only consider constraint if it is not disabled, and has influence */
745                         if (con->flag & CONSTRAINT_DISABLE) continue;
746                         if (con->enforce == 0.0f) continue;
747
748                         /* some constraints may alter these transforms */
749                         switch (con->type) {
750                                 /* multi-transform constraints */
751                                 case CONSTRAINT_TYPE_CHILDOF:
752                                         return true;
753                                 case CONSTRAINT_TYPE_TRANSFORM:
754                                 case CONSTRAINT_TYPE_TRANSLIKE:
755                                         return true;
756                                 case CONSTRAINT_TYPE_FOLLOWPATH:
757                                         return true;
758                                 case CONSTRAINT_TYPE_KINEMATIC:
759                                         return true;
760
761                                 /* single-transform constraits  */
762                                 case CONSTRAINT_TYPE_TRACKTO:
763                                         if (searchtype == VISUALKEY_ROT) return true;
764                                         break;
765                                 case CONSTRAINT_TYPE_DAMPTRACK:
766                                         if (searchtype == VISUALKEY_ROT) return true;
767                                         break;
768                                 case CONSTRAINT_TYPE_ROTLIMIT:
769                                         if (searchtype == VISUALKEY_ROT) return true;
770                                         break;
771                                 case CONSTRAINT_TYPE_LOCLIMIT:
772                                         if (searchtype == VISUALKEY_LOC) return true;
773                                         break;
774                                 case CONSTRAINT_TYPE_SIZELIMIT:
775                                         if (searchtype == VISUALKEY_SCA) return true;
776                                         break;
777                                 case CONSTRAINT_TYPE_DISTLIMIT:
778                                         if (searchtype == VISUALKEY_LOC) return true;
779                                         break;
780                                 case CONSTRAINT_TYPE_ROTLIKE:
781                                         if (searchtype == VISUALKEY_ROT) return true;
782                                         break;
783                                 case CONSTRAINT_TYPE_LOCLIKE:
784                                         if (searchtype == VISUALKEY_LOC) return true;
785                                         break;
786                                 case CONSTRAINT_TYPE_SIZELIKE:
787                                         if (searchtype == VISUALKEY_SCA) return true;
788                                         break;
789                                 case CONSTRAINT_TYPE_LOCKTRACK:
790                                         if (searchtype == VISUALKEY_ROT) return true;
791                                         break;
792                                 case CONSTRAINT_TYPE_MINMAX:
793                                         if (searchtype == VISUALKEY_LOC) return true;
794                                         break;
795
796                                 default:
797                                         break;
798                         }
799                 }
800         }
801
802         /* when some condition is met, this function returns, so that means we've got nothing */
803         return false;
804 }
805
806 /* This helper function extracts the value to use for visual-keyframing
807  * In the event that it is not possible to perform visual keying, try to fall-back
808  * to using the default method. Assumes that all data it has been passed is valid.
809  */
810 static float visualkey_get_value(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, int array_index)
811 {
812         const char *identifier = RNA_property_identifier(prop);
813         float tmat[4][4];
814         int rotmode;
815
816         /* handle for Objects or PoseChannels only
817          *  - only Location, Rotation or Scale keyframes are supported currently
818          *  - constraints can be on either Objects or PoseChannels, so we only check if the
819          *    ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
820          *        those structs, allowing us to identify the owner of the data
821          *  - assume that array_index will be sane
822          */
823         if (ptr->type == &RNA_Object) {
824                 Object *ob = (Object *)ptr->data;
825                 const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
826
827                 /* Loc code is specific... */
828                 if (strstr(identifier, "location")) {
829                         return ob_eval->obmat[3][array_index];
830                 }
831
832                 copy_m4_m4(tmat, ob_eval->obmat);
833                 rotmode = ob_eval->rotmode;
834         }
835         else if (ptr->type == &RNA_PoseBone) {
836                 Object *ob = (Object *)ptr->id.data;
837                 bPoseChannel *pchan = (bPoseChannel *)ptr->data;
838
839                 const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
840                 bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
841
842                 BKE_armature_mat_pose_to_bone(pchan_eval, pchan_eval->pose_mat, tmat);
843                 rotmode = pchan_eval->rotmode;
844
845                 /* Loc code is specific... */
846                 if (strstr(identifier, "location")) {
847                         /* only use for non-connected bones */
848                         if ((pchan->bone->parent == NULL) || !(pchan->bone->flag & BONE_CONNECTED))
849                                 return tmat[3][array_index];
850                 }
851         }
852         else {
853                 return setting_get_rna_value(depsgraph, ptr, prop, array_index, true);
854         }
855
856         /* Rot/Scale code are common! */
857         if (strstr(identifier, "rotation_euler")) {
858                 float eul[3];
859
860                 mat4_to_eulO(eul, rotmode, tmat);
861                 return eul[array_index];
862         }
863         else if (strstr(identifier, "rotation_quaternion")) {
864                 float mat3[3][3], quat[4];
865
866                 copy_m3_m4(mat3, tmat);
867                 mat3_to_quat_is_ok(quat, mat3);
868
869                 return quat[array_index];
870         }
871         else if (strstr(identifier, "rotation_axis_angle")) {
872                 float axis[3], angle;
873
874                 mat4_to_axis_angle(axis, &angle, tmat);
875
876                 /* w = 0, x,y,z = 1,2,3 */
877                 if (array_index == 0)
878                         return angle;
879                 else
880                         return axis[array_index - 1];
881         }
882         else if (strstr(identifier, "scale")) {
883                 float scale[3];
884
885                 mat4_to_size(scale, tmat);
886
887                 return scale[array_index];
888         }
889
890         /* as the function hasn't returned yet, read value from system in the default way */
891         return setting_get_rna_value(depsgraph, ptr, prop, array_index, true);
892 }
893
894 /* ------------------------- Insert Key API ------------------------- */
895
896 /* Secondary Keyframing API call:
897  *  Use this when validation of necessary animation data is not necessary, since an RNA-pointer to the necessary
898  *      data being keyframed, and a pointer to the F-Curve to use have both been provided.
899  *
900  *  keytype is the "keyframe type" (eBezTriple_KeyframeType), as shown in the Dope Sheet.
901  *
902  *      The flag argument is used for special settings that alter the behavior of
903  *      the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
904  *      and extra keyframe filtering.
905  */
906 bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag)
907 {
908         float curval = 0.0f;
909
910         /* no F-Curve to add keyframe to? */
911         if (fcu == NULL) {
912                 BKE_report(reports, RPT_ERROR, "No F-Curve to add keyframes to");
913                 return false;
914         }
915         /* F-Curve not editable? */
916         if (fcurve_is_keyframable(fcu) == 0) {
917                 BKE_reportf(reports, RPT_ERROR,
918                             "F-Curve with path '%s[%d]' cannot be keyframed, ensure that it is not locked or sampled, "
919                             "and try removing F-Modifiers",
920                             fcu->rna_path, fcu->array_index);
921                 return false;
922         }
923
924         /* if no property given yet, try to validate from F-Curve info */
925         if ((ptr.id.data == NULL) && (ptr.data == NULL)) {
926                 BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from");
927                 return false;
928         }
929         if (prop == NULL) {
930                 PointerRNA tmp_ptr;
931
932                 /* try to get property we should be affecting */
933                 if (RNA_path_resolve_property(&ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
934                         /* property not found... */
935                         const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : TIP_("<No ID pointer>");
936
937                         BKE_reportf(reports, RPT_ERROR,
938                                     "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
939                                     idname, fcu->rna_path);
940                         return false;
941                 }
942                 else {
943                         /* property found, so overwrite 'ptr' to make later code easier */
944                         ptr = tmp_ptr;
945                 }
946         }
947
948         /* update F-Curve flags to ensure proper behaviour for property type */
949         update_autoflags_fcurve_direct(fcu, prop);
950
951         /* adjust frame on which to add keyframe */
952         if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) {
953                 PathResolvedRNA anim_rna;
954
955                 if (RNA_path_resolved_create(&ptr, prop, fcu->array_index, &anim_rna)) {
956                         /* for making it easier to add corrective drivers... */
957                         cfra = evaluate_driver(&anim_rna, fcu->driver, cfra);
958                 }
959                 else {
960                         cfra = 0.0f;
961                 }
962         }
963
964         /* obtain value to give keyframe */
965         if ( (flag & INSERTKEY_MATRIX) &&
966              (visualkey_can_use(&ptr, prop)) )
967         {
968                 /* visual-keying is only available for object and pchan datablocks, as
969                  * it works by keyframing using a value extracted from the final matrix
970                  * instead of using the kt system to extract a value.
971                  */
972                 curval = visualkey_get_value(depsgraph, &ptr, prop, fcu->array_index);
973         }
974         else {
975                 /* read value from system */
976                 curval = setting_get_rna_value(depsgraph, &ptr, prop, fcu->array_index, false);
977         }
978
979         /* only insert keyframes where they are needed */
980         if (flag & INSERTKEY_NEEDED) {
981                 short insert_mode;
982
983                 /* check whether this curve really needs a new keyframe */
984                 insert_mode = new_key_needed(fcu, cfra, curval);
985
986                 /* insert new keyframe at current frame */
987                 if (insert_mode)
988                         insert_vert_fcurve(fcu, cfra, curval, keytype, flag);
989
990                 /* delete keyframe immediately before/after newly added */
991                 switch (insert_mode) {
992                         case KEYNEEDED_DELPREV:
993                                 delete_fcurve_key(fcu, fcu->totvert - 2, 1);
994                                 break;
995                         case KEYNEEDED_DELNEXT:
996                                 delete_fcurve_key(fcu, 1, 1);
997                                 break;
998                 }
999
1000                 /* only return success if keyframe added */
1001                 if (insert_mode)
1002                         return true;
1003         }
1004         else {
1005                 /* just insert keyframe */
1006                 insert_vert_fcurve(fcu, cfra, curval, keytype, flag);
1007
1008                 /* return success */
1009                 return true;
1010         }
1011
1012         /* failed */
1013         return false;
1014 }
1015
1016 /* Main Keyframing API call:
1017  *      Use this when validation of necessary animation data is necessary, since it may not exist yet.
1018  *
1019  *      The flag argument is used for special settings that alter the behavior of
1020  *      the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
1021  *      and extra keyframe filtering.
1022  *
1023  *      index of -1 keys all array indices
1024  */
1025 short insert_keyframe(
1026         Main *bmain, Depsgraph *depsgraph, ReportList *reports, ID *id, bAction *act,
1027         const char group[], const char rna_path[], int array_index, float cfra, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag)
1028 {
1029         PointerRNA id_ptr, ptr;
1030         PropertyRNA *prop = NULL;
1031         AnimData *adt;
1032         FCurve *fcu;
1033         int array_index_max = array_index + 1;
1034         int ret = 0;
1035
1036         /* validate pointer first - exit if failure */
1037         if (id == NULL) {
1038                 BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path);
1039                 return 0;
1040         }
1041
1042         RNA_id_pointer_create(id, &id_ptr);
1043         if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
1044                 BKE_reportf(reports, RPT_ERROR,
1045                             "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
1046                             (id) ? id->name : TIP_("<Missing ID block>"), rna_path);
1047                 return 0;
1048         }
1049
1050         /* if no action is provided, keyframe to the default one attached to this ID-block */
1051         if (act == NULL) {
1052                 /* get action to add F-Curve+keyframe to */
1053                 act = verify_adt_action(bmain, id, 1);
1054
1055                 if (act == NULL) {
1056                         BKE_reportf(reports, RPT_ERROR,
1057                                     "Could not insert keyframe, as this type does not support animation data (ID = %s, path = %s)",
1058                                     id->name, rna_path);
1059                         return 0;
1060                 }
1061         }
1062
1063         /* apply NLA-mapping to frame to use (if applicable) */
1064         adt = BKE_animdata_from_id(id);
1065         cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
1066
1067         /* key entire array convenience method */
1068         if (array_index == -1) {
1069                 array_index = 0;
1070                 array_index_max = RNA_property_array_length(&ptr, prop);
1071
1072                 /* for single properties, increase max_index so that the property itself gets included,
1073                  * but don't do this for standard arrays since that can cause corruption issues
1074                  * (extra unused curves)
1075                  */
1076                 if (array_index_max == array_index)
1077                         array_index_max++;
1078         }
1079
1080         /* will only loop once unless the array index was -1 */
1081         for (; array_index < array_index_max; array_index++) {
1082                 /* make sure the F-Curve exists
1083                  *      - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
1084                  *        but still try to get the F-Curve if it exists...
1085                  */
1086                 fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, (flag & INSERTKEY_REPLACE) == 0);
1087
1088                 /* we may not have a F-Curve when we're replacing only... */
1089                 if (fcu) {
1090                         /* set color mode if the F-Curve is new (i.e. without any keyframes) */
1091                         if ((fcu->totvert == 0) && (flag & INSERTKEY_XYZ2RGB)) {
1092                                 /* for Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor,
1093                                  * is determined by the array index for the F-Curve
1094                                  */
1095                                 PropertySubType prop_subtype = RNA_property_subtype(prop);
1096                                 if (ELEM(prop_subtype, PROP_TRANSLATION, PROP_XYZ, PROP_EULER, PROP_COLOR, PROP_COORDS)) {
1097                                         fcu->color_mode = FCURVE_COLOR_AUTO_RGB;
1098                                 }
1099                                 else if (ELEM(prop_subtype, PROP_QUATERNION)) {
1100                                         fcu->color_mode = FCURVE_COLOR_AUTO_YRGB;
1101                                 }
1102                         }
1103
1104                         /* insert keyframe */
1105                         ret += insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, keytype, flag);
1106                 }
1107         }
1108
1109         return ret;
1110 }
1111
1112 /* ************************************************** */
1113 /* KEYFRAME DELETION */
1114
1115 /* Main Keyframing API call:
1116  *      Use this when validation of necessary animation data isn't necessary as it
1117  *      already exists. It will delete a keyframe at the current frame.
1118  *
1119  *      The flag argument is used for special settings that alter the behavior of
1120  *      the keyframe deletion. These include the quick refresh options.
1121  */
1122
1123
1124
1125 /**
1126  * \note caller needs to run #BKE_nla_tweakedit_remap to get NLA relative frame.
1127  *       caller should also check #BKE_fcurve_is_protected before keying.
1128  */
1129 static bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra)
1130 {
1131         bool found;
1132         int i;
1133
1134         /* try to find index of beztriple to get rid of */
1135         i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
1136         if (found) {
1137                 /* delete the key at the index (will sanity check + do recalc afterwards) */
1138                 delete_fcurve_key(fcu, i, 1);
1139
1140                 /* Only delete curve too if it won't be doing anything anymore */
1141                 if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
1142                         ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
1143
1144                 /* return success */
1145                 return true;
1146         }
1147         return false;
1148 }
1149
1150 short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, eInsertKeyFlags UNUSED(flag))
1151 {
1152         AnimData *adt = BKE_animdata_from_id(id);
1153         PointerRNA id_ptr, ptr;
1154         PropertyRNA *prop;
1155         int array_index_max = array_index + 1;
1156         int ret = 0;
1157
1158         /* sanity checks */
1159         if (ELEM(NULL, id, adt)) {
1160                 BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
1161                 return 0;
1162         }
1163
1164         /* validate pointer first - exit if failure */
1165         RNA_id_pointer_create(id, &id_ptr);
1166         if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
1167                 BKE_reportf(reports, RPT_ERROR,
1168                             "Could not delete keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
1169                             id->name, rna_path);
1170                 return 0;
1171         }
1172
1173         /* get F-Curve
1174          * Note: here is one of the places where we don't want new Action + F-Curve added!
1175          *      so 'add' var must be 0
1176          */
1177         if (act == NULL) {
1178                 /* if no action is provided, use the default one attached to this ID-block
1179                  *  - if it doesn't exist, then we're out of options...
1180                  */
1181                 if (adt->action) {
1182                         act = adt->action;
1183
1184                         /* apply NLA-mapping to frame to use (if applicable) */
1185                         cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
1186                 }
1187                 else {
1188                         BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s", id->name);
1189                         return 0;
1190                 }
1191         }
1192
1193         /* key entire array convenience method */
1194         if (array_index == -1) {
1195                 array_index = 0;
1196                 array_index_max = RNA_property_array_length(&ptr, prop);
1197
1198                 /* for single properties, increase max_index so that the property itself gets included,
1199                  * but don't do this for standard arrays since that can cause corruption issues
1200                  * (extra unused curves)
1201                  */
1202                 if (array_index_max == array_index)
1203                         array_index_max++;
1204         }
1205
1206         /* will only loop once unless the array index was -1 */
1207         for (; array_index < array_index_max; array_index++) {
1208                 FCurve *fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, 0);
1209
1210                 /* check if F-Curve exists and/or whether it can be edited */
1211                 if (fcu == NULL)
1212                         continue;
1213
1214                 if (BKE_fcurve_is_protected(fcu)) {
1215                         BKE_reportf(reports, RPT_WARNING,
1216                                     "Not deleting keyframe for locked F-Curve '%s' for %s '%s'",
1217                                     fcu->rna_path, BKE_idcode_to_name(GS(id->name)), id->name + 2);
1218                         continue;
1219                 }
1220
1221                 ret += delete_keyframe_fcurve(adt, fcu, cfra);
1222
1223         }
1224
1225         /* return success/failure */
1226         return ret;
1227 }
1228
1229 /* ************************************************** */
1230 /* KEYFRAME CLEAR */
1231
1232 /* Main Keyframing API call:
1233  *      Use this when validation of necessary animation data isn't necessary as it
1234  *      already exists. It will clear the current buttons fcurve(s).
1235  *
1236  *      The flag argument is used for special settings that alter the behavior of
1237  *      the keyframe deletion. These include the quick refresh options.
1238  */
1239 static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, eInsertKeyFlags UNUSED(flag))
1240 {
1241         AnimData *adt = BKE_animdata_from_id(id);
1242         PointerRNA id_ptr, ptr;
1243         PropertyRNA *prop;
1244         int array_index_max = array_index + 1;
1245         int ret = 0;
1246
1247         /* sanity checks */
1248         if (ELEM(NULL, id, adt)) {
1249                 BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
1250                 return 0;
1251         }
1252
1253         /* validate pointer first - exit if failure */
1254         RNA_id_pointer_create(id, &id_ptr);
1255         if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
1256                 BKE_reportf(reports, RPT_ERROR,
1257                             "Could not clear keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
1258                             id->name, rna_path);
1259                 return 0;
1260         }
1261
1262         /* get F-Curve
1263          * Note: here is one of the places where we don't want new Action + F-Curve added!
1264          *      so 'add' var must be 0
1265          */
1266         if (act == NULL) {
1267                 /* if no action is provided, use the default one attached to this ID-block
1268                  *  - if it doesn't exist, then we're out of options...
1269                  */
1270                 if (adt->action) {
1271                         act = adt->action;
1272                 }
1273                 else {
1274                         BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s", id->name);
1275                         return 0;
1276                 }
1277         }
1278
1279         /* key entire array convenience method */
1280         if (array_index == -1) {
1281                 array_index = 0;
1282                 array_index_max = RNA_property_array_length(&ptr, prop);
1283
1284                 /* for single properties, increase max_index so that the property itself gets included,
1285                  * but don't do this for standard arrays since that can cause corruption issues
1286                  * (extra unused curves)
1287                  */
1288                 if (array_index_max == array_index)
1289                         array_index_max++;
1290         }
1291
1292         /* will only loop once unless the array index was -1 */
1293         for (; array_index < array_index_max; array_index++) {
1294                 FCurve *fcu = verify_fcurve(act, group, &ptr, rna_path, array_index, 0);
1295
1296                 /* check if F-Curve exists and/or whether it can be edited */
1297                 if (fcu == NULL)
1298                         continue;
1299
1300                 if (BKE_fcurve_is_protected(fcu)) {
1301                         BKE_reportf(reports, RPT_WARNING,
1302                                     "Not clearing all keyframes from locked F-Curve '%s' for %s '%s'",
1303                                     fcu->rna_path, BKE_idcode_to_name(GS(id->name)), id->name + 2);
1304                         continue;
1305                 }
1306
1307                 ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
1308
1309                 /* return success */
1310                 ret++;
1311         }
1312
1313         /* return success/failure */
1314         return ret;
1315 }
1316
1317 /* ******************************************* */
1318 /* KEYFRAME MODIFICATION */
1319
1320 /* mode for commonkey_modifykey */
1321 enum {
1322         COMMONKEY_MODE_INSERT = 0,
1323         COMMONKEY_MODE_DELETE,
1324 } /*eCommonModifyKey_Modes*/;
1325
1326 /* Polling callback for use with ANIM_*_keyframe() operators
1327  * This is based on the standard ED_operator_areaactive callback,
1328  * except that it does special checks for a few spacetypes too...
1329  */
1330 static int modify_key_op_poll(bContext *C)
1331 {
1332         ScrArea *sa = CTX_wm_area(C);
1333         Scene *scene = CTX_data_scene(C);
1334
1335         /* if no area or active scene */
1336         if (ELEM(NULL, sa, scene))
1337                 return false;
1338
1339         /* should be fine */
1340         return true;
1341 }
1342
1343 /* Insert Key Operator ------------------------ */
1344
1345 static int insert_key_exec(bContext *C, wmOperator *op)
1346 {
1347         Scene *scene = CTX_data_scene(C);
1348         Object *obedit = CTX_data_edit_object(C);
1349         bool ob_edit_mode = false;
1350         KeyingSet *ks = NULL;
1351         int type = RNA_enum_get(op->ptr, "type");
1352         float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
1353         short success;
1354
1355         /* type is the Keying Set the user specified to use when calling the operator:
1356          *      - type == 0: use scene's active Keying Set
1357          *      - type > 0: use a user-defined Keying Set from the active scene
1358          *      - type < 0: use a builtin Keying Set
1359          */
1360         if (type == 0)
1361                 type = scene->active_keyingset;
1362         if (type > 0)
1363                 ks = BLI_findlink(&scene->keyingsets, type - 1);
1364         else
1365                 ks = BLI_findlink(&builtin_keyingsets, -type - 1);
1366
1367         /* report failures */
1368         if (ks == NULL) {
1369                 BKE_report(op->reports, RPT_ERROR, "No active keying set");
1370                 return OPERATOR_CANCELLED;
1371         }
1372
1373         /* exit the edit mode to make sure that those object data properties that have been
1374          * updated since the last switching to the edit mode will be keyframed correctly
1375          */
1376         if (obedit && ANIM_keyingset_find_id(ks, (ID *)obedit->data)) {
1377                 ED_object_mode_toggle(C, OB_MODE_EDIT);
1378                 ob_edit_mode = true;
1379         }
1380
1381         /* try to insert keyframes for the channels specified by KeyingSet */
1382         success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
1383         if (G.debug & G_DEBUG)
1384                 BKE_reportf(op->reports, RPT_INFO, "Keying set '%s' - successfully added %d keyframes", ks->name, success);
1385
1386         /* restore the edit mode if necessary */
1387         if (ob_edit_mode) {
1388                 ED_object_mode_toggle(C, OB_MODE_EDIT);
1389         }
1390
1391         /* report failure or do updates? */
1392         if (success == MODIFYKEY_INVALID_CONTEXT) {
1393                 BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
1394                 return OPERATOR_CANCELLED;
1395         }
1396         else if (success) {
1397                 /* if the appropriate properties have been set, make a note that we've inserted something */
1398                 if (RNA_boolean_get(op->ptr, "confirm_success"))
1399                         BKE_reportf(op->reports, RPT_INFO, "Successfully added %d keyframes for keying set '%s'", success, ks->name);
1400
1401                 /* send notifiers that keyframes have been changed */
1402                 WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
1403         }
1404         else
1405                 BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes");
1406
1407         return OPERATOR_FINISHED;
1408 }
1409
1410 void ANIM_OT_keyframe_insert(wmOperatorType *ot)
1411 {
1412         PropertyRNA *prop;
1413
1414         /* identifiers */
1415         ot->name = "Insert Keyframe";
1416         ot->idname = "ANIM_OT_keyframe_insert";
1417         ot->description = "Insert keyframes on the current frame for all properties in the specified Keying Set";
1418
1419         /* callbacks */
1420         ot->exec = insert_key_exec;
1421         ot->poll = modify_key_op_poll;
1422
1423         /* flags */
1424         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1425
1426         /* keyingset to use (dynamic enum) */
1427         prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
1428         RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
1429         RNA_def_property_flag(prop, PROP_HIDDEN);
1430         ot->prop = prop;
1431
1432         /* confirm whether a keyframe was added by showing a popup
1433          *      - by default, this is enabled, since this operator is assumed to be called independently
1434          */
1435         prop = RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Insert",
1436                                "Show a popup when the keyframes get successfully added");
1437         RNA_def_property_flag(prop, PROP_HIDDEN);
1438 }
1439
1440 /* Insert Key Operator (With Menu) ------------------------ */
1441 /* This operator checks if a menu should be shown for choosing the KeyingSet to use,
1442  * then calls the menu if necessary before
1443  */
1444
1445 static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1446 {
1447         Scene *scene = CTX_data_scene(C);
1448
1449         /* if prompting or no active Keying Set, show the menu */
1450         if ((scene->active_keyingset == 0) || RNA_boolean_get(op->ptr, "always_prompt")) {
1451                 uiPopupMenu *pup;
1452                 uiLayout *layout;
1453
1454                 /* call the menu, which will call this operator again, hence the canceled */
1455                 pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
1456                 layout = UI_popup_menu_layout(pup);
1457                 uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type");
1458                 UI_popup_menu_end(C, pup);
1459
1460                 return OPERATOR_INTERFACE;
1461         }
1462         else {
1463                 /* just call the exec() on the active keyingset */
1464                 RNA_enum_set(op->ptr, "type", 0);
1465                 RNA_boolean_set(op->ptr, "confirm_success", true);
1466
1467                 return op->type->exec(C, op);
1468         }
1469 }
1470
1471 void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot)
1472 {
1473         PropertyRNA *prop;
1474
1475         /* identifiers */
1476         ot->name = "Insert Keyframe Menu";
1477         ot->idname = "ANIM_OT_keyframe_insert_menu";
1478         ot->description = "Insert Keyframes for specified Keying Set, with menu of available Keying Sets if undefined";
1479
1480         /* callbacks */
1481         ot->invoke = insert_key_menu_invoke;
1482         ot->exec = insert_key_exec;
1483         ot->poll = ED_operator_areaactive;
1484
1485         /* flags */
1486         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1487
1488         /* keyingset to use (dynamic enum) */
1489         prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
1490         RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
1491         RNA_def_property_flag(prop, PROP_HIDDEN);
1492         ot->prop = prop;
1493
1494         /* confirm whether a keyframe was added by showing a popup
1495          *      - by default, this is disabled so that if a menu is shown, this doesn't come up too
1496          */
1497         // XXX should this just be always on?
1498         prop = RNA_def_boolean(ot->srna, "confirm_success", 0, "Confirm Successful Insert",
1499                                "Show a popup when the keyframes get successfully added");
1500         RNA_def_property_flag(prop, PROP_HIDDEN);
1501
1502         /* whether the menu should always be shown
1503          *      - by default, the menu should only be shown when there is no active Keying Set (2.5 behavior),
1504          *        although in some cases it might be useful to always shown (pre 2.5 behavior)
1505          */
1506         prop = RNA_def_boolean(ot->srna, "always_prompt", 0, "Always Show Menu", "");
1507         RNA_def_property_flag(prop, PROP_HIDDEN);
1508 }
1509
1510 /* Delete Key Operator ------------------------ */
1511
1512 static int delete_key_exec(bContext *C, wmOperator *op)
1513 {
1514         Scene *scene = CTX_data_scene(C);
1515         KeyingSet *ks = NULL;
1516         int type = RNA_enum_get(op->ptr, "type");
1517         float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
1518         short success;
1519
1520         /* type is the Keying Set the user specified to use when calling the operator:
1521          *      - type == 0: use scene's active Keying Set
1522          *      - type > 0: use a user-defined Keying Set from the active scene
1523          *      - type < 0: use a builtin Keying Set
1524          */
1525         if (type == 0)
1526                 type = scene->active_keyingset;
1527         if (type > 0)
1528                 ks = BLI_findlink(&scene->keyingsets, type - 1);
1529         else
1530                 ks = BLI_findlink(&builtin_keyingsets, -type - 1);
1531
1532         /* report failure */
1533         if (ks == NULL) {
1534                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
1535                 return OPERATOR_CANCELLED;
1536         }
1537
1538         /* try to delete keyframes for the channels specified by KeyingSet */
1539         success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
1540         if (G.debug & G_DEBUG)
1541                 printf("KeyingSet '%s' - Successfully removed %d Keyframes\n", ks->name, success);
1542
1543         /* report failure or do updates? */
1544         if (success == MODIFYKEY_INVALID_CONTEXT) {
1545                 BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
1546                 return OPERATOR_CANCELLED;
1547         }
1548         else if (success) {
1549                 /* if the appropriate properties have been set, make a note that we've inserted something */
1550                 if (RNA_boolean_get(op->ptr, "confirm_success"))
1551                         BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", success, ks->name);
1552
1553                 /* send notifiers that keyframes have been changed */
1554                 WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
1555         }
1556         else
1557                 BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes");
1558
1559         return OPERATOR_FINISHED;
1560 }
1561
1562 void ANIM_OT_keyframe_delete(wmOperatorType *ot)
1563 {
1564         PropertyRNA *prop;
1565
1566         /* identifiers */
1567         ot->name = "Delete Keying-Set Keyframe";
1568         ot->idname = "ANIM_OT_keyframe_delete";
1569         ot->description = "Delete keyframes on the current frame for all properties in the specified Keying Set";
1570
1571         /* callbacks */
1572         ot->exec = delete_key_exec;
1573         ot->poll = modify_key_op_poll;
1574
1575         /* flags */
1576         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1577
1578         /* keyingset to use (dynamic enum) */
1579         prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
1580         RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
1581         RNA_def_property_flag(prop, PROP_HIDDEN);
1582         ot->prop = prop;
1583
1584         /* confirm whether a keyframe was added by showing a popup
1585          *      - by default, this is enabled, since this operator is assumed to be called independently
1586          */
1587         RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Delete",
1588                         "Show a popup when the keyframes get successfully removed");
1589 }
1590
1591 /* Delete Key Operator ------------------------ */
1592 /* NOTE: Although this version is simpler than the more generic version for KeyingSets,
1593  * it is more useful for animators working in the 3D view.
1594  */
1595
1596 static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
1597 {
1598         bool changed = false;
1599
1600         CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
1601         {
1602                 /* just those in active action... */
1603                 if ((ob->adt) && (ob->adt->action)) {
1604                         AnimData *adt = ob->adt;
1605                         bAction *act = adt->action;
1606                         FCurve *fcu, *fcn;
1607
1608                         for (fcu = act->curves.first; fcu; fcu = fcn) {
1609                                 bool can_delete = false;
1610
1611                                 fcn = fcu->next;
1612
1613                                 /* in pose mode, only delete the F-Curve if it belongs to a selected bone */
1614                                 if (ob->mode & OB_MODE_POSE) {
1615                                         if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) {
1616                                                 bPoseChannel *pchan;
1617                                                 char *bone_name;
1618
1619                                                 /* get bone-name, and check if this bone is selected */
1620                                                 bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
1621                                                 pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
1622                                                 if (bone_name) MEM_freeN(bone_name);
1623
1624                                                 /* delete if bone is selected*/
1625                                                 if ((pchan) && (pchan->bone)) {
1626                                                         if (pchan->bone->flag & BONE_SELECTED)
1627                                                                 can_delete = true;
1628                                                 }
1629                                         }
1630                                 }
1631                                 else {
1632                                         /* object mode - all of Object's F-Curves are affected */
1633                                         can_delete = true;
1634                                 }
1635
1636                                 /* delete F-Curve completely */
1637                                 if (can_delete) {
1638                                         ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
1639                                         DEG_id_tag_update(&ob->id, OB_RECALC_OB);
1640                                         changed = true;
1641                                 }
1642                         }
1643                 }
1644         }
1645         CTX_DATA_END;
1646
1647         if (!changed) {
1648                 return OPERATOR_CANCELLED;
1649         }
1650
1651         /* send updates */
1652         WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
1653
1654         return OPERATOR_FINISHED;
1655 }
1656
1657 void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot)
1658 {
1659         /* identifiers */
1660         ot->name = "Remove Animation";
1661         ot->description = "Remove all keyframe animation for selected objects";
1662         ot->idname = "ANIM_OT_keyframe_clear_v3d";
1663
1664         /* callbacks */
1665         ot->invoke = WM_operator_confirm;
1666         ot->exec = clear_anim_v3d_exec;
1667
1668         ot->poll = ED_operator_areaactive;
1669
1670         /* flags */
1671         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1672 }
1673
1674
1675 static int delete_key_v3d_exec(bContext *C, wmOperator *op)
1676 {
1677         Scene *scene = CTX_data_scene(C);
1678         float cfra = (float)CFRA;
1679
1680         CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
1681         {
1682                 ID *id = &ob->id;
1683                 int success = 0;
1684
1685                 /* just those in active action... */
1686                 if ((ob->adt) && (ob->adt->action)) {
1687                         AnimData *adt = ob->adt;
1688                         bAction *act = adt->action;
1689                         FCurve *fcu, *fcn;
1690                         const float cfra_unmap = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
1691
1692                         for (fcu = act->curves.first; fcu; fcu = fcn) {
1693                                 fcn = fcu->next;
1694
1695                                 /* don't touch protected F-Curves */
1696                                 if (BKE_fcurve_is_protected(fcu)) {
1697                                         BKE_reportf(op->reports, RPT_WARNING,
1698                                                     "Not deleting keyframe for locked F-Curve '%s', object '%s'",
1699                                                     fcu->rna_path, id->name + 2);
1700                                         continue;
1701                                 }
1702
1703                                 /* special exception for bones, as this makes this operator more convenient to use
1704                                  * NOTE: This is only done in pose mode. In object mode, we're dealign with the entire object.
1705                                  */
1706                                 if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) {
1707                                         bPoseChannel *pchan;
1708                                         char *bone_name;
1709
1710                                         /* get bone-name, and check if this bone is selected */
1711                                         bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
1712                                         pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
1713                                         if (bone_name) MEM_freeN(bone_name);
1714
1715                                         /* skip if bone is not selected */
1716                                         if ((pchan) && (pchan->bone)) {
1717                                                 /* bones are only selected/editable if visible... */
1718                                                 bArmature *arm = (bArmature *)ob->data;
1719
1720                                                 /* skipping - not visible on currently visible layers */
1721                                                 if ((arm->layer & pchan->bone->layer) == 0)
1722                                                         continue;
1723                                                 /* skipping - is currently hidden */
1724                                                 if (pchan->bone->flag & BONE_HIDDEN_P)
1725                                                         continue;
1726
1727                                                 /* selection flag... */
1728                                                 if ((pchan->bone->flag & BONE_SELECTED) == 0)
1729                                                         continue;
1730                                         }
1731                                 }
1732
1733                                 /* delete keyframes on current frame
1734                                  * WARNING: this can delete the next F-Curve, hence the "fcn" copying
1735                                  */
1736                                 success += delete_keyframe_fcurve(adt, fcu, cfra_unmap);
1737                         }
1738                 }
1739
1740                 /* report success (or failure) */
1741                 if (success)
1742                         BKE_reportf(op->reports, RPT_INFO, "Object '%s' successfully had %d keyframes removed", id->name + 2, success);
1743                 else
1744                         BKE_reportf(op->reports, RPT_ERROR, "No keyframes removed from Object '%s'", id->name + 2);
1745
1746                 DEG_id_tag_update(&ob->id, OB_RECALC_OB);
1747         }
1748         CTX_DATA_END;
1749
1750         /* send updates */
1751         WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
1752
1753         return OPERATOR_FINISHED;
1754 }
1755
1756 void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot)
1757 {
1758         /* identifiers */
1759         ot->name = "Delete Keyframe";
1760         ot->description = "Remove keyframes on current frame for selected objects and bones";
1761         ot->idname = "ANIM_OT_keyframe_delete_v3d";
1762
1763         /* callbacks */
1764         ot->invoke = WM_operator_confirm;
1765         ot->exec = delete_key_v3d_exec;
1766
1767         ot->poll = ED_operator_areaactive;
1768
1769         /* flags */
1770         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1771 }
1772
1773
1774 /* Insert Key Button Operator ------------------------ */
1775
1776 static int insert_key_button_exec(bContext *C, wmOperator *op)
1777 {
1778         Depsgraph *depsgraph = CTX_data_depsgraph(C);
1779         Main *bmain = CTX_data_main(C);
1780         Scene *scene = CTX_data_scene(C);
1781         ToolSettings *ts = scene->toolsettings;
1782         PointerRNA ptr = {{NULL}};
1783         PropertyRNA *prop = NULL;
1784         char *path;
1785         uiBut *but;
1786         float cfra = (float)CFRA;
1787         short success = 0;
1788         int index;
1789         const bool all = RNA_boolean_get(op->ptr, "all");
1790         eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
1791
1792
1793         /* flags for inserting keyframes */
1794         flag = ANIM_get_keyframing_flags(scene, 1);
1795
1796         /* try to insert keyframe using property retrieved from UI */
1797         if (!(but = UI_context_active_but_prop_get(C, &ptr, &prop, &index))) {
1798                 /* pass event on if no active button found */
1799                 return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
1800         }
1801
1802         if ((ptr.id.data && ptr.data && prop) && RNA_property_animateable(&ptr, prop)) {
1803                 if (ptr.type == &RNA_NlaStrip) {
1804                         /* Handle special properties for NLA Strips, whose F-Curves are stored on the
1805                          * strips themselves. These are stored separately or else the properties will
1806                          * not have any effect.
1807                          */
1808                         NlaStrip *strip = (NlaStrip *)ptr.data;
1809                         FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
1810
1811                         if (fcu) {
1812                                 success = insert_keyframe_direct(depsgraph, op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, 0);
1813                         }
1814                         else {
1815                                 BKE_report(op->reports, RPT_ERROR,
1816                                            "This property cannot be animated as it will not get updated correctly");
1817                         }
1818                 }
1819                 else if (UI_but_flag_is_set(but, UI_BUT_DRIVEN)) {
1820                         /* Driven property - Find driver */
1821                         FCurve *fcu;
1822                         bool driven, special;
1823
1824                         fcu = rna_get_fcurve_context_ui(C, &ptr, prop, index, NULL, NULL, &driven, &special);
1825
1826                         if (fcu && driven) {
1827                                 success = insert_keyframe_direct(depsgraph, op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, INSERTKEY_DRIVER);
1828                         }
1829                 }
1830                 else {
1831                         /* standard properties */
1832                         path = RNA_path_from_ID_to_property(&ptr, prop);
1833
1834                         if (path) {
1835                                 const char *identifier = RNA_property_identifier(prop);
1836                                 const char *group = NULL;
1837
1838                                 /* Special exception for keyframing transforms:
1839                                  * Set "group" for this manually, instead of having them appearing at the bottom (ungrouped)
1840                                  * part of the channels list. Leaving these ungrouped is not a nice user behaviour in this case.
1841                                  *
1842                                  * TODO: Perhaps we can extend this behaviour in future for other properties...
1843                                  */
1844                                 if (ptr.type == &RNA_PoseBone) {
1845                                         bPoseChannel *pchan = (bPoseChannel *)ptr.data;
1846                                         group = pchan->name;
1847                                 }
1848                                 else if ((ptr.type == &RNA_Object) &&
1849                                          (strstr(identifier, "location") || strstr(identifier, "rotation") || strstr(identifier, "scale")))
1850                                 {
1851                                         /* NOTE: Keep this label in sync with the "ID" case in
1852                                          * keyingsets_utils.py :: get_transform_generators_base_info()
1853                                          */
1854                                         group = "Object Transforms";
1855                                 }
1856
1857
1858                                 if (all) {
1859                                         /* -1 indicates operating on the entire array (or the property itself otherwise) */
1860                                         index = -1;
1861                                 }
1862
1863                                 success = insert_keyframe(bmain, depsgraph, op->reports, ptr.id.data, NULL, group, path, index, cfra, ts->keyframe_type, flag);
1864
1865                                 MEM_freeN(path);
1866                         }
1867                         else {
1868                                 BKE_report(op->reports, RPT_WARNING,
1869                                            "Failed to resolve path to property, "
1870                                            "try manually specifying this using a Keying Set instead");
1871                         }
1872                 }
1873         }
1874         else {
1875                 if (prop && !RNA_property_animateable(&ptr, prop)) {
1876                         BKE_reportf(op->reports, RPT_WARNING,
1877                                    "\"%s\" property cannot be animated",
1878                                    RNA_property_identifier(prop));
1879                 }
1880                 else {
1881                         BKE_reportf(op->reports, RPT_WARNING,
1882                                     "Button doesn't appear to have any property information attached (ptr.data = %p, prop = %p)",
1883                                     (void *)ptr.data, (void *)prop);
1884                 }
1885         }
1886
1887         if (success) {
1888                 /* send updates */
1889                 UI_context_update_anim_flag(C);
1890
1891                 /* send notifiers that keyframes have been changed */
1892                 WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
1893         }
1894
1895         return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1896 }
1897
1898 void ANIM_OT_keyframe_insert_button(wmOperatorType *ot)
1899 {
1900         /* identifiers */
1901         ot->name = "Insert Keyframe (Buttons)";
1902         ot->idname = "ANIM_OT_keyframe_insert_button";
1903         ot->description = "Insert a keyframe for current UI-active property";
1904
1905         /* callbacks */
1906         ot->exec = insert_key_button_exec;
1907         ot->poll = modify_key_op_poll;
1908
1909         /* flags */
1910         ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
1911
1912         /* properties */
1913         RNA_def_boolean(ot->srna, "all", 1, "All", "Insert a keyframe for all element of the array");
1914 }
1915
1916 /* Delete Key Button Operator ------------------------ */
1917
1918 static int delete_key_button_exec(bContext *C, wmOperator *op)
1919 {
1920         Scene *scene = CTX_data_scene(C);
1921         PointerRNA ptr = {{NULL}};
1922         PropertyRNA *prop = NULL;
1923         char *path;
1924         float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
1925         short success = 0;
1926         int index;
1927         const bool all = RNA_boolean_get(op->ptr, "all");
1928
1929         /* try to insert keyframe using property retrieved from UI */
1930         if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
1931                 /* pass event on if no active button found */
1932                 return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
1933         }
1934
1935         if (ptr.id.data && ptr.data && prop) {
1936                 if (BKE_nlastrip_has_curves_for_property(&ptr, prop)) {
1937                         /* Handle special properties for NLA Strips, whose F-Curves are stored on the
1938                          * strips themselves. These are stored separately or else the properties will
1939                          * not have any effect.
1940                          */
1941                         ID *id = ptr.id.data;
1942                         NlaStrip *strip = (NlaStrip *)ptr.data;
1943                         FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), 0);
1944
1945                         if (fcu) {
1946                                 if (BKE_fcurve_is_protected(fcu)) {
1947                                         BKE_reportf(op->reports, RPT_WARNING,
1948                                                     "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
1949                                                     strip->name, BKE_idcode_to_name(GS(id->name)), id->name + 2);
1950                                 }
1951                                 else {
1952                                         /* remove the keyframe directly
1953                                          * NOTE: cannot use delete_keyframe_fcurve(), as that will free the curve,
1954                                          *       and delete_keyframe() expects the FCurve to be part of an action
1955                                          */
1956                                         bool found = false;
1957                                         int i;
1958
1959                                         /* try to find index of beztriple to get rid of */
1960                                         i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
1961                                         if (found) {
1962                                                 /* delete the key at the index (will sanity check + do recalc afterwards) */
1963                                                 delete_fcurve_key(fcu, i, 1);
1964                                                 success = true;
1965                                         }
1966                                 }
1967                         }
1968                 }
1969                 else {
1970                         /* standard properties */
1971                         path = RNA_path_from_ID_to_property(&ptr, prop);
1972
1973                         if (path) {
1974                                 if (all) {
1975                                         /* -1 indicates operating on the entire array (or the property itself otherwise) */
1976                                         index = -1;
1977                                 }
1978
1979                                 success = delete_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index, cfra, 0);
1980                                 MEM_freeN(path);
1981                         }
1982                         else if (G.debug & G_DEBUG)
1983                                 printf("Button Delete-Key: no path to property\n");
1984                 }
1985         }
1986         else if (G.debug & G_DEBUG) {
1987                 printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
1988         }
1989
1990
1991         if (success) {
1992                 /* send updates */
1993                 UI_context_update_anim_flag(C);
1994
1995                 /* send notifiers that keyframes have been changed */
1996                 WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
1997         }
1998
1999         return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
2000 }
2001
2002 void ANIM_OT_keyframe_delete_button(wmOperatorType *ot)
2003 {
2004         /* identifiers */
2005         ot->name = "Delete Keyframe (Buttons)";
2006         ot->idname = "ANIM_OT_keyframe_delete_button";
2007         ot->description = "Delete current keyframe of current UI-active property";
2008
2009         /* callbacks */
2010         ot->exec = delete_key_button_exec;
2011         ot->poll = modify_key_op_poll;
2012
2013         /* flags */
2014         ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
2015
2016         /* properties */
2017         RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyframes from all elements of the array");
2018 }
2019
2020
2021 /* Clear Key Button Operator ------------------------ */
2022
2023 static int clear_key_button_exec(bContext *C, wmOperator *op)
2024 {
2025         PointerRNA ptr = {{NULL}};
2026         PropertyRNA *prop = NULL;
2027         char *path;
2028         short success = 0;
2029         int index;
2030         const bool all = RNA_boolean_get(op->ptr, "all");
2031
2032         /* try to insert keyframe using property retrieved from UI */
2033         if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
2034                 /* pass event on if no active button found */
2035                 return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
2036         }
2037
2038         if (ptr.id.data && ptr.data && prop) {
2039                 path = RNA_path_from_ID_to_property(&ptr, prop);
2040
2041                 if (path) {
2042                         if (all) {
2043                                 /* -1 indicates operating on the entire array (or the property itself otherwise) */
2044                                 index = -1;
2045                         }
2046
2047                         success += clear_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index, 0);
2048                         MEM_freeN(path);
2049                 }
2050                 else if (G.debug & G_DEBUG)
2051                         printf("Button Clear-Key: no path to property\n");
2052         }
2053         else if (G.debug & G_DEBUG) {
2054                 printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
2055         }
2056
2057
2058         if (success) {
2059                 /* send updates */
2060                 UI_context_update_anim_flag(C);
2061
2062                 /* send notifiers that keyframes have been changed */
2063                 WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
2064         }
2065
2066         return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
2067 }
2068
2069 void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
2070 {
2071         /* identifiers */
2072         ot->name = "Clear Keyframe (Buttons)";
2073         ot->idname = "ANIM_OT_keyframe_clear_button";
2074         ot->description = "Clear all keyframes on the currently active property";
2075
2076         /* callbacks */
2077         ot->exec = clear_key_button_exec;
2078         ot->poll = modify_key_op_poll;
2079
2080         /* flags */
2081         ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
2082
2083         /* properties */
2084         RNA_def_boolean(ot->srna, "all", 1, "All", "Clear keyframes from all elements of the array");
2085 }
2086
2087 /* ******************************************* */
2088 /* AUTO KEYFRAME */
2089
2090 bool autokeyframe_cfra_can_key(Scene *scene, ID *id)
2091 {
2092         float cfra = (float)CFRA; // XXX for now, this will do
2093
2094         /* only filter if auto-key mode requires this */
2095         if (IS_AUTOKEY_ON(scene) == 0)
2096                 return false;
2097
2098         if (IS_AUTOKEY_MODE(scene, EDITKEYS)) {
2099                 /* Replace Mode:
2100                  * For whole block, only key if there's a keyframe on that frame already
2101                  * This is a valid assumption when we're blocking + tweaking
2102                  */
2103                 return id_frame_has_keyframe(id, cfra, ANIMFILTER_KEYS_LOCAL);
2104         }
2105         else {
2106                 /* Normal Mode (or treat as being normal mode):
2107                  *
2108                  * Just in case the flags aren't set properly (i.e. only on/off is set, without a mode)
2109                  * let's set the "normal" flag too, so that it will all be sane everywhere...
2110                  */
2111                 scene->toolsettings->autokey_mode = AUTOKEY_MODE_NORMAL;
2112
2113                 /* Can insert anytime we like... */
2114                 return true;
2115         }
2116 }
2117
2118 /* ******************************************* */
2119 /* KEYFRAME DETECTION */
2120
2121 /* --------------- API/Per-Datablock Handling ------------------- */
2122
2123 /* Checks if some F-Curve has a keyframe for a given frame */
2124 bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
2125 {
2126         /* quick sanity check */
2127         if (ELEM(NULL, fcu, fcu->bezt))
2128                 return false;
2129
2130         /* we either include all regardless of muting, or only non-muted  */
2131         if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) {
2132                 bool replace;
2133                 int i = binarysearch_bezt_index(fcu->bezt, frame, fcu->totvert, &replace);
2134
2135                 /* binarysearch_bezt_index will set replace to be 0 or 1
2136                  * - obviously, 1 represents a match
2137                  */
2138                 if (replace) {
2139                         /* sanity check: 'i' may in rare cases exceed arraylen */
2140                         if ((i >= 0) && (i < fcu->totvert))
2141                                 return true;
2142                 }
2143         }
2144
2145         return false;
2146 }
2147
2148 /* Checks whether an Action has a keyframe for a given frame
2149  * Since we're only concerned whether a keyframe exists, we can simply loop until a match is found...
2150  */
2151 static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
2152 {
2153         FCurve *fcu;
2154
2155         /* can only find if there is data */
2156         if (act == NULL)
2157                 return false;
2158
2159         /* if only check non-muted, check if muted */
2160         if ((filter & ANIMFILTER_KEYS_MUTED) || (act->flag & ACT_MUTED))
2161                 return false;
2162
2163         /* loop over F-Curves, using binary-search to try to find matches
2164          *      - this assumes that keyframes are only beztriples
2165          */
2166         for (fcu = act->curves.first; fcu; fcu = fcu->next) {
2167                 /* only check if there are keyframes (currently only of type BezTriple) */
2168                 if (fcu->bezt && fcu->totvert) {
2169                         if (fcurve_frame_has_keyframe(fcu, frame, filter))
2170                                 return true;
2171                 }
2172         }
2173
2174         /* nothing found */
2175         return false;
2176 }
2177
2178 /* Checks whether an Object has a keyframe for a given frame */
2179 static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
2180 {
2181         /* error checking */
2182         if (ob == NULL)
2183                 return false;
2184
2185         /* check own animation data - specifically, the action it contains */
2186         if ((ob->adt) && (ob->adt->action)) {
2187                 /* T41525 - When the active action is a NLA strip being edited,
2188                  * we need to correct the frame number to "look inside" the
2189                  * remapped action
2190                  */
2191                 float ob_frame = BKE_nla_tweakedit_remap(ob->adt, frame, NLATIME_CONVERT_UNMAP);
2192
2193                 if (action_frame_has_keyframe(ob->adt->action, ob_frame, filter))
2194                         return true;
2195         }
2196
2197         /* try shapekey keyframes (if available, and allowed by filter) */
2198         if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOSKEY)) {
2199                 Key *key = BKE_key_from_object(ob);
2200
2201                 /* shapekeys can have keyframes ('Relative Shape Keys')
2202                  * or depend on time (old 'Absolute Shape Keys')
2203                  */
2204
2205                 /* 1. test for relative (with keyframes) */
2206                 if (id_frame_has_keyframe((ID *)key, frame, filter))
2207                         return true;
2208
2209                 /* 2. test for time */
2210                 /* TODO... yet to be implemented (this feature may evolve before then anyway) */
2211         }
2212
2213         /* try materials */
2214         if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOMAT)) {
2215                 /* if only active, then we can skip a lot of looping */
2216                 if (filter & ANIMFILTER_KEYS_ACTIVE) {
2217                         Material *ma = give_current_material(ob, (ob->actcol + 1));
2218
2219                         /* we only retrieve the active material... */
2220                         if (id_frame_has_keyframe((ID *)ma, frame, filter))
2221                                 return true;
2222                 }
2223                 else {
2224                         int a;
2225
2226                         /* loop over materials */
2227                         for (a = 0; a < ob->totcol; a++) {
2228                                 Material *ma = give_current_material(ob, a + 1);
2229
2230                                 if (id_frame_has_keyframe((ID *)ma, frame, filter))
2231                                         return true;
2232                         }
2233                 }
2234         }
2235
2236         /* nothing found */
2237         return false;
2238 }
2239
2240 /* --------------- API ------------------- */
2241
2242 /* Checks whether a keyframe exists for the given ID-block one the given frame */
2243 bool id_frame_has_keyframe(ID *id, float frame, short filter)
2244 {
2245         /* sanity checks */
2246         if (id == NULL)
2247                 return false;
2248
2249         /* perform special checks for 'macro' types */
2250         switch (GS(id->name)) {
2251                 case ID_OB: /* object */
2252                         return object_frame_has_keyframe((Object *)id, frame, filter);
2253 #if 0
2254                 // XXX TODO... for now, just use 'normal' behavior
2255                 case ID_SCE: /* scene */
2256                         break;
2257 #endif
2258                 default:  /* 'normal type' */
2259                 {
2260                         AnimData *adt = BKE_animdata_from_id(id);
2261
2262                         /* only check keyframes in active action */
2263                         if (adt)
2264                                 return action_frame_has_keyframe(adt->action, frame, filter);
2265                         break;
2266                 }
2267         }
2268
2269
2270         /* no keyframe found */
2271         return false;
2272 }
2273
2274 /* ************************************************** */
2275
2276 bool ED_autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks)
2277 {
2278         /* auto keyframing */
2279         if (autokeyframe_cfra_can_key(scene, &ob->id)) {
2280                 ListBase dsources = {NULL, NULL};
2281
2282                 /* now insert the keyframe(s) using the Keying Set
2283                  *      1) add datasource override for the Object
2284                  *      2) insert keyframes
2285                  *      3) free the extra info
2286                  */
2287                 ANIM_relative_keyingset_add_source(&dsources, &ob->id, NULL, NULL);
2288                 ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
2289                 BLI_freelistN(&dsources);
2290
2291                 return true;
2292         }
2293         else {
2294                 return false;
2295         }
2296 }
2297
2298 bool ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks)
2299 {
2300         if (autokeyframe_cfra_can_key(scene, &ob->id)) {
2301                 ListBase dsources = {NULL, NULL};
2302
2303                 /* now insert the keyframe(s) using the Keying Set
2304                  *      1) add datasource override for the PoseChannel
2305                  *      2) insert keyframes
2306                  *      3) free the extra info
2307                  */
2308                 ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan);
2309                 ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
2310                 BLI_freelistN(&dsources);
2311
2312                 /* clear any unkeyed tags */
2313                 if (pchan->bone) {
2314                         pchan->bone->flag &= ~BONE_UNKEYED;
2315                 }
2316
2317                 return true;
2318         }
2319         else {
2320                 /* add unkeyed tags */
2321                 if (pchan->bone) {
2322                         pchan->bone->flag |= BONE_UNKEYED;
2323                 }
2324
2325                 return false;
2326         }
2327 }