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