9 #include "testing/testing.h"
17 const int curve_length = points_size / curves_size;
18 for (
const int i :
curves.curves_range()) {
19 curves.offsets_for_write()[i] = curve_length * i;
21 curves.offsets_for_write().last() = points_size;
23 for (
const int i :
curves.points_range()) {
30 TEST(curves_geometry, Empty)
39 TEST(curves_geometry, Move)
43 const int *offsets_data =
curves.offsets().data();
44 const float3 *positions_data =
curves.positions().data();
66 TEST(curves_geometry, TypeCount)
69 curves.curve_types_for_write().copy_from({
81 curves.update_curve_types();
82 const std::array<int, CURVE_TYPES_NUM> &counts =
curves.curve_type_counts();
89 TEST(curves_geometry, CatmullRomEvaluation)
93 curves.resolution_for_write().fill(12);
94 curves.offsets_for_write().last() = 4;
95 curves.cyclic_for_write().fill(
false);
106 {0.948495, 1.00318, 0},
107 {0.87963, 1.01157, 0},
108 {0.796875, 1.02344, 0},
109 {0.703704, 1.03704, 0},
110 {0.603588, 1.05064, 0},
112 {0.396412, 1.07089, 0},
113 {0.296296, 1.07407, 0},
114 {0.203125, 1.07031, 0},
115 {0.12037, 1.05787, 0},
116 {0.0515046, 1.03501, 0},
118 {-0.0318287, 0.948495, 0},
119 {-0.0462963, 0.87963, 0},
120 {-0.046875, 0.796875, 0},
121 {-0.037037, 0.703704, 0},
122 {-0.0202546, 0.603588, 0},
124 {0.0202546, 0.396412, 0},
125 {0.037037, 0.296296, 0},
126 {0.046875, 0.203125, 0},
127 {0.0462963, 0.12037, 0},
128 {0.0318287, 0.0515046, 0},
130 {-0.0515046, -0.0350116, 0},
131 {-0.12037, -0.0578704, 0},
132 {-0.203125, -0.0703125, 0},
133 {-0.296296, -0.0740741, 0},
134 {-0.396412, -0.0708912, 0},
136 {-0.603588, -0.0506366, 0},
137 {-0.703704, -0.037037, 0},
138 {-0.796875, -0.0234375, 0},
139 {-0.87963, -0.0115741, 0},
140 {-0.948495, -0.00318287, 0},
143 for (
const int i : evaluated_positions.
index_range()) {
144 EXPECT_V3_NEAR(evaluated_positions[i], result_1[i], 1e-5f);
148 curves.tag_positions_changed();
149 curves.evaluated_positions();
160 curves.cyclic_for_write().fill(
true);
163 curves.tag_topology_changed();
166 evaluated_positions =
curves.evaluated_positions();
169 {1.03819, 0.0515046, 0},
170 {1.06944, 0.12037, 0},
171 {1.09375, 0.203125, 0},
172 {1.11111, 0.296296, 0},
173 {1.12153, 0.396412, 0},
175 {1.12153, 0.603588, 0},
176 {1.11111, 0.703704, 0},
177 {1.09375, 0.796875, 0},
178 {1.06944, 0.87963, 0},
179 {1.03819, 0.948495, 0},
181 {0.948495, 1.03819, 0},
182 {0.87963, 1.06944, 0},
183 {0.796875, 1.09375, 0},
184 {0.703704, 1.11111, 0},
185 {0.603588, 1.12153, 0},
187 {0.396412, 1.12153, 0},
188 {0.296296, 1.11111, 0},
189 {0.203125, 1.09375, 0},
190 {0.12037, 1.06944, 0},
191 {0.0515046, 1.03819, 0},
193 {-0.0381944, 0.948495, 0},
194 {-0.0694444, 0.87963, 0},
195 {-0.09375, 0.796875, 0},
196 {-0.111111, 0.703704, 0},
197 {-0.121528, 0.603588, 0},
199 {-0.121528, 0.396412, 0},
200 {-0.111111, 0.296296, 0},
201 {-0.09375, 0.203125, 0},
202 {-0.0694444, 0.12037, 0},
203 {-0.0381944, 0.0515046, 0},
205 {0.0515046, -0.0381944, 0},
206 {0.12037, -0.0694444, 0},
207 {0.203125, -0.09375, 0},
208 {0.296296, -0.111111, 0},
209 {0.396412, -0.121528, 0},
211 {0.603588, -0.121528, 0},
212 {0.703704, -0.111111, 0},
213 {0.796875, -0.09375, 0},
214 {0.87963, -0.0694444, 0},
215 {0.948495, -0.0381944, 0},
217 for (
const int i : evaluated_positions.
index_range()) {
218 EXPECT_V3_NEAR(evaluated_positions[i], result_2[i], 1e-5f);
222 TEST(curves_geometry, CatmullRomTwoPointCyclic)
226 curves.resolution_for_write().fill(12);
227 curves.offsets_for_write().last() = 2;
228 curves.cyclic_for_write().fill(
true);
234 TEST(curves_geometry, BezierPositionEvaluation)
238 curves.resolution_for_write().fill(12);
239 curves.offsets_for_write().last() = 2;
246 handles_right.
first() = {-0.5f, 0.5f, 0.0f};
247 handles_left.
last() = {0, 0, 0};
250 handles_left.
first() = {100, 100, 100};
251 handles_right.
last() = {100, 100, 100};
256 {-0.874711, 0.105035, 0},
257 {-0.747685, 0.173611, 0},
258 {-0.617188, 0.210937, 0},
259 {-0.481481, 0.222222, 0},
260 {-0.338831, 0.212674, 0},
261 {-0.1875, 0.1875, 0},
262 {-0.0257524, 0.15191, 0},
263 {0.148148, 0.111111, 0},
264 {0.335937, 0.0703125, 0},
265 {0.539352, 0.0347222, 0},
266 {0.760127, 0.00954859, 0},
269 for (
const int i : evaluated_positions.
index_range()) {
270 EXPECT_V3_NEAR(evaluated_positions[i], result_1[i], 1e-5f);
275 curves.resolution_for_write().fill(9);
276 curves.offsets_for_write().last() = 4;
277 handles_left =
curves.handle_positions_left_for_write();
278 handles_right =
curves.handle_positions_right_for_write();
282 handles_right[2] = {-0.5f, 1.5f, 0.0f};
283 handles_left[3] = {0, 1, 0};
286 handles_left[2] = {-100, -100, -100};
287 handles_right[3] = {-100, -100, -100};
289 evaluated_positions =
curves.evaluated_positions();
293 {-0.832647, 0.131687, 0},
294 {-0.66118, 0.201646, 0},
295 {-0.481481, 0.222222, 0},
296 {-0.289438, 0.205761, 0},
297 {-0.0809327, 0.164609, 0},
298 {0.148148, 0.111111, 0},
299 {0.40192, 0.0576133, 0},
300 {0.684499, 0.016461, 0},
303 {-0.832647, 1.13169, 0},
304 {-0.66118, 1.20165, 0},
305 {-0.481481, 1.22222, 0},
306 {-0.289438, 1.20576, 0},
307 {-0.0809327, 1.16461, 0},
308 {0.148148, 1.11111, 0},
309 {0.40192, 1.05761, 0},
310 {0.684499, 1.01646, 0},
313 for (
const int i : evaluated_positions.
index_range()) {
314 EXPECT_V3_NEAR(evaluated_positions[i], result_2[i], 1e-5f);
318 TEST(curves_geometry, NURBSEvaluation)
322 curves.resolution_for_write().fill(10);
323 curves.offsets_for_write().last() = 4;
333 {0.166667, 0.833333, 0}, {0.150006, 0.815511, 0}, {0.134453, 0.796582, 0},
334 {0.119924, 0.776627, 0}, {0.106339, 0.75573, 0}, {0.0936146, 0.733972, 0},
335 {0.0816693, 0.711434, 0}, {0.0704211, 0.6882, 0}, {0.0597879, 0.66435, 0},
336 {0.0496877, 0.639968, 0}, {0.0400385, 0.615134, 0}, {0.0307584, 0.589931, 0},
337 {0.0217653, 0.564442, 0}, {0.0129772, 0.538747, 0}, {0.00431208, 0.512929, 0},
338 {-0.00431208, 0.487071, 0}, {-0.0129772, 0.461253, 0}, {-0.0217653, 0.435558, 0},
339 {-0.0307584, 0.410069, 0}, {-0.0400385, 0.384866, 0}, {-0.0496877, 0.360032, 0},
340 {-0.0597878, 0.33565, 0}, {-0.0704211, 0.3118, 0}, {-0.0816693, 0.288566, 0},
341 {-0.0936146, 0.266028, 0}, {-0.106339, 0.24427, 0}, {-0.119924, 0.223373, 0},
342 {-0.134453, 0.203418, 0}, {-0.150006, 0.184489, 0}, {-0.166667, 0.166667, 0},
344 for (
const int i : evaluated_positions.
index_range()) {
345 EXPECT_V3_NEAR(evaluated_positions[i], result_1[i], 1e-5f);
349 curves.cyclic_for_write().fill(
true);
350 curves.tag_topology_changed();
351 evaluated_positions =
curves.evaluated_positions();
353 {0.166667, 0.833333, 0}, {0.121333, 0.778667, 0},
354 {0.084, 0.716, 0}, {0.0526667, 0.647333, 0},
355 {0.0253333, 0.574667, 0}, {0, 0.5, 0},
356 {-0.0253333, 0.425333, 0}, {-0.0526667, 0.352667, 0},
357 {-0.084, 0.284, 0}, {-0.121333, 0.221333, 0},
358 {-0.166667, 0.166667, 0}, {-0.221, 0.121667, 0},
359 {-0.281333, 0.0866667, 0}, {-0.343667, 0.0616666, 0},
360 {-0.404, 0.0466667, 0}, {-0.458333, 0.0416667, 0},
361 {-0.502667, 0.0466667, 0}, {-0.533, 0.0616666, 0},
362 {-0.545333, 0.0866667, 0}, {-0.535667, 0.121667, 0},
363 {-0.5, 0.166667, 0}, {-0.436, 0.221334, 0},
364 {-0.348, 0.284, 0}, {-0.242, 0.352667, 0},
365 {-0.124, 0.425333, 0}, {0, 0.5, 0},
366 {0.124, 0.574667, 0}, {0.242, 0.647333, 0},
367 {0.348, 0.716, 0}, {0.436, 0.778667, 0},
368 {0.5, 0.833333, 0}, {0.535667, 0.878334, 0},
369 {0.545333, 0.913333, 0}, {0.533, 0.938333, 0},
370 {0.502667, 0.953333, 0}, {0.458333, 0.958333, 0},
371 {0.404, 0.953333, 0}, {0.343667, 0.938333, 0},
372 {0.281333, 0.913333, 0}, {0.221, 0.878333, 0},
374 for (
const int i : evaluated_positions.
index_range()) {
375 EXPECT_V3_NEAR(evaluated_positions[i], result_2[i], 1e-5f);
383 curves.nurbs_weights_for_write().fill(1.0f);
384 curves.nurbs_weights_for_write()[0] = 4.0f;
385 curves.tag_positions_changed();
387 {0.888889, 0.555556, 0}, {0.837792, 0.643703, 0}, {0.773885, 0.727176, 0},
388 {0.698961, 0.800967, 0}, {0.616125, 0.860409, 0}, {0.529412, 0.901961, 0},
389 {0.443152, 0.923773, 0}, {0.361289, 0.925835, 0}, {0.286853, 0.909695, 0},
390 {0.221722, 0.877894, 0}, {0.166667, 0.833333, 0}, {0.122106, 0.778278, 0},
391 {0.0903055, 0.713148, 0}, {0.0741654, 0.638711, 0}, {0.0762274, 0.556847, 0},
392 {0.0980392, 0.470588, 0}, {0.139591, 0.383875, 0}, {0.199032, 0.301039, 0},
393 {0.272824, 0.226114, 0}, {0.356297, 0.162208, 0}, {0.444444, 0.111111, 0},
394 {0.531911, 0.0731388, 0}, {0.612554, 0.0468976, 0}, {0.683378, 0.0301622, 0},
395 {0.74391, 0.0207962, 0}, {0.794872, 0.017094, 0}, {0.837411, 0.017839, 0},
396 {0.872706, 0.0222583, 0}, {0.901798, 0.0299677, 0}, {0.925515, 0.0409445, 0},
397 {0.944444, 0.0555556, 0}, {0.959056, 0.0744855, 0}, {0.970032, 0.0982019, 0},
398 {0.977742, 0.127294, 0}, {0.982161, 0.162589, 0}, {0.982906, 0.205128, 0},
399 {0.979204, 0.256091, 0}, {0.969838, 0.316622, 0}, {0.953102, 0.387446, 0},
400 {0.926861, 0.468089, 0},
402 evaluated_positions =
curves.evaluated_positions();
403 for (
const int i : evaluated_positions.
index_range()) {
404 EXPECT_V3_NEAR(evaluated_positions[i], result_3[i], 1e-5f);
408 TEST(curves_geometry, BezierGenericEvaluation)
412 curves.resolution_for_write().fill(8);
413 curves.offsets_for_write().last() = 3;
419 handles_right.
first() = {-1, 1, 0};
420 handles_left[1] = {0, 0, 0};
422 handles_right[1] = {2, 0, 0};
423 handles_left.
last() = {1, 1, 0};
427 handles_left.
first() = {100, 100, 100};
428 handles_right.
last() = {100, 100, 100};
433 {-0.955078f, 0.287109f, 0.0f},
434 {-0.828125f, 0.421875f, 0.0f},
435 {-0.630859f, 0.439453f, 0.0f},
436 {-0.375f, 0.375f, 0.0f},
437 {-0.0722656f, 0.263672f, 0.0f},
438 {0.265625f, 0.140625f, 0.0f},
439 {0.626953f, 0.0410156f, 0.0f},
441 {1.28906f, 0.0429688f, 0.0f},
442 {1.4375f, 0.15625f, 0.0f},
443 {1.49219f, 0.316406f, 0.0f},
445 {1.50781f, 0.683594f, 0.0f},
446 {1.5625f, 0.84375f, 0.0f},
447 {1.71094f, 0.957031f, 0.0f},
450 for (
const int i : evaluated_positions.
index_range()) {
451 EXPECT_V3_NEAR(evaluated_positions[i], result_1[i], 1e-5f);
476 for (
const int i : evaluated_radii.
index_range()) {
477 EXPECT_NEAR(evaluated_radii[i], result_2[i], 1e-6f);
typedef float(TangentPoint)[2]
Low-level operations for curves.
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
IndexRange index_range() const
MutableSpan< T > as_mutable_span()
constexpr T & last(const int64_t n=0) const
constexpr T & first() const
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
Span< int > offsets() const
Span< float3 > positions() const
bool bounds_min_max(float3 &min, float3 &max) const
VArray< bool > cyclic() const
TEST(action_groups, ReconstructGroupsWithReordering)
static CurvesGeometry create_basic_curves(const int points_size, const int curves_size)
MutableSpan< float3 > positions
MutableSpan< float > radii