Loading...
Searching...
No Matches
ArraySamplers-Impl.hpp
Go to the documentation of this file.
1// This code is based on Jet framework.
2// Copyright (c) 2018 Doyub Kim
3// CubbyFlow is voxel-based fluid simulation engine for computer games.
4// Copyright (c) 2020 CubbyFlow Team
5// Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6// AI Part: Dongheon Cho, Minseo Kim
7// We are making my contributions/submissions to this project solely in our
8// personal capacity and are not conveying any rights to any intellectual
9// property of any third parties.
10
11#ifndef CUBBYFLOW_ARRAY_SAMPLERS_IMPL_HPP
12#define CUBBYFLOW_ARRAY_SAMPLERS_IMPL_HPP
13
15
16namespace CubbyFlow
17{
18namespace Internal
19{
20template <typename T, size_t N, size_t I>
21struct Lerp
22{
24
25 template <typename View, typename... RemainingIndices>
26 static auto Call(const View& view, Vector<ssize_t, N> i,
28 {
29 using Next = Lerp<T, N, I - 1>;
30
31 return CubbyFlow::Lerp(Next::Call(view, i, t, i[I - 1], indices...),
32 Next::Call(view, i, t, i[I - 1] + 1, indices...),
33 t[I - 1]);
34 }
35};
36
37template <typename T, size_t N>
38struct Lerp<T, N, 1>
39{
41
42 template <typename View, typename... RemainingIndices>
43 static auto Call(const View& view, Vector<ssize_t, N> i,
45 {
46 return CubbyFlow::Lerp(view(i[0], indices...),
47 view(i[0] + 1, indices...), t[0]);
48 }
49};
50
51template <typename T, size_t N, size_t I>
52struct Cubic
53{
55
56 template <typename View, typename CubicInterpolationOp,
57 typename... RemainingIndices>
58 static auto Call(const View& view, Vector<ssize_t, N> i,
61 {
62 using Next = Cubic<T, N, I - 1>;
63
64 return op(
65 Next::Call(view, i, t, op, std::max(i[I - 1] - 1, ZERO_SSIZE),
66 indices...),
67 Next::Call(view, i, t, op, i[I - 1], indices...),
68 Next::Call(view, i, t, op,
69 std::min(i[I - 1] + 1,
70 static_cast<ssize_t>(view.Size()[I - 1]) - 1),
71 indices...),
72 Next::Call(view, i, t, op,
73 std::min(i[I - 1] + 2,
74 static_cast<ssize_t>(view.Size()[I - 1]) - 1),
75 indices...),
76 t[I - 1]);
77 }
78};
79
80template <typename T, size_t N>
81struct Cubic<T, N, 1>
82{
84
85 template <typename View, typename CubicInterpolationOp,
86 typename... RemainingIndices>
87 static auto Call(const View& view, Vector<ssize_t, N> i,
90 {
91 return op(
92 view(std::max(i[0] - 1, ZERO_SSIZE), indices...),
93 view(i[0], indices...),
94 view(std::min(i[0] + 1, static_cast<ssize_t>(view.Size()[0]) - 1),
95 indices...),
96 view(std::min(i[0] + 2, static_cast<ssize_t>(view.Size()[0]) - 1),
97 indices...),
98 t[0]);
99 }
100};
101
102template <typename T, size_t N, size_t I>
104{
106
107 template <typename Coords, typename Weights, typename... RemainingIndices>
108 static void Call(Coords& c, Weights& w, Vector<size_t, N> i,
110 {
111 using Next = GetCoordinatesAndWeights<T, N, I - 1>;
112
113 Next::Call(c, w, i, t, acc * (1 - t[I - 1]), 0, idx...);
114 Next::Call(c, w, i, t, acc * t[I - 1], 1, idx...);
115 }
116};
117
118template <typename T, size_t N>
120{
122
123 template <typename Coords, typename Weights, typename... RemainingIndices>
124 static void Call(Coords& c, Weights& w, Vector<size_t, N> i,
126 {
127 c(0, idx...) = Vector<size_t, N>(0, idx...) + i;
128 c(1, idx...) = Vector<size_t, N>(1, idx...) + i;
129
130 w(0, idx...) = acc * (1 - t[0]);
131 w(1, idx...) = acc * (t[0]);
133};
134
135template <typename T, size_t N, size_t I>
137{
138 template <typename Coords, typename Weights, typename... RemainingIndices>
141 {
143 w0[I - 1] = -1;
145 w1[I - 1] = 1;
147 using Next = GetCoordinatesAndGradientWeights<T, N, I - 1>;
148 Next::Call(c, w, i, t, ElemMul(acc, w0), 0, idx...);
149 Next::Call(c, w, i, t, ElemMul(acc, w1), 1, idx...);
150 }
151};
153template <typename T, size_t N>
156 template <typename Coords, typename Weights, typename... RemainingIndices>
159 {
160 c(0, idx...) = Vector<size_t, N>(0, idx...) + i;
161 c(1, idx...) = Vector<size_t, N>(1, idx...) + i;
164 w0[0] = -1;
166 w1[0] = 1;
167
168 w(0, idx...) = ElemMul(acc, w0);
169 w(1, idx...) = ElemMul(acc, w1);
170 }
171};
172} // namespace Internal
173
174template <typename T, size_t N>
177 const VectorType& gridOrigin)
178 : m_view(view),
179 m_gridSpacing(gridSpacing),
180 m_invGridSpacing(ScalarType{ 1 } / gridSpacing),
181 m_gridOrigin(gridOrigin)
182{
183 // Do nothing
184}
185
186template <typename T, size_t N>
188 : m_view(other.m_view),
189 m_gridSpacing(other.m_gridSpacing),
190 m_invGridSpacing(other.m_invGridSpacing),
191 m_gridOrigin(other.m_gridOrigin)
192{
193 // Do nothing
194}
195
196template <typename T, size_t N>
198 : m_view(std::move(other.m_view)),
199 m_gridSpacing(std::move(other.m_gridSpacing)),
200 m_invGridSpacing(std::move(other.m_invGridSpacing)),
201 m_gridOrigin(std::move(other.m_gridOrigin))
202{
203 // Do nothing
204}
205
206template <typename T, size_t N>
209{
210 m_view = other.m_view;
211 m_gridSpacing = other.m_gridSpacing;
212 m_invGridSpacing = other.m_invGridSpacing;
213 m_gridOrigin = other.m_gridOrigin;
214
215 return *this;
216}
217
218template <typename T, size_t N>
220 NearestArraySampler&& other) noexcept
221{
222 m_view = std::move(other.m_view);
223 m_gridSpacing = std::move(other.m_gridSpacing);
224 m_invGridSpacing = std::move(other.m_invGridSpacing);
225 m_gridOrigin = std::move(other.m_gridOrigin);
226
227 return *this;
228}
229
230template <typename T, size_t N>
232{
233 return m_view(GetCoordinate(pt));
234}
235
236template <typename T, size_t N>
239{
241 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
242 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
243
244 for (size_t i = 0; i < N; ++i)
245 {
247 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
248 is[i] =
249 std::min(static_cast<ssize_t>(is[i] + ts[i] + 0.5), size[i] - 1);
250 }
251
252 return is.template CastTo<size_t>();
253}
254
255template <typename T, size_t N>
256std::function<T(const typename NearestArraySampler<T, N>::VectorType&)>
258{
260
261 return [sampler](const VectorType& x) -> T { return sampler(x); };
262}
263
264template <typename T, size_t N>
266 const VectorType& gridSpacing,
267 const VectorType& gridOrigin)
268 : m_view(view),
269 m_gridSpacing(gridSpacing),
270 m_invGridSpacing(ScalarType{ 1 } / gridSpacing),
271 m_gridOrigin(gridOrigin)
272{
273 // Do nothing
274}
275
276template <typename T, size_t N>
278 : m_view(other.m_view),
279 m_gridSpacing(other.m_gridSpacing),
280 m_invGridSpacing(other.m_invGridSpacing),
281 m_gridOrigin(other.m_gridOrigin)
282{
283 // Do nothing
284}
285
286template <typename T, size_t N>
288 : m_view(std::move(other.m_view)),
289 m_gridSpacing(std::move(other.m_gridSpacing)),
290 m_invGridSpacing(std::move(other.m_invGridSpacing)),
291 m_gridOrigin(std::move(other.m_gridOrigin))
292{
293 // Do nothing
294}
295
296template <typename T, size_t N>
299{
300 m_view = other.m_view;
301 m_gridSpacing = other.m_gridSpacing;
302 m_invGridSpacing = other.m_invGridSpacing;
303 m_gridOrigin = other.m_gridOrigin;
304
305 return *this;
306}
307
308template <typename T, size_t N>
310 LinearArraySampler&& other) noexcept
311{
312 m_view = std::move(other.m_view);
313 m_gridSpacing = std::move(other.m_gridSpacing);
314 m_invGridSpacing = std::move(other.m_invGridSpacing);
315 m_gridOrigin = std::move(other.m_gridOrigin);
316
317 return *this;
318}
319
320template <typename T, size_t N>
322{
325 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
326 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
327
328 for (size_t i = 0; i < N; ++i)
329 {
330 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
331 }
332
333 return Internal::Lerp<T, N, N>::Call(m_view, is, ts);
334}
335
336template <typename T, size_t N>
338 const VectorType& pt, std::array<CoordIndexType, FLAT_KERNEL_SIZE>& indices,
339 std::array<ScalarType, FLAT_KERNEL_SIZE>& weights) const
340{
343 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
344 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
345
346 for (size_t i = 0; i < N; ++i)
347 {
348 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
349 }
350
354
356 indexView, weightView, is.template CastTo<size_t>(), ts, 1);
357}
358
359template <typename T, size_t N>
361 const VectorType& pt, std::array<CoordIndexType, FLAT_KERNEL_SIZE>& indices,
362 std::array<VectorType, FLAT_KERNEL_SIZE>& weights) const
363{
366 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
367 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
368
369 for (size_t i = 0; i < N; ++i)
370 {
371 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
372 }
373
377
380 m_invGridSpacing);
381}
382
383template <typename T, size_t N>
384std::function<T(const typename LinearArraySampler<T, N>::VectorType&)>
386{
388
389 return [sampler](const VectorType& x) -> T { return sampler(x); };
390}
391
392template <typename T, size_t N, typename CIOp>
395 const VectorType& gridOrigin)
396 : m_view(view),
397 m_gridSpacing(gridSpacing),
398 m_invGridSpacing(ScalarType{ 1 } / gridSpacing),
399 m_gridOrigin(gridOrigin)
400{
401 // Do nothing
402}
403
404template <typename T, size_t N, typename CIOp>
406 : m_view(other.m_view),
407 m_gridSpacing(other.m_gridSpacing),
408 m_invGridSpacing(other.m_invGridSpacing),
409 m_gridOrigin(other.m_gridOrigin)
410{
411 // Do nothing
412}
413
414template <typename T, size_t N, typename CIOp>
416 : m_view(std::move(other.m_view)),
417 m_gridSpacing(std::move(other.m_gridSpacing)),
418 m_invGridSpacing(std::move(other.m_invGridSpacing)),
419 m_gridOrigin(std::move(other.m_gridOrigin))
420{
421 // Do nothing
422}
423
424template <typename T, size_t N, typename CIOp>
427{
428 m_view = other.m_view;
429 m_gridSpacing = other.m_gridSpacing;
430 m_invGridSpacing = other.m_invGridSpacing;
431 m_gridOrigin = other.m_gridOrigin;
432
433 return *this;
434}
435
436template <typename T, size_t N, typename CIOp>
438 CubicArraySampler&& other) noexcept
439{
440 m_view = std::move(other.m_view);
441 m_gridSpacing = std::move(other.m_gridSpacing);
442 m_invGridSpacing = std::move(other.m_invGridSpacing);
443 m_gridOrigin = std::move(other.m_gridOrigin);
444
445 return *this;
446}
447
448template <typename T, size_t N, typename CIOp>
450{
453 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
454 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
455
456 for (size_t i = 0; i < N; ++i)
457 {
458 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
459 }
460
461 return Internal::Cubic<T, N, N>::Call(m_view, is, ts, CIOp());
462}
463
464template <typename T, size_t N, typename CIOp>
465std::function<T(const typename CubicArraySampler<T, N, CIOp>::VectorType&)>
467{
469
470 return [sampler](const VectorType& x) -> T { return sampler(x); };
471}
472} // namespace CubbyFlow
473
474#endif
N-D cubic array sampler class.
Definition ArraySamplers.hpp:196
CubicArraySampler & operator=(const CubicArraySampler &other)
Copy assignment operator.
Definition ArraySamplers-Impl.hpp:425
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers.hpp:200
T operator()(const VectorType &pt) const
Returns sampled value at point pt.
Definition ArraySamplers-Impl.hpp:449
CubicArraySampler()=default
Default constructor.
std::function< T(const VectorType &)> Functor() const
Returns a std::function object that wraps this instance.
Definition ArraySamplers-Impl.hpp:466
N-D array sampler using linear interpolation.
Definition ArraySamplers.hpp:107
T operator()(const VectorType &pt) const
Returns sampled value at point pt.
Definition ArraySamplers-Impl.hpp:321
LinearArraySampler & operator=(const LinearArraySampler &other)
Copy assignment operator.
Definition ArraySamplers-Impl.hpp:297
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers.hpp:111
LinearArraySampler()=default
Default constructor.
void GetCoordinatesAndWeights(const VectorType &pt, std::array< CoordIndexType, FLAT_KERNEL_SIZE > &indices, std::array< ScalarType, FLAT_KERNEL_SIZE > &weights) const
Returns the indices of points and their sampling weight for given point.
Definition ArraySamplers-Impl.hpp:337
void GetCoordinatesAndGradientWeights(const VectorType &pt, std::array< CoordIndexType, FLAT_KERNEL_SIZE > &indices, std::array< VectorType, FLAT_KERNEL_SIZE > &weights) const
Definition ArraySamplers-Impl.hpp:360
std::function< T(const VectorType &)> Functor() const
Returns a std::function instance that wraps this instance.
Definition ArraySamplers-Impl.hpp:385
static std::enable_if_t< IsMatrixSizeStatic< Rows, Cols >(), D > MakeConstant(ValueType val)
Makes a static matrix with constant entries.
Definition MatrixDenseBase-Impl.hpp:152
Definition Matrix.hpp:30
Pointer data()
Definition Matrix-Impl.hpp:298
N-D nearest array sampler class.
Definition ArraySamplers.hpp:30
NearestArraySampler & operator=(const NearestArraySampler &other)
Copy assignment operator.
Definition ArraySamplers-Impl.hpp:207
CoordIndexType GetCoordinate(const VectorType &pt) const
Returns the nearest array index for point pt.
Definition ArraySamplers-Impl.hpp:238
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers.hpp:34
T operator()(const VectorType &pt) const
Returns sampled value at point pt.
Definition ArraySamplers-Impl.hpp:231
NearestArraySampler()=default
Default constructor.
std::function< T(const VectorType &)> Functor() const
Returns a std::function object that wraps this instance.
Definition ArraySamplers-Impl.hpp:257
Definition pybind11Utils.hpp:21
std::enable_if_t< std::is_arithmetic< T >::value, S > Lerp(const S &f0, const S &f1, T t)
Computes linear interpolation.
Definition MathUtils-Impl.hpp:295
std::enable_if_t< std::is_arithmetic< T >::value > GetBarycentric(T x, size_t begin, size_t end, size_t &i, T &t)
Computes the barycentric coordinate.
Definition MathUtils-Impl.hpp:196
constexpr ssize_t ZERO_SSIZE
Zero ssize_t.
Definition Constants.hpp:22
constexpr auto ElemMul(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition MatrixExpression-Impl.hpp:1085
Matrix< T, Rows, 1 > Vector
Definition Matrix.hpp:738
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers-Impl.hpp:83
static auto Call(const View &view, Vector< ssize_t, N > i, Vector< ScalarType, N > t, CubicInterpolationOp op, RemainingIndices... indices)
Definition ArraySamplers-Impl.hpp:87
Definition ArraySamplers-Impl.hpp:53
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers-Impl.hpp:54
static auto Call(const View &view, Vector< ssize_t, N > i, Vector< ScalarType, N > t, CubicInterpolationOp op, RemainingIndices... indices)
Definition ArraySamplers-Impl.hpp:58
static void Call(Coords &c, Weights &w, Vector< size_t, N > i, Vector< T, N > t, Vector< T, N > acc, RemainingIndices... idx)
Definition ArraySamplers-Impl.hpp:157
Definition ArraySamplers-Impl.hpp:137
static void Call(Coords &c, Weights &w, Vector< size_t, N > i, Vector< T, N > t, Vector< T, N > acc, RemainingIndices... idx)
Definition ArraySamplers-Impl.hpp:139
static void Call(Coords &c, Weights &w, Vector< size_t, N > i, Vector< ScalarType, N > t, T acc, RemainingIndices... idx)
Definition ArraySamplers-Impl.hpp:124
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers-Impl.hpp:121
Definition ArraySamplers-Impl.hpp:104
static void Call(Coords &c, Weights &w, Vector< size_t, N > i, Vector< ScalarType, N > t, T acc, RemainingIndices... idx)
Definition ArraySamplers-Impl.hpp:108
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers-Impl.hpp:105
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers-Impl.hpp:40
static auto Call(const View &view, Vector< ssize_t, N > i, Vector< ScalarType, N > t, RemainingIndices... indices)
Definition ArraySamplers-Impl.hpp:43
Definition ArraySamplers-Impl.hpp:22
typename GetScalarType< T >::value ScalarType
Definition ArraySamplers-Impl.hpp:23
static auto Call(const View &view, Vector< ssize_t, N > i, Vector< ScalarType, N > t, RemainingIndices... indices)
Definition ArraySamplers-Impl.hpp:26