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