Blender  V3.3
BLI_length_parameterize_test.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0 */
2 
3 #include "BLI_array.hh"
5 #include "BLI_vector.hh"
6 
7 #include "testing/testing.h"
8 
10 
11 template<typename T> Array<float> calculate_lengths(const Span<T> values, const bool cyclic)
12 {
13  Array<float> lengths(segments_num(values.size(), cyclic));
14  accumulate_lengths<T>(values, cyclic, lengths);
15  return lengths;
16 }
17 
18 template<typename T> void test_uniform_lengths(const Span<T> values)
19 {
20  const float segment_length = math::distance(values.first(), values.last()) / (values.size() - 1);
21  for (const int i : values.index_range().drop_back(1)) {
22  EXPECT_NEAR(math::distance(values[i], values[i + 1]), segment_length, 1e-5);
23  }
24 }
25 
26 TEST(length_parameterize, FloatSimple)
27 {
28  Array<float> values{{0, 1, 4}};
29  Array<float> lengths = calculate_lengths(values.as_span(), false);
30 
32  Array<float> factors(4);
33  sample_uniform(lengths, true, indices, factors);
34  Array<float> results(4);
35  interpolate<float>(values, indices, factors, results);
36  Array<float> expected({
37  0.0f,
38  1.33333f,
39  2.66667f,
40  4.0f,
41  });
42  for (const int i : results.index_range()) {
43  EXPECT_NEAR(results[i], expected[i], 1e-5);
44  }
45  test_uniform_lengths(results.as_span());
46 }
47 
48 TEST(length_parameterize, Float)
49 {
50  Array<float> values{{1, 2, 3, 5, 10}};
51  Array<float> lengths = calculate_lengths(values.as_span(), false);
52 
53  Array<int> indices(20);
54  Array<float> factors(20);
55  sample_uniform(lengths, true, indices, factors);
56  Array<float> results(20);
57  interpolate<float>(values, indices, factors, results);
58  Array<float> expected({
59  1.0f, 1.47368f, 1.94737f, 2.42105f, 2.89474f, 3.36842f, 3.84211f,
60  4.31579f, 4.78947f, 5.26316f, 5.73684f, 6.21053f, 6.68421f, 7.1579f,
61  7.63158f, 8.10526f, 8.57895f, 9.05263f, 9.52632f, 10.0f,
62  });
63  for (const int i : results.index_range()) {
64  EXPECT_NEAR(results[i], expected[i], 1e-5);
65  }
66  test_uniform_lengths(results.as_span());
67 }
68 
69 TEST(length_parameterize, Float2)
70 {
71  Array<float2> values{{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
72  Array<float> lengths = calculate_lengths(values.as_span(), false);
73 
74  Array<int> indices(12);
75  Array<float> factors(12);
76  sample_uniform(lengths, true, indices, factors);
77  Array<float2> results(12);
78  interpolate<float2>(values, indices, factors, results);
79  Array<float2> expected({
80  {0.0f, 0.0f},
81  {0.272727f, 0.0f},
82  {0.545455f, 0.0f},
83  {0.818182f, 0.0f},
84  {1.0f, 0.0909091f},
85  {1.0f, 0.363636f},
86  {1.0f, 0.636364f},
87  {1.0f, 0.909091f},
88  {0.818182f, 1.0f},
89  {0.545455f, 1.0f},
90  {0.272727f, 1.0f},
91  {0.0f, 1.0f},
92  });
93  for (const int i : results.index_range()) {
94  EXPECT_NEAR(results[i].x, expected[i].x, 1e-5);
95  EXPECT_NEAR(results[i].y, expected[i].y, 1e-5);
96  }
97 }
98 
99 TEST(length_parameterize, Float2Cyclic)
100 {
101  Array<float2> values{{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
102  Array<float> lengths = calculate_lengths(values.as_span(), true);
103 
104  Array<int> indices(12);
105  Array<float> factors(12);
106  sample_uniform(lengths, false, indices, factors);
107  Array<float2> results(12);
108  interpolate<float2>(values, indices, factors, results);
109  Array<float2> expected({
110  {0.0f, 0.0f},
111  {0.333333f, 0.0f},
112  {0.666667f, 0.0f},
113  {1.0f, 0.0f},
114  {1.0f, 0.333333f},
115  {1.0f, 0.666667f},
116  {1.0f, 1.0f},
117  {0.666667f, 1.0f},
118  {0.333333f, 1.0f},
119  {0.0f, 1.0f},
120  {0.0f, 0.666667f},
121  {0.0f, 0.333333f},
122  });
123  for (const int i : results.index_range()) {
124  EXPECT_NEAR(results[i].x, expected[i].x, 1e-5);
125  EXPECT_NEAR(results[i].y, expected[i].y, 1e-5);
126  }
127 }
128 
129 TEST(length_parameterize, LineMany)
130 {
131  Array<float> values{{1, 2}};
132  Array<float> lengths = calculate_lengths(values.as_span(), false);
133 
134  Array<int> indices(5007);
135  Array<float> factors(5007);
136  sample_uniform(lengths, true, indices, factors);
137  Array<float> results(5007);
138  interpolate<float>(values, indices, factors, results);
139  Array<float> expected({
140  1.9962f, 1.9964f, 1.9966f, 1.9968f, 1.997f, 1.9972f, 1.9974f, 1.9976f, 1.9978f, 1.998f,
141  1.9982f, 1.9984f, 1.9986f, 1.9988f, 1.999f, 1.9992f, 1.9994f, 1.9996f, 1.9998f, 2.0f,
142  });
143  for (const int i : expected.index_range()) {
144  EXPECT_NEAR(results.as_span().take_back(20)[i], expected[i], 1e-5);
145  }
146 }
147 
148 TEST(length_parameterize, CyclicMany)
149 {
150  Array<float2> values{{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
151  Array<float> lengths = calculate_lengths(values.as_span(), true);
152 
153  Array<int> indices(5007);
154  Array<float> factors(5007);
155  sample_uniform(lengths, false, indices, factors);
156  Array<float2> results(5007);
157  interpolate<float2>(values, indices, factors, results);
158  Array<float2> expected({
159  {0, 0.0159776}, {0, 0.0151787}, {0, 0.0143797}, {0, 0.013581}, {0, 0.0127821},
160  {0, 0.0119832}, {0, 0.0111842}, {0, 0.0103855}, {0, 0.00958657}, {0, 0.00878763},
161  {0, 0.00798869}, {0, 0.00718999}, {0, 0.00639105}, {0, 0.00559211}, {0, 0.00479317},
162  {0, 0.00399446}, {0, 0.00319552}, {0, 0.00239658}, {0, 0.00159764}, {0, 0.000798941},
163  });
164  for (const int i : expected.index_range()) {
165  EXPECT_NEAR(results.as_span().take_back(20)[i].x, expected[i].x, 1e-5);
166  EXPECT_NEAR(results.as_span().take_back(20)[i].y, expected[i].y, 1e-5);
167  }
168 }
169 
170 TEST(length_parameterize, InterpolateColor)
171 {
172  Array<float2> values{{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
173  Array<float> lengths = calculate_lengths(values.as_span(), true);
174 
175  Array<ColorGeometry4f> colors{{{0, 0, 0, 1}, {1, 0, 0, 1}, {1, 1, 0, 1}, {0, 1, 0, 1}}};
176 
177  Array<int> indices(10);
178  Array<float> factors(10);
179  sample_uniform(lengths, false, indices, factors);
180  Array<ColorGeometry4f> results(10);
181  interpolate<ColorGeometry4f>(colors, indices, factors, results);
182  Array<ColorGeometry4f> expected({
183  {0, 0, 0, 1},
184  {0.4, 0, 0, 1},
185  {0.8, 0, 0, 1},
186  {1, 0.2, 0, 1},
187  {1, 0.6, 0, 1},
188  {1, 1, 0, 1},
189  {0.6, 1, 0, 1},
190  {0.2, 1, 0, 1},
191  {0, 0.8, 0, 1},
192  {0, 0.4, 0, 1},
193  });
194  for (const int i : results.index_range()) {
195  EXPECT_NEAR(results[i].r, expected[i].r, 1e-6);
196  EXPECT_NEAR(results[i].g, expected[i].g, 1e-6);
197  EXPECT_NEAR(results[i].b, expected[i].b, 1e-6);
198  EXPECT_NEAR(results[i].a, expected[i].a, 1e-6);
199  }
200 }
201 
202 TEST(length_parameterize, ArbitraryFloatSimple)
203 {
204  Array<float> values{{0, 1, 4}};
205  Array<float> lengths = calculate_lengths(values.as_span(), false);
206 
207  Array<float> sample_lengths{{0.5f, 1.5f, 2.0f, 4.0f}};
208  Array<int> indices(4);
209  Array<float> factors(4);
210  sample_at_lengths(lengths, sample_lengths, indices, factors);
211  Array<float> results(4);
212  interpolate<float>(values, indices, factors, results);
213  Array<float> expected({
214  0.5f,
215  1.5f,
216  2.0f,
217  4.0f,
218  });
219  for (const int i : results.index_range()) {
220  EXPECT_NEAR(results[i], expected[i], 1e-5);
221  }
222 }
223 
224 TEST(length_parameterize, ArbitraryFloat2)
225 {
226  Array<float2> values{{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
227  Array<float> lengths = calculate_lengths(values.as_span(), true);
228 
229  Array<float> sample_lengths{
230  {0.5f, 1.5f, 2.0f, 2.0f, 2.1f, 2.5f, 3.5f, 3.6f, 3.8f, 3.85f, 3.90f, 4.0f}};
231  Array<int> indices(12);
232  Array<float> factors(12);
233  sample_at_lengths(lengths, sample_lengths, indices, factors);
234  Array<float2> results(12);
235  interpolate<float2>(values, indices, factors, results);
236  Array<float2> expected({
237  {0.5f, 0.0f},
238  {1.0f, 0.5f},
239  {1.0f, 1.0f},
240  {1.0f, 1.0f},
241  {0.9f, 1.0f},
242  {0.5f, 1.0f},
243  {0.0f, 0.5f},
244  {0.0f, 0.4f},
245  {0.0f, 0.2f},
246  {0.0f, 0.15f},
247  {0.0f, 0.1f},
248  {0.0f, 0.0f},
249  });
250  for (const int i : results.index_range()) {
251  EXPECT_NEAR(results[i].x, expected[i].x, 1e-5);
252  EXPECT_NEAR(results[i].y, expected[i].y, 1e-5);
253  }
254 }
255 
256 } // namespace blender::length_parameterize::tests
_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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_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
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
IndexRange index_range() const
Definition: BLI_array.hh:348
Span< T > as_span() const
Definition: BLI_array.hh:231
constexpr IndexRange drop_back(int64_t n) const
constexpr Span take_back(int64_t n) const
Definition: BLI_span.hh:192
constexpr const T & first() const
Definition: BLI_span.hh:303
constexpr const T & last(const int64_t n=0) const
Definition: BLI_span.hh:313
constexpr int64_t size() const
Definition: BLI_span.hh:240
constexpr IndexRange index_range() const
Definition: BLI_span.hh:401
ccl_gpu_kernel_postfix int ccl_global int * indices
static unsigned a[3]
Definition: RandGen.cpp:78
void test_uniform_lengths(const Span< T > values)
TEST(length_parameterize, FloatSimple)
Array< float > calculate_lengths(const Span< T > values, const bool cyclic)
int segments_num(const int points_num, const bool cyclic)
void sample_at_lengths(Span< float > accumulated_segment_lengths, Span< float > sample_lengths, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
void sample_uniform(Span< float > accumulated_segment_lengths, bool include_last_point, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
T distance(const T &a, const T &b)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)