Blender  V2.93
keyingsets.c
Go to the documentation of this file.
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 
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 */
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 */
76 {
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 */
89 {
91  KeyingSet *ks;
92 
93  if (scene == NULL) {
94  return 0;
95  }
96  if (scene->active_keyingset <= 0) {
97  return 0;
98  }
99 
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 
109 {
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 
126 
127  /* send notifiers */
129 
130  return OPERATOR_FINISHED;
131 }
132 
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 */
143 }
144 
145 /* Remove 'Active' Keying Set ------------------------- */
146 
148 {
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 
167 
168  /* free KeyingSet's data, then remove it from the scene */
169  BKE_keyingset_free(ks);
171 
172  /* the active one should now be the previously second-to-last one */
174 
175  /* send notifiers */
177 
178  return OPERATOR_FINISHED;
179 }
180 
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 */
191 }
192 
193 /* Add Empty Keying Set Path ------------------------- */
194 
196 {
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 
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);
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 
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 */
234 }
235 
236 /* Remove Active Keying Set Path ------------------------- */
237 
239 {
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 
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 */
277 }
278 
279 /* ************************************************** */
280 /* KEYING SETS - OPERATORS (for use in UI menus) */
281 
282 /* Add to KeyingSet Button Operator ------------------------ */
283 
285 {
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 */
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 
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 {
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);
353  changed = true;
354 
355  /* free the temp path created */
356  MEM_freeN(path);
357  }
358  }
359 
360  if (changed) {
361  /* send updates */
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 
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 */
380  // op->poll = ???
381 
382  /* flags */
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 
392 {
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 */
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 
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 */
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 
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 */
462  // op->poll = ???
463 
464  /* flags */
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 
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 
489 {
491  int type = RNA_enum_get(op->ptr, "type");
492 
493  /* If type == 0, it will deselect any active keying set. */
495 
496  /* send notifiers */
498 
499  return OPERATOR_FINISHED;
500 }
501 
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 */
515 
516  /* flags */
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");
523  // RNA_def_property_flag(prop, PROP_HIDDEN);
524 }
525 
526 /* ******************************************* */
527 /* REGISTERED KEYING SETS */
528 
529 /* Keying Set Type Info declarations */
531 
532 /* Built-In Keying Sets (referencing type infos)*/
534 
535 /* --------------- */
536 
537 /* Find KeyingSet type info given a 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. */
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. */
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 */
604 }
605 
606 /* Remove the given KeyingSetInfo from the list of type infos,
607  * and also remove the builtin set if appropriate. */
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);
623 
624  for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
626  }
627 
628  MEM_freeN(ks);
629  }
630  }
631 
632  /* free the type info */
634 }
635 
636 /* --------------- */
637 
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  }
651  }
652 
653  /* free builtin sets */
655 }
656 
657 /* Check if the ID appears in the paths specified by the KeyingSet */
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 */
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) {
688  }
690 }
691 
692 /* Get the index of the Keying Set provided, for the given Scene */
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 */
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)) {
733  }
734  if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
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 */
745  PropertyRNA *UNUSED(prop),
746  bool *r_free)
747 {
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++) {
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 */
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 
820 {
821  KeyingSet *ks = NULL;
822 
823  if (type == 0) {
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 
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 */
852 {
853  if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
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! */
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  */
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 */
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 
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) {
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) {
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)) {
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 */
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 */
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  */
1014 
1015 #undef APPLY_KEYINGFLAG_OVERRIDE
1016 
1017  return result;
1018 }
1019 
1029  bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
1030 {
1031  Main *bmain = CTX_data_main(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  */
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? */
1155  break;
1156  }
1157  default:
1159  break;
1160  }
1161 
1162  /* send notifiers for updates (this doesn't require context to work!) */
1164  }
1165 
1167 
1168  /* return the number of channels successfully affected */
1169  BLI_assert(num_channels >= 0);
1170  return num_channels;
1171 }
1172 
1173 /* ************************************************** */
void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache)
Definition: anim_sys.c:2756
struct KS_Path * BKE_keyingset_add_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
Definition: anim_sys.c:178
void BKE_keyingsets_free(struct ListBase *list)
Definition: anim_sys.c:304
struct KeyingSet * BKE_keyingset_add(struct ListBase *list, const char idname[], const char name[], short flag, short keyingflag)
Definition: anim_sys.c:144
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time)
Definition: anim_sys.c:637
struct KS_Path * BKE_keyingset_find_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode)
void BKE_keyingset_free(struct KeyingSet *ks)
Definition: anim_sys.c:287
void BKE_keyingset_free_path(struct KeyingSet *ks, struct KS_Path *ksp)
Definition: anim_sys.c:242
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ReportList * CTX_wm_reports(const bContext *C)
Definition: context.c:751
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1401
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
bool BLI_remlink_safe(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:159
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:599
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ ID_RECALC_ANIMATION_NO_FLUSH
Definition: DNA_ID.h:690
@ ID_OB
Definition: DNA_ID_enums.h:59
eKS_Settings
@ KEYINGSET_ABSOLUTE
eInsertKeyFlags
@ INSERTKEY_MATRIX
@ INSERTKEY_NEEDED
@ INSERTKEY_XYZ2RGB
@ KSP_GROUP_KSNAME
@ KSP_GROUP_NONE
@ KSP_FLAG_WHOLE_ARRAY
Object is a sort of wrapper for general info.
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
#define ANIM_KS_AVAILABLE_ID
#define IS_AUTOKEY_FLAG(scene, flag)
@ MODIFYKEY_MODE_INSERT
@ MODIFYKEY_MODE_DELETE
eModifyKey_Returns
@ MODIFYKEY_MISSING_TYPEINFO
@ MODIFYKEY_INVALID_CONTEXT
bool ED_operator_areaactive(struct bContext *C)
Definition: screen_ops.c:119
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
struct uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void uiItemsEnumO(uiLayout *layout, const char *opname, const char *propname)
uiBut * UI_context_active_but_prop_get(const struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop, int *r_index)
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL()
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define NC_ANIMATION
Definition: WM_types.h:289
#define ND_KEYINGSET
Definition: WM_types.h:348
#define NC_SCENE
Definition: WM_types.h:279
#define NA_ADDED
Definition: WM_types.h:464
#define ND_KEYFRAME
Definition: WM_types.h:394
Scene scene
const Depsgraph * depsgraph
#define GS(x)
Definition: iris.c:241
int delete_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act, const char rna_path[], int array_index, float cfra)
Definition: keyframing.c:1642
eInsertKeyFlags ANIM_get_keyframing_flags(Scene *scene, const bool use_autokey_mode)
Definition: keyframing.c:92
int insert_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, const AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, ListBase *nla_cache, eInsertKeyFlags flag)
Definition: keyframing.c:1413
eModifyKey_Returns ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
Definition: keyingsets.c:936
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
Definition: keyingsets.c:1028
static ListBase keyingset_type_infos
Definition: keyingsets.c:530
KeyingSet * ANIM_keyingset_get_from_enum_type(Scene *scene, int type)
Definition: keyingsets.c:819
void ANIM_OT_keying_set_add(wmOperatorType *ot)
Definition: keyingsets.c:133
static int keyingset_active_menu_exec(bContext *C, wmOperator *op)
Definition: keyingsets.c:488
static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
Definition: keyingsets.c:391
static void RKS_ITER_overrides_list(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks, ListBase *dsources)
Definition: keyingsets.c:884
static int remove_active_keyingset_exec(bContext *C, wmOperator *op)
Definition: keyingsets.c:147
static int add_default_keyingset_exec(bContext *C, wmOperator *UNUSED(op))
Definition: keyingsets.c:108
static bool keyingset_poll_active_edit(bContext *C)
Definition: keyingsets.c:75
static eInsertKeyFlags keyingset_apply_keying_flags(const eInsertKeyFlags base_flags, const eInsertKeyFlags overrides, const eInsertKeyFlags own_flags)
Definition: keyingsets.c:989
void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
Definition: keyingsets.c:267
static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: keyingsets.c:474
struct tRKS_DSource tRKS_DSource
KeyingSet * ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *transformKSName)
Definition: keyingsets.c:725
KeyingSetInfo * ANIM_keyingset_info_find_name(const char name[])
Definition: keyingsets.c:538
static bool keyingset_poll_activePath_edit(bContext *C)
Definition: keyingsets.c:88
void ANIM_OT_keyingset_button_add(wmOperatorType *ot)
Definition: keyingsets.c:371
void ANIM_OT_keying_set_remove(wmOperatorType *ot)
Definition: keyingsets.c:181
void ANIM_keyingset_infos_exit(void)
Definition: keyingsets.c:638
static bool keyingset_poll_default_add(bContext *C)
Definition: keyingsets.c:68
void ANIM_keyingset_info_unregister(Main *bmain, KeyingSetInfo *ksi)
Definition: keyingsets.c:608
KeyingSet * ANIM_scene_get_active_keyingset(const Scene *scene)
Definition: keyingsets.c:674
void ANIM_keyingset_info_register(KeyingSetInfo *ksi)
Definition: keyingsets.c:587
KeyingSet * ANIM_keyingset_get_from_idname(Scene *scene, const char *idname)
Definition: keyingsets.c:836
static int add_empty_ks_path_exec(bContext *C, wmOperator *op)
Definition: keyingsets.c:195
static int add_keyingset_button_exec(bContext *C, wmOperator *op)
Definition: keyingsets.c:284
ListBase builtin_keyingsets
Definition: keyingsets.c:533
KeyingSet * ANIM_builtin_keyingset_get_named(KeyingSet *prevKS, const char name[])
Definition: keyingsets.c:550
void ANIM_OT_keying_set_active_set(wmOperatorType *ot)
Definition: keyingsets.c:502
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
Definition: keyingsets.c:898
void ANIM_OT_keyingset_button_remove(wmOperatorType *ot)
Definition: keyingsets.c:453
void ANIM_OT_keying_set_path_add(wmOperatorType *ot)
Definition: keyingsets.c:224
int ANIM_scene_get_keyingset_index(Scene *scene, KeyingSet *ks)
Definition: keyingsets.c:693
#define APPLY_KEYINGFLAG_OVERRIDE(kflag)
bool ANIM_keyingset_find_id(KeyingSet *ks, ID *id)
Definition: keyingsets.c:658
static int remove_active_ks_path_exec(bContext *C, wmOperator *op)
Definition: keyingsets.c:238
const EnumPropertyItem * ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
Definition: keyingsets.c:743
bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
Definition: keyingsets.c:851
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static ulong * next
static void error(const char *str)
Definition: meshlaplacian.c:65
bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2168
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
char * RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6027
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1218
bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition: rna_access.c:5434
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
Definition: rna_define.c:4470
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
Definition: rna_define.c:4416
void RNA_enum_item_add_separator(EnumPropertyItem **items, int *totitem)
Definition: rna_define.c:4442
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
Definition: rna_define.c:3819
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
const EnumPropertyItem DummyRNA_DEFAULT_items[]
Definition: rna_rna.c:45
const char * identifier
Definition: RNA_types.h:446
void * data
Definition: RNA_types.h:680
StructFreeFunc free
Definition: RNA_types.h:683
Definition: DNA_ID.h:273
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
struct KS_Path * next
short keyingoverride
short flag
char group[64]
int array_index
short keyingflag
short groupmode
char * rna_path
struct ExtensionRNA rna_ext
cbKeyingSet_Generate generate
struct KeyingSetInfo * next
char description[240]
cbKeyingSet_Iterator iter
cbKeyingSet_Poll poll
char idname[64]
char description[240]
char name[64]
char typeinfo[64]
char idname[64]
struct KeyingSet * next
ListBase paths
short keyingflag
short keyingoverride
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase scenes
Definition: BKE_main.h:146
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
int active_keyingset
ListBase keyingsets
struct ToolSettings * toolsettings
struct tRKS_DSource * prev
Definition: keyingsets.c:876
struct tRKS_DSource * next
Definition: keyingsets.c:876
PointerRNA ptr
Definition: keyingsets.c:877
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
struct wmOperatorType * type
struct PointerRNA * ptr
__forceinline bool all(const avxb &b)
Definition: util_avxb.h:214
void WM_main_add_notifier(unsigned int type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156