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