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