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