b50943ba9f12ca598a6c5333f3925dd89316fa01
[blender.git] / source / blender / blenkernel / intern / fcurve.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Joshua Leung (full recode)
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29  
30
31 #include <math.h>
32 #include <stdio.h>
33 #include <stddef.h>
34 #include <string.h>
35 #include <float.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_anim_types.h"
40 #include "DNA_object_types.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_math.h"
44 #include "BLI_utildefines.h"
45
46 #include "BKE_fcurve.h"
47 #include "BKE_animsys.h"
48 #include "BKE_action.h"
49 #include "BKE_armature.h"
50 #include "BKE_curve.h" 
51 #include "BKE_global.h"
52 #include "BKE_object.h"
53 #include "BKE_utildefines.h"
54
55 #include "RNA_access.h"
56
57 #ifdef WITH_PYTHON
58 #include "BPY_extern.h" 
59 #endif
60
61 #define SMALL -1.0e-10
62 #define SELECT 1
63
64 /* ************************** Data-Level Functions ************************* */
65
66 /* ---------------------- Freeing --------------------------- */
67
68 /* Frees the F-Curve itself too, so make sure BLI_remlink is called before calling this... */
69 void free_fcurve (FCurve *fcu) 
70 {
71         if (fcu == NULL) 
72                 return;
73         
74         /* free curve data */
75         if (fcu) {
76                 if (fcu->bezt) MEM_freeN(fcu->bezt);
77                 if (fcu->fpt) MEM_freeN(fcu->fpt);
78         }
79         
80         /* free RNA-path, as this were allocated when getting the path string */
81         if (fcu->rna_path)
82                 MEM_freeN(fcu->rna_path);
83         
84         /* free extra data - i.e. modifiers, and driver */
85         fcurve_free_driver(fcu);
86         free_fmodifiers(&fcu->modifiers);
87         
88         /* free f-curve itself */
89         MEM_freeN(fcu);
90 }
91
92 /* Frees a list of F-Curves */
93 void free_fcurves (ListBase *list)
94 {
95         FCurve *fcu, *fcn;
96         
97         /* sanity check */
98         if (list == NULL)
99                 return;
100                 
101         /* free data - no need to call remlink before freeing each curve, 
102          * as we store reference to next, and freeing only touches the curve
103          * it's given
104          */
105         for (fcu= list->first; fcu; fcu= fcn) {
106                 fcn= fcu->next;
107                 free_fcurve(fcu);
108         }
109         
110         /* clear pointers just in case */
111         list->first= list->last= NULL;
112 }       
113
114 /* ---------------------- Copy --------------------------- */
115
116 /* duplicate an F-Curve */
117 FCurve *copy_fcurve (FCurve *fcu)
118 {
119         FCurve *fcu_d;
120         
121         /* sanity check */
122         if (fcu == NULL)
123                 return NULL;
124                 
125         /* make a copy */
126         fcu_d= MEM_dupallocN(fcu);
127         
128         fcu_d->next= fcu_d->prev= NULL;
129         fcu_d->grp= NULL;
130         
131         /* copy curve data */
132         fcu_d->bezt= MEM_dupallocN(fcu_d->bezt);
133         fcu_d->fpt= MEM_dupallocN(fcu_d->fpt);
134         
135         /* copy rna-path */
136         fcu_d->rna_path= MEM_dupallocN(fcu_d->rna_path);
137         
138         /* copy driver */
139         fcu_d->driver= fcurve_copy_driver(fcu_d->driver);
140         
141         /* copy modifiers */
142         copy_fmodifiers(&fcu_d->modifiers, &fcu->modifiers);
143         
144         /* return new data */
145         return fcu_d;
146 }
147
148 /* duplicate a list of F-Curves */
149 void copy_fcurves (ListBase *dst, ListBase *src)
150 {
151         FCurve *dfcu, *sfcu;
152         
153         /* sanity checks */
154         if ELEM(NULL, dst, src)
155                 return;
156         
157         /* clear destination list first */
158         dst->first= dst->last= NULL;
159         
160         /* copy one-by-one */
161         for (sfcu= src->first; sfcu; sfcu= sfcu->next) {
162                 dfcu= copy_fcurve(sfcu);
163                 BLI_addtail(dst, dfcu);
164         }
165 }
166
167 /* ----------------- Finding F-Curves -------------------------- */
168
169 /* high level function to get an fcurve from C without having the rna */
170 FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *prop_name, int index)
171 {
172         /* anim vars */
173         AnimData *adt= BKE_animdata_from_id(id);
174         FCurve *fcu= NULL;
175
176         /* rna vars */
177         PointerRNA ptr;
178         PropertyRNA *prop;
179         char *path;
180         
181         /* only use the current action ??? */
182         if (ELEM(NULL, adt, adt->action))
183                 return NULL;
184         
185         RNA_pointer_create(id, type, data, &ptr);
186         prop = RNA_struct_find_property(&ptr, prop_name);
187         
188         if (prop) {
189                 path= RNA_path_from_ID_to_property(&ptr, prop);
190                         
191                 if (path) {
192                         /* animation takes priority over drivers */
193                         if ((adt->action) && (adt->action->curves.first))
194                                 fcu= list_find_fcurve(&adt->action->curves, path, index);
195                         
196                         /* if not animated, check if driven */
197 #if 0
198                         if ((fcu == NULL) && (adt->drivers.first)) {
199                                 fcu= list_find_fcurve(&adt->drivers, path, but->rnaindex);
200                         }
201 #endif
202                         
203                         MEM_freeN(path);
204                 }
205         }
206
207         return fcu;
208 }
209
210
211 /* Find the F-Curve affecting the given RNA-access path + index, in the list of F-Curves provided */
212 FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array_index)
213 {
214         FCurve *fcu;
215         
216         /* sanity checks */
217         if ( ELEM(NULL, list, rna_path) || (array_index < 0) )
218                 return NULL;
219         
220         /* check paths of curves, then array indices... */
221         for (fcu= list->first; fcu; fcu= fcu->next) {
222                 /* simple string-compare (this assumes that they have the same root...) */
223                 if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
224                         /* now check indices */
225                         if (fcu->array_index == array_index)
226                                 return fcu;
227                 }
228         }
229         
230         /* return */
231         return NULL;
232 }
233
234 /* quick way to loop over all fcurves of a given 'path' */
235 FCurve *iter_step_fcurve (FCurve *fcu_iter, const char rna_path[])
236 {
237         FCurve *fcu;
238         
239         /* sanity checks */
240         if (ELEM(NULL, fcu_iter, rna_path))
241                 return NULL;
242
243         /* check paths of curves, then array indices... */
244         for (fcu= fcu_iter; fcu; fcu= fcu->next) {
245                 /* simple string-compare (this assumes that they have the same root...) */
246                 if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
247                         return fcu;
248                 }
249         }
250
251         /* return */
252         return NULL;
253 }
254
255 /* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated 
256  * Lists...
257  *      - dst: list of LinkData's matching the criteria returned. 
258  *        List must be freed after use, and is assumed to be empty when passed.
259  *      - src: list of F-Curves to search through
260  * Filters...
261  *      - dataPrefix: i.e. 'pose.bones[' or 'nodes['
262  *      - dataName: name of entity within "" immediately following the prefix
263  */
264 int list_find_data_fcurves (ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName)
265 {
266         FCurve *fcu;
267         int matches = 0;
268         
269         /* sanity checks */
270         if (ELEM4(NULL, dst, src, dataPrefix, dataName))
271                 return 0;
272         else if ((dataPrefix[0] == 0) || (dataName[0] == 0))
273                 return 0;
274         
275         /* search each F-Curve one by one */
276         for (fcu= src->first; fcu; fcu= fcu->next) {
277                 /* check if quoted string matches the path */
278                 if ((fcu->rna_path) && strstr(fcu->rna_path, dataPrefix)) {
279                         char *quotedName= BLI_getQuotedStr(fcu->rna_path, dataPrefix);
280                         
281                         if (quotedName) {
282                                 /* check if the quoted name matches the required name */
283                                 if (strcmp(quotedName, dataName) == 0) {
284                                         LinkData *ld= MEM_callocN(sizeof(LinkData), "list_find_data_fcurves");
285                                         
286                                         ld->data= fcu;
287                                         BLI_addtail(dst, ld);
288                                         
289                                         matches++;
290                                 }
291                                 
292                                 /* always free the quoted string, since it needs freeing */
293                                 MEM_freeN(quotedName);
294                         }
295                 }
296         }
297         
298         /* return the number of matches */
299         return matches;
300 }
301
302 FCurve *rna_get_fcurve (PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, int *driven)
303 {
304         FCurve *fcu= NULL;
305         
306         *driven= 0;
307         
308         /* there must be some RNA-pointer + property combon */
309         if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
310                 AnimData *adt= BKE_animdata_from_id(ptr->id.data);
311                 char *path;
312                 
313                 if (adt) {
314                         if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
315                                 /* XXX this function call can become a performance bottleneck */
316                                 path= RNA_path_from_ID_to_property(ptr, prop);
317                                 
318                                 if (path) {
319                                         /* animation takes priority over drivers */
320                                         if (adt->action && adt->action->curves.first)
321                                                 fcu= list_find_fcurve(&adt->action->curves, path, rnaindex);
322                                         
323                                         /* if not animated, check if driven */
324                                         if (!fcu && (adt->drivers.first)) {
325                                                 fcu= list_find_fcurve(&adt->drivers, path, rnaindex);
326                                                 
327                                                 if (fcu)
328                                                         *driven= 1;
329                                         }
330                                         
331                                         if (fcu && action)
332                                                 *action= adt->action;
333                                         
334                                         MEM_freeN(path);
335                                 }
336                         }
337                 }
338         }
339         
340         return fcu;
341 }
342
343 /* ----------------- Finding Keyframes/Extents -------------------------- */
344
345 /* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */
346 #define BEZT_BINARYSEARCH_THRESH        0.01f /* was 0.00001, but giving errors */
347
348 /* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
349  * Returns the index to insert at (data already at that index will be offset if replace is 0)
350  */
351 int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short *replace)
352 {
353         int start=0, end=arraylen;
354         int loopbreaker= 0, maxloop= arraylen * 2;
355         
356         /* initialise replace-flag first */
357         *replace= 0;
358         
359         /* sneaky optimisations (don't go through searching process if...):
360          *      - keyframe to be added is to be added out of current bounds
361          *      - keyframe to be added would replace one of the existing ones on bounds
362          */
363         if ((arraylen <= 0) || (array == NULL)) {
364                 printf("Warning: binarysearch_bezt_index() encountered invalid array \n");
365                 return 0;
366         }
367         else {
368                 /* check whether to add before/after/on */
369                 float framenum;
370                 
371                 /* 'First' Keyframe (when only one keyframe, this case is used) */
372                 framenum= array[0].vec[1][0];
373                 if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) {
374                         *replace = 1;
375                         return 0;
376                 }
377                 else if (frame < framenum)
378                         return 0;
379                         
380                 /* 'Last' Keyframe */
381                 framenum= array[(arraylen-1)].vec[1][0];
382                 if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) {
383                         *replace= 1;
384                         return (arraylen - 1);
385                 }
386                 else if (frame > framenum)
387                         return arraylen;
388         }
389         
390         
391         /* most of the time, this loop is just to find where to put it
392          * 'loopbreaker' is just here to prevent infinite loops 
393          */
394         for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
395                 /* compute and get midpoint */
396                 int mid = start + ((end - start) / 2);  /* we calculate the midpoint this way to avoid int overflows... */
397                 float midfra= array[mid].vec[1][0];
398                 
399                 /* check if exactly equal to midpoint */
400                 if (IS_EQT(frame, midfra, BEZT_BINARYSEARCH_THRESH)) {
401                         *replace = 1;
402                         return mid;
403                 }
404                 
405                 /* repeat in upper/lower half */
406                 if (frame > midfra)
407                         start= mid + 1;
408                 else if (frame < midfra)
409                         end= mid - 1;
410         }
411         
412         /* print error if loop-limit exceeded */
413         if (loopbreaker == (maxloop-1)) {
414                 printf("Error: binarysearch_bezt_index() was taking too long \n");
415                 
416                 // include debug info 
417                 printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
418         }
419         
420         /* not found, so return where to place it */
421         return start;
422 }
423
424 /* Calculate the extents of F-Curve's data */
425 void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax)
426 {
427         float xminv=999999999.0f, xmaxv=-999999999.0f;
428         float yminv=999999999.0f, ymaxv=-999999999.0f;
429         short foundvert=0;
430         unsigned int i;
431         
432         if (fcu->totvert) {
433                 if (fcu->bezt) {
434                         /* frame range can be directly calculated from end verts */
435                         if (xmin || xmax) {
436                                 xminv= MIN2(xminv, fcu->bezt[0].vec[1][0]);
437                                 xmaxv= MAX2(xmaxv, fcu->bezt[fcu->totvert-1].vec[1][0]);
438                         }
439                         
440                         /* only loop over keyframes to find extents for values if needed */
441                         if (ymin || ymax) {
442                                 BezTriple *bezt;
443                                 
444                                 for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) {
445                                         if (bezt->vec[1][1] < yminv)
446                                                 yminv= bezt->vec[1][1];
447                                         if (bezt->vec[1][1] > ymaxv)
448                                                 ymaxv= bezt->vec[1][1];
449                                 }
450                         }
451                 }
452                 else if (fcu->fpt) {
453                         /* frame range can be directly calculated from end verts */
454                         if (xmin || xmax) {
455                                 xminv= MIN2(xminv, fcu->fpt[0].vec[0]);
456                                 xmaxv= MAX2(xmaxv, fcu->fpt[fcu->totvert-1].vec[0]);
457                         }
458                         
459                         /* only loop over keyframes to find extents for values if needed */
460                         if (ymin || ymax) {
461                                 FPoint *fpt;
462                                 
463                                 for (fpt=fcu->fpt, i=0; i < fcu->totvert; fpt++, i++) {
464                                         if (fpt->vec[1] < yminv)
465                                                 yminv= fpt->vec[1];
466                                         if (fpt->vec[1] > ymaxv)
467                                                 ymaxv= fpt->vec[1];
468                                 }
469                         }
470                 }
471                 
472                 foundvert=1;
473         }
474         
475         if (foundvert) {
476                 if (xmin) *xmin= xminv;
477                 if (xmax) *xmax= xmaxv;
478                 
479                 if (ymin) *ymin= yminv;
480                 if (ymax) *ymax= ymaxv;
481         }
482         else {
483                 if (G.f & G_DEBUG)
484                         printf("F-Curve calc bounds didn't find anything, so assuming minimum bounds of 1.0\n");
485                         
486                 if (xmin) *xmin= 0.0f;
487                 if (xmax) *xmax= 1.0f;
488                 
489                 if (ymin) *ymin= 0.0f;
490                 if (ymax) *ymax= 1.0f;
491         }
492 }
493
494 /* Calculate the extents of F-Curve's keyframes */
495 void calc_fcurve_range (FCurve *fcu, float *start, float *end)
496 {
497         float min=999999999.0f, max=-999999999.0f;
498         short foundvert=0;
499
500         if (fcu->totvert) {
501                 if (fcu->bezt) {
502                         min= MIN2(min, fcu->bezt[0].vec[1][0]);
503                         max= MAX2(max, fcu->bezt[fcu->totvert-1].vec[1][0]);
504                 }
505                 else if (fcu->fpt) {
506                         min= MIN2(min, fcu->fpt[0].vec[0]);
507                         max= MAX2(max, fcu->fpt[fcu->totvert-1].vec[0]);
508                 }
509                 
510                 foundvert=1;
511         }
512         
513         /* minimum length is 1 frame */
514         if (foundvert) {
515                 if (min == max) max += 1.0f;
516                 *start= min;
517                 *end= max;
518         }
519         else {
520                 *start= 0.0f;
521                 *end= 1.0f;
522         }
523 }
524
525 /* ----------------- Status Checks -------------------------- */
526
527 /* Are keyframes on F-Curve of any use? 
528  * Usability of keyframes refers to whether they should be displayed,
529  * and also whether they will have any influence on the final result.
530  */
531 short fcurve_are_keyframes_usable (FCurve *fcu)
532 {
533         /* F-Curve must exist */
534         if (fcu == NULL)
535                 return 0;
536                 
537         /* F-Curve must not have samples - samples are mutually exclusive of keyframes */
538         if (fcu->fpt)
539                 return 0;
540         
541         /* if it has modifiers, none of these should "drastically" alter the curve */
542         if (fcu->modifiers.first) {
543                 FModifier *fcm;
544                 
545                 /* check modifiers from last to first, as last will be more influential */
546                 // TODO: optionally, only check modifier if it is the active one...
547                 for (fcm = fcu->modifiers.last; fcm; fcm = fcm->prev) {
548                         /* ignore if muted/disabled */
549                         if (fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED))
550                                 continue;
551                                 
552                         /* type checks */
553                         switch (fcm->type) {
554                                 /* clearly harmless - do nothing */
555                                 case FMODIFIER_TYPE_CYCLES:
556                                 case FMODIFIER_TYPE_STEPPED:
557                                 case FMODIFIER_TYPE_NOISE:
558                                         break;
559                                         
560                                 /* sometimes harmful - depending on whether they're "additive" or not */
561                                 case FMODIFIER_TYPE_GENERATOR:
562                                 {
563                                         FMod_Generator *data = (FMod_Generator *)fcm->data;
564                                         
565                                         if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
566                                                 return 0;
567                                 }
568                                         break;
569                                 case FMODIFIER_TYPE_FN_GENERATOR:
570                                 {
571                                         FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data;
572                                         
573                                         if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
574                                                 return 0;
575                                 }
576                                         break;
577                                         
578                                 /* always harmful - cannot allow */
579                                 default:
580                                         return 0;
581                         }
582                 }
583         }
584         
585         /* keyframes are usable */
586         return 1;
587 }
588
589 /* Can keyframes be added to F-Curve? 
590  * Keyframes can only be added if they are already visible
591  */
592 short fcurve_is_keyframable (FCurve *fcu)
593 {
594         /* F-Curve's keyframes must be "usable" (i.e. visible + have an effect on final result) */
595         if (fcurve_are_keyframes_usable(fcu) == 0)
596                 return 0;
597                 
598         /* F-Curve must currently be editable too */
599         if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) )
600                 return 0;
601         
602         /* F-Curve is keyframable */
603         return 1;
604 }
605
606 /* ***************************** Keyframe Column Tools ********************************* */
607
608 /* add a BezTriple to a column */
609 void bezt_add_to_cfra_elem (ListBase *lb, BezTriple *bezt)
610 {
611         CfraElem *ce, *cen;
612         
613         for (ce= lb->first; ce; ce= ce->next) {
614                 /* double key? */
615                 if (ce->cfra == bezt->vec[1][0]) {
616                         if (bezt->f2 & SELECT) ce->sel= bezt->f2;
617                         return;
618                 }
619                 /* should key be inserted before this column? */
620                 else if (ce->cfra > bezt->vec[1][0]) break;
621         }
622         
623         /* create a new column */
624         cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem"); 
625         if (ce) BLI_insertlinkbefore(lb, ce, cen);
626         else BLI_addtail(lb, cen);
627
628         cen->cfra= bezt->vec[1][0];
629         cen->sel= bezt->f2;
630 }
631
632 /* ***************************** Samples Utilities ******************************* */
633 /* Some utilities for working with FPoints (i.e. 'sampled' animation curve data, such as
634  * data imported from BVH/Mocap files), which are specialised for use with high density datasets,
635  * which BezTriples/Keyframe data are ill equipped to do.
636  */
637  
638  
639 /* Basic sampling callback which acts as a wrapper for evaluate_fcurve() 
640  *      'data' arg here is unneeded here...
641  */
642 float fcurve_samplingcb_evalcurve (FCurve *fcu, void *UNUSED(data), float evaltime)
643 {
644         /* assume any interference from drivers on the curve is intended... */
645         return evaluate_fcurve(fcu, evaltime);
646
647
648  
649 /* Main API function for creating a set of sampled curve data, given some callback function 
650  * used to retrieve the values to store.
651  */
652 void fcurve_store_samples (FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb)
653 {
654         FPoint *fpt, *new_fpt;
655         int cfra;
656         
657         /* sanity checks */
658         // TODO: make these tests report errors using reports not printf's
659         if ELEM(NULL, fcu, sample_cb) {
660                 printf("Error: No F-Curve with F-Curve Modifiers to Bake\n");
661                 return;
662         }
663         if (start >= end) {
664                 printf("Error: Frame range for Sampled F-Curve creation is inappropriate \n");
665                 return;
666         }
667         
668         /* set up sample data */
669         fpt= new_fpt= MEM_callocN(sizeof(FPoint)*(end-start+1), "FPoint Samples");
670         
671         /* use the sampling callback at 1-frame intervals from start to end frames */
672         for (cfra= start; cfra <= end; cfra++, fpt++) {
673                 fpt->vec[0]= (float)cfra;
674                 fpt->vec[1]= sample_cb(fcu, data, (float)cfra);
675         }
676         
677         /* free any existing sample/keyframe data on curve  */
678         if (fcu->bezt) MEM_freeN(fcu->bezt);
679         if (fcu->fpt) MEM_freeN(fcu->fpt);
680         
681         /* store the samples */
682         fcu->bezt= NULL;
683         fcu->fpt= new_fpt;
684         fcu->totvert= end - start + 1;
685 }
686
687 /* ***************************** F-Curve Sanity ********************************* */
688 /* The functions here are used in various parts of Blender, usually after some editing
689  * of keyframe data has occurred. They ensure that keyframe data is properly ordered and
690  * that the handles are correctly 
691  */
692
693 /* This function recalculates the handles of an F-Curve 
694  * If the BezTriples have been rearranged, sort them first before using this.
695  */
696 void calchandles_fcurve (FCurve *fcu)
697 {
698         BezTriple *bezt, *prev, *next;
699         int a= fcu->totvert;
700
701         /* Error checking:
702          *      - need at least two points
703          *      - need bezier keys
704          *      - only bezier-interpolation has handles (for now)
705          */
706         if (ELEM(NULL, fcu, fcu->bezt) || (a < 2) /*|| ELEM(fcu->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN)*/) 
707                 return;
708         
709         /* get initial pointers */
710         bezt= fcu->bezt;
711         prev= NULL;
712         next= (bezt + 1);
713         
714         /* loop over all beztriples, adjusting handles */
715         while (a--) {
716                 /* clamp timing of handles to be on either side of beztriple */
717                 if (bezt->vec[0][0] > bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
718                 if (bezt->vec[2][0] < bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
719                 
720                 /* calculate auto-handles */
721                 if (fcu->flag & FCURVE_AUTO_HANDLES) 
722                         calchandleNurb(bezt, prev, next, 2);    /* 2==special autohandle && keep extrema horizontal */
723                 else
724                         calchandleNurb(bezt, prev, next, 1);    /* 1==special autohandle */
725                 
726                 /* for automatic ease in and out */
727                 if ((bezt->h1==HD_AUTO) && (bezt->h2==HD_AUTO)) {
728                         /* only do this on first or last beztriple */
729                         if ((a == 0) || (a == fcu->totvert-1)) {
730                                 /* set both handles to have same horizontal value as keyframe */
731                                 if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) {
732                                         bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
733                                 }
734                         }
735                 }
736                 
737                 /* advance pointers for next iteration */
738                 prev= bezt;
739                 if (a == 1) next= NULL;
740                 else next++;
741                 bezt++;
742         }
743 }
744
745 /* Use when F-Curve with handles has changed
746  * It treats all BezTriples with the following rules:
747  *  - PHASE 1: do types have to be altered?
748  *              -> Auto handles: become aligned when selection status is NOT(000 || 111)
749  *              -> Vector handles: become 'nothing' when (one half selected AND other not)
750  *  - PHASE 2: recalculate handles
751 */
752 void testhandles_fcurve (FCurve *fcu)
753 {
754         BezTriple *bezt;
755         unsigned int a;
756
757         /* only beztriples have handles (bpoints don't though) */
758         if ELEM(NULL, fcu, fcu->bezt)
759                 return;
760         
761         /* loop over beztriples */
762         for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) {
763                 short flag= 0;
764                 
765                 /* flag is initialised as selection status
766                  * of beztriple control-points (labelled 0,1,2)
767                  */
768                 if (bezt->f1 & SELECT) flag |= (1<<0); // == 1
769                 if (bezt->f2 & SELECT) flag |= (1<<1); // == 2
770                 if (bezt->f3 & SELECT) flag |= (1<<2); // == 4
771                 
772                 /* one or two handles selected only */
773                 if (ELEM(flag, 0, 7)==0) {
774                         /* auto handles become aligned */
775                         if (bezt->h1==HD_AUTO)
776                                 bezt->h1= HD_ALIGN;
777                         if (bezt->h2==HD_AUTO)
778                                 bezt->h2= HD_ALIGN;
779                         
780                         /* vector handles become 'free' when only one half selected */
781                         if (bezt->h1==HD_VECT) {
782                                 /* only left half (1 or 2 or 1+2) */
783                                 if (flag < 4) 
784                                         bezt->h1= 0;
785                         }
786                         if (bezt->h2==HD_VECT) {
787                                 /* only right half (4 or 2+4) */
788                                 if (flag > 3) 
789                                         bezt->h2= 0;
790                         }
791                 }
792         }
793
794         /* recalculate handles */
795         calchandles_fcurve(fcu);
796 }
797
798 /* This function sorts BezTriples so that they are arranged in chronological order,
799  * as tools working on F-Curves expect that the BezTriples are in order.
800  */
801 void sort_time_fcurve (FCurve *fcu)
802 {
803         short ok= 1;
804         
805         /* keep adjusting order of beztriples until nothing moves (bubble-sort) */
806         while (ok) {
807                 ok= 0;
808                 
809                 /* currently, will only be needed when there are beztriples */
810                 if (fcu->bezt) {
811                         BezTriple *bezt;
812                         unsigned int a;
813                         
814                         /* loop over ALL points to adjust position in array and recalculate handles */
815                         for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) {
816                                 /* check if thee's a next beztriple which we could try to swap with current */
817                                 if (a < (fcu->totvert-1)) {
818                                         /* swap if one is after the other (and indicate that order has changed) */
819                                         if (bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
820                                                 SWAP(BezTriple, *bezt, *(bezt+1));
821                                                 ok= 1;
822                                         }
823                                         
824                                         /* if either one of both of the points exceeds crosses over the keyframe time... */
825                                         if ( (bezt->vec[0][0] > bezt->vec[1][0]) && (bezt->vec[2][0] < bezt->vec[1][0]) ) {
826                                                 /* swap handles if they have switched sides for some reason */
827                                                 SWAP(float, bezt->vec[0][0], bezt->vec[2][0]);
828                                                 SWAP(float, bezt->vec[0][1], bezt->vec[2][1]);
829                                         }
830                                         else {
831                                                 /* clamp handles */
832                                                 if (bezt->vec[0][0] > bezt->vec[1][0]) 
833                                                         bezt->vec[0][0]= bezt->vec[1][0];
834                                                 if (bezt->vec[2][0] < bezt->vec[1][0]) 
835                                                         bezt->vec[2][0]= bezt->vec[1][0];
836                                         }
837                                 }
838                         }
839                 }
840         }
841 }
842
843 /* This function tests if any BezTriples are out of order, thus requiring a sort */
844 short test_time_fcurve (FCurve *fcu)
845 {
846         unsigned int a;
847         
848         /* sanity checks */
849         if (fcu == NULL)
850                 return 0;
851         
852         /* currently, only need to test beztriples */
853         if (fcu->bezt) {
854                 BezTriple *bezt;
855                 
856                 /* loop through all BezTriples, stopping when one exceeds the one after it */
857                 for (a=0, bezt= fcu->bezt; a < (fcu->totvert - 1); a++, bezt++) {
858                         if (bezt->vec[1][0] > (bezt+1)->vec[1][0])
859                                 return 1;
860                 }
861         }
862         else if (fcu->fpt) {
863                 FPoint *fpt;
864                 
865                 /* loop through all FPoints, stopping when one exceeds the one after it */
866                 for (a=0, fpt= fcu->fpt; a < (fcu->totvert - 1); a++, fpt++) {
867                         if (fpt->vec[0] > (fpt+1)->vec[0])
868                                 return 1;
869                 }
870         }
871         
872         /* none need any swapping */
873         return 0;
874 }
875
876 /* ***************************** Drivers ********************************* */
877
878 /* Driver Variables --------------------------- */
879
880 /* TypeInfo for Driver Variables (dvti) */
881 typedef struct DriverVarTypeInfo {
882         /* evaluation callback */
883         float (*get_value)(ChannelDriver *driver, DriverVar *dvar);
884         
885         /* allocation of target slots */
886         int num_targets;                                                /* number of target slots required */
887         const char *target_names[MAX_DRIVER_TARGETS];   /* UI names that should be given to the slots */
888         int target_flags[MAX_DRIVER_TARGETS];   /* flags defining the requirements for each slot */
889 } DriverVarTypeInfo;
890
891 /* Macro to begin definitions */
892 #define BEGIN_DVAR_TYPEDEF(type) \
893         {
894         
895 /* Macro to end definitions */
896 #define END_DVAR_TYPEDEF \
897         }
898
899 /* ......... */
900
901 static ID *dtar_id_ensure_proxy_from(ID *id)
902 {
903         if (id && GS(id->name)==ID_OB && ((Object *)id)->proxy_from)
904                 return (ID *)(((Object *)id)->proxy_from);
905         return id;
906 }
907
908 /* Helper function to obtain a value using RNA from the specified source (for evaluating drivers) */
909 static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
910 {
911         PointerRNA id_ptr, ptr;
912         PropertyRNA *prop;
913         ID *id;
914         int index;
915         float value= 0.0f;
916         
917         /* sanity check */
918         if ELEM(NULL, driver, dtar)
919                 return 0.0f;
920         
921         id= dtar_id_ensure_proxy_from(dtar->id);
922         
923         /* error check for missing pointer... */
924         // TODO: tag the specific target too as having issues
925         if (id == NULL) {
926                 printf("Error: driver has an invalid target to use \n");
927                 if (G.f & G_DEBUG) printf("\tpath = %s\n", dtar->rna_path);
928                 driver->flag |= DRIVER_FLAG_INVALID;
929                 return 0.0f;
930         }
931         
932         /* get RNA-pointer for the ID-block given in target */
933         RNA_id_pointer_create(id, &id_ptr);
934         
935         /* get property to read from, and get value as appropriate */
936         if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
937                 if(RNA_property_array_check(&ptr, prop)) {
938                         /* array */
939                         if (index < RNA_property_array_length(&ptr, prop)) {    
940                                 switch (RNA_property_type(prop)) {
941                                 case PROP_BOOLEAN:
942                                         value= (float)RNA_property_boolean_get_index(&ptr, prop, index);
943                                         break;
944                                 case PROP_INT:
945                                         value= (float)RNA_property_int_get_index(&ptr, prop, index);
946                                         break;
947                                 case PROP_FLOAT:
948                                         value= RNA_property_float_get_index(&ptr, prop, index);
949                                         break;
950                                 default:
951                                         break;
952                                 }
953                         }
954                 }
955                 else {
956                         /* not an array */
957                         switch (RNA_property_type(prop)) {
958                         case PROP_BOOLEAN:
959                                 value= (float)RNA_property_boolean_get(&ptr, prop);
960                                 break;
961                         case PROP_INT:
962                                 value= (float)RNA_property_int_get(&ptr, prop);
963                                 break;
964                         case PROP_FLOAT:
965                                 value= RNA_property_float_get(&ptr, prop);
966                                 break;
967                         case PROP_ENUM:
968                                 value= (float)RNA_property_enum_get(&ptr, prop);
969                                 break;
970                         default:
971                                 break;
972                         }
973                 }
974
975         }
976         else {
977                 if (G.f & G_DEBUG)
978                         printf("Driver Evaluation Error: cannot resolve target for %s -> %s \n", id->name, dtar->rna_path);
979                 
980                 driver->flag |= DRIVER_FLAG_INVALID;
981                 return 0.0f;
982         }
983         
984         return value;
985 }
986
987 /* Helper function to obtain a pointer to a Pose Channel (for evaluating drivers) */
988 static bPoseChannel *dtar_get_pchan_ptr (ChannelDriver *driver, DriverTarget *dtar)
989 {
990         ID *id;
991         /* sanity check */
992         if ELEM(NULL, driver, dtar)
993                 return NULL;
994
995         id= dtar_id_ensure_proxy_from(dtar->id);
996
997         /* check if the ID here is a valid object */
998         if (id && GS(id->name)) {
999                 Object *ob= (Object *)id;
1000                 
1001                 /* get pose, and subsequently, posechannel */
1002                 return get_pose_channel(ob->pose, dtar->pchan_name);
1003         }
1004         else {
1005                 /* cannot find a posechannel this way */
1006                 return NULL;
1007         }
1008 }
1009
1010 /* ......... */
1011
1012 /* evaluate 'single prop' driver variable */
1013 static float dvar_eval_singleProp (ChannelDriver *driver, DriverVar *dvar)
1014 {
1015         /* just evaluate the first target slot */
1016         return dtar_get_prop_val(driver, &dvar->targets[0]);
1017 }
1018
1019 /* evaluate 'rotation difference' driver variable */
1020 static float dvar_eval_rotDiff (ChannelDriver *driver, DriverVar *dvar)
1021 {
1022         bPoseChannel *pchan, *pchan2;
1023         float q1[4], q2[4], quat[4], angle;
1024         
1025         /* get pose channels, and check if we've got two */
1026         pchan= dtar_get_pchan_ptr(driver, &dvar->targets[0]);
1027         pchan2= dtar_get_pchan_ptr(driver, &dvar->targets[1]);
1028         
1029         if (ELEM(NULL, pchan, pchan2)) {
1030                 /* disable this driver, since it doesn't work correctly... */
1031                 driver->flag |= DRIVER_FLAG_INVALID;
1032                 
1033                 /* check what the error was */
1034                 if ((pchan == NULL) && (pchan2 == NULL))
1035                         printf("Driver Evaluation Error: Rotational difference failed - first 2 targets invalid \n");
1036                 else if (pchan == NULL)
1037                         printf("Driver Evaluation Error: Rotational difference failed - first target not valid PoseChannel \n");
1038                 else if (pchan2 == NULL)
1039                         printf("Driver Evaluation Error: Rotational difference failed - second target not valid PoseChannel \n");
1040                         
1041                 /* stop here... */
1042                 return 0.0f;
1043         }                       
1044         
1045         /* use the final posed locations */
1046         mat4_to_quat(q1, pchan->pose_mat);
1047         mat4_to_quat(q2, pchan2->pose_mat);
1048         
1049         invert_qt(q1);
1050         mul_qt_qtqt(quat, q1, q2);
1051         angle = 2.0f * (saacos(quat[0]));
1052         angle= ABS(angle);
1053         
1054         return (angle > M_PI) ? (float)((2.0f * M_PI) - angle) : (float)(angle);
1055 }
1056
1057 /* evaluate 'location difference' driver variable */
1058 // TODO: this needs to take into account space conversions...
1059 static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar)
1060 {
1061         float loc1[3] = {0.0f,0.0f,0.0f};
1062         float loc2[3] = {0.0f,0.0f,0.0f};
1063         
1064         /* get two location values */
1065         // NOTE: for now, these are all just worldspace
1066         DRIVER_TARGETS_USED_LOOPER(dvar)
1067         {
1068                 /* get pointer to loc values to store in */
1069                 Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
1070                 bPoseChannel *pchan;
1071                 float tmp_loc[3];
1072                 
1073                 /* check if this target has valid data */
1074                 if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
1075                         /* invalid target, so will not have enough targets */
1076                         driver->flag |= DRIVER_FLAG_INVALID;
1077                         return 0.0f;
1078                 }
1079                 
1080                 /* try to get posechannel */
1081                 pchan= get_pose_channel(ob->pose, dtar->pchan_name);
1082                 
1083                 /* check if object or bone */
1084                 if (pchan) {
1085                         /* bone */
1086                         if ((dtar->flag & DTAR_FLAG_LOCALSPACE) == 0) {
1087                                 /* convert to worldspace */
1088                                 VECCOPY(tmp_loc, pchan->pose_head);
1089                                 mul_m4_v3(ob->obmat, tmp_loc);
1090                         }
1091                         else {
1092                                 /* local (use transform values directly) */
1093                                 VECCOPY(tmp_loc, pchan->loc);
1094                         }
1095                 }
1096                 else {
1097                         /* object */
1098                         if ((dtar->flag & DTAR_FLAG_LOCALSPACE) == 0) {
1099                                 /* worldspace */
1100                                 VECCOPY(tmp_loc, ob->obmat[3]); 
1101                         }
1102                         else {
1103                                 /* local (use transform values directly) */
1104                                 VECCOPY(tmp_loc, ob->loc);
1105                         }
1106                 }
1107                 
1108                 /* copy the location to the right place */
1109                 if (tarIndex) {
1110                         VECCOPY(loc2, tmp_loc);
1111                 }
1112                 else {
1113                         VECCOPY(loc1, tmp_loc);
1114                 }
1115         }
1116         DRIVER_TARGETS_LOOPER_END
1117         
1118         
1119         /* if we're still here, there should now be two targets to use,
1120          * so just take the length of the vector between these points 
1121          */
1122         return len_v3v3(loc1, loc2);
1123 }
1124
1125 /* evaluate 'transform channel' driver variable */
1126 static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
1127 {
1128         DriverTarget *dtar= &dvar->targets[0];
1129         Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
1130         bPoseChannel *pchan;
1131         float mat[4][4];
1132         float eul[3] = {0.0f,0.0f,0.0f};
1133         short useEulers=0, rotOrder=ROT_MODE_EUL;
1134         
1135         /* check if this target has valid data */
1136         if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
1137                 /* invalid target, so will not have enough targets */
1138                 driver->flag |= DRIVER_FLAG_INVALID;
1139                 return 0.0f;
1140         }
1141         
1142         /* try to get posechannel */
1143         pchan= get_pose_channel(ob->pose, dtar->pchan_name);
1144         
1145         /* check if object or bone, and get transform matrix accordingly */
1146         if (pchan) {
1147                 /* bone */
1148                 if (pchan->rotmode > 0) {
1149                         VECCOPY(eul, pchan->eul);
1150                         rotOrder= pchan->rotmode;
1151                         useEulers = 1;
1152                 }
1153                 
1154                 if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
1155                         /* specially calculate local matrix, since chan_mat is not valid 
1156                          * since it stores delta transform of pose_mat so that deforms work
1157                          */
1158                         pchan_to_mat4(pchan, mat);
1159                 }
1160                 else
1161                         mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat);
1162         }
1163         else {
1164                 /* object */
1165                 if (ob->rotmode > 0) {
1166                         VECCOPY(eul, ob->rot);
1167                         rotOrder= ob->rotmode;
1168                         useEulers = 1;
1169                 }
1170                 
1171                 if (dtar->flag & DTAR_FLAG_LOCALSPACE)
1172                         object_to_mat4(ob, mat);
1173                 else
1174                         copy_m4_m4(mat, ob->obmat);
1175         }
1176         
1177         /* check which transform */
1178         if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) {
1179                 /* not valid channel */
1180                 return 0.0f;
1181         }
1182         else if (dtar->transChan >= DTAR_TRANSCHAN_SCALEX) {
1183                 /* extract scale, and choose the right axis */
1184                 float scale[3];
1185                 
1186                 mat4_to_size(scale, mat);
1187                 return scale[dtar->transChan - DTAR_TRANSCHAN_SCALEX];
1188         }
1189         else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
1190                 /* extract euler rotation (if needed), and choose the right axis */
1191                 if ((dtar->flag & DTAR_FLAG_LOCALSPACE)==0 || (useEulers == 0))
1192                         mat4_to_eulO(eul, rotOrder, mat);
1193                 
1194                 return eul[dtar->transChan - DTAR_TRANSCHAN_ROTX];
1195         }
1196         else {
1197                 /* extract location and choose right axis */
1198                 return mat[3][dtar->transChan];
1199         }
1200 }
1201
1202 /* ......... */
1203
1204 /* Table of Driver Varaiable Type Info Data */
1205 static DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES] = {
1206         BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP)
1207                 dvar_eval_singleProp, /* eval callback */
1208                 1, /* number of targets used */
1209                 {"Property"}, /* UI names for targets */
1210                 {0} /* flags */
1211         END_DVAR_TYPEDEF,
1212         
1213         BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF)
1214                 dvar_eval_rotDiff, /* eval callback */
1215                 2, /* number of targets used */
1216                 {"Bone 1", "Bone 2"}, /* UI names for targets */
1217                 {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY, DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
1218         END_DVAR_TYPEDEF,
1219         
1220         BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF)
1221                 dvar_eval_locDiff, /* eval callback */
1222                 2, /* number of targets used */
1223                 {"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
1224                 {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY, DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
1225         END_DVAR_TYPEDEF,
1226         
1227         BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN)
1228                 dvar_eval_transChan, /* eval callback */
1229                 1, /* number of targets used */
1230                 {"Object/Bone"}, /* UI names for targets */
1231                 {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
1232         END_DVAR_TYPEDEF,
1233 };
1234
1235 /* Get driver variable typeinfo */
1236 static DriverVarTypeInfo *get_dvar_typeinfo (int type)
1237 {
1238         /* check if valid type */
1239         if ((type >= 0) && (type < MAX_DVAR_TYPES))
1240                 return &dvar_types[type];
1241         else
1242                 return NULL;
1243 }
1244
1245 /* Driver API --------------------------------- */
1246
1247 /* This frees the driver variable itself */
1248 void driver_free_variable (ChannelDriver *driver, DriverVar *dvar)
1249 {
1250         /* sanity checks */
1251         if (dvar == NULL)
1252                 return;
1253                 
1254         /* free target vars 
1255          *      - need to go over all of them, not just up to the ones that are used
1256          *        currently, since there may be some lingering RNA paths from 
1257          *        previous users needing freeing
1258          */
1259         DRIVER_TARGETS_LOOPER(dvar) 
1260         {
1261                 /* free RNA path if applicable */
1262                 if (dtar->rna_path)
1263                         MEM_freeN(dtar->rna_path);
1264         }
1265         DRIVER_TARGETS_LOOPER_END
1266         
1267         /* remove the variable from the driver */
1268         if (driver)
1269                 BLI_freelinkN(&driver->variables, dvar);
1270         else
1271                 MEM_freeN(dvar);
1272
1273 #ifdef WITH_PYTHON
1274         /* since driver variables are cached, the expression needs re-compiling too */
1275         if(driver->type==DRIVER_TYPE_PYTHON)
1276                 driver->flag |= DRIVER_FLAG_RENAMEVAR;
1277 #endif
1278 }
1279
1280 /* Change the type of driver variable */
1281 void driver_change_variable_type (DriverVar *dvar, int type)
1282 {
1283         DriverVarTypeInfo *dvti= get_dvar_typeinfo(type);
1284         
1285         /* sanity check */
1286         if (ELEM(NULL, dvar, dvti))
1287                 return;
1288                 
1289         /* set the new settings */
1290         dvar->type= type;
1291         dvar->num_targets= dvti->num_targets;
1292         
1293         /* make changes to the targets based on the defines for these types 
1294          * NOTE: only need to make sure the ones we're using here are valid...
1295          */
1296         DRIVER_TARGETS_USED_LOOPER(dvar)
1297         {
1298                 int flags = dvti->target_flags[tarIndex];
1299                 
1300                 /* store the flags */
1301                 dtar->flag = flags;
1302                 
1303                 /* object ID types only, or idtype not yet initialised*/
1304                 if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0))
1305                         dtar->idtype= ID_OB;
1306         }
1307         DRIVER_TARGETS_LOOPER_END
1308 }
1309
1310 /* Add a new driver variable */
1311 DriverVar *driver_add_new_variable (ChannelDriver *driver)
1312 {
1313         DriverVar *dvar;
1314         
1315         /* sanity checks */
1316         if (driver == NULL)
1317                 return NULL;
1318                 
1319         /* make a new variable */
1320         dvar= MEM_callocN(sizeof(DriverVar), "DriverVar");
1321         BLI_addtail(&driver->variables, dvar);
1322         
1323         /* give the variable a 'unique' name */
1324         strcpy(dvar->name, "var");
1325         BLI_uniquename(&driver->variables, dvar, "var", '_', offsetof(DriverVar, name), sizeof(dvar->name));
1326         
1327         /* set the default type to 'single prop' */
1328         driver_change_variable_type(dvar, DVAR_TYPE_SINGLE_PROP);
1329         
1330 #ifdef WITH_PYTHON
1331         /* since driver variables are cached, the expression needs re-compiling too */
1332         if (driver->type==DRIVER_TYPE_PYTHON)
1333                 driver->flag |= DRIVER_FLAG_RENAMEVAR;
1334 #endif
1335
1336         /* return the target */
1337         return dvar;
1338 }
1339
1340 /* This frees the driver itself */
1341 void fcurve_free_driver(FCurve *fcu)
1342 {
1343         ChannelDriver *driver;
1344         DriverVar *dvar, *dvarn;
1345         
1346         /* sanity checks */
1347         if ELEM(NULL, fcu, fcu->driver)
1348                 return;
1349         driver= fcu->driver;
1350         
1351         /* free driver targets */
1352         for (dvar= driver->variables.first; dvar; dvar= dvarn) {
1353                 dvarn= dvar->next;
1354                 driver_free_variable(driver, dvar);
1355         }
1356
1357 #ifdef WITH_PYTHON
1358         /* free compiled driver expression */
1359         if (driver->expr_comp)
1360                 BPY_DECREF(driver->expr_comp);
1361 #endif
1362
1363         /* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */
1364         MEM_freeN(driver);
1365         fcu->driver= NULL;
1366 }
1367
1368 /* This makes a copy of the given driver */
1369 ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
1370 {
1371         ChannelDriver *ndriver;
1372         DriverVar *dvar;
1373         
1374         /* sanity checks */
1375         if (driver == NULL)
1376                 return NULL;
1377                 
1378         /* copy all data */
1379         ndriver= MEM_dupallocN(driver);
1380         ndriver->expr_comp= NULL;
1381         
1382         /* copy variables */
1383         ndriver->variables.first= ndriver->variables.last= NULL;
1384         BLI_duplicatelist(&ndriver->variables, &driver->variables);
1385         
1386         for (dvar= ndriver->variables.first; dvar; dvar= dvar->next) {  
1387                 /* need to go over all targets so that we don't leave any dangling paths */
1388                 DRIVER_TARGETS_LOOPER(dvar) 
1389                 {       
1390                         /* make a copy of target's rna path if available */
1391                         if (dtar->rna_path)
1392                                 dtar->rna_path = MEM_dupallocN(dtar->rna_path);
1393                 }
1394                 DRIVER_TARGETS_LOOPER_END
1395         }
1396         
1397         /* return the new driver */
1398         return ndriver;
1399 }
1400
1401 /* Driver Evaluation -------------------------- */
1402
1403 /* Evaluate a Driver Variable to get a value that contributes to the final */
1404 float driver_get_variable_value (ChannelDriver *driver, DriverVar *dvar)
1405 {
1406         DriverVarTypeInfo *dvti;
1407
1408         /* sanity check */
1409         if (ELEM(NULL, driver, dvar))
1410                 return 0.0f;
1411         
1412         /* call the relevant callbacks to get the variable value 
1413          * using the variable type info, storing the obtained value
1414          * in dvar->curval so that drivers can be debugged
1415          */
1416         dvti= get_dvar_typeinfo(dvar->type);
1417         
1418         if (dvti && dvti->get_value)
1419                 dvar->curval= dvti->get_value(driver, dvar);
1420         else
1421                 dvar->curval= 0.0f;
1422         
1423         return dvar->curval;
1424 }
1425
1426 /* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime"
1427  *      - "evaltime" is the frame at which F-Curve is being evaluated
1428  *      - has to return a float value 
1429  */
1430 static float evaluate_driver (ChannelDriver *driver, float UNUSED(evaltime))
1431 {
1432         DriverVar *dvar;
1433         
1434         /* check if driver can be evaluated */
1435         if (driver->flag & DRIVER_FLAG_INVALID)
1436                 return 0.0f;
1437         
1438         switch (driver->type) {
1439                 case DRIVER_TYPE_AVERAGE: /* average values of driver targets */
1440                 case DRIVER_TYPE_SUM: /* sum values of driver targets */
1441                 {
1442                         /* check how many variables there are first (i.e. just one?) */
1443                         if (driver->variables.first == driver->variables.last) {
1444                                 /* just one target, so just use that */
1445                                 dvar= driver->variables.first;
1446                                 driver->curval= driver_get_variable_value(driver, dvar);
1447                         }
1448                         else {
1449                                 /* more than one target, so average the values of the targets */
1450                                 float value = 0.0f;
1451                                 int tot = 0;
1452                                 
1453                                 /* loop through targets, adding (hopefully we don't get any overflow!) */
1454                                 for (dvar= driver->variables.first; dvar; dvar=dvar->next) {
1455                                         value += driver_get_variable_value(driver, dvar);
1456                                         tot++;
1457                                 }
1458                                 
1459                                 /* perform operations on the total if appropriate */
1460                                 if (driver->type == DRIVER_TYPE_AVERAGE)
1461                                         driver->curval= (value / (float)tot);
1462                                 else
1463                                         driver->curval= value;
1464                         }
1465                 }
1466                         break;
1467                         
1468                 case DRIVER_TYPE_MIN: /* smallest value */
1469                 case DRIVER_TYPE_MAX: /* largest value */
1470                 {
1471                         float value = 0.0f;
1472                         
1473                         /* loop through the variables, getting the values and comparing them to existing ones */
1474                         for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
1475                                 /* get value */
1476                                 float tmp_val= driver_get_variable_value(driver, dvar);
1477                                 
1478                                 /* store this value if appropriate */
1479                                 if (dvar->prev) {
1480                                         /* check if greater/smaller than the baseline */
1481                                         if (driver->type == DRIVER_TYPE_MAX) {
1482                                                 /* max? */
1483                                                 if (tmp_val > value) 
1484                                                         value= tmp_val;
1485                                         }
1486                                         else {
1487                                                 /* min? */
1488                                                 if (tmp_val < value) 
1489                                                         value= tmp_val;
1490                                         }
1491                                 }
1492                                 else {
1493                                         /* first item - make this the baseline for comparisons */
1494                                         value= tmp_val;
1495                                 }
1496                         }
1497                         
1498                         /* store value in driver */
1499                         driver->curval= value;
1500                 }
1501                         break;
1502                         
1503                 case DRIVER_TYPE_PYTHON: /* expression */
1504                 {
1505 #ifdef WITH_PYTHON
1506                         /* check for empty or invalid expression */
1507                         if ( (driver->expression[0] == '\0') ||
1508                                  (driver->flag & DRIVER_FLAG_INVALID) )
1509                         {
1510                                 driver->curval= 0.0f;
1511                         }
1512                         else
1513                         {
1514                                 /* this evaluates the expression using Python,and returns its result:
1515                                  *      - on errors it reports, then returns 0.0f
1516                                  */
1517                                 driver->curval= BPY_driver_exec(driver);
1518                         }
1519 #endif /* WITH_PYTHON*/
1520                 }
1521                         break;
1522                 
1523                 default:
1524                 {
1525                         /* special 'hack' - just use stored value 
1526                          *      This is currently used as the mechanism which allows animated settings to be able
1527                          *      to be changed via the UI.
1528                          */
1529                 }
1530         }
1531         
1532         /* return value for driver */
1533         return driver->curval;
1534 }
1535
1536 /* ***************************** Curve Calculations ********************************* */
1537
1538 /* The total length of the handles is not allowed to be more
1539  * than the horizontal distance between (v1-v4).
1540  * This is to prevent curve loops.
1541 */
1542 void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
1543 {
1544         float h1[2], h2[2], len1, len2, len, fac;
1545         
1546         /* calculate handle deltas */
1547         h1[0]= v1[0] - v2[0];
1548         h1[1]= v1[1] - v2[1];
1549         
1550         h2[0]= v4[0] - v3[0];
1551         h2[1]= v4[1] - v3[1];
1552         
1553         /* calculate distances: 
1554          *      - len   = span of time between keyframes 
1555          *      - len1  = length of handle of start key
1556          *      - len2  = length of handle of end key
1557          */
1558         len= v4[0]- v1[0];
1559         len1= (float)fabs(h1[0]);
1560         len2= (float)fabs(h2[0]);
1561         
1562         /* if the handles have no length, no need to do any corrections */
1563         if ((len1+len2) == 0.0f) 
1564                 return;
1565                 
1566         /* the two handles cross over each other, so force them
1567          * apart using the proportion they overlap 
1568          */
1569         if ((len1+len2) > len) {
1570                 fac= len / (len1+len2);
1571                 
1572                 v2[0]= (v1[0] - fac*h1[0]);
1573                 v2[1]= (v1[1] - fac*h1[1]);
1574                 
1575                 v3[0]= (v4[0] - fac*h2[0]);
1576                 v3[1]= (v4[1] - fac*h2[1]);
1577         }
1578 }
1579
1580 /* find root ('zero') */
1581 static int findzero (float x, float q0, float q1, float q2, float q3, float *o)
1582 {
1583         double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
1584         int nr= 0;
1585
1586         c0= q0 - x;
1587         c1= 3.0 * (q1 - q0);
1588         c2= 3.0 * (q0 - 2.0*q1 + q2);
1589         c3= q3 - q0 + 3.0 * (q1 - q2);
1590         
1591         if (c3 != 0.0) {
1592                 a= c2/c3;
1593                 b= c1/c3;
1594                 c= c0/c3;
1595                 a= a/3;
1596                 
1597                 p= b/3 - a*a;
1598                 q= (2*a*a*a - a*b + c) / 2;
1599                 d= q*q + p*p*p;
1600                 
1601                 if (d > 0.0) {
1602                         t= sqrt(d);
1603                         o[0]= (float)(sqrt3d(-q+t) + sqrt3d(-q-t) - a);
1604                         
1605                         if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
1606                         else return 0;
1607                 }
1608                 else if (d == 0.0) {
1609                         t= sqrt3d(-q);
1610                         o[0]= (float)(2*t - a);
1611                         
1612                         if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
1613                         o[nr]= (float)(-t-a);
1614                         
1615                         if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
1616                         else return nr;
1617                 }
1618                 else {
1619                         phi= acos(-q / sqrt(-(p*p*p)));
1620                         t= sqrt(-p);
1621                         p= cos(phi/3);
1622                         q= sqrt(3 - 3*p*p);
1623                         o[0]= (float)(2*t*p - a);
1624                         
1625                         if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
1626                         o[nr]= (float)(-t * (p + q) - a);
1627                         
1628                         if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) nr++;
1629                         o[nr]= (float)(-t * (p - q) - a);
1630                         
1631                         if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
1632                         else return nr;
1633                 }
1634         }
1635         else {
1636                 a=c2;
1637                 b=c1;
1638                 c=c0;
1639                 
1640                 if (a != 0.0) {
1641                         // discriminant
1642                         p= b*b - 4*a*c;
1643                         
1644                         if (p > 0) {
1645                                 p= sqrt(p);
1646                                 o[0]= (float)((-b-p) / (2 * a));
1647                                 
1648                                 if ((o[0] >= SMALL) && (o[0] <= 1.000001)) nr++;
1649                                 o[nr]= (float)((-b+p)/(2*a));
1650                                 
1651                                 if ((o[nr] >= SMALL) && (o[nr] <= 1.000001)) return nr+1;
1652                                 else return nr;
1653                         }
1654                         else if (p == 0) {
1655                                 o[0]= (float)(-b / (2 * a));
1656                                 if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
1657                                 else return 0;
1658                         }
1659                 }
1660                 else if (b != 0.0) {
1661                         o[0]= (float)(-c/b);
1662                         
1663                         if ((o[0] >= SMALL) && (o[0] <= 1.000001)) return 1;
1664                         else return 0;
1665                 }
1666                 else if (c == 0.0) {
1667                         o[0]= 0.0;
1668                         return 1;
1669                 }
1670                 
1671                 return 0;       
1672         }
1673 }
1674
1675 static void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
1676 {
1677         float t, c0, c1, c2, c3;
1678         int a;
1679
1680         c0= f1;
1681         c1= 3.0f * (f2 - f1);
1682         c2= 3.0f * (f1 - 2.0f*f2 + f3);
1683         c3= f4 - f1 + 3.0f * (f2 - f3);
1684         
1685         for (a=0; a < b; a++) {
1686                 t= o[a];
1687                 o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
1688         }
1689 }
1690
1691 #if 0
1692 static void berekenx (float *f, float *o, int b)
1693 {
1694         float t, c0, c1, c2, c3;
1695         int a;
1696
1697         c0= f[0];
1698         c1= 3.0f * (f[3] - f[0]);
1699         c2= 3.0f * (f[0] - 2.0f*f[3] + f[6]);
1700         c3= f[9] - f[0] + 3.0f * (f[3] - f[6]);
1701         
1702         for (a=0; a < b; a++) {
1703                 t= o[a];
1704                 o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
1705         }
1706 }
1707 #endif
1708
1709
1710 /* -------------------------- */
1711
1712 /* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
1713 static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltime)
1714 {
1715         BezTriple *bezt, *prevbezt, *lastbezt;
1716         float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
1717         unsigned int a;
1718         int b;
1719         float cvalue = 0.0f;
1720         
1721         /* get pointers */
1722         a= fcu->totvert-1;
1723         prevbezt= bezts;
1724         bezt= prevbezt+1;
1725         lastbezt= prevbezt + a;
1726         
1727         /* evaluation time at or past endpoints? */
1728         if (prevbezt->vec[1][0] >= evaltime) 
1729         {
1730                 /* before or on first keyframe */
1731                 if ( (fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (prevbezt->ipo != BEZT_IPO_CONST) &&
1732                         !(fcu->flag & FCURVE_DISCRETE_VALUES) ) 
1733                 {
1734                         /* linear or bezier interpolation */
1735                         if (prevbezt->ipo==BEZT_IPO_LIN) 
1736                         {
1737                                 /* Use the next center point instead of our own handle for
1738                                  * linear interpolated extrapolate 
1739                                  */
1740                                 if (fcu->totvert == 1) 
1741                                         cvalue= prevbezt->vec[1][1];
1742                                 else 
1743                                 {
1744                                         bezt = prevbezt+1;
1745                                         dx= prevbezt->vec[1][0] - evaltime;
1746                                         fac= bezt->vec[1][0] - prevbezt->vec[1][0];
1747                                         
1748                                         /* prevent division by zero */
1749                                         if (fac) {
1750                                                 fac= (bezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
1751                                                 cvalue= prevbezt->vec[1][1] - (fac * dx);
1752                                         }
1753                                         else 
1754                                                 cvalue= prevbezt->vec[1][1];
1755                                 }
1756                         } 
1757                         else 
1758                         {
1759                                 /* Use the first handle (earlier) of first BezTriple to calculate the
1760                                  * gradient and thus the value of the curve at evaltime
1761                                  */
1762                                 dx= prevbezt->vec[1][0] - evaltime;
1763                                 fac= prevbezt->vec[1][0] - prevbezt->vec[0][0];
1764                                 
1765                                 /* prevent division by zero */
1766                                 if (fac) {
1767                                         fac= (prevbezt->vec[1][1] - prevbezt->vec[0][1]) / fac;
1768                                         cvalue= prevbezt->vec[1][1] - (fac * dx);
1769                                 }
1770                                 else 
1771                                         cvalue= prevbezt->vec[1][1];
1772                         }
1773                 }
1774                 else 
1775                 {
1776                         /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, 
1777                          * so just extend first keyframe's value 
1778                          */
1779                         cvalue= prevbezt->vec[1][1];
1780                 }
1781         }
1782         else if (lastbezt->vec[1][0] <= evaltime) 
1783         {
1784                 /* after or on last keyframe */
1785                 if ( (fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (lastbezt->ipo != BEZT_IPO_CONST) &&
1786                         !(fcu->flag & FCURVE_DISCRETE_VALUES) ) 
1787                 {
1788                         /* linear or bezier interpolation */
1789                         if (lastbezt->ipo==BEZT_IPO_LIN) 
1790                         {
1791                                 /* Use the next center point instead of our own handle for
1792                                  * linear interpolated extrapolate 
1793                                  */
1794                                 if (fcu->totvert == 1) 
1795                                         cvalue= lastbezt->vec[1][1];
1796                                 else 
1797                                 {
1798                                         prevbezt = lastbezt - 1;
1799                                         dx= evaltime - lastbezt->vec[1][0];
1800                                         fac= lastbezt->vec[1][0] - prevbezt->vec[1][0];
1801                                         
1802                                         /* prevent division by zero */
1803                                         if (fac) {
1804                                                 fac= (lastbezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
1805                                                 cvalue= lastbezt->vec[1][1] + (fac * dx);
1806                                         }
1807                                         else 
1808                                                 cvalue= lastbezt->vec[1][1];
1809                                 }
1810                         } 
1811                         else 
1812                         {
1813                                 /* Use the gradient of the second handle (later) of last BezTriple to calculate the
1814                                  * gradient and thus the value of the curve at evaltime
1815                                  */
1816                                 dx= evaltime - lastbezt->vec[1][0];
1817                                 fac= lastbezt->vec[2][0] - lastbezt->vec[1][0];
1818                                 
1819                                 /* prevent division by zero */
1820                                 if (fac) {
1821                                         fac= (lastbezt->vec[2][1] - lastbezt->vec[1][1]) / fac;
1822                                         cvalue= lastbezt->vec[1][1] + (fac * dx);
1823                                 }
1824                                 else 
1825                                         cvalue= lastbezt->vec[1][1];
1826                         }
1827                 }
1828                 else 
1829                 {
1830                         /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, 
1831                          * so just extend last keyframe's value 
1832                          */
1833                         cvalue= lastbezt->vec[1][1];
1834                 }
1835         }
1836         else 
1837         {
1838                 /* evaltime occurs somewhere in the middle of the curve */
1839                 for (a=0; prevbezt && bezt && (a < fcu->totvert-1); a++, prevbezt=bezt, bezt++) 
1840                 {
1841                         /* use if the key is directly on the frame, rare cases this is needed else we get 0.0 instead. */
1842                         if(fabs(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) {
1843                                 cvalue= bezt->vec[1][1];
1844                         }
1845                         /* evaltime occurs within the interval defined by these two keyframes */
1846                         else if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime))
1847                         {
1848                                 /* value depends on interpolation mode */
1849                                 if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES))
1850                                 {
1851                                         /* constant (evaltime not relevant, so no interpolation needed) */
1852                                         cvalue= prevbezt->vec[1][1];
1853                                 }
1854                                 else if (prevbezt->ipo == BEZT_IPO_LIN) 
1855                                 {
1856                                         /* linear - interpolate between values of the two keyframes */
1857                                         fac= bezt->vec[1][0] - prevbezt->vec[1][0];
1858                                         
1859                                         /* prevent division by zero */
1860                                         if (fac) {
1861                                                 fac= (evaltime - prevbezt->vec[1][0]) / fac;
1862                                                 cvalue= prevbezt->vec[1][1] + (fac * (bezt->vec[1][1] - prevbezt->vec[1][1]));
1863                                         }
1864                                         else
1865                                                 cvalue= prevbezt->vec[1][1];
1866                                 }
1867                                 else 
1868                                 {
1869                                         /* bezier interpolation */
1870                                                 /* v1,v2 are the first keyframe and its 2nd handle */
1871                                         v1[0]= prevbezt->vec[1][0];
1872                                         v1[1]= prevbezt->vec[1][1];
1873                                         v2[0]= prevbezt->vec[2][0];
1874                                         v2[1]= prevbezt->vec[2][1];
1875                                                 /* v3,v4 are the last keyframe's 1st handle + the last keyframe */
1876                                         v3[0]= bezt->vec[0][0];
1877                                         v3[1]= bezt->vec[0][1];
1878                                         v4[0]= bezt->vec[1][0];
1879                                         v4[1]= bezt->vec[1][1];
1880                                         
1881                                         /* adjust handles so that they don't overlap (forming a loop) */
1882                                         correct_bezpart(v1, v2, v3, v4);
1883                                         
1884                                         /* try to get a value for this position - if failure, try another set of points */
1885                                         b= findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
1886                                         if (b) {
1887                                                 berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
1888                                                 cvalue= opl[0];
1889                                                 break;
1890                                         }
1891                                 }
1892                         }
1893                 }
1894         }
1895         
1896         /* return value */
1897         return cvalue;
1898 }
1899
1900 /* Calculate F-Curve value for 'evaltime' using FPoint samples */
1901 static float fcurve_eval_samples (FCurve *fcu, FPoint *fpts, float evaltime)
1902 {
1903         FPoint *prevfpt, *lastfpt, *fpt;
1904         float cvalue= 0.0f;
1905         
1906         /* get pointers */
1907         prevfpt= fpts;
1908         lastfpt= prevfpt + fcu->totvert-1;
1909         
1910         /* evaluation time at or past endpoints? */
1911         if (prevfpt->vec[0] >= evaltime) {
1912                 /* before or on first sample, so just extend value */
1913                 cvalue= prevfpt->vec[1];
1914         }
1915         else if (lastfpt->vec[0] <= evaltime) {
1916                 /* after or on last sample, so just extend value */
1917                 cvalue= lastfpt->vec[1];
1918         }
1919         else {
1920                 float t= (float)abs(evaltime - (int)evaltime);
1921                 
1922                 /* find the one on the right frame (assume that these are spaced on 1-frame intervals) */
1923                 fpt= prevfpt + (int)(evaltime - prevfpt->vec[0]);
1924                 
1925                 /* if not exactly on the frame, perform linear interpolation with the next one */
1926                 if (t != 0.0f) 
1927                         cvalue= interpf(fpt->vec[1], (fpt+1)->vec[1], t);
1928                 else
1929                         cvalue= fpt->vec[1];
1930         }
1931         
1932         /* return value */
1933         return cvalue;
1934 }
1935
1936 /* ***************************** F-Curve - Evaluation ********************************* */
1937
1938 /* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime") 
1939  * Note: this is also used for drivers
1940  */
1941 float evaluate_fcurve (FCurve *fcu, float evaltime) 
1942 {
1943         float cvalue= 0.0f;
1944         float devaltime;
1945         
1946         /* if there is a driver (only if this F-Curve is acting as 'driver'), evaluate it to find value to use as "evaltime" 
1947          * since drivers essentially act as alternative input (i.e. in place of 'time') for F-Curves
1948          *      - this value will also be returned as the value of the 'curve', if there are no keyframes
1949          */
1950         if (fcu->driver) {
1951                 /* evaltime now serves as input for the curve */
1952                 evaltime= cvalue= evaluate_driver(fcu->driver, evaltime);
1953         }
1954         
1955         /* evaluate modifiers which modify time to evaluate the base curve at */
1956         devaltime= evaluate_time_fmodifiers(&fcu->modifiers, fcu, cvalue, evaltime);
1957         
1958         /* evaluate curve-data 
1959          *      - 'devaltime' instead of 'evaltime', as this is the time that the last time-modifying 
1960          *        F-Curve modifier on the stack requested the curve to be evaluated at
1961          */
1962         if (fcu->bezt)
1963                 cvalue= fcurve_eval_keyframes(fcu, fcu->bezt, devaltime);
1964         else if (fcu->fpt)
1965                 cvalue= fcurve_eval_samples(fcu, fcu->fpt, devaltime);
1966         
1967         /* evaluate modifiers */
1968         evaluate_value_fmodifiers(&fcu->modifiers, fcu, &cvalue, evaltime);
1969         
1970         /* if curve can only have integral values, perform truncation (i.e. drop the decimal part)
1971          * here so that the curve can be sampled correctly
1972          */
1973         if (fcu->flag & FCURVE_INT_VALUES)
1974                 cvalue= (float)((int)cvalue);
1975         
1976         /* return evaluated value */
1977         return cvalue;
1978 }
1979
1980 /* Calculate the value of the given F-Curve at the given frame, and set its curval */
1981 void calculate_fcurve (FCurve *fcu, float ctime)
1982 {
1983         /* only calculate + set curval (overriding the existing value) if curve has 
1984          * any data which warrants this...
1985          */
1986         if ( (fcu->totvert) || (fcu->driver && !(fcu->driver->flag & DRIVER_FLAG_INVALID)) ||
1987                  list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) )
1988         {
1989                 /* calculate and set curval (evaluates driver too if necessary) */
1990                 fcu->curval= evaluate_fcurve(fcu, ctime);
1991         }
1992 }
1993