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 <float.h>
25 #include <math.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <string.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_object_types.h"
37 #include "DNA_scene_types.h"
38 
39 #include "BKE_animsys.h"
40 #include "BKE_context.h"
41 #include "BKE_main.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 */
keyingset_poll_default_add(bContext * C)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 */
keyingset_poll_active_edit(bContext * C)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 */
keyingset_poll_activePath_edit(bContext * C)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 
100   ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
101 
102   /* there must be an active KeyingSet and an active path */
103   return ((ks) && (ks->paths.first) && (ks->active_path > 0));
104 }
105 
106 /* Add a Default (Empty) Keying Set ------------------------- */
107 
add_default_keyingset_exec(bContext * C,wmOperator * UNUSED (op))108 static int add_default_keyingset_exec(bContext *C, wmOperator *UNUSED(op))
109 {
110   Scene *scene = CTX_data_scene(C);
111   eKS_Settings flag = 0;
112   eInsertKeyFlags 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, false);
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 
ANIM_OT_keying_set_add(wmOperatorType * ot)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 
remove_active_keyingset_exec(bContext * C,wmOperator * op)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 
161   if (scene->active_keyingset < 0) {
162     BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set");
163     return OPERATOR_CANCELLED;
164   }
165 
166   ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
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 
ANIM_OT_keying_set_remove(wmOperatorType * ot)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 
add_empty_ks_path_exec(bContext * C,wmOperator * op)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 
210   ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
211 
212   /* don't use the API method for this, since that checks on values... */
213   ksp = MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
214   BLI_addtail(&ks->paths, ksp);
215   ks->active_path = BLI_listbase_count(&ks->paths);
216 
217   ksp->groupmode = KSP_GROUP_KSNAME; /* XXX? */
218   ksp->idtype = ID_OB;
219   ksp->flag = KSP_FLAG_WHOLE_ARRAY;
220 
221   return OPERATOR_FINISHED;
222 }
223 
ANIM_OT_keying_set_path_add(wmOperatorType * ot)224 void ANIM_OT_keying_set_path_add(wmOperatorType *ot)
225 {
226   /* identifiers */
227   ot->name = "Add Empty Keying Set Path";
228   ot->idname = "ANIM_OT_keying_set_path_add";
229   ot->description = "Add empty path to active Keying Set";
230 
231   /* callbacks */
232   ot->exec = add_empty_ks_path_exec;
233   ot->poll = keyingset_poll_active_edit;
234 }
235 
236 /* Remove Active Keying Set Path ------------------------- */
237 
remove_active_ks_path_exec(bContext * C,wmOperator * op)238 static int remove_active_ks_path_exec(bContext *C, wmOperator *op)
239 {
240   Scene *scene = CTX_data_scene(C);
241   KeyingSet *ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
242 
243   /* if there is a KeyingSet, find the nominated path to remove */
244   if (ks) {
245     KS_Path *ksp = BLI_findlink(&ks->paths, ks->active_path - 1);
246 
247     if (ksp) {
248       /* remove the active path from the KeyingSet */
249       BKE_keyingset_free_path(ks, ksp);
250 
251       /* the active path should now be the previously second-to-last active one */
252       ks->active_path--;
253     }
254     else {
255       BKE_report(op->reports, RPT_ERROR, "No active Keying Set path to remove");
256       return OPERATOR_CANCELLED;
257     }
258   }
259   else {
260     BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from");
261     return OPERATOR_CANCELLED;
262   }
263 
264   return OPERATOR_FINISHED;
265 }
266 
ANIM_OT_keying_set_path_remove(wmOperatorType * ot)267 void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
268 {
269   /* identifiers */
270   ot->name = "Remove Active Keying Set Path";
271   ot->idname = "ANIM_OT_keying_set_path_remove";
272   ot->description = "Remove active Path from active Keying Set";
273 
274   /* callbacks */
275   ot->exec = remove_active_ks_path_exec;
276   ot->poll = keyingset_poll_activePath_edit;
277 }
278 
279 /* ************************************************** */
280 /* KEYING SETS - OPERATORS (for use in UI menus) */
281 
282 /* Add to KeyingSet Button Operator ------------------------ */
283 
add_keyingset_button_exec(bContext * C,wmOperator * op)284 static int add_keyingset_button_exec(bContext *C, wmOperator *op)
285 {
286   Scene *scene = CTX_data_scene(C);
287   KeyingSet *ks = NULL;
288   PropertyRNA *prop = NULL;
289   PointerRNA ptr = {NULL};
290   char *path = NULL;
291   bool changed = false;
292   int index = 0, pflag = 0;
293   const bool all = RNA_boolean_get(op->ptr, "all");
294 
295   /* try to add to keyingset using property retrieved from UI */
296   if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
297     /* pass event on if no active button found */
298     return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
299   }
300 
301   /* verify the Keying Set to use:
302    * - use the active one for now (more control over this can be added later)
303    * - add a new one if it doesn't exist
304    */
305   if (scene->active_keyingset == 0) {
306     eKS_Settings flag = 0;
307     eInsertKeyFlags 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, false);
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.owner_id && 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.owner_id, NULL, path, index, pflag, KSP_GROUP_KSNAME);
352       ks->active_path = BLI_listbase_count(&ks->paths);
353       changed = true;
354 
355       /* free the temp path created */
356       MEM_freeN(path);
357     }
358   }
359 
360   if (changed) {
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 (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
369 }
370 
ANIM_OT_keyingset_button_add(wmOperatorType * ot)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 
remove_keyingset_button_exec(bContext * C,wmOperator * op)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   bool changed = false;
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 
416   if (scene->active_keyingset < 0) {
417     BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set");
418     return OPERATOR_CANCELLED;
419   }
420 
421   ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
422 
423   if (ptr.owner_id && 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.owner_id, ks->name, path, index, KSP_GROUP_KSNAME);
431 
432       if (ksp) {
433         BKE_keyingset_free_path(ks, ksp);
434         changed = true;
435       }
436 
437       /* free temp path used */
438       MEM_freeN(path);
439     }
440   }
441 
442   if (changed) {
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 (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
451 }
452 
ANIM_OT_keyingset_button_remove(wmOperatorType * ot)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 
keyingset_active_menu_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (event))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 
keyingset_active_menu_exec(bContext * C,wmOperator * op)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 
ANIM_OT_keying_set_active_set(wmOperatorType * ot)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. */
ANIM_keyingset_info_find_name(const char 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. */
ANIM_builtin_keyingset_get_named(KeyingSet * prevKS,const char 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. */
ANIM_keyingset_info_register(KeyingSetInfo * ksi)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. */
ANIM_keyingset_info_unregister(Main * bmain,KeyingSetInfo * ksi)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 
ANIM_keyingset_infos_exit(void)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->rna_ext.free) {
648       ksi->rna_ext.free(ksi->rna_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 */
ANIM_keyingset_find_id(KeyingSet * ks,ID * id)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 */
ANIM_scene_get_active_keyingset(const Scene * scene)674 KeyingSet *ANIM_scene_get_active_keyingset(const 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   return BLI_findlink(&builtin_keyingsets, (-scene->active_keyingset) - 1);
690 }
691 
692 /* Get the index of the Keying Set provided, for the given Scene */
ANIM_scene_get_keyingset_index(Scene * scene,KeyingSet * ks)693 int ANIM_scene_get_keyingset_index(Scene *scene, KeyingSet *ks)
694 {
695   int index;
696 
697   /* if no KeyingSet provided, have none */
698   if (ks == NULL) {
699     return 0;
700   }
701 
702   /* check if the KeyingSet exists in scene list */
703   if (scene) {
704     /* get index and if valid, return
705      * - (absolute) Scene KeyingSets are from (>= 1)
706      */
707     index = BLI_findindex(&scene->keyingsets, ks);
708     if (index != -1) {
709       return (index + 1);
710     }
711   }
712 
713   /* Still here, so try built-ins list too:
714    * - Built-ins are from (<= -1).
715    * - None/Invalid is (= 0).
716    */
717   index = BLI_findindex(&builtin_keyingsets, ks);
718   if (index != -1) {
719     return -(index + 1);
720   }
721   return 0;
722 }
723 
724 /* Get Keying Set to use for Auto-Keyframing some transforms */
ANIM_get_keyingset_for_autokeying(const Scene * scene,const char * transformKSName)725 KeyingSet *ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *transformKSName)
726 {
727   /* get KeyingSet to use
728    * - use the active KeyingSet if defined (and user wants to use it for all autokeying),
729    *   or otherwise key transforms only
730    */
731   if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (scene->active_keyingset)) {
732     return ANIM_scene_get_active_keyingset(scene);
733   }
734   if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
735     return ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_AVAILABLE_ID);
736   }
737   return ANIM_builtin_keyingset_get_named(NULL, transformKSName);
738 }
739 
740 /* Menu of All Keying Sets ----------------------------- */
741 
742 /* Dynamically populate an enum of Keying Sets */
ANIM_keying_sets_enum_itemf(bContext * C,PointerRNA * UNUSED (ptr),PropertyRNA * UNUSED (prop),bool * r_free)743 const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C,
744                                                     PointerRNA *UNUSED(ptr),
745                                                     PropertyRNA *UNUSED(prop),
746                                                     bool *r_free)
747 {
748   Scene *scene = CTX_data_scene(C);
749   KeyingSet *ks;
750   EnumPropertyItem *item = NULL, item_tmp = {0};
751   int totitem = 0;
752   int i = 0;
753 
754   if (C == NULL) {
755     return DummyRNA_DEFAULT_items;
756   }
757 
758   /* active Keying Set
759    * - only include entry if it exists
760    */
761   if (scene->active_keyingset) {
762     /* active Keying Set */
763     item_tmp.identifier = "__ACTIVE__";
764     item_tmp.name = "Active Keying Set";
765     item_tmp.value = i;
766     RNA_enum_item_add(&item, &totitem, &item_tmp);
767 
768     /* separator */
769     RNA_enum_item_add_separator(&item, &totitem);
770   }
771 
772   i++;
773 
774   /* user-defined Keying Sets
775    * - these are listed in the order in which they were defined for the active scene
776    */
777   if (scene->keyingsets.first) {
778     for (ks = scene->keyingsets.first; ks; ks = ks->next, i++) {
779       if (ANIM_keyingset_context_ok_poll(C, ks)) {
780         item_tmp.identifier = ks->idname;
781         item_tmp.name = ks->name;
782         item_tmp.description = ks->description;
783         item_tmp.value = i;
784         RNA_enum_item_add(&item, &totitem, &item_tmp);
785       }
786     }
787 
788     /* separator */
789     RNA_enum_item_add_separator(&item, &totitem);
790   }
791 
792   /* builtin Keying Sets */
793   i = -1;
794   for (ks = builtin_keyingsets.first; ks; ks = ks->next, i--) {
795     /* only show KeyingSet if context is suitable */
796     if (ANIM_keyingset_context_ok_poll(C, ks)) {
797       item_tmp.identifier = ks->idname;
798       item_tmp.name = ks->name;
799       item_tmp.description = ks->description;
800       item_tmp.value = i;
801       RNA_enum_item_add(&item, &totitem, &item_tmp);
802     }
803   }
804 
805   RNA_enum_item_end(&item, &totitem);
806   *r_free = true;
807 
808   return item;
809 }
810 
811 /**
812  * Get the keying set from enum values generated in #ANIM_keying_sets_enum_itemf.
813  *
814  * Type is the Keying Set the user specified to use when calling the operator:
815  * - type == 0: use scene's active Keying Set
816  * - type > 0: use a user-defined Keying Set from the active scene
817  * - type < 0: use a builtin Keying Set
818  */
ANIM_keyingset_get_from_enum_type(Scene * scene,int type)819 KeyingSet *ANIM_keyingset_get_from_enum_type(Scene *scene, int type)
820 {
821   KeyingSet *ks = NULL;
822 
823   if (type == 0) {
824     type = scene->active_keyingset;
825   }
826 
827   if (type > 0) {
828     ks = BLI_findlink(&scene->keyingsets, type - 1);
829   }
830   else {
831     ks = BLI_findlink(&builtin_keyingsets, -type - 1);
832   }
833   return ks;
834 }
835 
ANIM_keyingset_get_from_idname(Scene * scene,const char * idname)836 KeyingSet *ANIM_keyingset_get_from_idname(Scene *scene, const char *idname)
837 {
838   KeyingSet *ks = BLI_findstring(&scene->keyingsets, idname, offsetof(KeyingSet, idname));
839   if (ks == NULL) {
840     ks = BLI_findstring(&builtin_keyingsets, idname, offsetof(KeyingSet, idname));
841   }
842   return ks;
843 }
844 
845 /* ******************************************* */
846 /* KEYFRAME MODIFICATION */
847 
848 /* Polling API ----------------------------------------------- */
849 
850 /* Check if KeyingSet can be used in the current context */
ANIM_keyingset_context_ok_poll(bContext * C,KeyingSet * ks)851 bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
852 {
853   if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
854     KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
855 
856     /* get the associated 'type info' for this KeyingSet */
857     if (ksi == NULL) {
858       return 0;
859     }
860     /* TODO: check for missing callbacks! */
861 
862     /* check if it can be used in the current context */
863     return (ksi->poll(ksi, C));
864   }
865 
866   return true;
867 }
868 
869 /* Special 'Overrides' Iterator for Relative KeyingSets ------ */
870 
871 /* 'Data Sources' for relative Keying Set 'overrides'
872  * - this is basically a wrapper for PointerRNA's in a linked list
873  * - do not allow this to be accessed from outside for now
874  */
875 typedef struct tRKS_DSource {
876   struct tRKS_DSource *next, *prev;
877   PointerRNA ptr; /* the whole point of this exercise! */
878 } tRKS_DSource;
879 
880 /* Iterator used for overriding the behavior of iterators defined for
881  * relative Keying Sets, with the main usage of this being operators
882  * requiring Auto Keyframing. Internal Use Only!
883  */
RKS_ITER_overrides_list(KeyingSetInfo * ksi,bContext * C,KeyingSet * ks,ListBase * dsources)884 static void RKS_ITER_overrides_list(KeyingSetInfo *ksi,
885                                     bContext *C,
886                                     KeyingSet *ks,
887                                     ListBase *dsources)
888 {
889   tRKS_DSource *ds;
890 
891   for (ds = dsources->first; ds; ds = ds->next) {
892     /* run generate callback on this data */
893     ksi->generate(ksi, C, ks, &ds->ptr);
894   }
895 }
896 
897 /* Add new data source for relative Keying Sets */
ANIM_relative_keyingset_add_source(ListBase * dsources,ID * id,StructRNA * srna,void * data)898 void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
899 {
900   tRKS_DSource *ds;
901 
902   /* sanity checks
903    * - we must have somewhere to output the data
904    * - we must have both srna+data (and with id too optionally), or id by itself only
905    */
906   if (dsources == NULL) {
907     return;
908   }
909   if (ELEM(NULL, srna, data) && (id == NULL)) {
910     return;
911   }
912 
913   /* allocate new elem, and add to the list */
914   ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
915   BLI_addtail(dsources, ds);
916 
917   /* depending on what data we have, create using ID or full pointer call */
918   if (srna && data) {
919     RNA_pointer_create(id, srna, data, &ds->ptr);
920   }
921   else {
922     RNA_id_pointer_create(id, &ds->ptr);
923   }
924 }
925 
926 /* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
927 
928 /**
929  * Given a KeyingSet and context info, validate Keying Set's paths.
930  * This is only really necessary with relative/built-in KeyingSets
931  * where their list of paths is dynamically generated based on the
932  * current context info.
933  *
934  * Returns 0 if succeeded, otherwise an error code: eModifyKey_Returns
935  */
ANIM_validate_keyingset(bContext * C,ListBase * dsources,KeyingSet * ks)936 eModifyKey_Returns ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
937 {
938   /* sanity check */
939   if (ks == NULL) {
940     return 0;
941   }
942 
943   /* if relative Keying Sets, poll and build up the paths */
944   if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
945     KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
946 
947     /* clear all existing paths
948      * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
949      */
950     BKE_keyingset_free(ks);
951 
952     /* get the associated 'type info' for this KeyingSet */
953     if (ksi == NULL) {
954       return MODIFYKEY_MISSING_TYPEINFO;
955     }
956     /* TODO: check for missing callbacks! */
957 
958     /* check if it can be used in the current context */
959     if (ksi->poll(ksi, C)) {
960       /* if a list of data sources are provided, run a special iterator over them,
961        * otherwise, just continue per normal
962        */
963       if (dsources) {
964         RKS_ITER_overrides_list(ksi, C, ks, dsources);
965       }
966       else {
967         ksi->iter(ksi, C, ks);
968       }
969 
970       /* if we don't have any paths now, then this still qualifies as invalid context */
971       /* FIXME: we need some error conditions (to be retrieved from the iterator why this failed!)
972        */
973       if (BLI_listbase_is_empty(&ks->paths)) {
974         return MODIFYKEY_INVALID_CONTEXT;
975       }
976     }
977     else {
978       /* poll callback tells us that KeyingSet is useless in current context */
979       /* FIXME: the poll callback needs to give us more info why */
980       return MODIFYKEY_INVALID_CONTEXT;
981     }
982   }
983 
984   /* succeeded; return 0 to tag error free */
985   return 0;
986 }
987 
988 /* Determine which keying flags apply based on the override flags */
keyingset_apply_keying_flags(const eInsertKeyFlags base_flags,const eInsertKeyFlags overrides,const eInsertKeyFlags own_flags)989 static eInsertKeyFlags keyingset_apply_keying_flags(const eInsertKeyFlags base_flags,
990                                                     const eInsertKeyFlags overrides,
991                                                     const eInsertKeyFlags own_flags)
992 {
993   /* Pass through all flags by default (i.e. even not explicitly listed ones). */
994   eInsertKeyFlags result = base_flags;
995 
996   /* The logic for whether a keying flag applies is as follows:
997    * - If the flag in question is set in "overrides", that means that the
998    *   status of that flag in "own_flags" is used
999    * - If however the flag isn't set, then its value in "base_flags" is used
1000    *   instead (i.e. no override)
1001    */
1002 #define APPLY_KEYINGFLAG_OVERRIDE(kflag) \
1003   if (overrides & kflag) { \
1004     result &= ~kflag; \
1005     result |= (own_flags & kflag); \
1006   }
1007 
1008   /* Apply the flags one by one...
1009    * (See rna_def_common_keying_flags() for the supported flags)
1010    */
1011   APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_NEEDED)
1012   APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_MATRIX)
1013   APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_XYZ2RGB)
1014 
1015 #undef APPLY_KEYINGFLAG_OVERRIDE
1016 
1017   return result;
1018 }
1019 
1020 /**
1021  * Given a KeyingSet and context info (if required),
1022  * modify keyframes for the channels specified by the KeyingSet.
1023  * This takes into account many of the different combinations of using KeyingSets.
1024  *
1025  * \returns the number of channels that key-frames were added or
1026  * an #eModifyKey_Returns value (always a negative number).
1027  */
ANIM_apply_keyingset(bContext * C,ListBase * dsources,bAction * act,KeyingSet * ks,short mode,float cfra)1028 int ANIM_apply_keyingset(
1029     bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
1030 {
1031   Main *bmain = CTX_data_main(C);
1032   Scene *scene = CTX_data_scene(C);
1033   ReportList *reports = CTX_wm_reports(C);
1034   KS_Path *ksp;
1035   ListBase nla_cache = {NULL, NULL};
1036   const eInsertKeyFlags base_kflags = ANIM_get_keyframing_flags(scene, true);
1037   const char *groupname = NULL;
1038   eInsertKeyFlags kflag = 0;
1039   int num_channels = 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   {
1058     const eModifyKey_Returns error = ANIM_validate_keyingset(C, dsources, ks);
1059     if (error != 0) {
1060       BLI_assert(error < 0);
1061       /* return error code if failed */
1062       return error;
1063     }
1064   }
1065 
1066   /* apply the paths as specified in the KeyingSet now */
1067   for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
1068     int arraylen, i;
1069     eInsertKeyFlags kflag2;
1070 
1071     /* skip path if no ID pointer is specified */
1072     if (ksp->id == NULL) {
1073       BKE_reportf(reports,
1074                   RPT_WARNING,
1075                   "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s[%d]')",
1076                   ks->name,
1077                   ksp->rna_path,
1078                   ksp->array_index);
1079       continue;
1080     }
1081 
1082     /* Since keying settings can be defined on the paths too,
1083      * apply the settings for this path first. */
1084     kflag2 = keyingset_apply_keying_flags(kflag, ksp->keyingoverride, ksp->keyingflag);
1085 
1086     /* get pointer to name of group to add channels to */
1087     if (ksp->groupmode == KSP_GROUP_NONE) {
1088       groupname = NULL;
1089     }
1090     else if (ksp->groupmode == KSP_GROUP_KSNAME) {
1091       groupname = ks->name;
1092     }
1093     else {
1094       groupname = ksp->group;
1095     }
1096 
1097     /* init arraylen and i - arraylen should be greater than i so that
1098      * normal non-array entries get keyframed correctly
1099      */
1100     i = ksp->array_index;
1101     arraylen = i;
1102 
1103     /* get length of array if whole array option is enabled */
1104     if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
1105       PointerRNA id_ptr, ptr;
1106       PropertyRNA *prop;
1107 
1108       RNA_id_pointer_create(ksp->id, &id_ptr);
1109       if (RNA_path_resolve_property(&id_ptr, ksp->rna_path, &ptr, &prop)) {
1110         arraylen = RNA_property_array_length(&ptr, prop);
1111         /* start from start of array, instead of the previously specified index - T48020 */
1112         i = 0;
1113       }
1114     }
1115 
1116     /* we should do at least one step */
1117     if (arraylen == i) {
1118       arraylen++;
1119     }
1120 
1121     /* for each possible index, perform operation
1122      * - assume that arraylen is greater than index
1123      */
1124     Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
1125     const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
1126                                                                                       cfra);
1127     for (; i < arraylen; i++) {
1128       /* action to take depends on mode */
1129       if (mode == MODIFYKEY_MODE_INSERT) {
1130         num_channels += insert_keyframe(bmain,
1131                                         reports,
1132                                         ksp->id,
1133                                         act,
1134                                         groupname,
1135                                         ksp->rna_path,
1136                                         i,
1137                                         &anim_eval_context,
1138                                         keytype,
1139                                         &nla_cache,
1140                                         kflag2);
1141       }
1142       else if (mode == MODIFYKEY_MODE_DELETE) {
1143         num_channels += delete_keyframe(bmain, reports, ksp->id, act, ksp->rna_path, i, cfra);
1144       }
1145     }
1146 
1147     /* set recalc-flags */
1148     switch (GS(ksp->id->name)) {
1149       case ID_OB: /* Object (or Object-Related) Keyframes */
1150       {
1151         Object *ob = (Object *)ksp->id;
1152 
1153         /* XXX: only object transforms? */
1154         DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
1155         break;
1156       }
1157       default:
1158         DEG_id_tag_update(ksp->id, ID_RECALC_ANIMATION_NO_FLUSH);
1159         break;
1160     }
1161 
1162     /* send notifiers for updates (this doesn't require context to work!) */
1163     WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
1164   }
1165 
1166   BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
1167 
1168   /* return the number of channels successfully affected */
1169   BLI_assert(num_channels >= 0);
1170   return num_channels;
1171 }
1172 
1173 /* ************************************************** */
1174