4#include "testing/testing.h"
48 float time_epsilon = 0.00008f;
119 fcu->
bezt[0].
vec[0][0] = 0.71855f;
120 fcu->
bezt[0].
vec[0][1] = 6.22482f;
121 fcu->
bezt[0].
vec[2][0] = 1.35148f;
122 fcu->
bezt[0].
vec[2][1] = 7.96806f;
124 fcu->
bezt[1].
vec[0][0] = 1.66667f;
125 fcu->
bezt[1].
vec[0][1] = 10.4136f;
126 fcu->
bezt[1].
vec[2][0] = 2.33333f;
127 fcu->
bezt[1].
vec[2][1] = 15.5864f;
208 fcu->
bezt[0].
vec[0][0] = 0.71855f;
209 fcu->
bezt[0].
vec[0][1] = 6.22482f;
210 fcu->
bezt[0].
vec[2][0] = 1.35148f;
211 fcu->
bezt[0].
vec[2][1] = 7.96806f;
213 fcu->
bezt[1].
vec[0][0] = 1.66667f;
214 fcu->
bezt[1].
vec[0][1] = 10.4136f;
215 fcu->
bezt[1].
vec[2][0] = 2.33333f;
216 fcu->
bezt[1].
vec[2][1] = 15.5864f;
251 fcu->
bezt[0].
vec[0][0] = -5.0f;
257 fcu->
bezt[1].
vec[0][0] = 13.0f;
258 fcu->
bezt[1].
vec[0][1] = -2.0f;
259 fcu->
bezt[1].
vec[2][0] = 16.0f;
260 fcu->
bezt[1].
vec[2][1] = -3.0f;
264 const float x = 7.375f;
265 const float y = 1.000f;
266 beztr.
vec[0][0] = x - 1.0f;
270 beztr.
vec[2][0] = x + 1.0f;
279 EXPECT_FLOAT_EQ(y_delta, 0.0f);
281 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[0][0], -5.0f);
282 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[0][1], 0.0f);
283 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[1][0], 1.0f);
284 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[1][1], 0.0f);
285 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[2][0], 1.5f);
286 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[2][1], 2.0f);
288 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][0], 13.0f);
289 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][1], 0.0f);
290 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][0], 13.0f);
291 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][1], 2.0f);
292 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][0], 16.0f);
293 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][1], -3.0f);
295 EXPECT_FLOAT_EQ(beztr.
vec[0][0], 4.5f);
296 EXPECT_FLOAT_EQ(beztr.
vec[0][1], 1.5f);
297 EXPECT_FLOAT_EQ(beztr.
vec[1][0], 7.375f);
298 EXPECT_FLOAT_EQ(beztr.
vec[1][1], 1.0f);
299 EXPECT_FLOAT_EQ(beztr.
vec[2][0], 10.250);
300 EXPECT_FLOAT_EQ(beztr.
vec[2][1], 0.5);
305TEST(fcurve_active_keyframe, ActiveKeyframe)
340 "active keyframe must be selected");
346 <<
"Setting out-of-bounds value via the API should result in valid active_keyframe_index";
351 <<
"Even with active_keyframe_index out of bounds, getting it via the API should produce a "
357 <<
"Setting out-of-bounds value via the API should result in valid active_keyframe_index";
362 <<
"Even with active_keyframe_index out of bounds, getting it via the API should produce a "
377 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][0], 5.2671194f);
378 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][1], 15.0f);
380 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][0], 8.0f);
381 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][1], 15.0f);
383 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][0], 10.342469f);
384 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][1], 15.0f);
388 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][0], 5.2671194f) <<
"Left handle should not move in time";
389 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][1], 47.0f) <<
"Left handle value should have been updated";
391 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][0], 8.0f) <<
"Frame should not move in time";
392 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][1], 47.0f) <<
"Frame value should have been updated";
394 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][0], 10.342469f) <<
"Right handle should not move in time";
395 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][1], 47.0f) <<
"Right handle value should have been updated";
409 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][0], 5.2671194f);
410 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][1], 15.0f);
412 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][0], 8.0f);
413 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][1], 15.0f);
415 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][0], 10.342469f);
416 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][1], 15.0f);
420 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][0], 44.2671194f) <<
"Left handle time should be updated";
421 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[0][1], 15.0f) <<
"Left handle should not move in value";
423 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][0], 47.0f) <<
"Frame time should have been updated";
424 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][1], 15.0f) <<
"Frame should not move in value";
426 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][0], 49.342469f) <<
"Right handle time should be updated";
427 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[2][1], 15.0f) <<
"Right handle should not move in value";
443 for (
int i = 0; i < fcu->
totvert; i++) {
444 fcu->
bezt[i].
f1 &= ~SELECT;
445 fcu->
bezt[i].
f2 &= ~SELECT;
446 fcu->
bezt[i].
f3 &= ~SELECT;
454 EXPECT_TRUE(success) <<
"A non-empty FCurve should have a range.";
456 EXPECT_FLOAT_EQ(fcu->
bezt[4].
vec[1][0], max);
460 EXPECT_FALSE(success)
461 <<
"Using selected keyframes only should not find a range if nothing is selected.";
467 EXPECT_TRUE(success) <<
"Range of selected keyframes should have been found.";
469 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[1][0], max);
472 const int sample_start = 1;
473 const int sample_end = 20;
477 EXPECT_TRUE(success) <<
"FCurve samples should have a range.";
479 EXPECT_FLOAT_EQ(sample_start,
min);
480 EXPECT_FLOAT_EQ(sample_end, max);
496 for (
int i = 0; i < fcu->
totvert; i++) {
497 fcu->
bezt[i].
f1 &= ~SELECT;
498 fcu->
bezt[i].
f2 &= ~SELECT;
499 fcu->
bezt[i].
f3 &= ~SELECT;
502 fcu->
bezt[0].
vec[0][0] = -5.0f;
503 fcu->
bezt[4].
vec[2][0] = 25.0f;
514 EXPECT_TRUE(success) <<
"A non-empty FCurve should have bounds.";
515 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[1][0], bounds.
xmin);
516 EXPECT_FLOAT_EQ(fcu->
bezt[4].
vec[1][0], bounds.
xmax);
517 EXPECT_FLOAT_EQ(fcu->
bezt[4].
vec[1][1], bounds.
ymin);
518 EXPECT_FLOAT_EQ(fcu->
bezt[2].
vec[1][1], bounds.
ymax);
526 EXPECT_FALSE(success)
527 <<
"Using selected keyframes only should not find bounds if nothing is selected.";
537 EXPECT_TRUE(success) <<
"Selected keys should have been found.";
538 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][0], bounds.
xmin);
539 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[1][0], bounds.
xmax);
540 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][1], bounds.
ymin);
541 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[1][1], bounds.
ymax);
549 EXPECT_TRUE(success) <<
"A non-empty FCurve should have bounds including handles.";
550 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[0][0], bounds.
xmin);
551 EXPECT_FLOAT_EQ(fcu->
bezt[4].
vec[2][0], bounds.
xmax);
552 EXPECT_FLOAT_EQ(fcu->
bezt[4].
vec[1][1], bounds.
ymin);
553 EXPECT_FLOAT_EQ(fcu->
bezt[2].
vec[1][1], bounds.
ymax);
561 fcu,
false ,
false , range , &bounds);
562 EXPECT_FALSE(success) <<
"A frame range outside the range of keyframes should not find bounds.";
567 fcu,
false ,
false , range , &bounds);
568 EXPECT_TRUE(success) <<
"A frame range within the range of keyframes should find bounds.";
569 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[1][0], bounds.
xmin);
570 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[1][0], bounds.
xmax);
571 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][1], bounds.
ymin);
572 EXPECT_FLOAT_EQ(fcu->
bezt[2].
vec[1][1], bounds.
ymax);
576 fcu,
false ,
true , range , &bounds);
578 <<
"A frame range within the range of keyframes should find bounds with handles.";
579 EXPECT_FLOAT_EQ(fcu->
bezt[0].
vec[0][0], bounds.
xmin);
580 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[2][0], bounds.
xmax);
581 EXPECT_FLOAT_EQ(fcu->
bezt[1].
vec[1][1], bounds.
ymin);
582 EXPECT_FLOAT_EQ(fcu->
bezt[2].
vec[1][1], bounds.
ymax);
588 fcu,
true ,
true , range , &bounds);
590 <<
"A frame range within the range of keyframes should find bounds of selected keyframes.";
591 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[0][0], bounds.
xmin);
592 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[2][0], bounds.
xmax);
593 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[2][1], bounds.
ymin);
594 EXPECT_FLOAT_EQ(fcu->
bezt[3].
vec[0][1], bounds.
ymax);
597 const int sample_start = 1;
598 const int sample_end = 20;
606 EXPECT_TRUE(success) <<
"FCurve samples should have a range.";
608 EXPECT_FLOAT_EQ(sample_start, bounds.
xmin);
609 EXPECT_FLOAT_EQ(sample_end, bounds.
xmax);
610 EXPECT_FLOAT_EQ(-20.0f, bounds.
ymin);
611 EXPECT_FLOAT_EQ(15.0f, bounds.
ymax);
616 fcu,
false ,
false , range , &bounds);
617 EXPECT_TRUE(success) <<
"FCurve samples should have a range.";
619 EXPECT_FLOAT_EQ(range[0], bounds.
xmin);
620 EXPECT_FLOAT_EQ(range[1], bounds.
xmax);
621 EXPECT_FLOAT_EQ(-20.0f, bounds.
ymin);
622 EXPECT_FLOAT_EQ(15.0f, bounds.
ymax);
627 fcu,
false ,
false , range , &bounds);
628 EXPECT_FALSE(success)
629 <<
"A frame range outside the range of keyframe samples should not have bounds.";
634static void set_key(
FCurve *fcu,
const int index,
const float x,
const float y)
636 fcu->
bezt[index].
vec[0][0] = x - 0.5f;
638 fcu->
bezt[index].
vec[2][0] = x + 0.5f;
652 set_key(fcu, 1, 327.16f, 1.0f);
664TEST(BKE_fcurve, sort_time_fcurve_stability)
673 ASSERT_EQ(fcu->
totvert, 10) <<
"sorting should not influence number of keys";
707TEST(BKE_fcurve, BKE_fcurve_deduplicate_keys_edge_cases)
730TEST(BKE_fcurve, BKE_fcurve_deduplicate_keys_prefer_whole_frames)
Functions to modify FCurves.
void BKE_fcurve_deduplicate_keys(FCurve *fcu)
void BKE_fcurve_keyframe_move_time_with_handles(BezTriple *keyframe, const float new_time)
int BKE_fcurve_active_keyframe_index(const FCurve *fcu)
FCurve * BKE_fcurve_create(void)
void BKE_fcurve_active_keyframe_set(FCurve *fcu, const BezTriple *active_bezt)
#define BEZT_BINARYSEARCH_THRESH
bool BKE_fcurve_bezt_subdivide_handles(BezTriple *bezt, BezTriple *prev, BezTriple *next, float *r_pdelta)
void BKE_fcurve_keyframe_move_value_with_handles(BezTriple *keyframe, float new_value)
float evaluate_fcurve(const FCurve *fcu, float evaltime)
void BKE_fcurve_free(FCurve *fcu)
bool BKE_fcurve_calc_range(const FCurve *fcu, float *r_min, float *r_max, bool selected_keys_only)
void sort_time_fcurve(FCurve *fcu)
void fcurve_store_samples(FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb)
float fcurve_samplingcb_evalcurve(FCurve *fcu, void *data, float evaltime)
bool BKE_fcurve_calc_bounds(const FCurve *fcu, bool selected_keys_only, bool include_handles, const float frame_range[2], rctf *r_bounds)
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define FCURVE_ACTIVE_KEYFRAME_NONE
@ FCURVE_EXTRAPOLATE_CONSTANT
@ FCURVE_EXTRAPOLATE_LINEAR
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
void ED_keyframes_add(FCurve *fcu, int num_keys_to_add)
KeyframeSettings get_keyframe_settings(bool from_userprefs)
SingleKeyingResult insert_vert_fcurve(FCurve *fcu, const float2 position, const KeyframeSettings &settings, eInsertKeyFlags flag)
Main Key-framing API call.
static const float EPSILON
static void set_key(FCurve *fcu, const int index, const float x, const float y)
TEST(action_groups, ReconstructGroupsWithReordering)
static FCurve * testcurve_with_duplicates()
int active_keyframe_index