Blender  V3.3
drivers.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 <ctype.h>
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "BLI_blenlib.h"
15 #include "BLI_string.h"
16 #include "BLI_utildefines.h"
17 
18 #include "DNA_anim_types.h"
19 #include "DNA_object_types.h"
20 #include "DNA_texture_types.h"
21 
22 #include "BKE_anim_data.h"
23 #include "BKE_animsys.h"
24 #include "BKE_context.h"
25 #include "BKE_fcurve.h"
26 #include "BKE_fcurve_driver.h"
27 #include "BKE_report.h"
28 
29 #include "DEG_depsgraph.h"
30 #include "DEG_depsgraph_build.h"
31 
32 #include "ED_keyframing.h"
33 
34 #include "UI_interface.h"
35 #include "UI_resources.h"
36 
37 #include "WM_api.h"
38 #include "WM_types.h"
39 
40 #include "RNA_access.h"
41 #include "RNA_define.h"
42 #include "RNA_path.h"
43 #include "RNA_prototypes.h"
44 
45 #include "anim_intern.h"
46 
47 /* ************************************************** */
48 /* Animation Data Validation */
49 
51  const char rna_path[],
52  const int array_index,
53  eDriverFCurveCreationMode creation_mode)
54 {
55  AnimData *adt;
56  FCurve *fcu;
57 
58  /* sanity checks */
59  if (ELEM(NULL, id, rna_path)) {
60  return NULL;
61  }
62 
63  /* init animdata if none available yet */
64  adt = BKE_animdata_from_id(id);
65  if (adt == NULL && creation_mode != DRIVER_FCURVE_LOOKUP_ONLY) {
66  adt = BKE_animdata_ensure_id(id);
67  }
68  if (adt == NULL) {
69  /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
70  return NULL;
71  }
72 
73  /* try to find f-curve matching for this setting
74  * - add if not found and allowed to add one
75  * TODO: add auto-grouping support? how this works will need to be resolved
76  */
77  fcu = BKE_fcurve_find(&adt->drivers, rna_path, array_index);
78 
79  if (fcu == NULL && creation_mode != DRIVER_FCURVE_LOOKUP_ONLY) {
80  /* use default settings to make a F-Curve */
81  fcu = alloc_driver_fcurve(rna_path, array_index, creation_mode);
82 
83  /* just add F-Curve to end of driver list */
84  BLI_addtail(&adt->drivers, fcu);
85  }
86 
87  /* return the F-Curve */
88  return fcu;
89 }
90 
91 struct FCurve *alloc_driver_fcurve(const char rna_path[],
92  const int array_index,
93  eDriverFCurveCreationMode creation_mode)
94 {
95  FCurve *fcu = BKE_fcurve_create();
96 
98  fcu->auto_smoothing = U.auto_smoothing_new;
99 
100  /* store path - make copy, and store that */
101  if (rna_path) {
102  fcu->rna_path = BLI_strdup(rna_path);
103  }
104  fcu->array_index = array_index;
105 
106  if (!ELEM(creation_mode, DRIVER_FCURVE_LOOKUP_ONLY, DRIVER_FCURVE_EMPTY)) {
107  /* add some new driver data */
108  fcu->driver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
109 
110  /* F-Modifier or Keyframes? */
111  if (creation_mode == DRIVER_FCURVE_GENERATOR) {
112  /* Python API Backwards compatibility hack:
113  * Create FModifier so that old scripts won't break
114  * for now before 2.7 series -- (September 4, 2013)
115  */
117  }
118  else {
119  /* add 2 keyframes so that user has something to work with
120  * - These are configured to 0,0 and 1,1 to give a 1-1 mapping
121  * which can be easily tweaked from there.
122  */
129  }
130  }
131 
132  return fcu;
133 }
134 
135 /* ************************************************** */
136 /* Driver Management API */
137 
138 /* Helper for ANIM_add_driver_with_target - Adds the actual driver */
140  ID *dst_id,
141  const char dst_path[],
142  int dst_index,
143  ID *src_id,
144  const char src_path[],
145  int src_index,
146  PointerRNA *dst_ptr,
147  PropertyRNA *dst_prop,
148  PointerRNA *src_ptr,
149  PropertyRNA *src_prop,
150  short flag,
151  int driver_type)
152 {
153  FCurve *fcu;
156  const char *prop_name = RNA_property_identifier(src_prop);
157 
158  /* Create F-Curve with Driver */
159  fcu = verify_driver_fcurve(dst_id, dst_path, dst_index, add_mode);
160 
161  if (fcu && fcu->driver) {
162  ChannelDriver *driver = fcu->driver;
163  DriverVar *dvar;
164 
165  /* Set the type of the driver */
166  driver->type = driver_type;
167 
168  /* Set driver expression, so that the driver works out of the box
169  *
170  * The following checks define a bit of "auto-detection magic" we use
171  * to ensure that the drivers will behave as expected out of the box
172  * when faced with properties with different units.
173  */
174  /* XXX: if we have N-1 mapping, should we include all those in the expression? */
175  if ((RNA_property_unit(dst_prop) == PROP_UNIT_ROTATION) &&
176  (RNA_property_unit(src_prop) != PROP_UNIT_ROTATION)) {
177  /* Rotation Destination: normal -> radians, so convert src to radians
178  * (However, if both input and output is a rotation, don't apply such corrections)
179  */
180  BLI_strncpy(driver->expression, "radians(var)", sizeof(driver->expression));
181  }
182  else if ((RNA_property_unit(src_prop) == PROP_UNIT_ROTATION) &&
183  (RNA_property_unit(dst_prop) != PROP_UNIT_ROTATION)) {
184  /* Rotation Source: radians -> normal, so convert src to degrees
185  * (However, if both input and output is a rotation, don't apply such corrections)
186  */
187  BLI_strncpy(driver->expression, "degrees(var)", sizeof(driver->expression));
188  }
189  else {
190  /* Just a normal property without any unit problems */
191  BLI_strncpy(driver->expression, "var", sizeof(driver->expression));
192  }
193 
194  /* Create a driver variable for the target
195  * - For transform properties, we want to automatically use "transform channel" instead
196  * (The only issue is with quaternion rotations vs euler channels...)
197  * - To avoid problems with transform properties depending on the final transform that they
198  * control (thus creating pseudo-cycles - see T48734), we don't use transform channels
199  * when both the source and destinations are in same places.
200  */
202 
203  if (ELEM(src_ptr->type, &RNA_Object, &RNA_PoseBone) &&
204  (STREQ(prop_name, "location") || STREQ(prop_name, "scale") ||
205  STRPREFIX(prop_name, "rotation_")) &&
206  (src_ptr->data != dst_ptr->data)) {
207  /* Transform Channel */
208  DriverTarget *dtar;
209 
211  dtar = &dvar->targets[0];
212 
213  /* Bone or Object target? */
214  dtar->id = src_id;
215  dtar->idtype = GS(src_id->name);
216 
217  if (src_ptr->type == &RNA_PoseBone) {
218  RNA_string_get(src_ptr, "name", dtar->pchan_name);
219  }
220 
221  /* Transform channel depends on type */
222  if (STREQ(prop_name, "location")) {
223  if (src_index == 2) {
225  }
226  else if (src_index == 1) {
228  }
229  else {
231  }
232  }
233  else if (STREQ(prop_name, "scale")) {
234  if (src_index == 2) {
236  }
237  else if (src_index == 1) {
239  }
240  else {
242  }
243  }
244  else {
245  /* XXX: With quaternions and axis-angle, this mapping might not be correct...
246  * But since those have 4 elements instead, there's not much we can do
247  */
248  if (src_index == 2) {
250  }
251  else if (src_index == 1) {
253  }
254  else {
256  }
257  }
258  }
259  else {
260  /* Single RNA Property */
261  DriverTarget *dtar = &dvar->targets[0];
262 
263  /* ID is as-is */
264  dtar->id = src_id;
265  dtar->idtype = GS(src_id->name);
266 
267  /* Need to make a copy of the path (or build one with array index built in) */
268  if (RNA_property_array_check(src_prop)) {
269  dtar->rna_path = BLI_sprintfN("%s[%d]", src_path, src_index);
270  }
271  else {
272  dtar->rna_path = BLI_strdup(src_path);
273  }
274  }
275  }
276 
277  /* set the done status */
278  return (fcu != NULL);
279 }
280 
282  ID *dst_id,
283  const char dst_path[],
284  int dst_index,
285  ID *src_id,
286  const char src_path[],
287  int src_index,
288  short flag,
289  int driver_type,
290  short mapping_type)
291 {
292  PointerRNA id_ptr, ptr;
293  PropertyRNA *prop;
294 
295  PointerRNA id_ptr2, ptr2;
296  PropertyRNA *prop2;
297  int done_tot = 0;
298 
299  /* validate pointers first - exit if failure */
300  RNA_id_pointer_create(dst_id, &id_ptr);
301  if (RNA_path_resolve_property(&id_ptr, dst_path, &ptr, &prop) == false) {
302  BKE_reportf(
303  reports,
304  RPT_ERROR,
305  "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
306  dst_id->name,
307  dst_path);
308  return 0;
309  }
310 
311  RNA_id_pointer_create(src_id, &id_ptr2);
312  if ((RNA_path_resolve_property(&id_ptr2, src_path, &ptr2, &prop2) == false) ||
313  (mapping_type == CREATEDRIVER_MAPPING_NONE)) {
314  /* No target - So, fall back to default method for adding a "simple" driver normally */
315  return ANIM_add_driver(
316  reports, dst_id, dst_path, dst_index, flag | CREATEDRIVER_WITH_DEFAULT_DVAR, driver_type);
317  }
318 
319  /* handle curve-property mappings based on mapping_type */
320  switch (mapping_type) {
321  case CREATEDRIVER_MAPPING_N_N: /* N-N - Try to match as much as possible,
322  * then use the first one */
323  {
324  /* Use the shorter of the two (to avoid out of bounds access) */
325  int dst_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
326  int src_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr2, prop2) : 1;
327 
328  int len = MIN2(dst_len, src_len);
329 
330  for (int i = 0; i < len; i++) {
331  done_tot += add_driver_with_target(reports,
332  dst_id,
333  dst_path,
334  i,
335  src_id,
336  src_path,
337  i,
338  &ptr,
339  prop,
340  &ptr2,
341  prop2,
342  flag,
343  driver_type);
344  }
345  break;
346  }
347 
348  case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
349  default: {
350  int len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
351 
352  for (int i = 0; i < len; i++) {
353  done_tot += add_driver_with_target(reports,
354  dst_id,
355  dst_path,
356  i,
357  src_id,
358  src_path,
359  src_index,
360  &ptr,
361  prop,
362  &ptr2,
363  prop2,
364  flag,
365  driver_type);
366  }
367  break;
368  }
369 
370  case CREATEDRIVER_MAPPING_1_1: /* 1-1 - Use the specified index (unless -1) */
371  {
372  done_tot = add_driver_with_target(reports,
373  dst_id,
374  dst_path,
375  dst_index,
376  src_id,
377  src_path,
378  src_index,
379  &ptr,
380  prop,
381  &ptr2,
382  prop2,
383  flag,
384  driver_type);
385  break;
386  }
387  }
388 
389  /* done */
390  return done_tot;
391 }
392 
393 /* --------------------------------- */
394 
396  ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
397 {
398  PointerRNA id_ptr, ptr;
399  PropertyRNA *prop;
400  FCurve *fcu;
401  int array_index_max;
402  int done_tot = 0;
403 
404  /* validate pointer first - exit if failure */
405  RNA_id_pointer_create(id, &id_ptr);
406  if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
407  BKE_reportf(
408  reports,
409  RPT_ERROR,
410  "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
411  id->name,
412  rna_path);
413  return 0;
414  }
415 
416  /* key entire array convenience method */
417  if (array_index == -1) {
418  array_index_max = RNA_property_array_length(&ptr, prop);
419  array_index = 0;
420  }
421  else {
422  array_index_max = array_index;
423  }
424 
425  /* maximum index should be greater than the start index */
426  if (array_index == array_index_max) {
427  array_index_max += 1;
428  }
429 
430  /* will only loop once unless the array index was -1 */
431  for (; array_index < array_index_max; array_index++) {
432  short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
433 
434  /* create F-Curve with Driver */
435  fcu = verify_driver_fcurve(id, rna_path, array_index, add_mode);
436 
437  if (fcu && fcu->driver) {
438  ChannelDriver *driver = fcu->driver;
439 
440  /* set the type of the driver */
441  driver->type = type;
442 
443  /* Creating drivers for buttons will create the driver(s) with type
444  * "scripted expression" so that their values won't be lost immediately,
445  * so here we copy those values over to the driver's expression
446  *
447  * If the "default dvar" option (for easier UI setup of drivers) is provided,
448  * include "var" in the expressions too, so that the user doesn't have to edit
449  * it to get something to happen. It should be fine to just add it to the default
450  * value, so that we get both in the expression, even if it's a bit more confusing
451  * that way...
452  */
453  if (type == DRIVER_TYPE_PYTHON) {
454  PropertyType proptype = RNA_property_type(prop);
455  int array = RNA_property_array_length(&ptr, prop);
456  const char *dvar_prefix = (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) ? "var + " : "";
457  char *expression = driver->expression;
458  int val, maxlen = sizeof(driver->expression);
459  float fval;
460 
461  if (proptype == PROP_BOOLEAN) {
462  if (!array) {
463  val = RNA_property_boolean_get(&ptr, prop);
464  }
465  else {
467  }
468 
469  BLI_snprintf(expression, maxlen, "%s%s", dvar_prefix, (val) ? "True" : "False");
470  }
471  else if (proptype == PROP_INT) {
472  if (!array) {
473  val = RNA_property_int_get(&ptr, prop);
474  }
475  else {
477  }
478 
479  BLI_snprintf(expression, maxlen, "%s%d", dvar_prefix, val);
480  }
481  else if (proptype == PROP_FLOAT) {
482  if (!array) {
483  fval = RNA_property_float_get(&ptr, prop);
484  }
485  else {
487  }
488 
489  BLI_snprintf(expression, maxlen, "%s%.3f", dvar_prefix, fval);
490  BLI_str_rstrip_float_zero(expression, '\0');
491  }
493  BLI_strncpy(expression, "var", maxlen);
494  }
495  }
496 
497  /* for easier setup of drivers from UI, a driver variable should be
498  * added if flag is set (UI calls only)
499  */
501  /* assume that users will mostly want this to be of type "Transform Channel" too,
502  * since this allows the easiest setting up of common rig components
503  */
506  }
507  }
508 
509  /* set the done status */
510  done_tot += (fcu != NULL);
511  }
512 
513  /* done */
514  return done_tot;
515 }
516 
518  ID *id,
519  const char rna_path[],
520  int array_index,
521  short UNUSED(flag))
522 {
523  AnimData *adt;
524  FCurve *fcu;
525  bool success = false;
526 
527  /* we don't check the validity of the path here yet, but it should be ok... */
528  adt = BKE_animdata_from_id(id);
529 
530  if (adt) {
531  if (array_index == -1) {
532  /* step through all drivers, removing all of those with the same base path */
533  FCurve *fcu_iter = adt->drivers.first;
534 
535  while ((fcu = BKE_fcurve_iter_step(fcu_iter, rna_path)) != NULL) {
536  /* Store the next fcurve for looping. */
537  fcu_iter = fcu->next;
538 
539  /* remove F-Curve from driver stack, then free it */
540  BLI_remlink(&adt->drivers, fcu);
541  BKE_fcurve_free(fcu);
542 
543  /* done successfully */
544  success = true;
545  }
546  }
547  else {
548  /* find the matching driver and remove it only
549  * NOTE: here is one of the places where we don't want new F-Curve + Driver added!
550  * so 'add' var must be 0
551  */
553  if (fcu) {
554  BLI_remlink(&adt->drivers, fcu);
555  BKE_fcurve_free(fcu);
556 
557  success = true;
558  }
559  }
560  }
561 
562  return success;
563 }
564 
565 /* ************************************************** */
566 /* Driver Management API - Copy/Paste Drivers */
567 
568 /* Copy/Paste Buffer for Driver Data... */
570 
572 {
573  /* free the buffer F-Curve if it exists, as if it were just another F-Curve */
576  }
578 }
579 
581 {
582  return (channeldriver_copypaste_buf != NULL);
583 }
584 
585 /* ------------------- */
586 
588  ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
589 {
590  PointerRNA id_ptr, ptr;
591  PropertyRNA *prop;
592  FCurve *fcu;
593 
594  /* validate pointer first - exit if failure */
595  RNA_id_pointer_create(id, &id_ptr);
596  if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
597  BKE_reportf(reports,
598  RPT_ERROR,
599  "Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, "
600  "path = %s)",
601  id->name,
602  rna_path);
603  return 0;
604  }
605 
606  /* try to get F-Curve with Driver */
608 
609  /* clear copy/paste buffer first (for consistency with other copy/paste buffers) */
611 
612  /* copy this to the copy/paste buf if it exists */
613  if (fcu && fcu->driver) {
614  /* Make copies of some info such as the rna_path, then clear this info from the
615  * F-Curve temporarily so that we don't end up wasting memory storing the path
616  * which won't get used ever.
617  */
618  char *tmp_path = fcu->rna_path;
619  fcu->rna_path = NULL;
620 
621  /* make a copy of the F-Curve with */
623 
624  /* restore the path */
625  fcu->rna_path = tmp_path;
626 
627  /* copied... */
628  return 1;
629  }
630 
631  /* done */
632  return 0;
633 }
634 
636  ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
637 {
638  PointerRNA id_ptr, ptr;
639  PropertyRNA *prop;
640  FCurve *fcu;
641 
642  /* validate pointer first - exit if failure */
643  RNA_id_pointer_create(id, &id_ptr);
644  if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
645  BKE_reportf(
646  reports,
647  RPT_ERROR,
648  "Could not paste driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
649  id->name,
650  rna_path);
651  return 0;
652  }
653 
654  /* if the buffer is empty, cannot paste... */
656  BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste");
657  return 0;
658  }
659 
660  /* create Driver F-Curve, but without data which will be copied across... */
662 
663  if (fcu) {
664  /* copy across the curve data from the buffer curve
665  * NOTE: this step needs care to not miss new settings
666  */
667  /* keyframes/samples */
671 
672  /* modifiers */
674 
675  /* extrapolation mode */
677 
678  /* the 'juicy' stuff - the driver */
680  }
681 
682  /* done */
683  return (fcu != NULL);
684 }
685 
686 /* ************************************************** */
687 /* Driver Management API - Copy/Paste Driver Variables */
688 
689 /* Copy/Paste Buffer for Driver Variables... */
691 
693 {
694  /* Free the driver variables kept in the buffer */
696  DriverVar *dvar, *dvarn;
697 
698  /* Free variables (and any data they use) */
699  for (dvar = driver_vars_copybuf.first; dvar; dvar = dvarn) {
700  dvarn = dvar->next;
702  }
703  }
704 
706 }
707 
709 {
710  return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
711 }
712 
713 /* -------------------------------------------------- */
714 
716 {
717  /* sanity checks */
718  if (ELEM(NULL, fcu, fcu->driver)) {
719  BKE_report(reports, RPT_ERROR, "No driver to copy variables from");
720  return false;
721  }
722 
723  if (BLI_listbase_is_empty(&fcu->driver->variables)) {
724  BKE_report(reports, RPT_ERROR, "Driver has no variables to copy");
725  return false;
726  }
727 
728  /* clear buffer */
730 
731  /* copy over the variables */
733 
734  return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
735 }
736 
737 bool ANIM_driver_vars_paste(ReportList *reports, FCurve *fcu, bool replace)
738 {
739  ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
740  ListBase tmp_list = {NULL, NULL};
741 
742  /* sanity checks */
744  BKE_report(reports, RPT_ERROR, "No driver variables in clipboard to paste");
745  return false;
746  }
747 
748  if (ELEM(NULL, fcu, fcu->driver)) {
749  BKE_report(reports, RPT_ERROR, "Cannot paste driver variables without a driver");
750  return false;
751  }
752 
753  /* 1) Make a new copy of the variables in the buffer - these will get pasted later... */
755 
756  /* 2) Prepare destination array */
757  if (replace) {
758  DriverVar *dvar, *dvarn;
759 
760  /* Free all existing vars first - We aren't retaining anything */
761  for (dvar = driver->variables.first; dvar; dvar = dvarn) {
762  dvarn = dvar->next;
764  }
765 
767  }
768 
769  /* 3) Add new vars */
770  if (driver->variables.last) {
771  DriverVar *last = driver->variables.last;
772  DriverVar *first = tmp_list.first;
773 
774  last->next = first;
775  first->prev = last;
776 
777  driver->variables.last = tmp_list.last;
778  }
779  else {
780  driver->variables.first = tmp_list.first;
781  driver->variables.last = tmp_list.last;
782  }
783 
784  /* since driver variables are cached, the expression needs re-compiling too */
786 
787  return true;
788 }
789 
790 /* -------------------------------------------------- */
791 
792 void ANIM_copy_as_driver(struct ID *target_id, const char *target_path, const char *var_name)
793 {
794  /* Clear copy/paste buffer first (for consistency with other copy/paste buffers). */
797 
798  /* Create a dummy driver F-Curve. */
800  ChannelDriver *driver = fcu->driver;
801 
802  /* Create a variable. */
804  DriverTarget *target = &var->targets[0];
805 
806  target->idtype = GS(target_id->name);
807  target->id = target_id;
808  target->rna_path = MEM_dupallocN(target_path);
809 
810  /* Set the variable name. */
811  if (var_name) {
812  BLI_strncpy(var->name, var_name, sizeof(var->name));
813 
814  /* Sanitize the name. */
815  for (int i = 0; var->name[i]; i++) {
816  if (!(i > 0 ? isalnum(var->name[i]) : isalpha(var->name[i]))) {
817  var->name[i] = '_';
818  }
819  }
820  }
821 
823 
824  /* Store the driver into the copy/paste buffers. */
826 
828 }
829 
830 /* ************************************************** */
831 /* UI-Button Interface */
832 
833 /* Add Driver - Enum Defines ------------------------- */
834 
836  /* XXX: These names need reviewing. */
838  "SINGLE_MANY",
839  0,
840  "All from Target",
841  "Drive all components of this property using the target picked"},
843  "DIRECT",
844  0,
845  "Single from Target",
846  "Drive this component of this property using the target picked"},
847 
849  "MATCH",
850  ICON_COLOR,
851  "Match Indices",
852  "Create drivers for each pair of corresponding elements"},
853 
855  "NONE_ALL",
856  ICON_HAND,
857  "Manually Create Later",
858  "Create drivers for all properties without assigning any targets yet"},
860  "NONE_SINGLE",
861  0,
862  "Manually Create Later (Single)",
863  "Create driver for this property only and without assigning any targets yet"},
864  {0, NULL, 0, NULL, NULL},
865 };
866 
867 /* Filtering callback for driver mapping types enum */
869  PointerRNA *UNUSED(owner_ptr),
870  PropertyRNA *UNUSED(owner_prop),
871  bool *r_free)
872 {
874  EnumPropertyItem *item = NULL;
875 
876  PointerRNA ptr = {NULL};
877  PropertyRNA *prop = NULL;
878  int index;
879 
880  int totitem = 0;
881 
882  if (!C) { /* needed for docs */
884  }
885 
886  UI_context_active_but_prop_get(C, &ptr, &prop, &index);
887 
888  if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
889  const bool is_array = RNA_property_array_check(prop);
890 
891  while (input->identifier) {
892  if (ELEM(input->value, CREATEDRIVER_MAPPING_1_1, CREATEDRIVER_MAPPING_NONE) || (is_array)) {
893  RNA_enum_item_add(&item, &totitem, input);
894  }
895  input++;
896  }
897  }
898  else {
899  /* We need at least this one! */
901  }
902 
903  RNA_enum_item_end(&item, &totitem);
904 
905  *r_free = true;
906  return item;
907 }
908 
909 /* Add Driver (With Menu) Button Operator ------------------------ */
910 
912 {
913  PointerRNA ptr = {NULL};
914  PropertyRNA *prop = NULL;
915  int index;
916  bool driven, special;
917 
918  /* this operator can only run if there's a property button active, and it can be animated */
919  UI_context_active_but_prop_get(C, &ptr, &prop, &index);
920 
921  if (!(ptr.owner_id && ptr.data && prop)) {
922  return false;
923  }
924  if (!RNA_property_animateable(&ptr, prop)) {
925  return false;
926  }
927 
928  /* Don't do anything if there is an fcurve for animation without a driver. */
930  C, &ptr, prop, index, NULL, NULL, &driven, &special);
931  return (fcu == NULL || fcu->driver);
932 }
933 
934 /* Wrapper for creating a driver without knowing what the targets will be yet
935  * (i.e. "manual/add later"). */
936 static int add_driver_button_none(bContext *C, wmOperator *op, short mapping_type)
937 {
938  PointerRNA ptr = {NULL};
939  PropertyRNA *prop = NULL;
940  int index;
941  int success = 0;
942 
943  UI_context_active_but_prop_get(C, &ptr, &prop, &index);
944 
945  if (mapping_type == CREATEDRIVER_MAPPING_NONE_ALL) {
946  index = -1;
947  }
948 
949  if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
950  char *path = RNA_path_from_ID_to_property(&ptr, prop);
951  short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
952 
953  if (path) {
954  success += ANIM_add_driver(
955  op->reports, ptr.owner_id, path, index, flags, DRIVER_TYPE_PYTHON);
956  MEM_freeN(path);
957  }
958  }
959 
960  if (success) {
961  /* send updates */
965 
966  return OPERATOR_FINISHED;
967  }
968  return OPERATOR_CANCELLED;
969 }
970 
972 {
973  short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
975  /* Just create driver with no targets */
976  return add_driver_button_none(C, op, mapping_type);
977  }
978 
979  /* Create Driver using Eyedropper */
980  wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
981 
982  /* XXX: We assume that it's fine to use the same set of properties,
983  * since they're actually the same. */
985 
986  return OPERATOR_FINISHED;
987 }
988 
989 /* Show menu or create drivers */
991 {
992  PropertyRNA *prop;
993 
994  if ((prop = RNA_struct_find_property(op->ptr, "mapping_type")) &&
995  RNA_property_is_set(op->ptr, prop)) {
996  /* Mapping Type is Set - Directly go into creating drivers */
997  return add_driver_button_menu_exec(C, op);
998  }
999 
1000  /* Show menu */
1001  /* TODO: This should get filtered by the enum filter. */
1002  /* important to execute in the region we're currently in. */
1004 }
1005 
1007 {
1008  /* identifiers */
1009  ot->name = "Add Driver Menu";
1010  ot->idname = "ANIM_OT_driver_button_add_menu";
1011  ot->description = "Add driver(s) for the property(s) represented by the highlighted button";
1012 
1013  /* callbacks */
1017 
1018  /* flags */
1020 
1021  /* properties */
1022  ot->prop = RNA_def_enum(ot->srna,
1023  "mapping_type",
1025  0,
1026  "Mapping Type",
1027  "Method used to match target and driven properties");
1029 }
1030 
1031 /* Add Driver Button Operator ------------------------ */
1032 
1034 {
1035  PointerRNA ptr = {NULL};
1036  PropertyRNA *prop = NULL;
1037  int index;
1038 
1039  /* try to find driver using property retrieved from UI */
1040  UI_context_active_but_prop_get(C, &ptr, &prop, &index);
1041 
1042  if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
1043  /* 1) Create a new "empty" driver for this property */
1044  char *path = RNA_path_from_ID_to_property(&ptr, prop);
1045  short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
1046  bool changed = false;
1047 
1048  if (path) {
1049  changed |= (ANIM_add_driver(
1050  op->reports, ptr.owner_id, path, index, flags, DRIVER_TYPE_PYTHON) != 0);
1051  MEM_freeN(path);
1052  }
1053 
1054  if (changed) {
1055  /* send updates */
1060  }
1061 
1062  /* 2) Show editing panel for setting up this driver */
1063  /* TODO: Use a different one from the editing popover, so we can have the single/all toggle? */
1064  UI_popover_panel_invoke(C, "GRAPH_PT_drivers_popover", true, op->reports);
1065  }
1066 
1067  return OPERATOR_INTERFACE;
1068 }
1069 
1071 {
1072  /* identifiers */
1073  ot->name = "Add Driver";
1074  ot->idname = "ANIM_OT_driver_button_add";
1075  ot->description = "Add driver for the property under the cursor";
1076 
1077  /* callbacks */
1078  /* NOTE: No exec, as we need all these to use the current context info */
1081 
1082  /* flags */
1084 }
1085 
1086 /* Remove Driver Button Operator ------------------------ */
1087 
1089 {
1090  PointerRNA ptr = {NULL};
1091  PropertyRNA *prop = NULL;
1092  bool changed = false;
1093  int index;
1094  const bool all = RNA_boolean_get(op->ptr, "all");
1095 
1096  /* try to find driver using property retrieved from UI */
1097  UI_context_active_but_prop_get(C, &ptr, &prop, &index);
1098 
1099  if (all) {
1100  index = -1;
1101  }
1102 
1103  if (ptr.owner_id && ptr.data && prop) {
1104  char *path = RNA_path_from_ID_to_property(&ptr, prop);
1105 
1106  if (path) {
1107  changed = ANIM_remove_driver(op->reports, ptr.owner_id, path, index, 0);
1108 
1109  MEM_freeN(path);
1110  }
1111  }
1112 
1113  if (changed) {
1114  /* send updates */
1118  }
1119 
1120  return (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1121 }
1122 
1124 {
1125  /* identifiers */
1126  ot->name = "Remove Driver";
1127  ot->idname = "ANIM_OT_driver_button_remove";
1128  ot->description =
1129  "Remove the driver(s) for the property(s) connected represented by the highlighted button";
1130 
1131  /* callbacks */
1133  /* TODO: `op->poll` need to have some driver to be able to do this. */
1134 
1135  /* flags */
1137 
1138  /* properties */
1139  RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array");
1140 }
1141 
1142 /* Edit Driver Button Operator ------------------------ */
1143 
1145 {
1146  PointerRNA ptr = {NULL};
1147  PropertyRNA *prop = NULL;
1148  int index;
1149 
1150  /* try to find driver using property retrieved from UI */
1151  UI_context_active_but_prop_get(C, &ptr, &prop, &index);
1152 
1153  if (ptr.owner_id && ptr.data && prop) {
1154  UI_popover_panel_invoke(C, "GRAPH_PT_drivers_popover", true, op->reports);
1155  }
1156 
1157  return OPERATOR_INTERFACE;
1158 }
1159 
1161 {
1162  /* identifiers */
1163  ot->name = "Edit Driver";
1164  ot->idname = "ANIM_OT_driver_button_edit";
1165  ot->description =
1166  "Edit the drivers for the property connected represented by the highlighted button";
1167 
1168  /* callbacks */
1170  /* TODO: `op->poll` need to have some driver to be able to do this. */
1171 
1172  /* flags */
1174 }
1175 
1176 /* Copy Driver Button Operator ------------------------ */
1177 
1179 {
1180  PointerRNA ptr = {NULL};
1181  PropertyRNA *prop = NULL;
1182  bool changed = false;
1183  int index;
1184 
1185  /* try to create driver using property retrieved from UI */
1186  UI_context_active_but_prop_get(C, &ptr, &prop, &index);
1187 
1188  if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
1189  char *path = RNA_path_from_ID_to_property(&ptr, prop);
1190 
1191  if (path) {
1192  /* only copy the driver for the button that this was involved for */
1193  changed = ANIM_copy_driver(op->reports, ptr.owner_id, path, index, 0);
1194 
1196 
1197  MEM_freeN(path);
1198  }
1199  }
1200 
1201  /* Since we're just copying, we don't really need to do anything else. */
1202  return (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1203 }
1204 
1206 {
1207  /* identifiers */
1208  ot->name = "Copy Driver";
1209  ot->idname = "ANIM_OT_copy_driver_button";
1210  ot->description = "Copy the driver for the highlighted button";
1211 
1212  /* callbacks */
1214  /* TODO: `op->poll` need to have some driver to be able to do this. */
1215 
1216  /* flags */
1218 }
1219 
1220 /* Paste Driver Button Operator ------------------------ */
1221 
1223 {
1224  PointerRNA ptr = {NULL};
1225  PropertyRNA *prop = NULL;
1226  bool changed = false;
1227  int index;
1228 
1229  /* try to create driver using property retrieved from UI */
1230  UI_context_active_but_prop_get(C, &ptr, &prop, &index);
1231 
1232  if (ptr.owner_id && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
1233  char *path = RNA_path_from_ID_to_property(&ptr, prop);
1234 
1235  if (path) {
1236  /* only copy the driver for the button that this was involved for */
1237  changed = ANIM_paste_driver(op->reports, ptr.owner_id, path, index, 0);
1238 
1240 
1242 
1244 
1246 
1247  MEM_freeN(path);
1248  }
1249  }
1250 
1251  /* Since we're just copying, we don't really need to do anything else. */
1252  return (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1253 }
1254 
1256 {
1257  /* identifiers */
1258  ot->name = "Paste Driver";
1259  ot->idname = "ANIM_OT_paste_driver_button";
1260  ot->description = "Paste the driver in the copy/paste buffer for the highlighted button";
1261 
1262  /* callbacks */
1264  /* TODO: `op->poll` need to have some driver to be able to do this. */
1265 
1266  /* flags */
1268 }
1269 
1270 /* ************************************************** */
struct AnimData * BKE_animdata_ensure_id(struct ID *id)
Definition: anim_data.c:90
struct AnimData * BKE_animdata_from_id(const struct ID *id)
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
void copy_fmodifiers(ListBase *dst, const ListBase *src)
Definition: fmodifier.c:1164
void BKE_fcurve_free(struct FCurve *fcu)
Definition: fcurve.c:65
struct FCurve * BKE_fcurve_find_by_rna_context_ui(struct bContext *C, const struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct AnimData **r_animdata, struct bAction **r_action, bool *r_driven, bool *r_special)
struct FCurve * BKE_fcurve_copy(const struct FCurve *fcu)
struct FCurve * BKE_fcurve_iter_step(struct FCurve *fcu_iter, const char rna_path[])
Definition: fcurve.c:277
void BKE_fcurve_handles_recalc(struct FCurve *fcu)
Definition: fcurve.c:1303
struct FModifier * add_fmodifier(ListBase *modifiers, int type, struct FCurve *owner_fcu)
Definition: fmodifier.c:1087
struct FCurve * BKE_fcurve_create(void)
Definition: fcurve.c:53
struct FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], int array_index)
Definition: fcurve.c:249
void BKE_driver_invalidate_expression(struct ChannelDriver *driver, bool expr_changed, bool varname_changed)
void driver_variables_copy(struct ListBase *dst_vars, const struct ListBase *src_vars)
struct DriverVar * driver_add_new_variable(struct ChannelDriver *driver)
void driver_free_variable_ex(struct ChannelDriver *driver, struct DriverVar *dvar)
void driver_free_variable(struct ListBase *variables, struct DriverVar *dvar)
void driver_change_variable_type(struct DriverVar *dvar, int type)
struct ChannelDriver * fcurve_copy_driver(const struct ChannelDriver *driver)
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
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
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
size_t size_t char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
int BLI_str_rstrip_float_zero(char *str, char pad) ATTR_NONNULL()
Definition: string.c:963
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define UNUSED_FUNCTION(x)
#define STRPREFIX(a, b)
#define UNUSED(x)
#define ELEM(...)
#define MIN2(a, b)
#define STREQ(a, b)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_ANIMATION
Definition: DNA_ID.h:794
@ DTAR_TRANSCHAN_ROTZ
@ DTAR_TRANSCHAN_SCALEX
@ DTAR_TRANSCHAN_SCALEZ
@ DTAR_TRANSCHAN_LOCX
@ DTAR_TRANSCHAN_LOCY
@ DTAR_TRANSCHAN_ROTX
@ DTAR_TRANSCHAN_LOCZ
@ DTAR_TRANSCHAN_SCALEY
@ DTAR_TRANSCHAN_ROTY
@ DRIVER_TYPE_PYTHON
@ DVAR_TYPE_TRANSFORM_CHAN
@ INSERTKEY_FAST
@ INSERTKEY_NO_USERPREF
@ FMODIFIER_TYPE_GENERATOR
@ FCURVE_SELECTED
@ FCURVE_VISIBLE
@ FCURVE_EXTRAPOLATE_LINEAR
@ BEZT_KEYTYPE_KEYFRAME
Object is a sort of wrapper for general info.
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ CREATEDRIVER_WITH_FMODIFIER
@ CREATEDRIVER_WITH_DEFAULT_DVAR
@ CREATEDRIVER_MAPPING_NONE_ALL
@ CREATEDRIVER_MAPPING_1_N
@ CREATEDRIVER_MAPPING_NONE
@ CREATEDRIVER_MAPPING_N_N
@ CREATEDRIVER_MAPPING_1_1
eDriverFCurveCreationMode
@ DRIVER_FCURVE_LOOKUP_ONLY
@ DRIVER_FCURVE_KEYFRAMES
@ DRIVER_FCURVE_EMPTY
@ DRIVER_FCURVE_GENERATOR
_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.
PropertyType
Definition: RNA_types.h:58
@ PROP_FLOAT
Definition: RNA_types.h:61
@ PROP_BOOLEAN
Definition: RNA_types.h:59
@ PROP_INT
Definition: RNA_types.h:60
@ PROP_UNIT_ROTATION
Definition: RNA_types.h:75
#define C
Definition: RandGen.cpp:25
uiBut * UI_context_active_but_prop_get(const struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop, int *r_index)
int UI_popover_panel_invoke(struct bContext *C, const char *idname, bool keep_open, struct ReportList *reports)
void UI_context_update_anim_flag(const struct bContext *C)
@ OPTYPE_INTERNAL
Definition: WM_types.h:168
@ OPTYPE_UNDO
Definition: WM_types.h:148
#define NC_ANIMATION
Definition: WM_types.h:338
#define ND_KEYFRAME_PROP
Definition: WM_types.h:443
#define ND_FCURVES_ORDER
Definition: WM_types.h:447
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:201
__forceinline bool all(const avxb &b)
Definition: avxb.h:201
unsigned int U
Definition: btGjkEpa3.h:78
int len
Definition: draw_manager.c:108
static int add_driver_button_none(bContext *C, wmOperator *op, short mapping_type)
Definition: drivers.c:936
void ANIM_copy_as_driver(struct ID *target_id, const char *target_path, const char *var_name)
Definition: drivers.c:792
void ANIM_OT_driver_button_remove(wmOperatorType *ot)
Definition: drivers.c:1123
static int remove_driver_button_exec(bContext *C, wmOperator *op)
Definition: drivers.c:1088
void ANIM_driver_vars_copybuf_free(void)
Definition: drivers.c:692
void ANIM_OT_driver_button_add(wmOperatorType *ot)
Definition: drivers.c:1070
static void UNUSED_FUNCTION() ANIM_OT_driver_button_add_menu(wmOperatorType *ot)
Definition: drivers.c:1006
static int edit_driver_button_exec(bContext *C, wmOperator *op)
Definition: drivers.c:1144
static int add_driver_button_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: drivers.c:1033
void ANIM_OT_driver_button_edit(wmOperatorType *ot)
Definition: drivers.c:1160
static int add_driver_button_menu_exec(bContext *C, wmOperator *op)
Definition: drivers.c:971
static bool add_driver_button_poll(bContext *C)
Definition: drivers.c:911
static int add_driver_with_target(ReportList *UNUSED(reports), ID *dst_id, const char dst_path[], int dst_index, ID *src_id, const char src_path[], int src_index, PointerRNA *dst_ptr, PropertyRNA *dst_prop, PointerRNA *src_ptr, PropertyRNA *src_prop, short flag, int driver_type)
Definition: drivers.c:139
bool ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_path[], int array_index, short UNUSED(flag))
Definition: drivers.c:517
static const EnumPropertyItem * driver_mapping_type_itemf(bContext *C, PointerRNA *UNUSED(owner_ptr), PropertyRNA *UNUSED(owner_prop), bool *r_free)
Definition: drivers.c:868
bool ANIM_driver_vars_copy(ReportList *reports, FCurve *fcu)
Definition: drivers.c:715
bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
Definition: drivers.c:635
bool ANIM_driver_can_paste(void)
Definition: drivers.c:580
EnumPropertyItem prop_driver_create_mapping_types[]
Definition: drivers.c:835
int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
Main Driver Management API calls.
Definition: drivers.c:395
int ANIM_add_driver_with_target(ReportList *reports, ID *dst_id, const char dst_path[], int dst_index, ID *src_id, const char src_path[], int src_index, short flag, int driver_type, short mapping_type)
Main Driver Management API calls.
Definition: drivers.c:281
bool ANIM_driver_vars_paste(ReportList *reports, FCurve *fcu, bool replace)
Definition: drivers.c:737
void ANIM_OT_paste_driver_button(wmOperatorType *ot)
Definition: drivers.c:1255
bool ANIM_driver_vars_can_paste(void)
Definition: drivers.c:708
bool ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
Definition: drivers.c:587
struct FCurve * alloc_driver_fcurve(const char rna_path[], const int array_index, eDriverFCurveCreationMode creation_mode)
Definition: drivers.c:91
static int add_driver_button_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: drivers.c:990
void ANIM_OT_copy_driver_button(wmOperatorType *ot)
Definition: drivers.c:1205
static ListBase driver_vars_copybuf
Definition: drivers.c:690
void ANIM_drivers_copybuf_free(void)
Definition: drivers.c:571
static int paste_driver_button_exec(bContext *C, wmOperator *op)
Definition: drivers.c:1222
FCurve * verify_driver_fcurve(ID *id, const char rna_path[], const int array_index, eDriverFCurveCreationMode creation_mode)
Definition: drivers.c:50
static int copy_driver_button_exec(bContext *C, wmOperator *op)
Definition: drivers.c:1178
static FCurve * channeldriver_copypaste_buf
Definition: drivers.c:569
#define GS(x)
Definition: iris.c:225
ccl_global KernelShaderEvalInput * input
int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag)
Main Key-framing API call.
Definition: keyframing.c:545
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
bool RNA_property_array_check(PropertyRNA *prop)
Definition: rna_access.c:1080
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2581
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
bool RNA_property_animateable(const PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1993
PropertyUnit RNA_property_unit(PropertyRNA *prop)
Definition: rna_access.c:1032
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2954
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2153
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2429
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:5116
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
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2275
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_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
Definition: rna_define.c:3830
void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item, int value)
Definition: rna_define.c:4472
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
ListBase drivers
ListBase variables
char expression[256]
char pchan_name[64]
struct DriverVar * next
DriverTarget targets[8]
char name[64]
struct DriverVar * prev
struct FCurve * next
char * rna_path
FPoint * fpt
ChannelDriver * driver
BezTriple * bezt
short extend
int array_index
short flag
unsigned int totvert
char auto_smoothing
ListBase modifiers
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
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
PropertyRNA * prop
Definition: WM_types.h:981
struct ReportList * reports
struct PointerRNA * ptr
int WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
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
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
int WM_menu_invoke_ex(bContext *C, wmOperator *op, wmOperatorCallContext opcontext)