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