Line data Source code
1 : #pragma once 2 : 3 : #include "Logger.h" 4 : #include "TypeCasts.hpp" 5 : 6 : #include <array> 7 : 8 : #define DEFAULT_PROJECTOR_LUT_SIZE 100 9 : 10 : namespace elsa 11 : { 12 : namespace detail 13 : { 14 : template <typename data_t, index_t N> 15 : constexpr std::array<data_t, N> generate_lut(std::function<data_t(data_t)> gen, 16 : data_t radius) 17 17328 : { 18 17328 : Logger::get("generate_lut")->debug("Calculating lut"); 19 : 20 17328 : std::array<data_t, N> lut; 21 : 22 17328 : const auto step = radius / (N - 1); 23 : 24 1743042 : for (std::size_t i = 0; i < N; ++i) { 25 1725714 : lut[i] = gen(step * i); 26 1725714 : } 27 : 28 17328 : return lut; 29 17328 : } 30 : 31 : } // namespace detail 32 : 33 : template <typename data_t, std::size_t N> 34 : class Lut 35 : { 36 : public: 37 : constexpr Lut(std::function<data_t(data_t)> gen, data_t support = 1) 38 : : _support(support), data_(detail::generate_lut<data_t, N>(gen, support)) 39 17328 : { 40 17328 : } 41 : 42 : constexpr Lut(std::array<data_t, N>&& data, data_t support = 1) 43 : : _support(support), data_(data) 44 14 : { 45 14 : } 46 : 47 : template <typename T, std::enable_if_t<std::is_integral_v<T>, index_t> = 0> 48 : constexpr data_t operator()(T index) const 49 400 : { 50 400 : if (index < 0 || index > asSigned(N)) { 51 0 : return 0; 52 0 : } 53 : 54 400 : return data_[index]; 55 400 : } 56 : 57 : /// TODO: Handle boundary conditions 58 : /// lerp(last, last+1, t), for some t > 0, yields f(last) / 2, as f(last + 1) = 0, 59 : /// this should be handled 60 : template <typename T, std::enable_if_t<std::is_floating_point_v<T>, index_t> = 0> 61 : constexpr data_t operator()(T distance) const 62 9744373 : { 63 9744373 : T index = (distance / _support) * (N - 1); 64 9744377 : if (index < 0 || index > asSigned(N - 1)) { 65 8194142 : return 0; 66 8194142 : } 67 : 68 : // Get the two closes indices 69 1550231 : const auto a = static_cast<std::size_t>(std::floor(index)); 70 1550231 : const auto b = static_cast<std::size_t>(std::ceil(index)); 71 : 72 : // Get the function values 73 1550231 : const auto fa = data_[a]; 74 1550231 : const auto fb = data_[b]; 75 : 76 1550231 : const auto t = index - static_cast<data_t>(a); 77 1550231 : return t * fb + (1 - t) * fa; 78 1550231 : } 79 : 80 : constexpr auto data() const { return data_; } 81 : 82 : constexpr auto size() const { return N; } 83 : 84 13467020 : constexpr auto support() const { return _support; } 85 : 86 : private: 87 : const data_t _support; 88 : const std::array<data_t, N> data_; 89 : }; 90 : } // namespace elsa