Blender
V5.0
source
blender
blenlib
tests
BLI_index_mask_expression_test.cc
Go to the documentation of this file.
1
/* SPDX-FileCopyrightText: 2024 Blender Authors
2
*
3
* SPDX-License-Identifier: Apache-2.0 */
4
5
#include "
BLI_array.hh
"
6
#include "
BLI_index_mask_expression.hh
"
7
#include "
BLI_rand.hh
"
8
#include "
BLI_set.hh
"
9
#include "
BLI_timeit.hh
"
10
11
#include "testing/testing.h"
12
13
#include "
BLI_strict_flags.h
"
/* IWYU pragma: keep */
14
15
namespace
blender::index_mask::tests
{
16
17
TEST
(index_mask_expression, Union)
18
{
19
IndexMaskMemory
memory;
20
const
IndexMask
mask_a =
IndexMask::from_initializers
({5,
IndexRange
(50, 100), 100'000}, memory);
21
const
IndexMask
mask_b =
IndexMask::from_initializers
({
IndexRange
(10, 10), 60, 200}, memory);
22
23
ExprBuilder
builder;
24
const
Expr
&expr = builder.merge({&mask_a, &mask_b});
25
const
IndexMask
union_mask =
evaluate_expression
(expr, memory);
26
27
EXPECT_EQ
(union_mask,
28
IndexMask::from_initializers
(
29
{5,
IndexRange
(10, 10),
IndexRange
(50, 100), 200, 100'000}, memory));
30
}
31
32
TEST
(index_mask_expression, UnionMulti)
33
{
34
IndexMaskMemory
memory;
35
const
IndexMask
mask_a =
IndexMask::from_initializers
({3, 5, 6, 8, 9}, memory);
36
const
IndexMask
mask_b =
IndexMask::from_initializers
({4, 6, 7, 12}, memory);
37
const
IndexMask
mask_c =
IndexMask::from_initializers
({0, 5}, memory);
38
const
IndexMask
mask_d =
IndexMask::from_initializers
({6, 7, 10}, memory);
39
40
ExprBuilder
builder;
41
const
Expr
&expr = builder.merge({&mask_a, &mask_b, &mask_c, &mask_d});
42
const
IndexMask
union_mask =
evaluate_expression
(expr, memory);
43
44
EXPECT_EQ
(union_mask,
IndexMask::from_initializers
({0, 3, 4, 5, 6, 7, 8, 9, 10, 12}, memory));
45
}
46
47
TEST
(index_mask_expression, IntersectMulti)
48
{
49
IndexMaskMemory
memory;
50
const
IndexMask
mask_a =
IndexMask::from_initializers
({3, 5, 6, 8, 9}, memory);
51
const
IndexMask
mask_b =
IndexMask::from_initializers
({2, 5, 6, 10}, memory);
52
const
IndexMask
mask_c =
IndexMask::from_initializers
({4, 5, 6}, memory);
53
const
IndexMask
mask_d =
IndexMask::from_initializers
({1, 5, 10}, memory);
54
55
ExprBuilder
builder;
56
const
Expr
&expr = builder.intersect({&mask_a, &mask_b, &mask_c, &mask_d});
57
const
IndexMask
intersect_mask =
evaluate_expression
(expr, memory);
58
59
EXPECT_EQ
(intersect_mask,
IndexMask::from_initializers
({5}, memory));
60
}
61
62
TEST
(index_mask_expression, DifferenceMulti)
63
{
64
IndexMaskMemory
memory;
65
const
IndexMask
mask_a =
IndexMask::from_initializers
({1, 2, 3, 5, 6, 7, 9, 10}, memory);
66
const
IndexMask
mask_b =
IndexMask::from_initializers
({2, 5, 6, 10}, memory);
67
const
IndexMask
mask_c =
IndexMask::from_initializers
({4, 5, 6}, memory);
68
const
IndexMask
mask_d =
IndexMask::from_initializers
({1, 5, 10}, memory);
69
70
ExprBuilder
builder;
71
const
Expr
&expr = builder.subtract(&mask_a, {&mask_b, &mask_c, &mask_d});
72
const
IndexMask
difference_mask =
evaluate_expression
(expr, memory);
73
74
EXPECT_EQ
(difference_mask,
IndexMask::from_initializers
({3, 7, 9}, memory));
75
}
76
77
TEST
(index_mask_expression,
Intersection
)
78
{
79
IndexMaskMemory
memory;
80
const
IndexMask
mask_a =
IndexMask::from_initializers
({5,
IndexRange
(50, 100), 100'000}, memory);
81
const
IndexMask
mask_b =
IndexMask::from_initializers
(
82
{5, 6,
IndexRange
(100, 100), 80000, 100'000}, memory);
83
84
ExprBuilder
builder;
85
const
Expr
&expr = builder.intersect({&mask_a, &mask_b});
86
const
IndexMask
intersection_mask =
evaluate_expression
(expr, memory);
87
88
EXPECT_EQ
(intersection_mask,
89
IndexMask::from_initializers
({5,
IndexRange
(100, 50), 100'000}, memory));
90
}
91
92
TEST
(index_mask_expression, Difference)
93
{
94
IndexMaskMemory
memory;
95
const
IndexMask
mask_a =
IndexMask::from_initializers
({5,
IndexRange
(50, 100), 100'000}, memory);
96
const
IndexMask
mask_b =
IndexMask::from_initializers
({5, 60,
IndexRange
(100, 20)}, memory);
97
98
ExprBuilder
builder;
99
const
Expr
&expr = builder.subtract(&mask_a, {&mask_b});
100
const
IndexMask
difference_mask =
evaluate_expression
(expr, memory);
101
102
EXPECT_EQ
(difference_mask,
103
IndexMask::from_initializers
(
104
{
IndexRange
(50, 10),
IndexRange
(61, 39),
IndexRange
(120, 30), 100'000}, memory));
105
}
106
107
TEST
(index_mask_expression, FizzBuzz)
108
{
109
IndexMaskMemory
memory;
110
const
IndexMask
mask_3 =
IndexMask::from_every_nth
(3, 11, 0, memory);
/* 0 - 30 */
111
const
IndexMask
mask_5 =
IndexMask::from_every_nth
(5, 11, 0, memory);
/* 0 - 50 */
112
113
{
114
ExprBuilder
builder;
115
const
Expr
&expr = builder.
merge
({&mask_3, &mask_5});
116
const
IndexMask
result
=
evaluate_expression
(expr, memory);
117
EXPECT_EQ
(
118
result
,
119
IndexMask::from_initializers
(
120
{0, 3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24, 25, 27, 30, 35, 40, 45, 50}, memory));
121
}
122
{
123
ExprBuilder
builder;
124
const
Expr
&expr = builder.
intersect
({&mask_3, &mask_5});
125
const
IndexMask
result
=
evaluate_expression
(expr, memory);
126
EXPECT_EQ
(
result
,
IndexMask::from_initializers
({0, 15, 30}, memory));
127
}
128
{
129
ExprBuilder
builder;
130
const
Expr
&expr = builder.
subtract
(&mask_3, {&mask_5});
131
const
IndexMask
result
=
evaluate_expression
(expr, memory);
132
EXPECT_EQ
(
result
,
IndexMask::from_initializers
({3, 6, 9, 12, 18, 21, 24, 27}, memory));
133
}
134
{
135
ExprBuilder
builder;
136
const
Expr
&expr = builder.
merge
(
137
{&builder.
intersect
({&mask_3, &mask_5}), &builder.
subtract
(&mask_3, {&mask_5})});
138
const
IndexMask
&
result
=
evaluate_expression
(expr, memory);
139
EXPECT_EQ
(
result
,
140
IndexMask::from_initializers
({0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30}, memory));
141
}
142
}
143
144
TEST
(index_mask_expression, UnionToFullRange)
145
{
146
IndexMaskMemory
memory;
147
const
IndexMask
mask_1 =
IndexMask::from_initializers
({2, 4, 5, 7}, memory);
148
const
IndexMask
mask_2 =
IndexMask::from_initializers
({6, 8}, memory);
149
const
IndexMask
mask_3 =
IndexMask::from_initializers
({1, 3}, memory);
150
151
ExprBuilder
builder;
152
const
Expr
&expr = builder.merge({&mask_1, &mask_2, &mask_3});
153
const
IndexMask
result
=
evaluate_expression
(expr, memory);
154
EXPECT_TRUE(
result
.to_range().has_value());
155
EXPECT_EQ
(*
result
.to_range(),
IndexRange::from_begin_end_inclusive
(1, 8));
156
EXPECT_EQ
(
result
.segments_num(), 1);
157
}
158
159
TEST
(index_mask_expression, UnionIndividualIndices)
160
{
161
IndexMaskMemory
memory;
162
const
IndexMask
mask_1 =
IndexMask::from_initializers
({3}, memory);
163
const
IndexMask
mask_2 =
IndexMask::from_initializers
({6}, memory);
164
const
IndexMask
mask_3 =
IndexMask::from_initializers
({5}, memory);
165
166
ExprBuilder
builder;
167
const
Expr
&expr = builder.merge({&mask_1, &mask_2, &mask_3});
168
const
IndexMask
result
=
evaluate_expression
(expr, memory);
169
EXPECT_EQ
(
result
,
IndexMask::from_initializers
({3, 5, 6}, memory));
170
EXPECT_EQ
(
result
.segments_num(), 1);
171
}
172
173
TEST
(index_mask_expression, UnionLargeRanges)
174
{
175
IndexMaskMemory
memory;
176
const
IndexMask
mask_a(
IndexRange
(0, 1'000'000));
177
const
IndexMask
mask_b(
IndexRange
(900'000, 1'100'000));
178
179
ExprBuilder
builder;
180
const
Expr
&expr = builder.
merge
({&mask_a, &mask_b});
181
const
IndexMask
result_mask =
evaluate_expression
(expr, memory);
182
183
EXPECT_EQ
(result_mask,
IndexMask
(
IndexRange
(0, 2'000'000)));
184
}
185
186
TEST
(index_mask_expression, SubtractSmall)
187
{
188
IndexMaskMemory
memory;
189
const
IndexMask
mask_a =
IndexMask::from_initializers
({3, 4, 5, 6, 7, 8, 9}, memory);
190
const
IndexMask
mask_b =
IndexMask::from_initializers
({5, 7}, memory);
191
const
IndexMask
mask_c =
IndexMask::from_initializers
({8}, memory);
192
193
ExprBuilder
builder;
194
const
Expr
&expr = builder.subtract(&mask_a, {&mask_b, &mask_c});
195
const
IndexMask
result
=
evaluate_expression
(expr, memory);
196
197
EXPECT_EQ
(
result
,
IndexMask::from_initializers
({3, 4, 6, 9}, memory));
198
EXPECT_EQ
(
result
.segments_num(), 1);
199
}
200
201
TEST
(index_mask_expression, RangeTerms)
202
{
203
IndexMaskMemory
memory;
204
ExprBuilder
builder;
205
206
const
IndexRange
range_a =
IndexRange::from_begin_end
(30'000, 50'000);
207
const
IndexRange
range_b =
IndexRange::from_begin_end
(40'000, 100'000);
208
const
IndexRange
range_c =
IndexRange::from_begin_end
(45'000, 48'000);
209
210
const
Expr
&expr = builder.
subtract
(&builder.
merge
({range_a, range_b}), {range_c});
211
const
IndexMask
result_mask =
evaluate_expression
(expr, memory);
212
213
EXPECT_EQ
(result_mask,
214
IndexMask::from_initializers
({
IndexRange::from_begin_end
(30'000, 45'000),
215
IndexRange::from_begin_end
(48'000, 100'000)},
216
memory));
217
}
218
219
TEST
(index_mask_expression, SingleMask)
220
{
221
IndexMaskMemory
memory;
222
const
IndexMask
mask
=
IndexMask::from_initializers
({5, 6, 8, 9}, memory);
223
224
ExprBuilder
builder;
225
const
Expr
&expr = builder.merge({&
mask
});
226
const
IndexMask
result
=
evaluate_expression
(expr, memory);
227
228
EXPECT_EQ
(
result
,
mask
);
229
}
230
231
TEST
(index_mask_expression, SubtractSelf)
232
{
233
IndexMaskMemory
memory;
234
const
IndexMask
mask
= IndexMask ::from_initializers({6, 8, 10, 100}, memory);
235
236
ExprBuilder
builder;
237
const
Expr
&expr = builder.subtract(&
mask
, {&
mask
});
238
const
IndexMask
result
=
evaluate_expression
(expr, memory);
239
240
EXPECT_TRUE(
result
.is_empty());
241
}
242
243
/* Disable benchmark by default. */
244
#if 0
245
TEST
(index_mask_expression, Benchmark)
246
{
247
# ifdef NDEBUG
248
const
int64_t
iterations = 100;
249
# else
250
const
int64_t
iterations = 1;
251
# endif
252
253
for
([[maybe_unused]]
const
int64_t
_1 :
IndexRange
(5)) {
254
IndexMaskMemory
m;
255
const
IndexMask
a =
IndexMask::from_every_nth
(3, 1'000'000, 0, m);
256
const
IndexMask
b
=
IndexMask::from_every_nth
(100, 5'000, 0, m);
257
ExprBuilder
builder;
258
const
Expr
&expr = builder.
merge
({&a, &
b
});
259
260
SCOPED_TIMER
(
"benchmark"
);
261
for
([[maybe_unused]]
const
int64_t
_2 :
IndexRange
(iterations)) {
262
IndexMaskMemory
memory;
263
const
IndexMask
result
=
evaluate_expression
(expr, memory);
264
UNUSED_VARS
(
result
);
265
}
266
}
267
}
268
#endif
269
270
}
// namespace blender::index_mask::tests
BLI_array.hh
result
double result
Definition
BLI_expr_pylike_eval_test.cc:351
EXPECT_EQ
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
BLI_index_mask_expression.hh
BLI_rand.hh
BLI_set.hh
BLI_strict_flags.h
BLI_timeit.hh
SCOPED_TIMER
#define SCOPED_TIMER(name)
Definition
BLI_timeit.hh:70
UNUSED_VARS
#define UNUSED_VARS(...)
Definition
BLI_utildefines.h:505
int64_t
long long int int64_t
Definition
btConvexHullComputer.cpp:31
blender::IndexRange
Definition
BLI_index_range.hh:50
blender::IndexRange::from_begin_end
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
Definition
BLI_index_range.hh:74
blender::IndexRange::from_begin_end_inclusive
static constexpr IndexRange from_begin_end_inclusive(const int64_t begin, const int64_t last)
Definition
BLI_index_range.hh:79
blender::index_mask::ExprBuilder
Definition
BLI_index_mask_expression.hh:51
blender::index_mask::ExprBuilder::intersect
const IntersectionExpr & intersect(const Span< Term > terms)
Definition
index_mask_expression.cc:1328
blender::index_mask::ExprBuilder::merge
const UnionExpr & merge(const Span< Term > terms)
Definition
index_mask_expression.cc:1301
blender::index_mask::ExprBuilder::subtract
const DifferenceExpr & subtract(const Term &main_term, const Span< Term > subtract_terms)
Definition
index_mask_expression.cc:1314
blender::index_mask::IndexMaskMemory
Definition
BLI_index_mask.hh:112
blender::index_mask::IndexMask
Definition
BLI_index_mask.hh:188
blender::index_mask::IndexMask::from_every_nth
static IndexMask from_every_nth(int64_t n, int64_t indices_num, const int64_t initial_offset, IndexMaskMemory &memory)
Definition
index_mask.cc:1069
blender::index_mask::IndexMask::from_initializers
static IndexMask from_initializers(const Span< Initializer > initializers, IndexMaskMemory &memory)
Definition
index_mask.cc:718
b
b
Definition
compositor_morphological_distance_infos.hh:24
mask
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
Definition
math_float2.h:157
blender::index_mask::tests
Definition
BLI_index_mask_expression_test.cc:15
blender::index_mask::tests::TEST
TEST(index_mask_expression, Union)
Definition
BLI_index_mask_expression_test.cc:17
blender::index_mask::evaluate_expression
IndexMask evaluate_expression(const Expr &expression, IndexMaskMemory &memory)
Definition
index_mask_expression.cc:1284
Intersection
Definition
kernel/types.h:749
blender::index_mask::Expr
Definition
BLI_index_mask_expression.hh:21
Generated on
for Blender by
doxygen
1.16.1