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