Blender V4.3
keyframes_keylist_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7#include "BLI_utildefines.h"
8
10
11#include "DNA_anim_types.h"
12#include "DNA_curve_types.h"
13
14#include "MEM_guardedalloc.h"
15
16#include "BKE_fcurve.hh"
17
18#include <functional>
19#include <optional>
20
22
23const float KEYLIST_NEAR_ERROR = 0.1;
24const float FRAME_STEP = 0.005;
25
26/* Build FCurve with keys on frames 10, 20, and 30. */
27static void build_fcurve(FCurve &fcurve)
28{
29 fcurve.totvert = 3;
30 fcurve.bezt = static_cast<BezTriple *>(
31 MEM_callocN(sizeof(BezTriple) * fcurve.totvert, "BezTriples"));
32 fcurve.bezt[0].vec[1][0] = 10.0f;
33 fcurve.bezt[0].vec[1][1] = 1.0f;
34 fcurve.bezt[1].vec[1][0] = 20.0f;
35 fcurve.bezt[1].vec[1][1] = 2.0f;
36 fcurve.bezt[2].vec[1][0] = 30.0f;
37 fcurve.bezt[2].vec[1][1] = 1.0f;
38}
39
41{
42 FCurve *fcurve = BKE_fcurve_create();
43 build_fcurve(*fcurve);
44
45 AnimKeylist *keylist = ED_keylist_create();
46 fcurve_to_keylist(nullptr, fcurve, keylist, 0, {-FLT_MAX, FLT_MAX});
47 BKE_fcurve_free(fcurve);
48
50 return keylist;
51}
52
53static void assert_act_key_column(const ActKeyColumn *column,
54 const std::optional<float> expected_frame)
55{
56 if (expected_frame.has_value()) {
57 ASSERT_NE(column, nullptr) << "Expected a frame to be found at " << *expected_frame;
58 EXPECT_NEAR(column->cfra, *expected_frame, KEYLIST_NEAR_ERROR);
59 }
60 else {
61 EXPECT_EQ(column, nullptr) << "Expected no frame to be found, but found " << column->cfra;
62 }
63}
64
65using KeylistFindFunction = std::function<const ActKeyColumn *(const AnimKeylist *, float)>;
66
67static void check_keylist_find_range(const AnimKeylist *keylist,
68 KeylistFindFunction keylist_find_func,
69 const float frame_from,
70 const float frame_to,
71 const std::optional<float> expected_frame)
72{
73 float cfra = frame_from;
74 for (; cfra < frame_to; cfra += FRAME_STEP) {
75 const ActKeyColumn *found = keylist_find_func(keylist, cfra);
76 assert_act_key_column(found, expected_frame);
77 }
78}
79
80static void check_keylist_find_next_range(const AnimKeylist *keylist,
81 const float frame_from,
82 const float frame_to,
83 const std::optional<float> expected_frame)
84{
85 check_keylist_find_range(keylist, ED_keylist_find_next, frame_from, frame_to, expected_frame);
86}
87
88TEST(keylist, find_next)
89{
91
92 check_keylist_find_next_range(keylist, 0.0f, 9.99f, 10.0f);
93 check_keylist_find_next_range(keylist, 10.0f, 19.99f, 20.0f);
94 check_keylist_find_next_range(keylist, 20.0f, 29.99f, 30.0f);
95 check_keylist_find_next_range(keylist, 30.0f, 39.99f, std::nullopt);
96
97 ED_keylist_free(keylist);
98}
99
101 const float frame_from,
102 const float frame_to,
103 const std::optional<float> expected_frame)
104{
105 check_keylist_find_range(keylist, ED_keylist_find_prev, frame_from, frame_to, expected_frame);
106}
107
108TEST(keylist, find_prev)
109{
110 AnimKeylist *keylist = create_test_keylist();
111
112 check_keylist_find_prev_range(keylist, 0.0f, 10.00f, std::nullopt);
113 check_keylist_find_prev_range(keylist, 10.01f, 20.00f, 10.0f);
114 check_keylist_find_prev_range(keylist, 20.01f, 30.00f, 20.0f);
115 check_keylist_find_prev_range(keylist, 30.01f, 49.99f, 30.0f);
116
117 ED_keylist_free(keylist);
118}
119
121 const float frame_from,
122 const float frame_to,
123 const std::optional<float> expected_frame)
124{
125 check_keylist_find_range(keylist, ED_keylist_find_exact, frame_from, frame_to, expected_frame);
126}
127
128TEST(keylist, find_exact)
129{
130 AnimKeylist *keylist = create_test_keylist();
131
132 check_keylist_find_exact_range(keylist, 0.0f, 9.99f, std::nullopt);
133 check_keylist_find_exact_range(keylist, 9.9901f, 10.01f, 10.0f);
134 check_keylist_find_exact_range(keylist, 10.01f, 19.99f, std::nullopt);
135 check_keylist_find_exact_range(keylist, 19.9901f, 20.01f, 20.0f);
136 check_keylist_find_exact_range(keylist, 20.01f, 29.99f, std::nullopt);
137 check_keylist_find_exact_range(keylist, 29.9901f, 30.01f, 30.0f);
138 check_keylist_find_exact_range(keylist, 30.01f, 49.99f, std::nullopt);
139
140 ED_keylist_free(keylist);
141}
142
143} // namespace blender::editor::animation::tests
FCurve * BKE_fcurve_create(void)
void BKE_fcurve_free(FCurve *fcu)
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
Read Guarded memory(de)allocation.
draw_view in_light_buf[] float
const ActKeyColumn * ED_keylist_find_prev(const AnimKeylist *keylist, const float cfra)
void ED_keylist_prepare_for_direct_access(AnimKeylist *keylist)
AnimKeylist * ED_keylist_create()
void ED_keylist_free(AnimKeylist *keylist)
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, AnimKeylist *keylist, const int saction_flag, blender::float2 range)
const ActKeyColumn * ED_keylist_find_next(const AnimKeylist *keylist, const float cfra)
const ActKeyColumn * ED_keylist_find_exact(const AnimKeylist *keylist, const float cfra)
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
static void check_keylist_find_next_range(const AnimKeylist *keylist, const float frame_from, const float frame_to, const std::optional< float > expected_frame)
static void check_keylist_find_exact_range(const AnimKeylist *keylist, const float frame_from, const float frame_to, const std::optional< float > expected_frame)
static void assert_act_key_column(const ActKeyColumn *column, const std::optional< float > expected_frame)
static void build_fcurve(FCurve &fcurve)
static void check_keylist_find_prev_range(const AnimKeylist *keylist, const float frame_from, const float frame_to, const std::optional< float > expected_frame)
std::function< const ActKeyColumn *(const AnimKeylist *, float)> KeylistFindFunction
static void check_keylist_find_range(const AnimKeylist *keylist, KeylistFindFunction keylist_find_func, const float frame_from, const float frame_to, const std::optional< float > expected_frame)
#define FLT_MAX
Definition stdcycles.h:14
float vec[3][3]
BezTriple * bezt
unsigned int totvert