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 bke
22  */
23 
24 #include <float.h>
25 #include <math.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <string.h>
29 
30 #include "MEM_guardedalloc.h"
31 
32 #include "DNA_anim_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_text_types.h"
35 
36 #include "BLI_blenlib.h"
37 #include "BLI_easing.h"
38 #include "BLI_math.h"
39 
40 #include "BKE_anim_data.h"
41 #include "BKE_animsys.h"
42 #include "BKE_context.h"
43 #include "BKE_curve.h"
44 #include "BKE_fcurve.h"
45 #include "BKE_fcurve_driver.h"
46 #include "BKE_global.h"
47 #include "BKE_idprop.h"
48 #include "BKE_lib_query.h"
49 #include "BKE_nla.h"
50 
51 #include "BLO_read_write.h"
52 
53 #include "RNA_access.h"
54 
55 #include "CLG_log.h"
56 
57 #define SMALL -1.0e-10
58 #define SELECT 1
59 
60 static CLG_LogRef LOG = {"bke.fcurve"};
61 
62 /* -------------------------------------------------------------------- */
63 /** \name F-Curve Data Create
64  * \{ */
65 
BKE_fcurve_create(void)66 FCurve *BKE_fcurve_create(void)
67 {
68   FCurve *fcu = MEM_callocN(sizeof(FCurve), __func__);
69   return fcu;
70 }
71 
72 /** \} */
73 
74 /* -------------------------------------------------------------------- */
75 /** \name F-Curve Data Free
76  * \{ */
77 
78 /* Frees the F-Curve itself too, so make sure BLI_remlink is called before calling this... */
BKE_fcurve_free(FCurve * fcu)79 void BKE_fcurve_free(FCurve *fcu)
80 {
81   if (fcu == NULL) {
82     return;
83   }
84 
85   /* Free curve data. */
86   MEM_SAFE_FREE(fcu->bezt);
87   MEM_SAFE_FREE(fcu->fpt);
88 
89   /* Free RNA-path, as this were allocated when getting the path string. */
90   MEM_SAFE_FREE(fcu->rna_path);
91 
92   /* Free extra data - i.e. modifiers, and driver. */
93   fcurve_free_driver(fcu);
94   free_fmodifiers(&fcu->modifiers);
95 
96   /* Free the f-curve itself. */
97   MEM_freeN(fcu);
98 }
99 
100 /* Frees a list of F-Curves. */
BKE_fcurves_free(ListBase * list)101 void BKE_fcurves_free(ListBase *list)
102 {
103   FCurve *fcu, *fcn;
104 
105   /* Sanity check. */
106   if (list == NULL) {
107     return;
108   }
109 
110   /* Free data - no need to call remlink before freeing each curve,
111    * as we store reference to next, and freeing only touches the curve
112    * it's given.
113    */
114   for (fcu = list->first; fcu; fcu = fcn) {
115     fcn = fcu->next;
116     BKE_fcurve_free(fcu);
117   }
118 
119   /* Clear pointers just in case. */
120   BLI_listbase_clear(list);
121 }
122 
123 /** \} */
124 
125 /* -------------------------------------------------------------------- */
126 /** \name F-Curve Data Copy
127  * \{ */
128 
129 /* Duplicate a F-Curve. */
BKE_fcurve_copy(const FCurve * fcu)130 FCurve *BKE_fcurve_copy(const FCurve *fcu)
131 {
132   FCurve *fcu_d;
133 
134   /* Sanity check. */
135   if (fcu == NULL) {
136     return NULL;
137   }
138 
139   /* Make a copy. */
140   fcu_d = MEM_dupallocN(fcu);
141 
142   fcu_d->next = fcu_d->prev = NULL;
143   fcu_d->grp = NULL;
144 
145   /* Copy curve data. */
146   fcu_d->bezt = MEM_dupallocN(fcu_d->bezt);
147   fcu_d->fpt = MEM_dupallocN(fcu_d->fpt);
148 
149   /* Copy rna-path. */
150   fcu_d->rna_path = MEM_dupallocN(fcu_d->rna_path);
151 
152   /* Copy driver. */
153   fcu_d->driver = fcurve_copy_driver(fcu_d->driver);
154 
155   /* Copy modifiers. */
156   copy_fmodifiers(&fcu_d->modifiers, &fcu->modifiers);
157 
158   /* Return new data. */
159   return fcu_d;
160 }
161 
162 /* Duplicate a list of F-Curves. */
BKE_fcurves_copy(ListBase * dst,ListBase * src)163 void BKE_fcurves_copy(ListBase *dst, ListBase *src)
164 {
165   FCurve *dfcu, *sfcu;
166 
167   /* Sanity checks. */
168   if (ELEM(NULL, dst, src)) {
169     return;
170   }
171 
172   /* Clear destination list first. */
173   BLI_listbase_clear(dst);
174 
175   /* Copy one-by-one. */
176   for (sfcu = src->first; sfcu; sfcu = sfcu->next) {
177     dfcu = BKE_fcurve_copy(sfcu);
178     BLI_addtail(dst, dfcu);
179   }
180 }
181 
182 /** Callback used by lib_query to walk over all ID usages (mimics `foreach_id` callback of
183  * `IDTypeInfo` structure). */
BKE_fcurve_foreach_id(FCurve * fcu,LibraryForeachIDData * data)184 void BKE_fcurve_foreach_id(FCurve *fcu, LibraryForeachIDData *data)
185 {
186   ChannelDriver *driver = fcu->driver;
187 
188   if (driver != NULL) {
189     LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
190       /* only used targets */
191       DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
192         BKE_LIB_FOREACHID_PROCESS_ID(data, dtar->id, IDWALK_CB_NOP);
193       }
194       DRIVER_TARGETS_LOOPER_END;
195     }
196   }
197 
198   LISTBASE_FOREACH (FModifier *, fcm, &fcu->modifiers) {
199     switch (fcm->type) {
200       case FMODIFIER_TYPE_PYTHON: {
201         FMod_Python *fcm_py = (FMod_Python *)fcm->data;
202         BKE_LIB_FOREACHID_PROCESS(data, fcm_py->script, IDWALK_CB_NOP);
203 
204         IDP_foreach_property(fcm_py->prop,
205                              IDP_TYPE_FILTER_ID,
206                              BKE_lib_query_idpropertiesForeachIDLink_callback,
207                              data);
208         break;
209       }
210     }
211   }
212 }
213 
214 /* ----------------- Finding F-Curves -------------------------- */
215 
216 /* High level function to get an fcurve from C without having the RNA. */
id_data_find_fcurve(ID * id,void * data,StructRNA * type,const char * prop_name,int index,bool * r_driven)217 FCurve *id_data_find_fcurve(
218     ID *id, void *data, StructRNA *type, const char *prop_name, int index, bool *r_driven)
219 {
220   /* Anim vars */
221   AnimData *adt = BKE_animdata_from_id(id);
222   FCurve *fcu = NULL;
223 
224   /* Rna vars */
225   PointerRNA ptr;
226   PropertyRNA *prop;
227   char *path;
228 
229   if (r_driven) {
230     *r_driven = false;
231   }
232 
233   /* Only use the current action ??? */
234   if (ELEM(NULL, adt, adt->action)) {
235     return NULL;
236   }
237 
238   RNA_pointer_create(id, type, data, &ptr);
239   prop = RNA_struct_find_property(&ptr, prop_name);
240   if (prop == NULL) {
241     return NULL;
242   }
243 
244   path = RNA_path_from_ID_to_property(&ptr, prop);
245   if (path == NULL) {
246     return NULL;
247   }
248 
249   /* Animation takes priority over drivers. */
250   if (adt->action && adt->action->curves.first) {
251     fcu = BKE_fcurve_find(&adt->action->curves, path, index);
252   }
253 
254   /* If not animated, check if driven. */
255   if (fcu == NULL && adt->drivers.first) {
256     fcu = BKE_fcurve_find(&adt->drivers, path, index);
257     if (fcu && r_driven) {
258       *r_driven = true;
259     }
260     fcu = NULL;
261   }
262 
263   MEM_freeN(path);
264 
265   return fcu;
266 }
267 
268 /* Find the F-Curve affecting the given RNA-access path + index,
269  * in the list of F-Curves provided. */
BKE_fcurve_find(ListBase * list,const char rna_path[],const int array_index)270 FCurve *BKE_fcurve_find(ListBase *list, const char rna_path[], const int array_index)
271 {
272   FCurve *fcu;
273 
274   /* Sanity checks. */
275   if (ELEM(NULL, list, rna_path) || (array_index < 0)) {
276     return NULL;
277   }
278 
279   /* Check paths of curves, then array indices... */
280   for (fcu = list->first; fcu; fcu = fcu->next) {
281     /* Simple string-compare (this assumes that they have the same root...) */
282     if (fcu->rna_path && STREQ(fcu->rna_path, rna_path)) {
283       /* Now check indices. */
284       if (fcu->array_index == array_index) {
285         return fcu;
286       }
287     }
288   }
289 
290   return NULL;
291 }
292 
293 /* Quick way to loop over all fcurves of a given 'path'. */
BKE_fcurve_iter_step(FCurve * fcu_iter,const char rna_path[])294 FCurve *BKE_fcurve_iter_step(FCurve *fcu_iter, const char rna_path[])
295 {
296   FCurve *fcu;
297 
298   /* Sanity checks. */
299   if (ELEM(NULL, fcu_iter, rna_path)) {
300     return NULL;
301   }
302 
303   /* Check paths of curves, then array indices... */
304   for (fcu = fcu_iter; fcu; fcu = fcu->next) {
305     /* Simple string-compare (this assumes that they have the same root...) */
306     if (fcu->rna_path && STREQ(fcu->rna_path, rna_path)) {
307       return fcu;
308     }
309   }
310 
311   return NULL;
312 }
313 
314 /**
315  * Get list of LinkData's containing pointers to the F-Curves
316  * which control the types of data indicated.
317  *
318  * Lists...
319  * - dst: list of LinkData's matching the criteria returned.
320  *   List must be freed after use, and is assumed to be empty when passed.
321  * - src: list of F-Curves to search through
322  * Filters...
323  * - dataPrefix: i.e. 'pose.bones[' or 'nodes['
324  * - dataName: name of entity within "" immediately following the prefix
325  */
BKE_fcurves_filter(ListBase * dst,ListBase * src,const char * dataPrefix,const char * dataName)326 int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName)
327 {
328   FCurve *fcu;
329   int matches = 0;
330 
331   /* Sanity checks. */
332   if (ELEM(NULL, dst, src, dataPrefix, dataName)) {
333     return 0;
334   }
335   if ((dataPrefix[0] == 0) || (dataName[0] == 0)) {
336     return 0;
337   }
338 
339   /* Search each F-Curve one by one. */
340   for (fcu = src->first; fcu; fcu = fcu->next) {
341     /* Check if quoted string matches the path. */
342     if (fcu->rna_path == NULL || !strstr(fcu->rna_path, dataPrefix)) {
343       continue;
344     }
345 
346     char *quotedName = BLI_str_quoted_substrN(fcu->rna_path, dataPrefix);
347     if (quotedName == NULL) {
348       continue;
349     }
350 
351     /* Check if the quoted name matches the required name. */
352     if (STREQ(quotedName, dataName)) {
353       LinkData *ld = MEM_callocN(sizeof(LinkData), __func__);
354 
355       ld->data = fcu;
356       BLI_addtail(dst, ld);
357 
358       matches++;
359     }
360 
361     /* Always free the quoted string, since it needs freeing. */
362     MEM_freeN(quotedName);
363   }
364   /* Return the number of matches. */
365   return matches;
366 }
367 
BKE_fcurve_find_by_rna(PointerRNA * ptr,PropertyRNA * prop,int rnaindex,AnimData ** r_adt,bAction ** r_action,bool * r_driven,bool * r_special)368 FCurve *BKE_fcurve_find_by_rna(PointerRNA *ptr,
369                                PropertyRNA *prop,
370                                int rnaindex,
371                                AnimData **r_adt,
372                                bAction **r_action,
373                                bool *r_driven,
374                                bool *r_special)
375 {
376   return BKE_fcurve_find_by_rna_context_ui(
377       NULL, ptr, prop, rnaindex, r_adt, r_action, r_driven, r_special);
378 }
379 
BKE_fcurve_find_by_rna_context_ui(bContext * C,PointerRNA * ptr,PropertyRNA * prop,int rnaindex,AnimData ** r_animdata,bAction ** r_action,bool * r_driven,bool * r_special)380 FCurve *BKE_fcurve_find_by_rna_context_ui(bContext *C,
381                                           PointerRNA *ptr,
382                                           PropertyRNA *prop,
383                                           int rnaindex,
384                                           AnimData **r_animdata,
385                                           bAction **r_action,
386                                           bool *r_driven,
387                                           bool *r_special)
388 {
389   FCurve *fcu = NULL;
390   PointerRNA tptr = *ptr;
391 
392   *r_driven = false;
393   *r_special = false;
394 
395   if (r_animdata) {
396     *r_animdata = NULL;
397   }
398   if (r_action) {
399     *r_action = NULL;
400   }
401 
402   /* Special case for NLA Control Curves... */
403   if (BKE_nlastrip_has_curves_for_property(ptr, prop)) {
404     NlaStrip *strip = ptr->data;
405 
406     /* Set the special flag, since it cannot be a normal action/driver
407      * if we've been told to start looking here...
408      */
409     *r_special = true;
410 
411     /* The F-Curve either exists or it doesn't here... */
412     fcu = BKE_fcurve_find(&strip->fcurves, RNA_property_identifier(prop), rnaindex);
413     return fcu;
414   }
415 
416   /* There must be some RNA-pointer + property combo. */
417   if (prop && tptr.owner_id && RNA_property_animateable(&tptr, prop)) {
418     AnimData *adt = BKE_animdata_from_id(tptr.owner_id);
419     int step = (
420         /* Always 1 in case we have no context (can't check in 'ancestors' of given RNA ptr). */
421         C ? 2 : 1);
422     char *path = NULL;
423 
424     if (!adt && C) {
425       path = BKE_animdata_driver_path_hack(C, &tptr, prop, NULL);
426       adt = BKE_animdata_from_id(tptr.owner_id);
427       step--;
428     }
429 
430     /* Standard F-Curve - Animation (Action) or Drivers. */
431     while (adt && step--) {
432       if ((adt->action == NULL || adt->action->curves.first == NULL) &&
433           (adt->drivers.first == NULL)) {
434         continue;
435       }
436 
437       /* XXX This function call can become a performance bottleneck. */
438       if (step) {
439         path = RNA_path_from_ID_to_property(&tptr, prop);
440       }
441       if (path == NULL) {
442         continue;
443       }
444 
445       /* XXX: The logic here is duplicated with a function up above. */
446       /* animation takes priority over drivers. */
447       if (adt->action && adt->action->curves.first) {
448         fcu = BKE_fcurve_find(&adt->action->curves, path, rnaindex);
449 
450         if (fcu && r_action) {
451           *r_action = adt->action;
452         }
453       }
454 
455       /* If not animated, check if driven. */
456       if (!fcu && (adt->drivers.first)) {
457         fcu = BKE_fcurve_find(&adt->drivers, path, rnaindex);
458 
459         if (fcu) {
460           if (r_animdata) {
461             *r_animdata = adt;
462           }
463           *r_driven = true;
464         }
465       }
466 
467       if (fcu && r_action) {
468         if (r_animdata) {
469           *r_animdata = adt;
470         }
471         *r_action = adt->action;
472         break;
473       }
474 
475       if (step) {
476         char *tpath = BKE_animdata_driver_path_hack(C, &tptr, prop, path);
477         if (tpath && tpath != path) {
478           MEM_freeN(path);
479           path = tpath;
480           adt = BKE_animdata_from_id(tptr.owner_id);
481         }
482         else {
483           adt = NULL;
484         }
485       }
486     }
487     MEM_SAFE_FREE(path);
488   }
489 
490   return fcu;
491 }
492 
493 /** \} */
494 
495 /* -------------------------------------------------------------------- */
496 /** \name Finding Keyframes/Extents
497  * \{ */
498 
499 /* Binary search algorithm for finding where to insert BezTriple,
500  * with optional argument for precision required.
501  * Returns the index to insert at (data already at that index will be offset if replace is 0)
502  */
BKE_fcurve_bezt_binarysearch_index_ex(BezTriple array[],float frame,int arraylen,float threshold,bool * r_replace)503 static int BKE_fcurve_bezt_binarysearch_index_ex(
504     BezTriple array[], float frame, int arraylen, float threshold, bool *r_replace)
505 {
506   int start = 0, end = arraylen;
507   int loopbreaker = 0, maxloop = arraylen * 2;
508 
509   /* Initialize replace-flag first. */
510   *r_replace = false;
511 
512   /* Sneaky optimizations (don't go through searching process if...):
513    * - Keyframe to be added is to be added out of current bounds.
514    * - Keyframe to be added would replace one of the existing ones on bounds.
515    */
516   if ((arraylen <= 0) || (array == NULL)) {
517     CLOG_WARN(&LOG, "encountered invalid array");
518     return 0;
519   }
520 
521   /* Check whether to add before/after/on. */
522   float framenum;
523 
524   /* 'First' Keyframe (when only one keyframe, this case is used) */
525   framenum = array[0].vec[1][0];
526   if (IS_EQT(frame, framenum, threshold)) {
527     *r_replace = true;
528     return 0;
529   }
530   if (frame < framenum) {
531     return 0;
532   }
533 
534   /* 'Last' Keyframe */
535   framenum = array[(arraylen - 1)].vec[1][0];
536   if (IS_EQT(frame, framenum, threshold)) {
537     *r_replace = true;
538     return (arraylen - 1);
539   }
540   if (frame > framenum) {
541     return arraylen;
542   }
543 
544   /* Most of the time, this loop is just to find where to put it
545    * 'loopbreaker' is just here to prevent infinite loops.
546    */
547   for (loopbreaker = 0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
548     /* Compute and get midpoint. */
549 
550     /* We calculate the midpoint this way to avoid int overflows... */
551     int mid = start + ((end - start) / 2);
552 
553     float midfra = array[mid].vec[1][0];
554 
555     /* Check if exactly equal to midpoint. */
556     if (IS_EQT(frame, midfra, threshold)) {
557       *r_replace = true;
558       return mid;
559     }
560 
561     /* Repeat in upper/lower half. */
562     if (frame > midfra) {
563       start = mid + 1;
564     }
565     else if (frame < midfra) {
566       end = mid - 1;
567     }
568   }
569 
570   /* Print error if loop-limit exceeded. */
571   if (loopbreaker == (maxloop - 1)) {
572     CLOG_ERROR(&LOG, "search taking too long");
573 
574     /* Include debug info. */
575     CLOG_ERROR(&LOG,
576                "\tround = %d: start = %d, end = %d, arraylen = %d",
577                loopbreaker,
578                start,
579                end,
580                arraylen);
581   }
582 
583   /* Not found, so return where to place it. */
584   return start;
585 }
586 
587 /* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
588  * Returns the index to insert at (data already at that index will be offset if replace is 0)
589  */
BKE_fcurve_bezt_binarysearch_index(BezTriple array[],float frame,int arraylen,bool * r_replace)590 int BKE_fcurve_bezt_binarysearch_index(BezTriple array[],
591                                        float frame,
592                                        int arraylen,
593                                        bool *r_replace)
594 {
595   /* This is just a wrapper which uses the default threshold. */
596   return BKE_fcurve_bezt_binarysearch_index_ex(
597       array, frame, arraylen, BEZT_BINARYSEARCH_THRESH, r_replace);
598 }
599 
600 /* ...................................... */
601 
602 /* Helper for calc_fcurve_* functions -> find first and last BezTriple to be used. */
get_fcurve_end_keyframes(FCurve * fcu,BezTriple ** first,BezTriple ** last,const bool do_sel_only)603 static short get_fcurve_end_keyframes(FCurve *fcu,
604                                       BezTriple **first,
605                                       BezTriple **last,
606                                       const bool do_sel_only)
607 {
608   bool found = false;
609 
610   /* Init outputs. */
611   *first = NULL;
612   *last = NULL;
613 
614   /* Sanity checks. */
615   if (fcu->bezt == NULL) {
616     return found;
617   }
618 
619   /* Only include selected items? */
620   if (do_sel_only) {
621     BezTriple *bezt;
622 
623     /* Find first selected. */
624     bezt = fcu->bezt;
625     for (int i = 0; i < fcu->totvert; bezt++, i++) {
626       if (BEZT_ISSEL_ANY(bezt)) {
627         *first = bezt;
628         found = true;
629         break;
630       }
631     }
632 
633     /* Find last selected. */
634     bezt = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, fcu->totvert);
635     for (int i = 0; i < fcu->totvert; bezt--, i++) {
636       if (BEZT_ISSEL_ANY(bezt)) {
637         *last = bezt;
638         found = true;
639         break;
640       }
641     }
642   }
643   else {
644     /* Use the whole array. */
645     *first = fcu->bezt;
646     *last = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, fcu->totvert);
647     found = true;
648   }
649 
650   return found;
651 }
652 
653 /* Calculate the extents of F-Curve's data. */
BKE_fcurve_calc_bounds(FCurve * fcu,float * xmin,float * xmax,float * ymin,float * ymax,const bool do_sel_only,const bool include_handles)654 bool BKE_fcurve_calc_bounds(FCurve *fcu,
655                             float *xmin,
656                             float *xmax,
657                             float *ymin,
658                             float *ymax,
659                             const bool do_sel_only,
660                             const bool include_handles)
661 {
662   float xminv = 999999999.0f, xmaxv = -999999999.0f;
663   float yminv = 999999999.0f, ymaxv = -999999999.0f;
664   bool foundvert = false;
665 
666   if (fcu->totvert) {
667     if (fcu->bezt) {
668       BezTriple *bezt_first = NULL, *bezt_last = NULL;
669 
670       if (xmin || xmax) {
671         /* Get endpoint keyframes. */
672         foundvert = get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
673 
674         if (bezt_first) {
675           BLI_assert(bezt_last != NULL);
676 
677           if (include_handles) {
678             xminv = min_fff(xminv, bezt_first->vec[0][0], bezt_first->vec[1][0]);
679             xmaxv = max_fff(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]);
680           }
681           else {
682             xminv = min_ff(xminv, bezt_first->vec[1][0]);
683             xmaxv = max_ff(xmaxv, bezt_last->vec[1][0]);
684           }
685         }
686       }
687 
688       /* Only loop over keyframes to find extents for values if needed. */
689       if (ymin || ymax) {
690         BezTriple *bezt, *prevbezt = NULL;
691 
692         int i;
693         for (bezt = fcu->bezt, i = 0; i < fcu->totvert; prevbezt = bezt, bezt++, i++) {
694           if ((do_sel_only == false) || BEZT_ISSEL_ANY(bezt)) {
695             /* Keyframe itself. */
696             yminv = min_ff(yminv, bezt->vec[1][1]);
697             ymaxv = max_ff(ymaxv, bezt->vec[1][1]);
698 
699             if (include_handles) {
700               /* Left handle - only if applicable.
701                * NOTE: for the very first keyframe,
702                * the left handle actually has no bearings on anything. */
703               if (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ)) {
704                 yminv = min_ff(yminv, bezt->vec[0][1]);
705                 ymaxv = max_ff(ymaxv, bezt->vec[0][1]);
706               }
707 
708               /* Right handle - only if applicable. */
709               if (bezt->ipo == BEZT_IPO_BEZ) {
710                 yminv = min_ff(yminv, bezt->vec[2][1]);
711                 ymaxv = max_ff(ymaxv, bezt->vec[2][1]);
712               }
713             }
714 
715             foundvert = true;
716           }
717         }
718       }
719     }
720     else if (fcu->fpt) {
721       /* Frame range can be directly calculated from end verts. */
722       if (xmin || xmax) {
723         xminv = min_ff(xminv, fcu->fpt[0].vec[0]);
724         xmaxv = max_ff(xmaxv, fcu->fpt[fcu->totvert - 1].vec[0]);
725       }
726 
727       /* Only loop over keyframes to find extents for values if needed. */
728       if (ymin || ymax) {
729         FPoint *fpt;
730         int i;
731 
732         for (fpt = fcu->fpt, i = 0; i < fcu->totvert; fpt++, i++) {
733           if (fpt->vec[1] < yminv) {
734             yminv = fpt->vec[1];
735           }
736           if (fpt->vec[1] > ymaxv) {
737             ymaxv = fpt->vec[1];
738           }
739 
740           foundvert = true;
741         }
742       }
743     }
744   }
745 
746   if (foundvert) {
747     if (xmin) {
748       *xmin = xminv;
749     }
750     if (xmax) {
751       *xmax = xmaxv;
752     }
753 
754     if (ymin) {
755       *ymin = yminv;
756     }
757     if (ymax) {
758       *ymax = ymaxv;
759     }
760   }
761   else {
762     if (G.debug & G_DEBUG) {
763       printf("F-Curve calc bounds didn't find anything, so assuming minimum bounds of 1.0\n");
764     }
765 
766     if (xmin) {
767       *xmin = 0.0f;
768     }
769     if (xmax) {
770       *xmax = 1.0f;
771     }
772 
773     if (ymin) {
774       *ymin = 0.0f;
775     }
776     if (ymax) {
777       *ymax = 1.0f;
778     }
779   }
780 
781   return foundvert;
782 }
783 
784 /* Calculate the extents of F-Curve's keyframes. */
BKE_fcurve_calc_range(FCurve * fcu,float * start,float * end,const bool do_sel_only,const bool do_min_length)785 bool BKE_fcurve_calc_range(
786     FCurve *fcu, float *start, float *end, const bool do_sel_only, const bool do_min_length)
787 {
788   float min = 999999999.0f, max = -999999999.0f;
789   bool foundvert = false;
790 
791   if (fcu->totvert) {
792     if (fcu->bezt) {
793       BezTriple *bezt_first = NULL, *bezt_last = NULL;
794 
795       /* Get endpoint keyframes. */
796       get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
797 
798       if (bezt_first) {
799         BLI_assert(bezt_last != NULL);
800 
801         min = min_ff(min, bezt_first->vec[1][0]);
802         max = max_ff(max, bezt_last->vec[1][0]);
803 
804         foundvert = true;
805       }
806     }
807     else if (fcu->fpt) {
808       min = min_ff(min, fcu->fpt[0].vec[0]);
809       max = max_ff(max, fcu->fpt[fcu->totvert - 1].vec[0]);
810 
811       foundvert = true;
812     }
813   }
814 
815   if (foundvert == false) {
816     min = max = 0.0f;
817   }
818 
819   if (do_min_length) {
820     /* Minimum length is 1 frame. */
821     if (min == max) {
822       max += 1.0f;
823     }
824   }
825 
826   *start = min;
827   *end = max;
828 
829   return foundvert;
830 }
831 
832 /** \} */
833 
834 /* -------------------------------------------------------------------- */
835 /** \name Active Keyframe
836  * \{ */
837 
838 /**
839  * Set the index that stores the FCurve's active keyframe, assuming that \a active_bezt
840  * is already part of `fcu->bezt`. If NULL, set active keyframe index to "none."
841  */
BKE_fcurve_active_keyframe_set(FCurve * fcu,const BezTriple * active_bezt)842 void BKE_fcurve_active_keyframe_set(FCurve *fcu, const BezTriple *active_bezt)
843 {
844   if (active_bezt == NULL) {
845     fcu->active_keyframe_index = FCURVE_ACTIVE_KEYFRAME_NONE;
846     return;
847   }
848 
849   /* Gracefully handle out-of-bounds pointers. Ideally this would do a BLI_assert() as well, but
850    * then the unit tests would break in debug mode. */
851   ptrdiff_t offset = active_bezt - fcu->bezt;
852   if (offset < 0 || offset >= fcu->totvert) {
853     fcu->active_keyframe_index = FCURVE_ACTIVE_KEYFRAME_NONE;
854     return;
855   }
856 
857   /* The active keyframe should always be selected. */
858   BLI_assert(BEZT_ISSEL_ANY(active_bezt));
859 
860   fcu->active_keyframe_index = (int)offset;
861 }
862 
863 /**
864  * Get the active keyframe index, with sanity checks for point bounds.
865  */
BKE_fcurve_active_keyframe_index(const FCurve * fcu)866 int BKE_fcurve_active_keyframe_index(const FCurve *fcu)
867 {
868   const int active_keyframe_index = fcu->active_keyframe_index;
869 
870   /* Array access boundary checks. */
871   if ((fcu->bezt == NULL) || (active_keyframe_index >= fcu->totvert) ||
872       (active_keyframe_index < 0)) {
873     return FCURVE_ACTIVE_KEYFRAME_NONE;
874   }
875 
876   const BezTriple *active_bezt = &fcu->bezt[active_keyframe_index];
877   if (((active_bezt->f1 | active_bezt->f2 | active_bezt->f3) & SELECT) == 0) {
878     /* The active keyframe should always be selected. If it's not selected, it can't be active. */
879     return FCURVE_ACTIVE_KEYFRAME_NONE;
880   }
881 
882   return active_keyframe_index;
883 }
884 
885 /** \} */
886 
887 /* -------------------------------------------------------------------- */
888 /** \name Status Checks
889  * \{ */
890 
891 /* Are keyframes on F-Curve of any use?
892  * Usability of keyframes refers to whether they should be displayed,
893  * and also whether they will have any influence on the final result.
894  */
BKE_fcurve_are_keyframes_usable(FCurve * fcu)895 bool BKE_fcurve_are_keyframes_usable(FCurve *fcu)
896 {
897   /* F-Curve must exist. */
898   if (fcu == NULL) {
899     return false;
900   }
901 
902   /* F-Curve must not have samples - samples are mutually exclusive of keyframes. */
903   if (fcu->fpt) {
904     return false;
905   }
906 
907   /* If it has modifiers, none of these should "drastically" alter the curve. */
908   if (fcu->modifiers.first) {
909     FModifier *fcm;
910 
911     /* Check modifiers from last to first, as last will be more influential. */
912     /* TODO: optionally, only check modifier if it is the active one... (Joshua Leung 2010) */
913     for (fcm = fcu->modifiers.last; fcm; fcm = fcm->prev) {
914       /* Ignore if muted/disabled. */
915       if (fcm->flag & (FMODIFIER_FLAG_DISABLED | FMODIFIER_FLAG_MUTED)) {
916         continue;
917       }
918 
919       /* Type checks. */
920       switch (fcm->type) {
921         /* Clearly harmless - do nothing. */
922         case FMODIFIER_TYPE_CYCLES:
923         case FMODIFIER_TYPE_STEPPED:
924         case FMODIFIER_TYPE_NOISE:
925           break;
926 
927         /* Sometimes harmful - depending on whether they're "additive" or not. */
928         case FMODIFIER_TYPE_GENERATOR: {
929           FMod_Generator *data = (FMod_Generator *)fcm->data;
930 
931           if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) {
932             return false;
933           }
934           break;
935         }
936         case FMODIFIER_TYPE_FN_GENERATOR: {
937           FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data;
938 
939           if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) {
940             return false;
941           }
942           break;
943         }
944         /* Always harmful - cannot allow. */
945         default:
946           return false;
947       }
948     }
949   }
950 
951   /* Keyframes are usable. */
952   return true;
953 }
954 
BKE_fcurve_is_protected(FCurve * fcu)955 bool BKE_fcurve_is_protected(FCurve *fcu)
956 {
957   return ((fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)));
958 }
959 
960 /* Can keyframes be added to F-Curve?
961  * Keyframes can only be added if they are already visible.
962  */
BKE_fcurve_is_keyframable(FCurve * fcu)963 bool BKE_fcurve_is_keyframable(FCurve *fcu)
964 {
965   /* F-Curve's keyframes must be "usable" (i.e. visible + have an effect on final result) */
966   if (BKE_fcurve_are_keyframes_usable(fcu) == 0) {
967     return false;
968   }
969 
970   /* F-Curve must currently be editable too. */
971   if (BKE_fcurve_is_protected(fcu)) {
972     return false;
973   }
974 
975   /* F-Curve is keyframable. */
976   return true;
977 }
978 
979 /** \} */
980 
981 /* -------------------------------------------------------------------- */
982 /** \name Keyframe Column Tools
983  * \{ */
984 
985 /* Add a BezTriple to a column. */
UNUSED_FUNCTION(bezt_add_to_cfra_elem)986 static void UNUSED_FUNCTION(bezt_add_to_cfra_elem)(ListBase *lb, BezTriple *bezt)
987 {
988   CfraElem *ce, *cen;
989 
990   for (ce = lb->first; ce; ce = ce->next) {
991     /* Double key? */
992     if (IS_EQT(ce->cfra, bezt->vec[1][0], BEZT_BINARYSEARCH_THRESH)) {
993       if (bezt->f2 & SELECT) {
994         ce->sel = bezt->f2;
995       }
996       return;
997     }
998     /* Should key be inserted before this column? */
999     if (ce->cfra > bezt->vec[1][0]) {
1000       break;
1001     }
1002   }
1003 
1004   /* Create a new column */
1005   cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
1006   if (ce) {
1007     BLI_insertlinkbefore(lb, ce, cen);
1008   }
1009   else {
1010     BLI_addtail(lb, cen);
1011   }
1012 
1013   cen->cfra = bezt->vec[1][0];
1014   cen->sel = bezt->f2;
1015 }
1016 
1017 /** \} */
1018 
1019 /* -------------------------------------------------------------------- */
1020 /** \name Samples Utilities
1021  * \{ */
1022 
1023 /* Some utilities for working with FPoints (i.e. 'sampled' animation curve data, such as
1024  * data imported from BVH/Mocap files), which are specialized for use with high density datasets,
1025  * which BezTriples/Keyframe data are ill equipped to do.
1026  */
1027 
1028 /* Basic sampling callback which acts as a wrapper for evaluate_fcurve()
1029  * 'data' arg here is unneeded here...
1030  */
fcurve_samplingcb_evalcurve(FCurve * fcu,void * UNUSED (data),float evaltime)1031 float fcurve_samplingcb_evalcurve(FCurve *fcu, void *UNUSED(data), float evaltime)
1032 {
1033   /* Assume any interference from drivers on the curve is intended... */
1034   return evaluate_fcurve(fcu, evaltime);
1035 }
1036 
1037 /* Main API function for creating a set of sampled curve data, given some callback function
1038  * used to retrieve the values to store.
1039  */
fcurve_store_samples(FCurve * fcu,void * data,int start,int end,FcuSampleFunc sample_cb)1040 void fcurve_store_samples(FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb)
1041 {
1042   FPoint *fpt, *new_fpt;
1043   int cfra;
1044 
1045   /* Sanity checks. */
1046   /* TODO: make these tests report errors using reports not CLOG's (Joshua Leung 2009) */
1047   if (ELEM(NULL, fcu, sample_cb)) {
1048     CLOG_ERROR(&LOG, "No F-Curve with F-Curve Modifiers to Bake");
1049     return;
1050   }
1051   if (start > end) {
1052     CLOG_ERROR(&LOG, "Error: Frame range for Sampled F-Curve creation is inappropriate");
1053     return;
1054   }
1055 
1056   /* Set up sample data. */
1057   fpt = new_fpt = MEM_callocN(sizeof(FPoint) * (end - start + 1), "FPoint Samples");
1058 
1059   /* Use the sampling callback at 1-frame intervals from start to end frames. */
1060   for (cfra = start; cfra <= end; cfra++, fpt++) {
1061     fpt->vec[0] = (float)cfra;
1062     fpt->vec[1] = sample_cb(fcu, data, (float)cfra);
1063   }
1064 
1065   /* Free any existing sample/keyframe data on curve. */
1066   if (fcu->bezt) {
1067     MEM_freeN(fcu->bezt);
1068   }
1069   if (fcu->fpt) {
1070     MEM_freeN(fcu->fpt);
1071   }
1072 
1073   /* Store the samples. */
1074   fcu->bezt = NULL;
1075   fcu->fpt = new_fpt;
1076   fcu->totvert = end - start + 1;
1077 }
1078 
1079 /* ***************************** F-Curve Sanity ********************************* */
1080 /* The functions here are used in various parts of Blender, usually after some editing
1081  * of keyframe data has occurred. They ensure that keyframe data is properly ordered and
1082  * that the handles are correct.
1083  */
1084 
1085 /* Checks if the F-Curve has a Cycles modifier, and returns the type of the cycle behavior. */
BKE_fcurve_get_cycle_type(FCurve * fcu)1086 eFCU_Cycle_Type BKE_fcurve_get_cycle_type(FCurve *fcu)
1087 {
1088   FModifier *fcm = fcu->modifiers.first;
1089 
1090   if (!fcm || fcm->type != FMODIFIER_TYPE_CYCLES) {
1091     return FCU_CYCLE_NONE;
1092   }
1093 
1094   if (fcm->flag & (FMODIFIER_FLAG_DISABLED | FMODIFIER_FLAG_MUTED)) {
1095     return FCU_CYCLE_NONE;
1096   }
1097 
1098   if (fcm->flag & (FMODIFIER_FLAG_RANGERESTRICT | FMODIFIER_FLAG_USEINFLUENCE)) {
1099     return FCU_CYCLE_NONE;
1100   }
1101 
1102   FMod_Cycles *data = (FMod_Cycles *)fcm->data;
1103 
1104   if (data && data->after_cycles == 0 && data->before_cycles == 0) {
1105     if (data->before_mode == FCM_EXTRAPOLATE_CYCLIC &&
1106         data->after_mode == FCM_EXTRAPOLATE_CYCLIC) {
1107       return FCU_CYCLE_PERFECT;
1108     }
1109 
1110     if (ELEM(data->before_mode, FCM_EXTRAPOLATE_CYCLIC, FCM_EXTRAPOLATE_CYCLIC_OFFSET) &&
1111         ELEM(data->after_mode, FCM_EXTRAPOLATE_CYCLIC, FCM_EXTRAPOLATE_CYCLIC_OFFSET)) {
1112       return FCU_CYCLE_OFFSET;
1113     }
1114   }
1115 
1116   return FCU_CYCLE_NONE;
1117 }
1118 
1119 /* Checks if the F-Curve has a Cycles modifier with simple settings
1120  * that warrant transition smoothing. */
BKE_fcurve_is_cyclic(FCurve * fcu)1121 bool BKE_fcurve_is_cyclic(FCurve *fcu)
1122 {
1123   return BKE_fcurve_get_cycle_type(fcu) != FCU_CYCLE_NONE;
1124 }
1125 
1126 /* Shifts 'in' by the difference in coordinates between 'to' and 'from',
1127  * using 'out' as the output buffer.
1128  * When 'to' and 'from' are end points of the loop, this moves the 'in' point one loop cycle.
1129  */
cycle_offset_triple(bool cycle,BezTriple * out,const BezTriple * in,const BezTriple * from,const BezTriple * to)1130 static BezTriple *cycle_offset_triple(
1131     bool cycle, BezTriple *out, const BezTriple *in, const BezTriple *from, const BezTriple *to)
1132 {
1133   if (!cycle) {
1134     return NULL;
1135   }
1136 
1137   memcpy(out, in, sizeof(BezTriple));
1138 
1139   float delta[3];
1140   sub_v3_v3v3(delta, to->vec[1], from->vec[1]);
1141 
1142   for (int i = 0; i < 3; i++) {
1143     add_v3_v3(out->vec[i], delta);
1144   }
1145 
1146   return out;
1147 }
1148 
1149 /**
1150  * Variant of #calchandles_fcurve() that allows calculating based on a different select flag.
1151  *
1152  * \param handle_sel_flag: The flag (bezt.f1/2/3) value to use to determine selection.
1153  * Usually `SELECT`, but may want to use a different one at times
1154  * (if caller does not operate on selection).
1155  */
calchandles_fcurve_ex(FCurve * fcu,eBezTriple_Flag handle_sel_flag)1156 void calchandles_fcurve_ex(FCurve *fcu, eBezTriple_Flag handle_sel_flag)
1157 {
1158   BezTriple *bezt, *prev, *next;
1159   int a = fcu->totvert;
1160 
1161   /* Error checking:
1162    * - Need at least two points.
1163    * - Need bezier keys.
1164    * - Only bezier-interpolation has handles (for now).
1165    */
1166   if (ELEM(NULL, fcu, fcu->bezt) || (a < 2) /*|| ELEM(fcu->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN)*/) {
1167     return;
1168   }
1169 
1170   /* If the first modifier is Cycles, smooth the curve through the cycle. */
1171   BezTriple *first = &fcu->bezt[0], *last = &fcu->bezt[fcu->totvert - 1];
1172   BezTriple tmp;
1173 
1174   bool cycle = BKE_fcurve_is_cyclic(fcu) && BEZT_IS_AUTOH(first) && BEZT_IS_AUTOH(last);
1175 
1176   /* Get initial pointers. */
1177   bezt = fcu->bezt;
1178   prev = cycle_offset_triple(cycle, &tmp, &fcu->bezt[fcu->totvert - 2], last, first);
1179   next = (bezt + 1);
1180 
1181   /* Loop over all beztriples, adjusting handles. */
1182   while (a--) {
1183     /* Clamp timing of handles to be on either side of beztriple. */
1184     if (bezt->vec[0][0] > bezt->vec[1][0]) {
1185       bezt->vec[0][0] = bezt->vec[1][0];
1186     }
1187     if (bezt->vec[2][0] < bezt->vec[1][0]) {
1188       bezt->vec[2][0] = bezt->vec[1][0];
1189     }
1190 
1191     /* Calculate auto-handles. */
1192     BKE_nurb_handle_calc_ex(bezt, prev, next, handle_sel_flag, true, fcu->auto_smoothing);
1193 
1194     /* For automatic ease in and out. */
1195     if (BEZT_IS_AUTOH(bezt) && !cycle) {
1196       /* Only do this on first or last beztriple. */
1197       if ((a == 0) || (a == fcu->totvert - 1)) {
1198         /* Set both handles to have same horizontal value as keyframe. */
1199         if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) {
1200           bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1];
1201           /* Remember that these keyframes are special, they don't need to be adjusted. */
1202           bezt->f5 = HD_AUTOTYPE_SPECIAL;
1203         }
1204       }
1205     }
1206 
1207     /* Avoid total smoothing failure on duplicate keyframes (can happen during grab). */
1208     if (prev && prev->vec[1][0] >= bezt->vec[1][0]) {
1209       prev->f5 = bezt->f5 = HD_AUTOTYPE_SPECIAL;
1210     }
1211 
1212     /* Advance pointers for next iteration. */
1213     prev = bezt;
1214 
1215     if (a == 1) {
1216       next = cycle_offset_triple(cycle, &tmp, &fcu->bezt[1], first, last);
1217     }
1218     else {
1219       next++;
1220     }
1221 
1222     bezt++;
1223   }
1224 
1225   /* If cyclic extrapolation and Auto Clamp has triggered, ensure it is symmetric. */
1226   if (cycle && (first->f5 != HD_AUTOTYPE_NORMAL || last->f5 != HD_AUTOTYPE_NORMAL)) {
1227     first->vec[0][1] = first->vec[2][1] = first->vec[1][1];
1228     last->vec[0][1] = last->vec[2][1] = last->vec[1][1];
1229     first->f5 = last->f5 = HD_AUTOTYPE_SPECIAL;
1230   }
1231 
1232   /* Do a second pass for auto handle: compute the handle to have 0 acceleration step. */
1233   if (fcu->auto_smoothing != FCURVE_SMOOTH_NONE) {
1234     BKE_nurb_handle_smooth_fcurve(fcu->bezt, fcu->totvert, cycle);
1235   }
1236 }
1237 
1238 /**
1239  * This function recalculates the handles of an F-Curve. Acts based on selection with `SELECT`
1240  * flag. To use a different flag, use #calchandles_fcurve_ex().
1241  *
1242  * If the BezTriples have been rearranged, sort them first before using this.
1243  */
calchandles_fcurve(FCurve * fcu)1244 void calchandles_fcurve(FCurve *fcu)
1245 {
1246   calchandles_fcurve_ex(fcu, SELECT);
1247 }
1248 
1249 /**
1250  * Update handles, making sure the handle-types are valid (e.g. correctly deduced from an "Auto"
1251  * type), and recalculating their position vectors.
1252  * Use when something has changed handle positions.
1253  *
1254  * \param sel_flag: The flag (bezt.f1/2/3) value to use to determine selection. Usually `SELECT`,
1255  *                  but may want to use a different one at times (if caller does not operate on
1256  *                  selection).
1257  * \param use_handle: Check selection state of individual handles, otherwise always update both
1258  *                    handles if the key is selected.
1259  */
testhandles_fcurve(FCurve * fcu,eBezTriple_Flag sel_flag,const bool use_handle)1260 void testhandles_fcurve(FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_handle)
1261 {
1262   BezTriple *bezt;
1263   unsigned int a;
1264 
1265   /* Only beztriples have handles (bpoints don't though). */
1266   if (ELEM(NULL, fcu, fcu->bezt)) {
1267     return;
1268   }
1269 
1270   /* Loop over beztriples. */
1271   for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
1272     BKE_nurb_bezt_handle_test(bezt, sel_flag, use_handle, false);
1273   }
1274 
1275   /* Recalculate handles. */
1276   calchandles_fcurve_ex(fcu, sel_flag);
1277 }
1278 
1279 /* This function sorts BezTriples so that they are arranged in chronological order,
1280  * as tools working on F-Curves expect that the BezTriples are in order.
1281  */
sort_time_fcurve(FCurve * fcu)1282 void sort_time_fcurve(FCurve *fcu)
1283 {
1284   if (fcu->bezt == NULL) {
1285     return;
1286   }
1287 
1288   /* Keep adjusting order of beztriples until nothing moves (bubble-sort). */
1289   BezTriple *bezt;
1290   uint a;
1291 
1292   bool ok = true;
1293   while (ok) {
1294     ok = 0;
1295     /* Currently, will only be needed when there are beztriples. */
1296 
1297     /* Loop over ALL points to adjust position in array and recalculate handles. */
1298     for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
1299       /* Check if thee's a next beztriple which we could try to swap with current. */
1300       if (a < (fcu->totvert - 1)) {
1301         /* Swap if one is after the other (and indicate that order has changed). */
1302         if (bezt->vec[1][0] > (bezt + 1)->vec[1][0]) {
1303           SWAP(BezTriple, *bezt, *(bezt + 1));
1304           ok = 1;
1305         }
1306       }
1307     }
1308   }
1309 
1310   for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
1311     /* If either one of both of the points exceeds crosses over the keyframe time... */
1312     if ((bezt->vec[0][0] > bezt->vec[1][0]) && (bezt->vec[2][0] < bezt->vec[1][0])) {
1313       /* Swap handles if they have switched sides for some reason. */
1314       swap_v2_v2(bezt->vec[0], bezt->vec[2]);
1315     }
1316     else {
1317       /* Clamp handles. */
1318       CLAMP_MAX(bezt->vec[0][0], bezt->vec[1][0]);
1319       CLAMP_MIN(bezt->vec[2][0], bezt->vec[1][0]);
1320     }
1321   }
1322 }
1323 
1324 /* This function tests if any BezTriples are out of order, thus requiring a sort. */
test_time_fcurve(FCurve * fcu)1325 bool test_time_fcurve(FCurve *fcu)
1326 {
1327   unsigned int a;
1328 
1329   /* Sanity checks. */
1330   if (fcu == NULL) {
1331     return false;
1332   }
1333 
1334   /* Currently, only need to test beztriples. */
1335   if (fcu->bezt) {
1336     BezTriple *bezt;
1337 
1338     /* Loop through all BezTriples, stopping when one exceeds the one after it. */
1339     for (a = 0, bezt = fcu->bezt; a < (fcu->totvert - 1); a++, bezt++) {
1340       if (bezt->vec[1][0] > (bezt + 1)->vec[1][0]) {
1341         return true;
1342       }
1343     }
1344   }
1345   else if (fcu->fpt) {
1346     FPoint *fpt;
1347 
1348     /* Loop through all FPoints, stopping when one exceeds the one after it. */
1349     for (a = 0, fpt = fcu->fpt; a < (fcu->totvert - 1); a++, fpt++) {
1350       if (fpt->vec[0] > (fpt + 1)->vec[0]) {
1351         return true;
1352       }
1353     }
1354   }
1355 
1356   /* None need any swapping. */
1357   return false;
1358 }
1359 
1360 /** \} */
1361 
1362 /* -------------------------------------------------------------------- */
1363 /** \name F-Curve Calculations
1364  * \{ */
1365 
1366 /* The length of each handle is not allowed to be more
1367  * than the horizontal distance between (v1-v4).
1368  * This is to prevent curve loops.
1369  *
1370  * This function is very similar to BKE_curve_correct_bezpart(), but allows a steeper tangent for
1371  * more snappy animations. This is not desired for other areas in which curves are used, though.
1372  */
BKE_fcurve_correct_bezpart(const float v1[2],float v2[2],float v3[2],const float v4[2])1373 void BKE_fcurve_correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2])
1374 {
1375   float h1[2], h2[2], len1, len2, len, fac;
1376 
1377   /* Calculate handle deltas. */
1378   h1[0] = v1[0] - v2[0];
1379   h1[1] = v1[1] - v2[1];
1380 
1381   h2[0] = v4[0] - v3[0];
1382   h2[1] = v4[1] - v3[1];
1383 
1384   /* Calculate distances:
1385    * - len  = Span of time between keyframes.
1386    * - len1 = Length of handle of start key.
1387    * - len2 = Length of handle of end key.
1388    */
1389   len = v4[0] - v1[0];
1390   len1 = fabsf(h1[0]);
1391   len2 = fabsf(h2[0]);
1392 
1393   /* If the handles have no length, no need to do any corrections. */
1394   if ((len1 + len2) == 0.0f) {
1395     return;
1396   }
1397 
1398   /* To prevent looping or rewinding, handles cannot
1399    * exceed the adjacent key-frames time position. */
1400   if (len1 > len) {
1401     fac = len / len1;
1402     v2[0] = (v1[0] - fac * h1[0]);
1403     v2[1] = (v1[1] - fac * h1[1]);
1404   }
1405 
1406   if (len2 > len) {
1407     fac = len / len2;
1408     v3[0] = (v4[0] - fac * h2[0]);
1409     v3[1] = (v4[1] - fac * h2[1]);
1410   }
1411 }
1412 
1413 /** Find roots of cubic equation (c0 x³ + c1 x² + c2 x + c3)
1414  * \return number of roots in `o`.
1415  * NOTE: it is up to the caller to allocate enough memory for `o`. */
solve_cubic(double c0,double c1,double c2,double c3,float * o)1416 static int solve_cubic(double c0, double c1, double c2, double c3, float *o)
1417 {
1418   double a, b, c, p, q, d, t, phi;
1419   int nr = 0;
1420 
1421   if (c3 != 0.0) {
1422     a = c2 / c3;
1423     b = c1 / c3;
1424     c = c0 / c3;
1425     a = a / 3;
1426 
1427     p = b / 3 - a * a;
1428     q = (2 * a * a * a - a * b + c) / 2;
1429     d = q * q + p * p * p;
1430 
1431     if (d > 0.0) {
1432       t = sqrt(d);
1433       o[0] = (float)(sqrt3d(-q + t) + sqrt3d(-q - t) - a);
1434 
1435       if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) {
1436         return 1;
1437       }
1438       return 0;
1439     }
1440 
1441     if (d == 0.0) {
1442       t = sqrt3d(-q);
1443       o[0] = (float)(2 * t - a);
1444 
1445       if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) {
1446         nr++;
1447       }
1448       o[nr] = (float)(-t - a);
1449 
1450       if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) {
1451         return nr + 1;
1452       }
1453       return nr;
1454     }
1455 
1456     phi = acos(-q / sqrt(-(p * p * p)));
1457     t = sqrt(-p);
1458     p = cos(phi / 3);
1459     q = sqrt(3 - 3 * p * p);
1460     o[0] = (float)(2 * t * p - a);
1461 
1462     if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) {
1463       nr++;
1464     }
1465     o[nr] = (float)(-t * (p + q) - a);
1466 
1467     if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) {
1468       nr++;
1469     }
1470     o[nr] = (float)(-t * (p - q) - a);
1471 
1472     if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) {
1473       return nr + 1;
1474     }
1475     return nr;
1476   }
1477   a = c2;
1478   b = c1;
1479   c = c0;
1480 
1481   if (a != 0.0) {
1482     /* Discriminant */
1483     p = b * b - 4 * a * c;
1484 
1485     if (p > 0) {
1486       p = sqrt(p);
1487       o[0] = (float)((-b - p) / (2 * a));
1488 
1489       if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) {
1490         nr++;
1491       }
1492       o[nr] = (float)((-b + p) / (2 * a));
1493 
1494       if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) {
1495         return nr + 1;
1496       }
1497       return nr;
1498     }
1499 
1500     if (p == 0) {
1501       o[0] = (float)(-b / (2 * a));
1502       if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) {
1503         return 1;
1504       }
1505     }
1506 
1507     return 0;
1508   }
1509 
1510   if (b != 0.0) {
1511     o[0] = (float)(-c / b);
1512 
1513     if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) {
1514       return 1;
1515     }
1516     return 0;
1517   }
1518 
1519   if (c == 0.0) {
1520     o[0] = 0.0;
1521     return 1;
1522   }
1523 
1524   return 0;
1525 }
1526 
1527 /* Find root(s) ('zero') of a Bezier curve. */
findzero(float x,float q0,float q1,float q2,float q3,float * o)1528 static int findzero(float x, float q0, float q1, float q2, float q3, float *o)
1529 {
1530   const double c0 = q0 - x;
1531   const double c1 = 3.0f * (q1 - q0);
1532   const double c2 = 3.0f * (q0 - 2.0f * q1 + q2);
1533   const double c3 = q3 - q0 + 3.0f * (q1 - q2);
1534 
1535   return solve_cubic(c0, c1, c2, c3, o);
1536 }
1537 
berekeny(float f1,float f2,float f3,float f4,float * o,int b)1538 static void berekeny(float f1, float f2, float f3, float f4, float *o, int b)
1539 {
1540   float t, c0, c1, c2, c3;
1541   int a;
1542 
1543   c0 = f1;
1544   c1 = 3.0f * (f2 - f1);
1545   c2 = 3.0f * (f1 - 2.0f * f2 + f3);
1546   c3 = f4 - f1 + 3.0f * (f2 - f3);
1547 
1548   for (a = 0; a < b; a++) {
1549     t = o[a];
1550     o[a] = c0 + t * c1 + t * t * c2 + t * t * t * c3;
1551   }
1552 }
1553 
1554 /**
1555  * Adjust Bezier handles of all three given BezTriples, so that `bezt` can be inserted between
1556  * `prev` and `next` without changing the resulting curve shape.
1557  *
1558  * \param r_pdelta: return Y difference between `bezt` and the original curve value at its X
1559  * position.
1560  * \return Whether the split was successful.
1561  */
BKE_fcurve_bezt_subdivide_handles(struct BezTriple * bezt,struct BezTriple * prev,struct BezTriple * next,float * r_pdelta)1562 bool BKE_fcurve_bezt_subdivide_handles(struct BezTriple *bezt,
1563                                        struct BezTriple *prev,
1564                                        struct BezTriple *next,
1565                                        float *r_pdelta)
1566 {
1567   /* The four points that make up this section of the Bezier curve. */
1568   const float *prev_coords = prev->vec[1];
1569   float *prev_handle_right = prev->vec[2];
1570   float *next_handle_left = next->vec[0];
1571   const float *next_coords = next->vec[1];
1572 
1573   float *new_handle_left = bezt->vec[0];
1574   const float *new_coords = bezt->vec[1];
1575   float *new_handle_right = bezt->vec[2];
1576 
1577   if (new_coords[0] <= prev_coords[0] || new_coords[0] >= next_coords[0]) {
1578     /* The new keyframe is outside the (prev_coords, next_coords) range. */
1579     return false;
1580   }
1581 
1582   /* Apply evaluation-time limits and compute the effective curve. */
1583   BKE_fcurve_correct_bezpart(prev_coords, prev_handle_right, next_handle_left, next_coords);
1584   float roots[4];
1585   if (!findzero(new_coords[0],
1586                 prev_coords[0],
1587                 prev_handle_right[0],
1588                 next_handle_left[0],
1589                 next_coords[0],
1590                 roots)) {
1591     return false;
1592   }
1593 
1594   const float t = roots[0]; /* Percentage of the curve at which the split should occur. */
1595   if (t <= 0.0f || t >= 1.0f) {
1596     /* The split would occur outside the curve, which isn't possible. */
1597     return false;
1598   }
1599 
1600   /* De Casteljau split, requires three iterations of splitting.
1601    * See https://pomax.github.io/bezierinfo/#decasteljau */
1602   float split1[3][2], split2[2][2], split3[2];
1603   interp_v2_v2v2(split1[0], prev_coords, prev_handle_right, t);
1604   interp_v2_v2v2(split1[1], prev_handle_right, next_handle_left, t);
1605   interp_v2_v2v2(split1[2], next_handle_left, next_coords, t);
1606   interp_v2_v2v2(split2[0], split1[0], split1[1], t);
1607   interp_v2_v2v2(split2[1], split1[1], split1[2], t);
1608   interp_v2_v2v2(split3, split2[0], split2[1], t);
1609 
1610   /* Update the existing handles. */
1611   copy_v2_v2(prev_handle_right, split1[0]);
1612   copy_v2_v2(next_handle_left, split1[2]);
1613 
1614   float diff_coords[2];
1615   sub_v2_v2v2(diff_coords, new_coords, split3);
1616   add_v2_v2v2(new_handle_left, split2[0], diff_coords);
1617   add_v2_v2v2(new_handle_right, split2[1], diff_coords);
1618 
1619   *r_pdelta = diff_coords[1];
1620   return true;
1621 }
1622 
1623 /** \} */
1624 
1625 /* -------------------------------------------------------------------- */
1626 /** \name F-Curve Evaluation
1627  * \{ */
1628 
fcurve_eval_keyframes_extrapolate(FCurve * fcu,BezTriple * bezts,float evaltime,int endpoint_offset,int direction_to_neighbor)1629 static float fcurve_eval_keyframes_extrapolate(
1630     FCurve *fcu, BezTriple *bezts, float evaltime, int endpoint_offset, int direction_to_neighbor)
1631 {
1632   BezTriple *endpoint_bezt = bezts + endpoint_offset; /* The first/last keyframe. */
1633   BezTriple *neighbor_bezt = endpoint_bezt +
1634                              direction_to_neighbor; /* The second (to last) keyframe. */
1635 
1636   if (endpoint_bezt->ipo == BEZT_IPO_CONST || fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT ||
1637       (fcu->flag & FCURVE_DISCRETE_VALUES) != 0) {
1638     /* Constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, so just extend the
1639      * endpoint's value. */
1640     return endpoint_bezt->vec[1][1];
1641   }
1642 
1643   if (endpoint_bezt->ipo == BEZT_IPO_LIN) {
1644     /* Use the next center point instead of our own handle for linear interpolated extrapolate. */
1645     if (fcu->totvert == 1) {
1646       return endpoint_bezt->vec[1][1];
1647     }
1648 
1649     float dx = endpoint_bezt->vec[1][0] - evaltime;
1650     float fac = neighbor_bezt->vec[1][0] - endpoint_bezt->vec[1][0];
1651 
1652     /* Prevent division by zero. */
1653     if (fac == 0.0f) {
1654       return endpoint_bezt->vec[1][1];
1655     }
1656 
1657     fac = (neighbor_bezt->vec[1][1] - endpoint_bezt->vec[1][1]) / fac;
1658     return endpoint_bezt->vec[1][1] - (fac * dx);
1659   }
1660 
1661   /* Use the gradient of the second handle (later) of neighbour to calculate the gradient and thus
1662    * the value of the curve at evaluation time. */
1663   int handle = direction_to_neighbor > 0 ? 0 : 2;
1664   float dx = endpoint_bezt->vec[1][0] - evaltime;
1665   float fac = endpoint_bezt->vec[1][0] - endpoint_bezt->vec[handle][0];
1666 
1667   /* Prevent division by zero. */
1668   if (fac == 0.0f) {
1669     return endpoint_bezt->vec[1][1];
1670   }
1671 
1672   fac = (endpoint_bezt->vec[1][1] - endpoint_bezt->vec[handle][1]) / fac;
1673   return endpoint_bezt->vec[1][1] - (fac * dx);
1674 }
1675 
fcurve_eval_keyframes_interpolate(FCurve * fcu,BezTriple * bezts,float evaltime)1676 static float fcurve_eval_keyframes_interpolate(FCurve *fcu, BezTriple *bezts, float evaltime)
1677 {
1678   const float eps = 1.e-8f;
1679   BezTriple *bezt, *prevbezt;
1680   unsigned int a;
1681 
1682   /* Evaltime occurs somewhere in the middle of the curve. */
1683   bool exact = false;
1684 
1685   /* Use binary search to find appropriate keyframes...
1686    *
1687    * The threshold here has the following constraints:
1688    * - 0.001 is too coarse:
1689    *   We get artifacts with 2cm driver movements at 1BU = 1m (see T40332).
1690    *
1691    * - 0.00001 is too fine:
1692    *   Weird errors, like selecting the wrong keyframe range (see T39207), occur.
1693    *   This lower bound was established in b888a32eee8147b028464336ad2404d8155c64dd.
1694    */
1695   a = BKE_fcurve_bezt_binarysearch_index_ex(bezts, evaltime, fcu->totvert, 0.0001, &exact);
1696   bezt = bezts + a;
1697 
1698   if (exact) {
1699     /* Index returned must be interpreted differently when it sits on top of an existing keyframe
1700      * - That keyframe is the start of the segment we need (see action_bug_2.blend in T39207).
1701      */
1702     return bezt->vec[1][1];
1703   }
1704 
1705   /* Index returned refers to the keyframe that the eval-time occurs *before*
1706    * - hence, that keyframe marks the start of the segment we're dealing with.
1707    */
1708   prevbezt = (a > 0) ? (bezt - 1) : bezt;
1709 
1710   /* Use if the key is directly on the frame, in rare cases this is needed else we get 0.0 instead.
1711    * XXX: consult T39207 for examples of files where failure of these checks can cause issues. */
1712   if (fabsf(bezt->vec[1][0] - evaltime) < eps) {
1713     return bezt->vec[1][1];
1714   }
1715 
1716   if (evaltime < prevbezt->vec[1][0] || bezt->vec[1][0] < evaltime) {
1717     if (G.debug & G_DEBUG) {
1718       printf("   ERROR: failed eval - p=%f b=%f, t=%f (%f)\n",
1719              prevbezt->vec[1][0],
1720              bezt->vec[1][0],
1721              evaltime,
1722              fabsf(bezt->vec[1][0] - evaltime));
1723     }
1724     return 0.0f;
1725   }
1726 
1727   /* Evaltime occurs within the interval defined by these two keyframes. */
1728   const float begin = prevbezt->vec[1][1];
1729   const float change = bezt->vec[1][1] - prevbezt->vec[1][1];
1730   const float duration = bezt->vec[1][0] - prevbezt->vec[1][0];
1731   const float time = evaltime - prevbezt->vec[1][0];
1732   const float amplitude = prevbezt->amplitude;
1733   const float period = prevbezt->period;
1734 
1735   /* Value depends on interpolation mode. */
1736   if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES) ||
1737       (duration == 0)) {
1738     /* Constant (evaltime not relevant, so no interpolation needed). */
1739     return prevbezt->vec[1][1];
1740   }
1741 
1742   switch (prevbezt->ipo) {
1743     /* Interpolation ...................................... */
1744     case BEZT_IPO_BEZ: {
1745       float v1[2], v2[2], v3[2], v4[2], opl[32];
1746 
1747       /* Bezier interpolation. */
1748       /* (v1, v2) are the first keyframe and its 2nd handle. */
1749       v1[0] = prevbezt->vec[1][0];
1750       v1[1] = prevbezt->vec[1][1];
1751       v2[0] = prevbezt->vec[2][0];
1752       v2[1] = prevbezt->vec[2][1];
1753       /* (v3, v4) are the last keyframe's 1st handle + the last keyframe. */
1754       v3[0] = bezt->vec[0][0];
1755       v3[1] = bezt->vec[0][1];
1756       v4[0] = bezt->vec[1][0];
1757       v4[1] = bezt->vec[1][1];
1758 
1759       if (fabsf(v1[1] - v4[1]) < FLT_EPSILON && fabsf(v2[1] - v3[1]) < FLT_EPSILON &&
1760           fabsf(v3[1] - v4[1]) < FLT_EPSILON) {
1761         /* Optimization: If all the handles are flat/at the same values,
1762          * the value is simply the shared value (see T40372 -> F91346).
1763          */
1764         return v1[1];
1765       }
1766       /* Adjust handles so that they don't overlap (forming a loop). */
1767       BKE_fcurve_correct_bezpart(v1, v2, v3, v4);
1768 
1769       /* Try to get a value for this position - if failure, try another set of points. */
1770       if (!findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl)) {
1771         if (G.debug & G_DEBUG) {
1772           printf("    ERROR: findzero() failed at %f with %f %f %f %f\n",
1773                  evaltime,
1774                  v1[0],
1775                  v2[0],
1776                  v3[0],
1777                  v4[0]);
1778         }
1779         return 0.0;
1780       }
1781 
1782       berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
1783       return opl[0];
1784     }
1785     case BEZT_IPO_LIN:
1786       /* Linear - simply linearly interpolate between values of the two keyframes. */
1787       return BLI_easing_linear_ease(time, begin, change, duration);
1788 
1789     /* Easing ............................................ */
1790     case BEZT_IPO_BACK:
1791       switch (prevbezt->easing) {
1792         case BEZT_IPO_EASE_IN:
1793           return BLI_easing_back_ease_in(time, begin, change, duration, prevbezt->back);
1794         case BEZT_IPO_EASE_OUT:
1795           return BLI_easing_back_ease_out(time, begin, change, duration, prevbezt->back);
1796         case BEZT_IPO_EASE_IN_OUT:
1797           return BLI_easing_back_ease_in_out(time, begin, change, duration, prevbezt->back);
1798 
1799         default: /* Default/Auto: same as ease out. */
1800           return BLI_easing_back_ease_out(time, begin, change, duration, prevbezt->back);
1801       }
1802       break;
1803 
1804     case BEZT_IPO_BOUNCE:
1805       switch (prevbezt->easing) {
1806         case BEZT_IPO_EASE_IN:
1807           return BLI_easing_bounce_ease_in(time, begin, change, duration);
1808         case BEZT_IPO_EASE_OUT:
1809           return BLI_easing_bounce_ease_out(time, begin, change, duration);
1810         case BEZT_IPO_EASE_IN_OUT:
1811           return BLI_easing_bounce_ease_in_out(time, begin, change, duration);
1812 
1813         default: /* Default/Auto: same as ease out. */
1814           return BLI_easing_bounce_ease_out(time, begin, change, duration);
1815       }
1816       break;
1817 
1818     case BEZT_IPO_CIRC:
1819       switch (prevbezt->easing) {
1820         case BEZT_IPO_EASE_IN:
1821           return BLI_easing_circ_ease_in(time, begin, change, duration);
1822         case BEZT_IPO_EASE_OUT:
1823           return BLI_easing_circ_ease_out(time, begin, change, duration);
1824         case BEZT_IPO_EASE_IN_OUT:
1825           return BLI_easing_circ_ease_in_out(time, begin, change, duration);
1826 
1827         default: /* Default/Auto: same as ease in. */
1828           return BLI_easing_circ_ease_in(time, begin, change, duration);
1829       }
1830       break;
1831 
1832     case BEZT_IPO_CUBIC:
1833       switch (prevbezt->easing) {
1834         case BEZT_IPO_EASE_IN:
1835           return BLI_easing_cubic_ease_in(time, begin, change, duration);
1836         case BEZT_IPO_EASE_OUT:
1837           return BLI_easing_cubic_ease_out(time, begin, change, duration);
1838         case BEZT_IPO_EASE_IN_OUT:
1839           return BLI_easing_cubic_ease_in_out(time, begin, change, duration);
1840 
1841         default: /* Default/Auto: same as ease in. */
1842           return BLI_easing_cubic_ease_in(time, begin, change, duration);
1843       }
1844       break;
1845 
1846     case BEZT_IPO_ELASTIC:
1847       switch (prevbezt->easing) {
1848         case BEZT_IPO_EASE_IN:
1849           return BLI_easing_elastic_ease_in(time, begin, change, duration, amplitude, period);
1850         case BEZT_IPO_EASE_OUT:
1851           return BLI_easing_elastic_ease_out(time, begin, change, duration, amplitude, period);
1852         case BEZT_IPO_EASE_IN_OUT:
1853           return BLI_easing_elastic_ease_in_out(time, begin, change, duration, amplitude, period);
1854 
1855         default: /* Default/Auto: same as ease out. */
1856           return BLI_easing_elastic_ease_out(time, begin, change, duration, amplitude, period);
1857       }
1858       break;
1859 
1860     case BEZT_IPO_EXPO:
1861       switch (prevbezt->easing) {
1862         case BEZT_IPO_EASE_IN:
1863           return BLI_easing_expo_ease_in(time, begin, change, duration);
1864         case BEZT_IPO_EASE_OUT:
1865           return BLI_easing_expo_ease_out(time, begin, change, duration);
1866         case BEZT_IPO_EASE_IN_OUT:
1867           return BLI_easing_expo_ease_in_out(time, begin, change, duration);
1868 
1869         default: /* Default/Auto: same as ease in. */
1870           return BLI_easing_expo_ease_in(time, begin, change, duration);
1871       }
1872       break;
1873 
1874     case BEZT_IPO_QUAD:
1875       switch (prevbezt->easing) {
1876         case BEZT_IPO_EASE_IN:
1877           return BLI_easing_quad_ease_in(time, begin, change, duration);
1878         case BEZT_IPO_EASE_OUT:
1879           return BLI_easing_quad_ease_out(time, begin, change, duration);
1880         case BEZT_IPO_EASE_IN_OUT:
1881           return BLI_easing_quad_ease_in_out(time, begin, change, duration);
1882 
1883         default: /* Default/Auto: same as ease in. */
1884           return BLI_easing_quad_ease_in(time, begin, change, duration);
1885       }
1886       break;
1887 
1888     case BEZT_IPO_QUART:
1889       switch (prevbezt->easing) {
1890         case BEZT_IPO_EASE_IN:
1891           return BLI_easing_quart_ease_in(time, begin, change, duration);
1892         case BEZT_IPO_EASE_OUT:
1893           return BLI_easing_quart_ease_out(time, begin, change, duration);
1894         case BEZT_IPO_EASE_IN_OUT:
1895           return BLI_easing_quart_ease_in_out(time, begin, change, duration);
1896 
1897         default: /* Default/Auto: same as ease in. */
1898           return BLI_easing_quart_ease_in(time, begin, change, duration);
1899       }
1900       break;
1901 
1902     case BEZT_IPO_QUINT:
1903       switch (prevbezt->easing) {
1904         case BEZT_IPO_EASE_IN:
1905           return BLI_easing_quint_ease_in(time, begin, change, duration);
1906         case BEZT_IPO_EASE_OUT:
1907           return BLI_easing_quint_ease_out(time, begin, change, duration);
1908         case BEZT_IPO_EASE_IN_OUT:
1909           return BLI_easing_quint_ease_in_out(time, begin, change, duration);
1910 
1911         default: /* Default/Auto: same as ease in. */
1912           return BLI_easing_quint_ease_in(time, begin, change, duration);
1913       }
1914       break;
1915 
1916     case BEZT_IPO_SINE:
1917       switch (prevbezt->easing) {
1918         case BEZT_IPO_EASE_IN:
1919           return BLI_easing_sine_ease_in(time, begin, change, duration);
1920         case BEZT_IPO_EASE_OUT:
1921           return BLI_easing_sine_ease_out(time, begin, change, duration);
1922         case BEZT_IPO_EASE_IN_OUT:
1923           return BLI_easing_sine_ease_in_out(time, begin, change, duration);
1924 
1925         default: /* Default/Auto: same as ease in. */
1926           return BLI_easing_sine_ease_in(time, begin, change, duration);
1927       }
1928       break;
1929 
1930     default:
1931       return prevbezt->vec[1][1];
1932   }
1933 
1934   return 0.0f;
1935 }
1936 
1937 /* Calculate F-Curve value for 'evaltime' using BezTriple keyframes. */
fcurve_eval_keyframes(FCurve * fcu,BezTriple * bezts,float evaltime)1938 static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime)
1939 {
1940   if (evaltime <= bezts->vec[1][0]) {
1941     return fcurve_eval_keyframes_extrapolate(fcu, bezts, evaltime, 0, +1);
1942   }
1943 
1944   BezTriple *lastbezt = bezts + fcu->totvert - 1;
1945   if (lastbezt->vec[1][0] <= evaltime) {
1946     return fcurve_eval_keyframes_extrapolate(fcu, bezts, evaltime, fcu->totvert - 1, -1);
1947   }
1948 
1949   return fcurve_eval_keyframes_interpolate(fcu, bezts, evaltime);
1950 }
1951 
1952 /* Calculate F-Curve value for 'evaltime' using FPoint samples. */
fcurve_eval_samples(FCurve * fcu,FPoint * fpts,float evaltime)1953 static float fcurve_eval_samples(FCurve *fcu, FPoint *fpts, float evaltime)
1954 {
1955   FPoint *prevfpt, *lastfpt, *fpt;
1956   float cvalue = 0.0f;
1957 
1958   /* Get pointers. */
1959   prevfpt = fpts;
1960   lastfpt = prevfpt + fcu->totvert - 1;
1961 
1962   /* Evaluation time at or past endpoints? */
1963   if (prevfpt->vec[0] >= evaltime) {
1964     /* Before or on first sample, so just extend value. */
1965     cvalue = prevfpt->vec[1];
1966   }
1967   else if (lastfpt->vec[0] <= evaltime) {
1968     /* After or on last sample, so just extend value. */
1969     cvalue = lastfpt->vec[1];
1970   }
1971   else {
1972     float t = fabsf(evaltime - floorf(evaltime));
1973 
1974     /* Find the one on the right frame (assume that these are spaced on 1-frame intervals). */
1975     fpt = prevfpt + ((int)evaltime - (int)prevfpt->vec[0]);
1976 
1977     /* If not exactly on the frame, perform linear interpolation with the next one. */
1978     if ((t != 0.0f) && (t < 1.0f)) {
1979       cvalue = interpf(fpt->vec[1], (fpt + 1)->vec[1], 1.0f - t);
1980     }
1981     else {
1982       cvalue = fpt->vec[1];
1983     }
1984   }
1985 
1986   return cvalue;
1987 }
1988 
1989 /** \} */
1990 
1991 /* -------------------------------------------------------------------- */
1992 /** \name F-Curve - Evaluation
1993  * \{ */
1994 
1995 /* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime")
1996  * Note: this is also used for drivers.
1997  */
evaluate_fcurve_ex(FCurve * fcu,float evaltime,float cvalue)1998 static float evaluate_fcurve_ex(FCurve *fcu, float evaltime, float cvalue)
1999 {
2000   float devaltime;
2001 
2002   /* Evaluate modifiers which modify time to evaluate the base curve at. */
2003   FModifiersStackStorage storage;
2004   storage.modifier_count = BLI_listbase_count(&fcu->modifiers);
2005   storage.size_per_modifier = evaluate_fmodifiers_storage_size_per_modifier(&fcu->modifiers);
2006   storage.buffer = alloca(storage.modifier_count * storage.size_per_modifier);
2007 
2008   devaltime = evaluate_time_fmodifiers(&storage, &fcu->modifiers, fcu, cvalue, evaltime);
2009 
2010   /* Evaluate curve-data
2011    * - 'devaltime' instead of 'evaltime', as this is the time that the last time-modifying
2012    *   F-Curve modifier on the stack requested the curve to be evaluated at.
2013    */
2014   if (fcu->bezt) {
2015     cvalue = fcurve_eval_keyframes(fcu, fcu->bezt, devaltime);
2016   }
2017   else if (fcu->fpt) {
2018     cvalue = fcurve_eval_samples(fcu, fcu->fpt, devaltime);
2019   }
2020 
2021   /* Evaluate modifiers. */
2022   evaluate_value_fmodifiers(&storage, &fcu->modifiers, fcu, &cvalue, devaltime);
2023 
2024   /* If curve can only have integral values, perform truncation (i.e. drop the decimal part)
2025    * here so that the curve can be sampled correctly.
2026    */
2027   if (fcu->flag & FCURVE_INT_VALUES) {
2028     cvalue = floorf(cvalue + 0.5f);
2029   }
2030 
2031   return cvalue;
2032 }
2033 
evaluate_fcurve(FCurve * fcu,float evaltime)2034 float evaluate_fcurve(FCurve *fcu, float evaltime)
2035 {
2036   BLI_assert(fcu->driver == NULL);
2037 
2038   return evaluate_fcurve_ex(fcu, evaltime, 0.0);
2039 }
2040 
evaluate_fcurve_only_curve(FCurve * fcu,float evaltime)2041 float evaluate_fcurve_only_curve(FCurve *fcu, float evaltime)
2042 {
2043   /* Can be used to evaluate the (keyframed) fcurve only.
2044    * Also works for driver-fcurves when the driver itself is not relevant.
2045    * E.g. when inserting a keyframe in a driver fcurve. */
2046   return evaluate_fcurve_ex(fcu, evaltime, 0.0);
2047 }
2048 
evaluate_fcurve_driver(PathResolvedRNA * anim_rna,FCurve * fcu,ChannelDriver * driver_orig,const AnimationEvalContext * anim_eval_context)2049 float evaluate_fcurve_driver(PathResolvedRNA *anim_rna,
2050                              FCurve *fcu,
2051                              ChannelDriver *driver_orig,
2052                              const AnimationEvalContext *anim_eval_context)
2053 {
2054   BLI_assert(fcu->driver != NULL);
2055   float cvalue = 0.0f;
2056   float evaltime = anim_eval_context->eval_time;
2057 
2058   /* If there is a driver (only if this F-Curve is acting as 'driver'),
2059    * evaluate it to find value to use as "evaltime" since drivers essentially act as alternative
2060    * input (i.e. in place of 'time') for F-Curves. */
2061   if (fcu->driver) {
2062     /* Evaltime now serves as input for the curve. */
2063     evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, anim_eval_context);
2064 
2065     /* Only do a default 1-1 mapping if it's unlikely that anything else will set a value... */
2066     if (fcu->totvert == 0) {
2067       FModifier *fcm;
2068       bool do_linear = true;
2069 
2070       /* Out-of-range F-Modifiers will block, as will those which just plain overwrite the values
2071        * XXX: additive is a bit more dicey; it really depends then if things are in range or not...
2072        */
2073       for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
2074         /* If there are range-restrictions, we must definitely block T36950. */
2075         if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) == 0 ||
2076             ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime))) {
2077           /* Within range: here it probably doesn't matter,
2078            * though we'd want to check on additive. */
2079         }
2080         else {
2081           /* Outside range: modifier shouldn't contribute to the curve here,
2082            * though it does in other areas, so neither should the driver! */
2083           do_linear = false;
2084         }
2085       }
2086 
2087       /* Only copy over results if none of the modifiers disagreed with this. */
2088       if (do_linear) {
2089         cvalue = evaltime;
2090       }
2091     }
2092   }
2093 
2094   return evaluate_fcurve_ex(fcu, evaltime, cvalue);
2095 }
2096 
2097 /* Checks if the curve has valid keys, drivers or modifiers that produce an actual curve. */
BKE_fcurve_is_empty(FCurve * fcu)2098 bool BKE_fcurve_is_empty(FCurve *fcu)
2099 {
2100   return (fcu->totvert == 0) && (fcu->driver == NULL) &&
2101          !list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE);
2102 }
2103 
2104 /* Calculate the value of the given F-Curve at the given frame, and set its curval. */
calculate_fcurve(PathResolvedRNA * anim_rna,FCurve * fcu,const AnimationEvalContext * anim_eval_context)2105 float calculate_fcurve(PathResolvedRNA *anim_rna,
2106                        FCurve *fcu,
2107                        const AnimationEvalContext *anim_eval_context)
2108 {
2109   /* Only calculate + set curval (overriding the existing value) if curve has
2110    * any data which warrants this...
2111    */
2112   if (BKE_fcurve_is_empty(fcu)) {
2113     return 0.0f;
2114   }
2115 
2116   /* Calculate and set curval (evaluates driver too if necessary). */
2117   float curval;
2118   if (fcu->driver) {
2119     curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, anim_eval_context);
2120   }
2121   else {
2122     curval = evaluate_fcurve(fcu, anim_eval_context->eval_time);
2123   }
2124   fcu->curval = curval; /* Debug display only, not thread safe! */
2125   return curval;
2126 }
2127 
2128 /** \} */
2129 
2130 /* -------------------------------------------------------------------- */
2131 /** \name F-Curve - .blend file API
2132  * \{ */
2133 
BKE_fmodifiers_blend_write(BlendWriter * writer,ListBase * fmodifiers)2134 void BKE_fmodifiers_blend_write(BlendWriter *writer, ListBase *fmodifiers)
2135 {
2136   /* Write all modifiers first (for faster reloading) */
2137   BLO_write_struct_list(writer, FModifier, fmodifiers);
2138 
2139   /* Modifiers */
2140   LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
2141     const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
2142 
2143     /* Write the specific data */
2144     if (fmi && fcm->data) {
2145       /* firstly, just write the plain fmi->data struct */
2146       BLO_write_struct_by_name(writer, fmi->structName, fcm->data);
2147 
2148       /* do any modifier specific stuff */
2149       switch (fcm->type) {
2150         case FMODIFIER_TYPE_GENERATOR: {
2151           FMod_Generator *data = fcm->data;
2152 
2153           /* write coefficients array */
2154           if (data->coefficients) {
2155             BLO_write_float_array(writer, data->arraysize, data->coefficients);
2156           }
2157 
2158           break;
2159         }
2160         case FMODIFIER_TYPE_ENVELOPE: {
2161           FMod_Envelope *data = fcm->data;
2162 
2163           /* write envelope data */
2164           if (data->data) {
2165             BLO_write_struct_array(writer, FCM_EnvelopeData, data->totvert, data->data);
2166           }
2167 
2168           break;
2169         }
2170         case FMODIFIER_TYPE_PYTHON: {
2171           FMod_Python *data = fcm->data;
2172 
2173           /* Write ID Properties -- and copy this comment EXACTLY for easy finding
2174            * of library blocks that implement this.*/
2175           IDP_BlendWrite(writer, data->prop);
2176 
2177           break;
2178         }
2179       }
2180     }
2181   }
2182 }
2183 
BKE_fmodifiers_blend_read_data(BlendDataReader * reader,ListBase * fmodifiers,FCurve * curve)2184 void BKE_fmodifiers_blend_read_data(BlendDataReader *reader, ListBase *fmodifiers, FCurve *curve)
2185 {
2186   LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
2187     /* relink general data */
2188     BLO_read_data_address(reader, &fcm->data);
2189     fcm->curve = curve;
2190 
2191     /* do relinking of data for specific types */
2192     switch (fcm->type) {
2193       case FMODIFIER_TYPE_GENERATOR: {
2194         FMod_Generator *data = (FMod_Generator *)fcm->data;
2195         BLO_read_float_array(reader, data->arraysize, &data->coefficients);
2196         break;
2197       }
2198       case FMODIFIER_TYPE_ENVELOPE: {
2199         FMod_Envelope *data = (FMod_Envelope *)fcm->data;
2200 
2201         BLO_read_data_address(reader, &data->data);
2202 
2203         break;
2204       }
2205       case FMODIFIER_TYPE_PYTHON: {
2206         FMod_Python *data = (FMod_Python *)fcm->data;
2207 
2208         BLO_read_data_address(reader, &data->prop);
2209         IDP_BlendDataRead(reader, &data->prop);
2210 
2211         break;
2212       }
2213     }
2214   }
2215 }
2216 
BKE_fmodifiers_blend_read_lib(BlendLibReader * reader,ID * id,ListBase * fmodifiers)2217 void BKE_fmodifiers_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *fmodifiers)
2218 {
2219   LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
2220     /* data for specific modifiers */
2221     switch (fcm->type) {
2222       case FMODIFIER_TYPE_PYTHON: {
2223         FMod_Python *data = (FMod_Python *)fcm->data;
2224         BLO_read_id_address(reader, id->lib, &data->script);
2225         break;
2226       }
2227     }
2228   }
2229 }
2230 
BKE_fmodifiers_blend_read_expand(BlendExpander * expander,ListBase * fmodifiers)2231 void BKE_fmodifiers_blend_read_expand(BlendExpander *expander, ListBase *fmodifiers)
2232 {
2233   LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
2234     /* library data for specific F-Modifier types */
2235     switch (fcm->type) {
2236       case FMODIFIER_TYPE_PYTHON: {
2237         FMod_Python *data = (FMod_Python *)fcm->data;
2238         BLO_expand(expander, data->script);
2239         break;
2240       }
2241     }
2242   }
2243 }
2244 
BKE_fcurve_blend_write(BlendWriter * writer,ListBase * fcurves)2245 void BKE_fcurve_blend_write(BlendWriter *writer, ListBase *fcurves)
2246 {
2247   BLO_write_struct_list(writer, FCurve, fcurves);
2248   LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
2249     /* curve data */
2250     if (fcu->bezt) {
2251       BLO_write_struct_array(writer, BezTriple, fcu->totvert, fcu->bezt);
2252     }
2253     if (fcu->fpt) {
2254       BLO_write_struct_array(writer, FPoint, fcu->totvert, fcu->fpt);
2255     }
2256 
2257     if (fcu->rna_path) {
2258       BLO_write_string(writer, fcu->rna_path);
2259     }
2260 
2261     /* driver data */
2262     if (fcu->driver) {
2263       ChannelDriver *driver = fcu->driver;
2264 
2265       BLO_write_struct(writer, ChannelDriver, driver);
2266 
2267       /* variables */
2268       BLO_write_struct_list(writer, DriverVar, &driver->variables);
2269       LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
2270         DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
2271           if (dtar->rna_path) {
2272             BLO_write_string(writer, dtar->rna_path);
2273           }
2274         }
2275         DRIVER_TARGETS_LOOPER_END;
2276       }
2277     }
2278 
2279     /* write F-Modifiers */
2280     BKE_fmodifiers_blend_write(writer, &fcu->modifiers);
2281   }
2282 }
2283 
BKE_fcurve_blend_read_data(BlendDataReader * reader,ListBase * fcurves)2284 void BKE_fcurve_blend_read_data(BlendDataReader *reader, ListBase *fcurves)
2285 {
2286   /* link F-Curve data to F-Curve again (non ID-libs) */
2287   LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
2288     /* curve data */
2289     BLO_read_data_address(reader, &fcu->bezt);
2290     BLO_read_data_address(reader, &fcu->fpt);
2291 
2292     /* rna path */
2293     BLO_read_data_address(reader, &fcu->rna_path);
2294 
2295     /* group */
2296     BLO_read_data_address(reader, &fcu->grp);
2297 
2298     /* clear disabled flag - allows disabled drivers to be tried again (T32155),
2299      * but also means that another method for "reviving disabled F-Curves" exists
2300      */
2301     fcu->flag &= ~FCURVE_DISABLED;
2302 
2303     /* driver */
2304     BLO_read_data_address(reader, &fcu->driver);
2305     if (fcu->driver) {
2306       ChannelDriver *driver = fcu->driver;
2307 
2308       /* Compiled expression data will need to be regenerated
2309        * (old pointer may still be set here). */
2310       driver->expr_comp = NULL;
2311       driver->expr_simple = NULL;
2312 
2313       /* Give the driver a fresh chance - the operating environment may be different now
2314        * (addons, etc. may be different) so the driver namespace may be sane now T32155. */
2315       driver->flag &= ~DRIVER_FLAG_INVALID;
2316 
2317       /* relink variables, targets and their paths */
2318       BLO_read_list(reader, &driver->variables);
2319       LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
2320         DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
2321           /* only relink the targets being used */
2322           if (tarIndex < dvar->num_targets) {
2323             BLO_read_data_address(reader, &dtar->rna_path);
2324           }
2325           else {
2326             dtar->rna_path = NULL;
2327           }
2328         }
2329         DRIVER_TARGETS_LOOPER_END;
2330       }
2331     }
2332 
2333     /* modifiers */
2334     BLO_read_list(reader, &fcu->modifiers);
2335     BKE_fmodifiers_blend_read_data(reader, &fcu->modifiers, fcu);
2336   }
2337 }
2338 
BKE_fcurve_blend_read_lib(BlendLibReader * reader,ID * id,ListBase * fcurves)2339 void BKE_fcurve_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *fcurves)
2340 {
2341   if (fcurves == NULL) {
2342     return;
2343   }
2344 
2345   /* relink ID-block references... */
2346   LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
2347     /* driver data */
2348     if (fcu->driver) {
2349       ChannelDriver *driver = fcu->driver;
2350       LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
2351         DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
2352           /* only relink if still used */
2353           if (tarIndex < dvar->num_targets) {
2354             BLO_read_id_address(reader, id->lib, &dtar->id);
2355           }
2356           else {
2357             dtar->id = NULL;
2358           }
2359         }
2360         DRIVER_TARGETS_LOOPER_END;
2361       }
2362     }
2363 
2364     /* modifiers */
2365     BKE_fmodifiers_blend_read_lib(reader, id, &fcu->modifiers);
2366   }
2367 }
2368 
BKE_fcurve_blend_read_expand(BlendExpander * expander,ListBase * fcurves)2369 void BKE_fcurve_blend_read_expand(BlendExpander *expander, ListBase *fcurves)
2370 {
2371   LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
2372     /* Driver targets if there is a driver */
2373     if (fcu->driver) {
2374       ChannelDriver *driver = fcu->driver;
2375 
2376       LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
2377         DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
2378           // TODO: only expand those that are going to get used?
2379           BLO_expand(expander, dtar->id);
2380         }
2381         DRIVER_TARGETS_LOOPER_END;
2382       }
2383     }
2384 
2385     /* F-Curve Modifiers */
2386     BKE_fmodifiers_blend_read_expand(expander, &fcu->modifiers);
2387   }
2388 }
2389 
2390 /** \} */
2391