1#ifndef _BBM_PRECOMPUTE_H_
2#define _BBM_PRECOMPUTE_H_
36 template<
typename T, std::array DIM,
typename... MAP>
requires (
sizeof...(MAP) == DIM.size() ||
sizeof...(MAP) == 0)
37 struct tab :
public std::array<T, std::accumulate(std::begin(DIM), std::end(DIM), 1, std::multiplies<>())>
39 using base_type = std::array<T, std::accumulate(std::begin(DIM), std::end(DIM), 1, std::multiplies<>())>;
45 static constexpr auto sizes(
void) {
return DIM; }
48 static constexpr auto dim(
void) {
return DIM.size(); }
54 template<
typename... Cs>
requires (
sizeof...(Cs) ==
dim())
55 static constexpr auto map(Cs&&... coord)
58 if constexpr (
sizeof...(MAP) == 0)
60 using type =
decltype((coord + ...));
61 return std::array{ bbm::cast<type>(coord)...};
68 using type =
decltype((MAP()(coord...) + ...));
69 return std::array{ bbm::cast<type>(MAP()(coord...))... };
75 using type =
decltype((MAP()(coord) + ...));
76 return std::array{ bbm::cast<type>(MAP()(coord))... };
90 static constexpr auto index(
const std::array<I,
dim()>& mapped)
95 idx = bbm::cast<index_t<I>>(bbm::clamp(mapped[i],0,DIM[i]-1)) + idx*DIM[i];
105 static constexpr auto valid(
const std::array<I,
dim()>& mapped)
107 index_mask_t<I> mask =
true;
108 CONSTFOR(i,
dim(), { mask &= bbm::cast<index_mask_t<I>>((mapped[i] < DIM[i]) && (mapped[i] >= 0)); });
119 template<
typename RET,
typename I,
typename Mask>
requires std::convertible_to<index_mask_t<I>, Mask>
120 inline constexpr auto _lookup(
const std::array<I,
dim()>& mapped, Mask& mask)
const
122 mask &=
valid(mapped);
123 auto idx =
index(mapped);
124 return bbm::lookup<RET>(*
this, idx);
132 template<
typename RET,
size_t IDX,
typename A,
typename Mask>
135 auto a_idx(mapped); a_idx[IDX] = bbm::floor(mapped[IDX]);
136 auto b_idx(mapped); b_idx[IDX] = bbm::ceil(mapped[IDX]);
137 auto weight = mapped[IDX] - bbm::floor(mapped[IDX]);
139 if constexpr (IDX == DIM.size()-1)
return bbm::lerp( _lookup<RET>(a_idx, mask), _lookup<RET>(b_idx, mask), weight );
140 else return bbm::lerp( _interpolate<RET,IDX+1>(a_idx, mask), _interpolate<RET,IDX+1>(b_idx, mask), weight );
147 template<
typename... Is>
requires (
sizeof...(Is) ==
dim())
148 inline T&
operator()(Is&&... indices) {
return base_type::operator[](
index(std::array<
size_t,
dim()>{size_t(indices)...})); }
150 template<
typename... Is>
requires (
sizeof...(Is) ==
dim())
151 inline const T&
operator()(Is&&... indices)
const {
return base_type::operator[](
index(std::array<
size_t,
dim()>{size_t(indices)...})); }
167 template<
typename RET,
typename... Cs>
requires (
sizeof...(Cs) ==
dim())
168 inline constexpr auto lookup(Cs&&... coords)
const
170 mask_t<RET> mask =
true;
171 RET
value = _lookup<RET>(
map(std::forward<Cs>(coords)...), mask );
176 template<
typename... Cs>
requires (
sizeof...(Cs) ==
dim())
177 inline constexpr auto lookup(Cs&&... coords)
const {
return lookup<T>(std::forward<Cs>(coords)...); }
193 template<
typename RET,
typename... Cs>
requires (
sizeof...(Cs) ==
dim())
196 mask_t<RET> mask =
true;
197 RET
value = _interpolate<RET,0>(
map(std::forward<Cs>(coords)...), mask );
202 template<
typename... Cs>
requires (
sizeof...(Cs) ==
dim())
203 inline constexpr auto interpolate(Cs&&... coords)
const {
return interpolate<T>(std::forward<Cs>(coords)...); }
Check if lambda/functor takes a set of arguments.
Definition: util.h:185
#define CONSTFOR(IDX, NUMITR,...)
HELPER MACRO.
Definition: constfor.h:63
Predefined exceptions for common errors.
#define BBM_INVALID_LAMBDA
Definition: error.h:53
Definition: aggregatebsdf.h:29
constexpr named< anonymize_t< T >, NAMES... > make_named(T &&t)
Make a named of a gettable type (with size == #NAMES); renames if the type is a named container.
Definition: named.h:293
static constexpr bool dependent_false_v
Definition: error.h:33
std::array wrapper for precomputed data with optional remapping of the indices.
Definition: precompute.h:38
constexpr auto interpolate(Cs &&... coords) const
Lookup the value in the data structure given a set of coordinates. In contrast to 'lookup' this metho...
Definition: precompute.h:194
constexpr auto lookup(Cs &&... coords) const
Lookup the value in the data structure given a set of coordinates for each dimension....
Definition: precompute.h:168
static constexpr auto dim(void)
number of dimensions.
Definition: precompute.h:48
constexpr auto _lookup(const std::array< I, dim()> &mapped, Mask &mask) const
PRIVATE: given an array of indices and a mask, return the corresponding stored value and update the m...
Definition: precompute.h:120
constexpr RET _interpolate(const A &mapped, Mask &mask) const
PRIVATE: Similar to _lookup, except that the each value is the interpolation result of the floor and ...
Definition: precompute.h:133
constexpr auto interpolate(Cs &&... coords) const
interpolate with the native type
Definition: precompute.h:203
static constexpr auto map(Cs &&... coord)
PRIVATE method to map a coordinate to an array of indices.
Definition: precompute.h:55
static constexpr auto valid(const std::array< I, dim()> &mapped)
PRIVATE: returns false if any index lies outside the corresponding dimension's size.
Definition: precompute.h:105
constexpr auto lookup(Cs &&... coords) const
Lookup with the native type.
Definition: precompute.h:177
T value
value type
Definition: precompute.h:42
static constexpr auto index(const std::array< I, dim()> &mapped)
PRIVATE: linearizes an array of indices (per dimension) to a single index in the underlying std::arra...
Definition: precompute.h:90
std::array< T, std::accumulate(std::begin(DIM), std::end(DIM), 1, std::multiplies<>())> base_type
Definition: precompute.h:39
static constexpr auto sizes(void)
sizes of each dimension.
Definition: precompute.h:45
A wrapper for STL containers such as tuple, pair, and array. These containers force the programmer to...
Additional basic helper concepts.