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;
146
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 const NearestArraySampler& other) = default;
189
190template <typename T, size_t N>
192 NearestArraySampler&& other) noexcept = default;
193
194template <typename T, size_t N>
196 const NearestArraySampler& other) = default;
197
198template <typename T, size_t N>
200 NearestArraySampler&& other) noexcept = default;
201
202template <typename T, size_t N>
204{
205 return m_view(GetCoordinate(pt));
206}
207
208template <typename T, size_t N>
211{
213 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
214 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
215
216 for (size_t i = 0; i < N; ++i)
217 {
219 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
220 is[i] =
221 std::min(static_cast<ssize_t>(is[i] + ts[i] + 0.5), size[i] - 1);
222 }
223
224 return is.template CastTo<size_t>();
225}
226
227template <typename T, size_t N>
228std::function<T(const typename NearestArraySampler<T, N>::VectorType&)>
230{
232
233 return [sampler](const VectorType& x) -> T { return sampler(x); };
234}
235
236template <typename T, size_t N>
238 const VectorType& gridSpacing,
239 const VectorType& gridOrigin)
240 : m_view(view),
241 m_gridSpacing(gridSpacing),
242 m_invGridSpacing(ScalarType{ 1 } / gridSpacing),
243 m_gridOrigin(gridOrigin)
244{
245 // Do nothing
246}
247
248template <typename T, size_t N>
250 default;
251
252template <typename T, size_t N>
254 LinearArraySampler&& other) noexcept = default;
255
256template <typename T, size_t N>
258 const LinearArraySampler& other) = default;
259
260template <typename T, size_t N>
262 LinearArraySampler&& other) noexcept = default;
263
264template <typename T, size_t N>
266{
269 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
270 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
271
272 for (size_t i = 0; i < N; ++i)
273 {
274 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
275 }
276
277 return Internal::Lerp<T, N, N>::Call(m_view, is, ts);
278}
279
280template <typename T, size_t N>
282 const VectorType& pt, std::array<CoordIndexType, FLAT_KERNEL_SIZE>& indices,
283 std::array<ScalarType, FLAT_KERNEL_SIZE>& weights) const
284{
287 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
288 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
289
290 for (size_t i = 0; i < N; ++i)
291 {
292 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
293 }
294
298
300 indexView, weightView, is.template CastTo<size_t>(), ts, 1);
301}
302
303template <typename T, size_t N>
305 const VectorType& pt, std::array<CoordIndexType, FLAT_KERNEL_SIZE>& indices,
306 std::array<VectorType, FLAT_KERNEL_SIZE>& weights) const
307{
310 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
311 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
312
313 for (size_t i = 0; i < N; ++i)
314 {
315 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
316 }
317
321
324 m_invGridSpacing);
325}
326
327template <typename T, size_t N>
328std::function<T(const typename LinearArraySampler<T, N>::VectorType&)>
330{
332
333 return [sampler](const VectorType& x) -> T { return sampler(x); };
334}
335
336template <typename T, size_t N, typename CIOp>
339 const VectorType& gridOrigin)
340 : m_view(view),
341 m_gridSpacing(gridSpacing),
342 m_invGridSpacing(ScalarType{ 1 } / gridSpacing),
343 m_gridOrigin(gridOrigin)
344{
345 // Do nothing
346}
347
348template <typename T, size_t N, typename CIOp>
350 const CubicArraySampler& other) = default;
351
352template <typename T, size_t N, typename CIOp>
354 CubicArraySampler&& other) noexcept = default;
355
356template <typename T, size_t N, typename CIOp>
358 const CubicArraySampler& other) = default;
359
360template <typename T, size_t N, typename CIOp>
362 CubicArraySampler&& other) noexcept = default;
363
364template <typename T, size_t N, typename CIOp>
366{
369 VectorType npt = ElemMul(pt - m_gridOrigin, m_invGridSpacing);
370 Vector<ssize_t, N> size = m_view.Size().template CastTo<ssize_t>();
371
372 for (size_t i = 0; i < N; ++i)
373 {
374 GetBarycentric(npt[i], 0, size[i], is[i], ts[i]);
375 }
376
377 return Internal::Cubic<T, N, N>::Call(m_view, is, ts, CIOp());
378}
379
380template <typename T, size_t N, typename CIOp>
381std::function<T(const typename CubicArraySampler<T, N, CIOp>::VectorType&)>
383{
385
386 return [sampler](const VectorType& x) -> T { return sampler(x); };
387}
388} // namespace CubbyFlow
389
390#endif
N-D cubic array sampler class.
Definition ArraySamplers.hpp:196
CubicArraySampler & operator=(const CubicArraySampler &other)
Copy assignment operator.
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:365
CubicArraySampler()=default
Default constructor.
std::function< T(const VectorType &)> Functor() const
Returns a std::function object that wraps this instance.
Definition ArraySamplers-Impl.hpp:382
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:265
LinearArraySampler & operator=(const LinearArraySampler &other)
Copy assignment operator.
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:281
void GetCoordinatesAndGradientWeights(const VectorType &pt, std::array< CoordIndexType, FLAT_KERNEL_SIZE > &indices, std::array< VectorType, FLAT_KERNEL_SIZE > &weights) const
Definition ArraySamplers-Impl.hpp:304
std::function< T(const VectorType &)> Functor() const
Returns a std::function instance that wraps this instance.
Definition ArraySamplers-Impl.hpp:329
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.
CoordIndexType GetCoordinate(const VectorType &pt) const
Returns the nearest array index for point pt.
Definition ArraySamplers-Impl.hpp:210
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:203
NearestArraySampler()=default
Default constructor.
std::function< T(const VectorType &)> Functor() const
Returns a std::function object that wraps this instance.
Definition ArraySamplers-Impl.hpp:229
Definition pybind11Utils.hpp:22
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:1084
Matrix< T, Rows, 1 > Vector
Definition Matrix.hpp:648
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