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