280 lines
8.4 KiB
C++
280 lines
8.4 KiB
C++
/*
|
|
* <Short Description>
|
|
* Copyright (C) 2024 Brett Terpstra
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef GP_IMAGE_TEST_FUNCTIONS_H
|
|
#define GP_IMAGE_TEST_FUNCTIONS_H
|
|
|
|
// FUNC_DEFINE(NAME, REQUIRED_ARGS, FUNC, ALLOWED_FUNCS)
|
|
// FUNC_ALLOW_ANY
|
|
|
|
#include <initializer_list>
|
|
#include <vector>
|
|
#include "blt/std/hashmap.h"
|
|
#include "blt/std/logging.h"
|
|
#include "blt/std/types.h"
|
|
#include <variant>
|
|
#include <array>
|
|
#include <image.h>
|
|
|
|
template<typename T>
|
|
using allowed_funcs = std::vector<T>;
|
|
|
|
template<typename T>
|
|
using allowed_funcs_set = HASHSET<T>;
|
|
|
|
template<typename T>
|
|
using func_list = std::vector<allowed_funcs<T>>;
|
|
|
|
template<typename T>
|
|
using func_set = std::vector<allowed_funcs_set<T>>;
|
|
|
|
template<typename T>
|
|
inline constexpr func_set<T> convert(const func_list<T>& func)
|
|
{
|
|
func_set<T> set_list;
|
|
for (const auto& v : func)
|
|
{
|
|
allowed_funcs_set<T> set;
|
|
for (const auto& f : v)
|
|
set.insert(f);
|
|
set_list.push_back(set);
|
|
}
|
|
return set_list;
|
|
}
|
|
|
|
using data_t = std::array<float, 3>;
|
|
|
|
class empty
|
|
{
|
|
};
|
|
|
|
// #define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ALLOWED...)
|
|
|
|
#define FUNC_ALLOW_ANY
|
|
#define FUNC_ALLOW_NONE
|
|
#define FUNC_ALLOW_BOOL
|
|
#define FUNC_ALLOW_COORD
|
|
#define FUNC_ALLOW_SCALAR
|
|
#define FUNC_ALLOW_SCALAR_COORD
|
|
#define FUNC_ALLOW_TERMINALS
|
|
|
|
/*
|
|
* Define Functions
|
|
*/
|
|
|
|
#define ARGS image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data
|
|
|
|
void f_x(ARGS);
|
|
|
|
void f_y(ARGS);
|
|
|
|
void f_random(ARGS);
|
|
|
|
void f_noise(ARGS);
|
|
|
|
void f_cnoise(ARGS);
|
|
|
|
void f_scalar(ARGS);
|
|
|
|
void f_color(ARGS);
|
|
|
|
void f_log(ARGS);
|
|
|
|
void f_sqrt(ARGS);
|
|
|
|
void f_sin(ARGS);
|
|
|
|
void f_cos(ARGS);
|
|
|
|
void f_atan(ARGS);
|
|
|
|
void f_add(ARGS);
|
|
|
|
void f_sub(ARGS);
|
|
|
|
void f_mul(ARGS);
|
|
|
|
void f_div(ARGS);
|
|
|
|
void f_or(ARGS);
|
|
|
|
void f_and(ARGS);
|
|
|
|
void f_xor(ARGS);
|
|
|
|
void f_if(ARGS);
|
|
|
|
void f_equ(ARGS);
|
|
|
|
void f_lt(ARGS);
|
|
|
|
void f_gt(ARGS);
|
|
|
|
void f_lte(ARGS);
|
|
|
|
void f_gte(ARGS);
|
|
|
|
/*
|
|
* Define function enums / lists
|
|
*/
|
|
|
|
// NAME MIN MAX FUNC ALLOWED FUNC LIST
|
|
#define FUNC_FUNCTIONS \
|
|
FUNC_DEFINE(X, 0, 0, f_x, FUNC_ALLOW_NONE) \
|
|
FUNC_DEFINE(Y, 0, 0, f_y, FUNC_ALLOW_NONE) \
|
|
FUNC_DEFINE(RANDOM, 0, 0, f_random, FUNC_ALLOW_NONE) \
|
|
FUNC_DEFINE(NOISE, 0, 2, f_noise, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR) \
|
|
FUNC_DEFINE(CNOISE, 0, 6, f_cnoise, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR) \
|
|
FUNC_DEFINE(SCALAR, 0, 0, f_scalar, FUNC_ALLOW_NONE) \
|
|
FUNC_DEFINE(COLOR, 0, 0, f_color, FUNC_ALLOW_NONE) \
|
|
FUNC_DEFINE(LOG, 1, 1, f_log, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(SQRT, 1, 1, f_sqrt, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(SIN, 1, 1, f_sin, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(COS, 1, 1, f_cos, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(ATAN, 1, 1, f_atan, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(ADD, 2, 2, f_add, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(SUB, 2, 2, f_sub, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(MUL, 2, 2, f_mul, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(DIV, 2, 2, f_div, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(OR, 2, 2, f_or, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(AND, 2, 2, f_and, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(XOR, 2, 2, f_xor, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(IF, 3, 3, f_if, FUNC_ALLOW_BOOL, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(EQU, 2, 2, f_equ, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(LT, 2, 2, f_lt, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(GT, 2, 2, f_gt, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(LTE, 2, 2, f_lte, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
|
|
FUNC_DEFINE(GTE, 2, 2, f_gte, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY)
|
|
|
|
|
|
#undef FUNC_ALLOW_ANY
|
|
#undef FUNC_ALLOW_NONE
|
|
#undef FUNC_ALLOW_BOOL
|
|
#undef FUNC_ALLOW_COORD
|
|
#undef FUNC_ALLOW_SCALAR
|
|
#undef FUNC_ALLOW_SCALAR_COORD
|
|
#undef FUNC_ALLOW_TERMINALS
|
|
|
|
/*
|
|
* Construct enum
|
|
*/
|
|
|
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) NAME,
|
|
enum class function_t : blt::i32
|
|
{
|
|
FUNC_FUNCTIONS
|
|
m_END
|
|
};
|
|
#undef FUNC_DEFINE
|
|
|
|
static inline blt::i32 to_underlying(function_t f)
|
|
{
|
|
return static_cast<blt::i32>(f);
|
|
}
|
|
|
|
static inline constexpr blt::i32 OPERATOR_COUNT = static_cast<int>(function_t::m_END);
|
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) MAX_ARGS,
|
|
static inline constexpr blt::i32 MAX_ARGS = std::max({FUNC_FUNCTIONS});
|
|
#undef FUNC_DEFINE
|
|
|
|
/*
|
|
* Define function lists
|
|
*/
|
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) function_t::NAME,
|
|
#define DEF_FUNC_LIST(NAME, ...) \
|
|
static inline const allowed_funcs_set<function_t> NAME##_SET{__VA_ARGS__}; \
|
|
static inline const allowed_funcs<function_t> NAME{__VA_ARGS__};
|
|
DEF_FUNC_LIST(FUNC_ALLOW_ANY, FUNC_FUNCTIONS);
|
|
DEF_FUNC_LIST(FUNC_ALLOW_NONE,);
|
|
DEF_FUNC_LIST(FUNC_ALLOW_BOOL, function_t::OR, function_t::AND, function_t::XOR, function_t::EQU, function_t::GT, function_t::LT, function_t::GTE,
|
|
function_t::LTE);
|
|
DEF_FUNC_LIST(FUNC_ALLOW_COORD, function_t::X, function_t::Y);
|
|
DEF_FUNC_LIST(FUNC_ALLOW_SCALAR, function_t::SCALAR);
|
|
DEF_FUNC_LIST(FUNC_ALLOW_SCALAR_COORD, function_t::SCALAR, function_t::X, function_t::Y);
|
|
DEF_FUNC_LIST(FUNC_ALLOW_TERMINALS, function_t::SCALAR, function_t::X, function_t::Y, function_t::COLOR, function_t::RANDOM);
|
|
#undef FUNC_DEFINE
|
|
|
|
/*
|
|
* Create mappings
|
|
*/
|
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) MIN_ARGS,
|
|
[[maybe_unused]] static inline std::array<blt::i32, OPERATOR_COUNT> function_arg_min_map = {
|
|
FUNC_FUNCTIONS
|
|
};
|
|
#undef FUNC_DEFINE
|
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) MAX_ARGS,
|
|
[[maybe_unused]] static inline std::array<blt::i32, OPERATOR_COUNT> function_arg_max_map = {
|
|
FUNC_FUNCTIONS
|
|
};
|
|
#undef FUNC_DEFINE
|
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) func_list<function_t>{__VA_ARGS__},
|
|
[[maybe_unused]] static inline std::array<func_list<function_t>, OPERATOR_COUNT> function_arg_allowed_map = {
|
|
FUNC_FUNCTIONS
|
|
};
|
|
#undef FUNC_DEFINE
|
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) convert(func_list<function_t>{__VA_ARGS__}),
|
|
[[maybe_unused]] static inline std::array<func_set<function_t>, OPERATOR_COUNT> function_arg_allowed_set_map = {
|
|
FUNC_FUNCTIONS
|
|
};
|
|
#undef FUNC_DEFINE
|
|
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) #NAME,
|
|
[[maybe_unused]] static inline std::array<std::string, OPERATOR_COUNT> function_name_map = {
|
|
FUNC_FUNCTIONS
|
|
};
|
|
#undef FUNC_DEFINE
|
|
|
|
/*
|
|
* Helper functions
|
|
*/
|
|
inline static allowed_funcs<function_t> intersection(const allowed_funcs<function_t>& vec, const allowed_funcs_set<function_t>& has)
|
|
{
|
|
allowed_funcs<function_t> set;
|
|
for (auto v : vec)
|
|
if (has.contains(v))
|
|
set.push_back(v);
|
|
return set;
|
|
}
|
|
|
|
inline static allowed_funcs<function_t> intersection_comp(const allowed_funcs<function_t>& vec, const allowed_funcs_set<function_t>& has)
|
|
{
|
|
allowed_funcs<function_t> set;
|
|
for (auto v : vec)
|
|
if (!has.contains(v))
|
|
set.push_back(v);
|
|
return set;
|
|
}
|
|
|
|
// distribution from normality (DFN)
|
|
float eval_DNF_SW(const image& img);
|
|
|
|
float eval_DNF_SW_1(const image& img);
|
|
|
|
//template<typename F>
|
|
//bool isNan(F f)
|
|
//{
|
|
// return f == std::numeric_limits<F>::quiet_NaN() || f == std::numeric_limits<F>::signaling_NaN();
|
|
//}
|
|
|
|
template<typename F>
|
|
bool isInf(F f)
|
|
{
|
|
return f == std::numeric_limits<F>::infinity() || f == -std::numeric_limits<F>::infinity();
|
|
}
|
|
|
|
#endif //GP_IMAGE_TEST_FUNCTIONS_H
|