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