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