90651a55a42720afed024ae6e2fb15dca766421b
[blender.git] / source / blender / editors / animation / keyingsets.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edanimation
22  */
23
24 #include <stdio.h>
25 #include <stddef.h>
26 #include <string.h>
27 #include <math.h>
28 #include <float.h>
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BLI_blenlib.h"
33 #include "BLI_utildefines.h"
34
35 #include "DNA_anim_types.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_object_types.h"
38
39 #include "BKE_main.h"
40 #include "BKE_animsys.h"
41 #include "BKE_context.h"
42 #include "BKE_report.h"
43
44 #include "DEG_depsgraph.h"
45
46 #include "ED_keyframing.h"
47 #include "ED_screen.h"
48
49 #include "UI_interface.h"
50 #include "UI_resources.h"
51
52 #include "WM_api.h"
53 #include "WM_types.h"
54
55 #include "RNA_access.h"
56 #include "RNA_define.h"
57 #include "RNA_enum_types.h"
58
59 #include "anim_intern.h"
60
61 /* ************************************************** */
62 /* KEYING SETS - OPERATORS (for use in UI panels) */
63 /* These operators are really duplication of existing functionality, but just for completeness,
64  * they're here too, and will give the basic data needed...
65  */
66
67 /* poll callback for adding default KeyingSet */
68 static bool keyingset_poll_default_add(bContext *C)
69 {
70   /* as long as there's an active Scene, it's fine */
71   return (CTX_data_scene(C) != NULL);
72 }
73
74 /* poll callback for editing active KeyingSet */
75 static bool keyingset_poll_active_edit(bContext *C)
76 {
77   Scene *scene = CTX_data_scene(C);
78
79   if (scene == NULL)
80     return 0;
81
82   /* there must be an active KeyingSet (and KeyingSets) */
83   return ((scene->active_keyingset > 0) && (scene->keyingsets.first));
84 }
85
86 /* poll callback for editing active KeyingSet Path */
87 static bool keyingset_poll_activePath_edit(bContext *C)
88 {
89   Scene *scene = CTX_data_scene(C);
90   KeyingSet *ks;
91
92   if (scene == NULL)
93     return 0;
94   if (scene->active_keyingset <= 0)
95     return 0;
96   else
97     ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
98
99   /* there must be an active KeyingSet and an active path */
100   return ((ks) && (ks->paths.first) && (ks->active_path > 0));
101 }
102
103 /* Add a Default (Empty) Keying Set ------------------------- */
104
105 static int add_default_keyingset_exec(bContext *C, wmOperator *UNUSED(op))
106 {
107   Scene *scene = CTX_data_scene(C);
108   short flag = 0, keyingflag = 0;
109
110   /* validate flags
111    * - absolute KeyingSets should be created by default
112    */
113   flag |= KEYINGSET_ABSOLUTE;
114
115   /* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
116   keyingflag = ANIM_get_keyframing_flags(scene, 0);
117
118   /* call the API func, and set the active keyingset index */
119   BKE_keyingset_add(&scene->keyingsets, NULL, NULL, flag, keyingflag);
120
121   scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
122
123   /* send notifiers */
124   WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
125
126   return OPERATOR_FINISHED;
127 }
128
129 void ANIM_OT_keying_set_add(wmOperatorType *ot)
130 {
131   /* identifiers */
132   ot->name = "Add Empty Keying Set";
133   ot->idname = "ANIM_OT_keying_set_add";
134   ot->description = "Add a new (empty) Keying Set to the active Scene";
135
136   /* callbacks */
137   ot->exec = add_default_keyingset_exec;
138   ot->poll = keyingset_poll_default_add;
139 }
140
141 /* Remove 'Active' Keying Set ------------------------- */
142
143 static int remove_active_keyingset_exec(bContext *C, wmOperator *op)
144 {
145   Scene *scene = CTX_data_scene(C);
146   KeyingSet *ks;
147
148   /* verify the Keying Set to use:
149    * - use the active one
150    * - return error if it doesn't exist
151    */
152   if (scene->active_keyingset == 0) {
153     BKE_report(op->reports, RPT_ERROR, "No active keying set to remove");
154     return OPERATOR_CANCELLED;
155   }
156   else if (scene->active_keyingset < 0) {
157     BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set");
158     return OPERATOR_CANCELLED;
159   }
160   else
161     ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
162
163   /* free KeyingSet's data, then remove it from the scene */
164   BKE_keyingset_free(ks);
165   BLI_freelinkN(&scene->keyingsets, ks);
166
167   /* the active one should now be the previously second-to-last one */
168   scene->active_keyingset--;
169
170   /* send notifiers */
171   WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
172
173   return OPERATOR_FINISHED;
174 }
175
176 void ANIM_OT_keying_set_remove(wmOperatorType *ot)
177 {
178   /* identifiers */
179   ot->name = "Remove Active Keying Set";
180   ot->idname = "ANIM_OT_keying_set_remove";
181   ot->description = "Remove the active Keying Set";
182
183   /* callbacks */
184   ot->exec = remove_active_keyingset_exec;
185   ot->poll = keyingset_poll_active_edit;
186 }
187
188 /* Add Empty Keying Set Path ------------------------- */
189
190 static int add_empty_ks_path_exec(bContext *C, wmOperator *op)
191 {
192   Scene *scene = CTX_data_scene(C);
193   KeyingSet *ks;
194   KS_Path *ksp;
195
196   /* verify the Keying Set to use:
197    * - use the active one
198    * - return error if it doesn't exist
199    */
200   if (scene->active_keyingset == 0) {
201     BKE_report(op->reports, RPT_ERROR, "No active keying set to add empty path to");
202     return OPERATOR_CANCELLED;
203   }
204   else
205     ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
206
207   /* don't use the API method for this, since that checks on values... */
208   ksp = MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
209   BLI_addtail(&ks->paths, ksp);
210   ks->active_path = BLI_listbase_count(&ks->paths);
211
212   ksp->groupmode = KSP_GROUP_KSNAME;  // XXX?
213   ksp->idtype = ID_OB;
214   ksp->flag = KSP_FLAG_WHOLE_ARRAY;
215
216   return OPERATOR_FINISHED;
217 }
218
219 void ANIM_OT_keying_set_path_add(wmOperatorType *ot)
220 {
221   /* identifiers */
222   ot->name = "Add Empty Keying Set Path";
223   ot->idname = "ANIM_OT_keying_set_path_add";
224   ot->description = "Add empty path to active Keying Set";
225
226   /* callbacks */
227   ot->exec = add_empty_ks_path_exec;
228   ot->poll = keyingset_poll_active_edit;
229 }
230
231 /* Remove Active Keying Set Path ------------------------- */
232
233 static int remove_active_ks_path_exec(bContext *C, wmOperator *op)
234 {
235   Scene *scene = CTX_data_scene(C);
236   KeyingSet *ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
237
238   /* if there is a KeyingSet, find the nominated path to remove */
239   if (ks) {
240     KS_Path *ksp = BLI_findlink(&ks->paths, ks->active_path - 1);
241
242     if (ksp) {
243       /* remove the active path from the KeyingSet */
244       BKE_keyingset_free_path(ks, ksp);
245
246       /* the active path should now be the previously second-to-last active one */
247       ks->active_path--;
248     }
249     else {
250       BKE_report(op->reports, RPT_ERROR, "No active keying set path to remove");
251       return OPERATOR_CANCELLED;
252     }
253   }
254   else {
255     BKE_report(op->reports, RPT_ERROR, "No active keying set to remove a path from");
256     return OPERATOR_CANCELLED;
257   }
258
259   return OPERATOR_FINISHED;
260 }
261
262 void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
263 {
264   /* identifiers */
265   ot->name = "Remove Active Keying Set Path";
266   ot->idname = "ANIM_OT_keying_set_path_remove";
267   ot->description = "Remove active Path from active Keying Set";
268
269   /* callbacks */
270   ot->exec = remove_active_ks_path_exec;
271   ot->poll = keyingset_poll_activePath_edit;
272 }
273
274 /* ************************************************** */
275 /* KEYING SETS - OPERATORS (for use in UI menus) */
276
277 /* Add to KeyingSet Button Operator ------------------------ */
278
279 static int add_keyingset_button_exec(bContext *C, wmOperator *op)
280 {
281   Scene *scene = CTX_data_scene(C);
282   KeyingSet *ks = NULL;
283   PropertyRNA *prop = NULL;
284   PointerRNA ptr = {{NULL}};
285   char *path = NULL;
286   short success = 0;
287   int index = 0, pflag = 0;
288   const bool all = RNA_boolean_get(op->ptr, "all");
289
290   /* try to add to keyingset using property retrieved from UI */
291   if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
292     /* pass event on if no active button found */
293     return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
294   }
295
296   /* verify the Keying Set to use:
297    * - use the active one for now (more control over this can be added later)
298    * - add a new one if it doesn't exist
299    */
300   if (scene->active_keyingset == 0) {
301     short flag = 0, keyingflag = 0;
302
303     /* validate flags
304      * - absolute KeyingSets should be created by default
305      */
306     flag |= KEYINGSET_ABSOLUTE;
307
308     keyingflag |= ANIM_get_keyframing_flags(scene, 0);
309
310     if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
311       keyingflag |= INSERTKEY_XYZ2RGB;
312
313     /* call the API func, and set the active keyingset index */
314     ks = BKE_keyingset_add(
315         &scene->keyingsets, "ButtonKeyingSet", "Button Keying Set", flag, keyingflag);
316
317     scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
318   }
319   else if (scene->active_keyingset < 0) {
320     BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set");
321     return OPERATOR_CANCELLED;
322   }
323   else {
324     ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
325   }
326
327   /* check if property is able to be added */
328   if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
329     path = RNA_path_from_ID_to_property(&ptr, prop);
330
331     if (path) {
332       /* set flags */
333       if (all) {
334         pflag |= KSP_FLAG_WHOLE_ARRAY;
335
336         /* we need to set the index for this to 0, even though it may break in some cases, this is
337          * necessary if we want the entire array for most cases to get included without the user
338          * having to worry about where they clicked
339          */
340         index = 0;
341       }
342
343       /* add path to this setting */
344       BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
345       ks->active_path = BLI_listbase_count(&ks->paths);
346       success = 1;
347
348       /* free the temp path created */
349       MEM_freeN(path);
350     }
351   }
352
353   if (success) {
354     /* send updates */
355     WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
356
357     /* show notification/report header, so that users notice that something changed */
358     BKE_reportf(op->reports, RPT_INFO, "Property added to Keying Set: '%s'", ks->name);
359   }
360
361   return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
362 }
363
364 void ANIM_OT_keyingset_button_add(wmOperatorType *ot)
365 {
366   /* identifiers */
367   ot->name = "Add to Keying Set";
368   ot->idname = "ANIM_OT_keyingset_button_add";
369   ot->description = "Add current UI-active property to current keying set";
370
371   /* callbacks */
372   ot->exec = add_keyingset_button_exec;
373   //op->poll = ???
374
375   /* flags */
376   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
377
378   /* properties */
379   RNA_def_boolean(ot->srna, "all", 1, "All", "Add all elements of the array to a Keying Set");
380 }
381
382 /* Remove from KeyingSet Button Operator ------------------------ */
383
384 static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
385 {
386   Scene *scene = CTX_data_scene(C);
387   KeyingSet *ks = NULL;
388   PropertyRNA *prop = NULL;
389   PointerRNA ptr = {{NULL}};
390   char *path = NULL;
391   short success = 0;
392   int index = 0;
393
394   /* try to add to keyingset using property retrieved from UI */
395   if (UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
396     /* pass event on if no active button found */
397     return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
398   }
399
400   /* verify the Keying Set to use:
401    * - use the active one for now (more control over this can be added later)
402    * - return error if it doesn't exist
403    */
404   if (scene->active_keyingset == 0) {
405     BKE_report(op->reports, RPT_ERROR, "No active keying set to remove property from");
406     return OPERATOR_CANCELLED;
407   }
408   else if (scene->active_keyingset < 0) {
409     BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set");
410     return OPERATOR_CANCELLED;
411   }
412   else {
413     ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
414   }
415
416   if (ptr.id.data && ptr.data && prop) {
417     path = RNA_path_from_ID_to_property(&ptr, prop);
418
419     if (path) {
420       KS_Path *ksp;
421
422       /* try to find a path matching this description */
423       ksp = BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
424
425       if (ksp) {
426         BKE_keyingset_free_path(ks, ksp);
427         success = 1;
428       }
429
430       /* free temp path used */
431       MEM_freeN(path);
432     }
433   }
434
435   if (success) {
436     /* send updates */
437     WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
438
439     /* show warning */
440     BKE_report(op->reports, RPT_INFO, "Property removed from Keying Set");
441   }
442
443   return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
444 }
445
446 void ANIM_OT_keyingset_button_remove(wmOperatorType *ot)
447 {
448   /* identifiers */
449   ot->name = "Remove from Keying Set";
450   ot->idname = "ANIM_OT_keyingset_button_remove";
451   ot->description = "Remove current UI-active property from current keying set";
452
453   /* callbacks */
454   ot->exec = remove_keyingset_button_exec;
455   //op->poll = ???
456
457   /* flags */
458   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
459 }
460
461 /* ******************************************* */
462
463 /* Change Active KeyingSet Operator ------------------------ */
464 /* This operator checks if a menu should be shown
465  * for choosing the KeyingSet to make the active one. */
466
467 static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
468 {
469   uiPopupMenu *pup;
470   uiLayout *layout;
471
472   /* call the menu, which will call this operator again, hence the canceled */
473   pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
474   layout = UI_popup_menu_layout(pup);
475   uiItemsEnumO(layout, "ANIM_OT_keying_set_active_set", "type");
476   UI_popup_menu_end(C, pup);
477
478   return OPERATOR_INTERFACE;
479 }
480
481 static int keyingset_active_menu_exec(bContext *C, wmOperator *op)
482 {
483   Scene *scene = CTX_data_scene(C);
484   int type = RNA_enum_get(op->ptr, "type");
485
486   /* If type == 0, it will deselect any active keying set. */
487   scene->active_keyingset = type;
488
489   /* send notifiers */
490   WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
491
492   return OPERATOR_FINISHED;
493 }
494
495 void ANIM_OT_keying_set_active_set(wmOperatorType *ot)
496 {
497   PropertyRNA *prop;
498
499   /* identifiers */
500   ot->name = "Set Active Keying Set";
501   ot->idname = "ANIM_OT_keying_set_active_set";
502   ot->description = "Select a new keying set as the active one";
503
504   /* callbacks */
505   ot->invoke = keyingset_active_menu_invoke;
506   ot->exec = keyingset_active_menu_exec;
507   ot->poll = ED_operator_areaactive;
508
509   /* flags */
510   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
511
512   /* keyingset to use (dynamic enum) */
513   prop = RNA_def_enum(
514       ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
515   RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
516   // RNA_def_property_flag(prop, PROP_HIDDEN);
517 }
518
519 /* ******************************************* */
520 /* REGISTERED KEYING SETS */
521
522 /* Keying Set Type Info declarations */
523 static ListBase keyingset_type_infos = {NULL, NULL};
524
525 /* Built-In Keying Sets (referencing type infos)*/
526 ListBase builtin_keyingsets = {NULL, NULL};
527
528 /* --------------- */
529
530 /* Find KeyingSet type info given a name. */
531 KeyingSetInfo *ANIM_keyingset_info_find_name(const char name[])
532 {
533   /* sanity checks */
534   if ((name == NULL) || (name[0] == 0))
535     return NULL;
536
537   /* search by comparing names */
538   return BLI_findstring(&keyingset_type_infos, name, offsetof(KeyingSetInfo, idname));
539 }
540
541 /* Find builtin KeyingSet by name. */
542 KeyingSet *ANIM_builtin_keyingset_get_named(KeyingSet *prevKS, const char name[])
543 {
544   KeyingSet *ks, *first = NULL;
545
546   /* sanity checks  any name to check? */
547   if (name[0] == 0)
548     return NULL;
549
550   /* get first KeyingSet to use */
551   if (prevKS && prevKS->next)
552     first = prevKS->next;
553   else
554     first = builtin_keyingsets.first;
555
556   /* loop over KeyingSets checking names */
557   for (ks = first; ks; ks = ks->next) {
558     if (STREQ(name, ks->idname))
559       return ks;
560   }
561
562   /* complain about missing keying sets on debug builds */
563 #ifndef NDEBUG
564   printf("%s: '%s' not found\n", __func__, name);
565 #endif
566
567   /* no matches found */
568   return NULL;
569 }
570
571 /* --------------- */
572
573 /* Add the given KeyingSetInfo to the list of type infos,
574  * and create an appropriate builtin set too. */
575 void ANIM_keyingset_info_register(KeyingSetInfo *ksi)
576 {
577   KeyingSet *ks;
578
579   /* create a new KeyingSet
580    * - inherit name and keyframing settings from the typeinfo
581    */
582   ks = BKE_keyingset_add(&builtin_keyingsets, ksi->idname, ksi->name, 1, ksi->keyingflag);
583
584   /* link this KeyingSet with its typeinfo */
585   memcpy(&ks->typeinfo, ksi->idname, sizeof(ks->typeinfo));
586
587   /* Copy description... */
588   BLI_strncpy(ks->description, ksi->description, sizeof(ks->description));
589
590   /* add type-info to the list */
591   BLI_addtail(&keyingset_type_infos, ksi);
592 }
593
594 /* Remove the given KeyingSetInfo from the list of type infos,
595  * and also remove the builtin set if appropriate. */
596 void ANIM_keyingset_info_unregister(Main *bmain, KeyingSetInfo *ksi)
597 {
598   KeyingSet *ks, *ksn;
599
600   /* find relevant builtin KeyingSets which use this, and remove them */
601   /* TODO: this isn't done now, since unregister is really only used atm when we
602    * reload the scripts, which kindof defeats the purpose of "builtin"? */
603   for (ks = builtin_keyingsets.first; ks; ks = ksn) {
604     ksn = ks->next;
605
606     /* remove if matching typeinfo name */
607     if (STREQ(ks->typeinfo, ksi->idname)) {
608       Scene *scene;
609       BKE_keyingset_free(ks);
610       BLI_remlink(&builtin_keyingsets, ks);
611
612       for (scene = bmain->scenes.first; scene; scene = scene->id.next)
613         BLI_remlink_safe(&scene->keyingsets, ks);
614
615       MEM_freeN(ks);
616     }
617   }
618
619   /* free the type info */
620   BLI_freelinkN(&keyingset_type_infos, ksi);
621 }
622
623 /* --------------- */
624
625 void ANIM_keyingset_infos_exit(void)
626 {
627   KeyingSetInfo *ksi, *next;
628
629   /* free type infos */
630   for (ksi = keyingset_type_infos.first; ksi; ksi = next) {
631     next = ksi->next;
632
633     /* free extra RNA data, and remove from list */
634     if (ksi->ext.free)
635       ksi->ext.free(ksi->ext.data);
636     BLI_freelinkN(&keyingset_type_infos, ksi);
637   }
638
639   /* free builtin sets */
640   BKE_keyingsets_free(&builtin_keyingsets);
641 }
642
643 /* Check if the ID appears in the paths specified by the KeyingSet */
644 bool ANIM_keyingset_find_id(KeyingSet *ks, ID *id)
645 {
646   /* sanity checks */
647   if (ELEM(NULL, ks, id))
648     return false;
649
650   return BLI_findptr(&ks->paths, id, offsetof(KS_Path, id)) != NULL;
651 }
652
653 /* ******************************************* */
654 /* KEYING SETS API (for UI) */
655
656 /* Getters for Active/Indices ----------------------------- */
657
658 /* Get the active Keying Set for the Scene provided */
659 KeyingSet *ANIM_scene_get_active_keyingset(Scene *scene)
660 {
661   /* if no scene, we've got no hope of finding the Keying Set */
662   if (scene == NULL)
663     return NULL;
664
665   /* currently, there are several possibilities here:
666    * -   0: no active keying set
667    * - > 0: one of the user-defined Keying Sets, but indices start from 0 (hence the -1)
668    * - < 0: a builtin keying set
669    */
670   if (scene->active_keyingset > 0)
671     return BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
672   else
673     return BLI_findlink(&builtin_keyingsets, (-scene->active_keyingset) - 1);
674 }
675
676 /* Get the index of the Keying Set provided, for the given Scene */
677 int ANIM_scene_get_keyingset_index(Scene *scene, KeyingSet *ks)
678 {
679   int index;
680
681   /* if no KeyingSet provided, have none */
682   if (ks == NULL)
683     return 0;
684
685   /* check if the KeyingSet exists in scene list */
686   if (scene) {
687     /* get index and if valid, return
688      * - (absolute) Scene KeyingSets are from (>= 1)
689      */
690     index = BLI_findindex(&scene->keyingsets, ks);
691     if (index != -1)
692       return (index + 1);
693   }
694
695   /* still here, so try builtins list too
696    * - builtins are from (<= -1)
697    * - none/invalid is (= 0)
698    */
699   index = BLI_findindex(&builtin_keyingsets, ks);
700   if (index != -1)
701     return -(index + 1);
702   else
703     return 0;
704 }
705
706 /* Get Keying Set to use for Auto-Keyframing some transforms */
707 KeyingSet *ANIM_get_keyingset_for_autokeying(Scene *scene, const char *transformKSName)
708 {
709   /* get KeyingSet to use
710    * - use the active KeyingSet if defined (and user wants to use it for all autokeying),
711    *   or otherwise key transforms only
712    */
713   if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (scene->active_keyingset))
714     return ANIM_scene_get_active_keyingset(scene);
715   else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL))
716     return ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_AVAILABLE_ID);
717   else
718     return ANIM_builtin_keyingset_get_named(NULL, transformKSName);
719 }
720
721 /* Menu of All Keying Sets ----------------------------- */
722
723 /* Dynamically populate an enum of Keying Sets */
724 const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C,
725                                                     PointerRNA *UNUSED(ptr),
726                                                     PropertyRNA *UNUSED(prop),
727                                                     bool *r_free)
728 {
729   Scene *scene = CTX_data_scene(C);
730   KeyingSet *ks;
731   EnumPropertyItem *item = NULL, item_tmp = {0};
732   int totitem = 0;
733   int i = 0;
734
735   if (C == NULL) {
736     return DummyRNA_DEFAULT_items;
737   }
738
739   /* active Keying Set
740    * - only include entry if it exists
741    */
742   if (scene->active_keyingset) {
743     /* active Keying Set */
744     item_tmp.identifier = "__ACTIVE__";
745     item_tmp.name = "Active Keying Set";
746     item_tmp.value = i;
747     RNA_enum_item_add(&item, &totitem, &item_tmp);
748
749     /* separator */
750     RNA_enum_item_add_separator(&item, &totitem);
751   }
752
753   i++;
754
755   /* user-defined Keying Sets
756    * - these are listed in the order in which they were defined for the active scene
757    */
758   if (scene->keyingsets.first) {
759     for (ks = scene->keyingsets.first; ks; ks = ks->next, i++) {
760       if (ANIM_keyingset_context_ok_poll(C, ks)) {
761         item_tmp.identifier = ks->idname;
762         item_tmp.name = ks->name;
763         item_tmp.description = ks->description;
764         item_tmp.value = i;
765         RNA_enum_item_add(&item, &totitem, &item_tmp);
766       }
767     }
768
769     /* separator */
770     RNA_enum_item_add_separator(&item, &totitem);
771   }
772
773   /* builtin Keying Sets */
774   i = -1;
775   for (ks = builtin_keyingsets.first; ks; ks = ks->next, i--) {
776     /* only show KeyingSet if context is suitable */
777     if (ANIM_keyingset_context_ok_poll(C, ks)) {
778       item_tmp.identifier = ks->idname;
779       item_tmp.name = ks->name;
780       item_tmp.description = ks->description;
781       item_tmp.value = i;
782       RNA_enum_item_add(&item, &totitem, &item_tmp);
783     }
784   }
785
786   RNA_enum_item_end(&item, &totitem);
787   *r_free = true;
788
789   return item;
790 }
791
792 /**
793  * Get the keying set from enum values generated in #ANIM_keying_sets_enum_itemf.
794  *
795  * Type is the Keying Set the user specified to use when calling the operator:
796  * - type == 0: use scene's active Keying Set
797  * - type > 0: use a user-defined Keying Set from the active scene
798  * - type < 0: use a builtin Keying Set
799  */
800 KeyingSet *ANIM_keyingset_get_from_enum_type(Scene *scene, int type)
801 {
802   KeyingSet *ks = NULL;
803
804   if (type == 0) {
805     type = scene->active_keyingset;
806   }
807
808   if (type > 0) {
809     ks = BLI_findlink(&scene->keyingsets, type - 1);
810   }
811   else {
812     ks = BLI_findlink(&builtin_keyingsets, -type - 1);
813   }
814   return ks;
815 }
816
817 KeyingSet *ANIM_keyingset_get_from_idname(Scene *scene, const char *idname)
818 {
819   KeyingSet *ks = BLI_findstring(&scene->keyingsets, idname, offsetof(KeyingSet, idname));
820   if (ks == NULL) {
821     ks = BLI_findstring(&builtin_keyingsets, idname, offsetof(KeyingSet, idname));
822   }
823   return ks;
824 }
825
826 /* ******************************************* */
827 /* KEYFRAME MODIFICATION */
828
829 /* Polling API ----------------------------------------------- */
830
831 /* Check if KeyingSet can be used in the current context */
832 bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
833 {
834   if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
835     KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
836
837     /* get the associated 'type info' for this KeyingSet */
838     if (ksi == NULL)
839       return 0;
840     /* TODO: check for missing callbacks! */
841
842     /* check if it can be used in the current context */
843     return (ksi->poll(ksi, C));
844   }
845
846   return true;
847 }
848
849 /* Special 'Overrides' Iterator for Relative KeyingSets ------ */
850
851 /* 'Data Sources' for relative Keying Set 'overrides'
852  * - this is basically a wrapper for PointerRNA's in a linked list
853  * - do not allow this to be accessed from outside for now
854  */
855 typedef struct tRKS_DSource {
856   struct tRKS_DSource *next, *prev;
857   PointerRNA ptr; /* the whole point of this exercise! */
858 } tRKS_DSource;
859
860 /* Iterator used for overriding the behavior of iterators defined for
861  * relative Keying Sets, with the main usage of this being operators
862  * requiring Auto Keyframing. Internal Use Only!
863  */
864 static void RKS_ITER_overrides_list(KeyingSetInfo *ksi,
865                                     bContext *C,
866                                     KeyingSet *ks,
867                                     ListBase *dsources)
868 {
869   tRKS_DSource *ds;
870
871   for (ds = dsources->first; ds; ds = ds->next) {
872     /* run generate callback on this data */
873     ksi->generate(ksi, C, ks, &ds->ptr);
874   }
875 }
876
877 /* Add new data source for relative Keying Sets */
878 void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
879 {
880   tRKS_DSource *ds;
881
882   /* sanity checks
883    * - we must have somewhere to output the data
884    * - we must have both srna+data (and with id too optionally), or id by itself only
885    */
886   if (dsources == NULL)
887     return;
888   if (ELEM(NULL, srna, data) && (id == NULL))
889     return;
890
891   /* allocate new elem, and add to the list */
892   ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
893   BLI_addtail(dsources, ds);
894
895   /* depending on what data we have, create using ID or full pointer call */
896   if (srna && data)
897     RNA_pointer_create(id, srna, data, &ds->ptr);
898   else
899     RNA_id_pointer_create(id, &ds->ptr);
900 }
901
902 /* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
903
904 /* Given a KeyingSet and context info, validate Keying Set's paths.
905  * This is only really necessary with relative/built-in KeyingSets
906  * where their list of paths is dynamically generated based on the
907  * current context info.
908  *
909  * Returns 0 if succeeded, otherwise an error code: eModifyKey_Returns
910  */
911 short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
912 {
913   /* sanity check */
914   if (ks == NULL)
915     return 0;
916
917   /* if relative Keying Sets, poll and build up the paths */
918   if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
919     KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
920
921     /* clear all existing paths
922      * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
923      */
924     BKE_keyingset_free(ks);
925
926     /* get the associated 'type info' for this KeyingSet */
927     if (ksi == NULL)
928       return MODIFYKEY_MISSING_TYPEINFO;
929     /* TODO: check for missing callbacks! */
930
931     /* check if it can be used in the current context */
932     if (ksi->poll(ksi, C)) {
933       /* if a list of data sources are provided, run a special iterator over them,
934        * otherwise, just continue per normal
935        */
936       if (dsources)
937         RKS_ITER_overrides_list(ksi, C, ks, dsources);
938       else
939         ksi->iter(ksi, C, ks);
940
941       /* if we don't have any paths now, then this still qualifies as invalid context */
942       // FIXME: we need some error conditions (to be retrieved from the iterator why this failed!)
943       if (BLI_listbase_is_empty(&ks->paths))
944         return MODIFYKEY_INVALID_CONTEXT;
945     }
946     else {
947       /* poll callback tells us that KeyingSet is useless in current context */
948       // FIXME: the poll callback needs to give us more info why
949       return MODIFYKEY_INVALID_CONTEXT;
950     }
951   }
952
953   /* succeeded; return 0 to tag error free */
954   return 0;
955 }
956
957 /* Determine which keying flags apply based on the override flags */
958 static short keyingset_apply_keying_flags(const short base_flags,
959                                           const short overrides,
960                                           const short own_flags)
961 {
962   /* Pass through all flags by default (i.e. even not explicitly listed ones). */
963   short result = base_flags;
964
965   /* The logic for whether a keying flag applies is as follows:
966    * - If the flag in question is set in "overrides", that means that the
967    *   status of that flag in "own_flags" is used
968    * - If however the flag isn't set, then its value in "base_flags" is used
969    *   instead (i.e. no override)
970    */
971 #define APPLY_KEYINGFLAG_OVERRIDE(kflag) \
972   if (overrides & kflag) { \
973     result &= ~kflag; \
974     result |= (own_flags & kflag); \
975   }
976
977   /* Apply the flags one by one...
978    * (See rna_def_common_keying_flags() for the supported flags)
979    */
980   APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_NEEDED)
981   APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_MATRIX)
982   APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_XYZ2RGB)
983
984 #undef APPLY_KEYINGFLAG_OVERRIDE
985
986   return result;
987 }
988
989 /* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
990  * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
991  * Returns the number of channels that keyframes were added to
992  */
993 int ANIM_apply_keyingset(
994     bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
995 {
996   Depsgraph *depsgraph = CTX_data_depsgraph(C);
997   Main *bmain = CTX_data_main(C);
998   Scene *scene = CTX_data_scene(C);
999   ReportList *reports = CTX_wm_reports(C);
1000   KS_Path *ksp;
1001   ListBase nla_cache = {NULL, NULL};
1002   const short base_kflags = ANIM_get_keyframing_flags(scene, 1);
1003   const char *groupname = NULL;
1004   short kflag = 0, success = 0;
1005   char keytype = scene->toolsettings->keyframe_type;
1006
1007   /* sanity checks */
1008   if (ks == NULL)
1009     return 0;
1010
1011   /* get flags to use */
1012   if (mode == MODIFYKEY_MODE_INSERT) {
1013     /* use context settings as base */
1014     kflag = keyingset_apply_keying_flags(base_kflags, ks->keyingoverride, ks->keyingflag);
1015   }
1016   else if (mode == MODIFYKEY_MODE_DELETE)
1017     kflag = 0;
1018
1019   /* if relative Keying Sets, poll and build up the paths */
1020   success = ANIM_validate_keyingset(C, dsources, ks);
1021
1022   if (success != 0) {
1023     /* return error code if failed */
1024     return success;
1025   }
1026
1027   /* apply the paths as specified in the KeyingSet now */
1028   for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
1029     int arraylen, i;
1030     short kflag2;
1031
1032     /* skip path if no ID pointer is specified */
1033     if (ksp->id == NULL) {
1034       BKE_reportf(reports,
1035                   RPT_WARNING,
1036                   "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s[%d]')",
1037                   ks->name,
1038                   ksp->rna_path,
1039                   ksp->array_index);
1040       continue;
1041     }
1042
1043     /* Since keying settings can be defined on the paths too,
1044      * apply the settings for this path first. */
1045     kflag2 = keyingset_apply_keying_flags(kflag, ksp->keyingoverride, ksp->keyingflag);
1046
1047     /* get pointer to name of group to add channels to */
1048     if (ksp->groupmode == KSP_GROUP_NONE)
1049       groupname = NULL;
1050     else if (ksp->groupmode == KSP_GROUP_KSNAME)
1051       groupname = ks->name;
1052     else
1053       groupname = ksp->group;
1054
1055     /* init arraylen and i - arraylen should be greater than i so that
1056      * normal non-array entries get keyframed correctly
1057      */
1058     i = ksp->array_index;
1059     arraylen = i;
1060
1061     /* get length of array if whole array option is enabled */
1062     if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
1063       PointerRNA id_ptr, ptr;
1064       PropertyRNA *prop;
1065
1066       RNA_id_pointer_create(ksp->id, &id_ptr);
1067       if (RNA_path_resolve_property(&id_ptr, ksp->rna_path, &ptr, &prop)) {
1068         arraylen = RNA_property_array_length(&ptr, prop);
1069         /* start from start of array, instead of the previously specified index - T48020 */
1070         i = 0;
1071       }
1072     }
1073
1074     /* we should do at least one step */
1075     if (arraylen == i)
1076       arraylen++;
1077
1078     /* for each possible index, perform operation
1079      * - assume that arraylen is greater than index
1080      */
1081     for (; i < arraylen; i++) {
1082       /* action to take depends on mode */
1083       if (mode == MODIFYKEY_MODE_INSERT)
1084         success += insert_keyframe(bmain,
1085                                    depsgraph,
1086                                    reports,
1087                                    ksp->id,
1088                                    act,
1089                                    groupname,
1090                                    ksp->rna_path,
1091                                    i,
1092                                    cfra,
1093                                    keytype,
1094                                    &nla_cache,
1095                                    kflag2);
1096       else if (mode == MODIFYKEY_MODE_DELETE)
1097         success += delete_keyframe(
1098             bmain, reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
1099     }
1100
1101     /* set recalc-flags */
1102     switch (GS(ksp->id->name)) {
1103       case ID_OB: /* Object (or Object-Related) Keyframes */
1104       {
1105         Object *ob = (Object *)ksp->id;
1106
1107         // XXX: only object transforms?
1108         DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
1109         break;
1110       }
1111       default:
1112         DEG_id_tag_update(ksp->id, ID_RECALC_ANIMATION_NO_FLUSH);
1113         break;
1114     }
1115
1116     /* send notifiers for updates (this doesn't require context to work!) */
1117     WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
1118   }
1119
1120   BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
1121
1122   /* return the number of channels successfully affected */
1123   return success;
1124 }
1125
1126 /* ************************************************** */