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