diff --git a/include/genetic/util.h b/include/genetic/util.h index b276dfa..78927d9 100644 --- a/include/genetic/util.h +++ b/include/genetic/util.h @@ -17,163 +17,6 @@ namespace parks { constexpr unsigned int HEIGHT = 512; constexpr unsigned int CHANNELS = 3; - enum class ParameterType { - SCALAR, COLOR, VARIABLE, IMAGE - }; - - struct Image { - std::shared_ptr image; - unsigned int width, height; - - void write(unsigned int x, unsigned int y, const blt::vec3d& color) const { - auto pos = x * CHANNELS + y * width * CHANNELS; - image.get()[pos] = color.x(); - image.get()[pos + 1] = color.y(); - image.get()[pos + 2] = color.z(); - } - - [[nodiscard]] blt::vec3d read(unsigned int x, unsigned int y) const { - auto pos = x * CHANNELS + y * width * CHANNELS; - auto r = image.get()[pos]; - auto g = image.get()[pos + 1]; - auto b = image.get()[pos + 2]; - return blt::vec3d{r, g, b}; - } - }; - - struct Parameter { - private: - ParameterType type; - std::variant value; - public: - explicit Parameter(double s): value(s) {type = ParameterType::SCALAR;} - explicit Parameter(blt::vec3d c): value(c) {type = ParameterType::COLOR;} - explicit Parameter(unsigned int v): value(v) {type = ParameterType::VARIABLE;} - explicit Parameter(Image&& i): value(i) {type = ParameterType::IMAGE;} - - [[nodiscard]] ParameterType getType() const { - return type; - } - - template - [[nodiscard]] T& get() { - return std::get(value); - } - - template - [[nodiscard]] const T& get() const { - return std::get(value); - } - - template - Parameter apply(Op f, double scalar) const { - if (type == ParameterType::SCALAR) - return Parameter{f(get(), scalar)}; - else if (type == ParameterType::COLOR) { - auto color = get(); - return Parameter{blt::vec3d{f(color.x(), scalar), f(color.y(), scalar), f(color.z(), scalar)}}; - } else if (type == ParameterType::VARIABLE){ - return Parameter{f((double)get(), scalar)}; - } else if (type == ParameterType::IMAGE){ - auto image = get(); - auto newImage = Image{std::shared_ptr(new double[image.width * image.height * CHANNELS]), image.width, image.height}; - - for (unsigned int i = 0; i < image.width; i++){ - for (unsigned int j = 0; j < image.height; j++){ - auto oldColor = image.read(i, j); - newImage.write(i, j, blt::vec3d{f(oldColor.x(), scalar), f(oldColor.y(), scalar), f(oldColor.z(), scalar)}); - } - } - - return Parameter{std::move(newImage)}; - } - } - - template - Parameter apply(Op f, const blt::vec3d& color) const { - if (type == ParameterType::SCALAR) - return Parameter{blt::vec3d{f(get(), color.x()), f(get(), color.y()), f(get(), color.z())}}; - else if (type == ParameterType::COLOR) { - auto ourColor = get(); - return Parameter{blt::vec3d{f(ourColor.x(), color.x()), f(ourColor.y(), color.y()), f(ourColor.z(), color.z())}}; - } else if (type == ParameterType::VARIABLE){ - return Parameter{blt::vec3d{f(get(), color.x()), f(get(), color.y()), f(get(), color.z())}}; - } else if (type == ParameterType::IMAGE){ - auto image = get(); - auto newImage = Image{std::shared_ptr(new double[image.width * image.height * CHANNELS]), image.width, image.height}; - - for (unsigned int i = 0; i < image.width; i++){ - for (unsigned int j = 0; j < image.height; j++){ - auto oldColor = image.read(i, j); - newImage.write(i, j, blt::vec3d{f(oldColor.x(), color.x()), f(oldColor.y(), color.y()), f(oldColor.z(), color.z())}); - } - } - - return Parameter{std::move(newImage)}; - } - } - - template - Parameter apply(Op f, unsigned int variable) const { - if (type == ParameterType::SCALAR) - return Parameter{f(get(), (double) variable)}; - else if (type == ParameterType::COLOR) { - auto color = get(); - return Parameter{blt::vec3d{f(color.x(), (double) variable), f(color.y(), (double)variable), f(color.z(), (double)variable)}}; - } else if (type == ParameterType::VARIABLE){ - return Parameter{f(get(), variable)}; - } else if (type == ParameterType::IMAGE){ - auto image = get(); - auto newImage = Image{std::shared_ptr(new double[image.width * image.height * CHANNELS]), image.width, image.height}; - - for (unsigned int i = 0; i < image.width; i++){ - for (unsigned int j = 0; j < image.height; j++){ - auto oldColor = image.read(i, j); - newImage.write(i, j, blt::vec3d{f(oldColor.x(), (double)variable), f(oldColor.y(), (double)variable), f(oldColor.z(), (double)variable)}); - } - } - - return Parameter{std::move(newImage)}; - } - } - - template - Parameter apply(Op f, const Image& image) const { - if (type == ParameterType::IMAGE){ - auto ourImage = get(); - if (ourImage.width != image.width || ourImage.height != image.height){ - BLT_ERROR("Unable to apply to images of differing sizes!"); - throw std::runtime_error("Unable to apply to images of differing sizes!"); - } - auto newImage = Image{std::shared_ptr(new double[ourImage.width * ourImage.height * CHANNELS]), ourImage.width, ourImage.height}; - - for (unsigned int i = 0; i < ourImage.width; i++){ - for (unsigned int j = 0; j < ourImage.height; j++){ - auto oldColor = ourImage.read(i, j); - auto newColor = image.read(i, j); - newImage.write(i, j, blt::vec3d{f(oldColor.x(), (double)newColor.x()), f(oldColor.y(), (double)newColor.y()), f(oldColor.z(), (double)newColor.z())}); - } - } - - return Parameter{std::move(newImage)}; - } else { - BLT_WARN("Please apply non-images to images instead of images to non-images"); - } - } - - template - inline Parameter apply(Op f, const Parameter& param) const { - if (param.type == ParameterType::SCALAR) - return apply(f, param.get()); - else if (type == ParameterType::COLOR) - return apply(f, param.get()); - else if (type == ParameterType::VARIABLE) - return apply(f, param.get()); - else - return apply(f, param.get()); - } - }; - inline static double randomDouble(double min, double max) { std::mt19937 rng(blt::system::getCurrentTimeNanoseconds()); static std::uniform_real_distribution gen(0, 1); diff --git a/include/genetic/v2/functions.h b/include/genetic/v2/functions.h index 2216747..02dff28 100644 --- a/include/genetic/v2/functions.h +++ b/include/genetic/v2/functions.h @@ -8,6 +8,7 @@ #include #include #include +#include namespace parks::genetic { diff --git a/include/genetic/v2/util.h b/include/genetic/v2/util.h new file mode 100644 index 0000000..ee03f5e --- /dev/null +++ b/include/genetic/v2/util.h @@ -0,0 +1,171 @@ +// +// Created by brett on 7/17/23. +// + +#ifndef PARKSNREC_UTIL_H +#define PARKSNREC_UTIL_H + + +namespace parks { + +enum class ParameterType { + SCALAR, COLOR, VARIABLE, IMAGE +}; + +struct Image { + std::shared_ptr image; + unsigned int width, height; + + void write(unsigned int x, unsigned int y, const blt::vec3d& color) const { + auto pos = x * CHANNELS + y * width * CHANNELS; + image.get()[pos] = color.x(); + image.get()[pos + 1] = color.y(); + image.get()[pos + 2] = color.z(); + } + + [[nodiscard]] blt::vec3d read(unsigned int x, unsigned int y) const { + auto pos = x * CHANNELS + y * width * CHANNELS; + auto r = image.get()[pos]; + auto g = image.get()[pos + 1]; + auto b = image.get()[pos + 2]; + return blt::vec3d{r, g, b}; + } +}; + +struct Parameter { + private: + ParameterType type; + std::variant value; + public: + explicit Parameter(double s): value(s) {type = ParameterType::SCALAR;} + explicit Parameter(blt::vec3d c): value(c) {type = ParameterType::COLOR;} + explicit Parameter(unsigned int v): value(v) {type = ParameterType::VARIABLE;} + explicit Parameter(Image&& i): value(i) {type = ParameterType::IMAGE;} + + [[nodiscard]] ParameterType getType() const { + return type; + } + + template + [[nodiscard]] T& get() { + return std::get(value); + } + + template + [[nodiscard]] const T& get() const { + return std::get(value); + } + + template + Parameter apply(Op f, double scalar) const { + if (type == ParameterType::SCALAR) + return Parameter{f(get(), scalar)}; + else if (type == ParameterType::COLOR) { + auto color = get(); + return Parameter{blt::vec3d{f(color.x(), scalar), f(color.y(), scalar), f(color.z(), scalar)}}; + } else if (type == ParameterType::VARIABLE){ + return Parameter{f((double)get(), scalar)}; + } else if (type == ParameterType::IMAGE){ + auto image = get(); + auto newImage = Image{std::shared_ptr(new double[image.width * image.height * CHANNELS]), image.width, image.height}; + + for (unsigned int i = 0; i < image.width; i++){ + for (unsigned int j = 0; j < image.height; j++){ + auto oldColor = image.read(i, j); + newImage.write(i, j, blt::vec3d{f(oldColor.x(), scalar), f(oldColor.y(), scalar), f(oldColor.z(), scalar)}); + } + } + + return Parameter{std::move(newImage)}; + } + } + + template + Parameter apply(Op f, const blt::vec3d& color) const { + if (type == ParameterType::SCALAR) + return Parameter{blt::vec3d{f(get(), color.x()), f(get(), color.y()), f(get(), color.z())}}; + else if (type == ParameterType::COLOR) { + auto ourColor = get(); + return Parameter{blt::vec3d{f(ourColor.x(), color.x()), f(ourColor.y(), color.y()), f(ourColor.z(), color.z())}}; + } else if (type == ParameterType::VARIABLE){ + return Parameter{blt::vec3d{f(get(), color.x()), f(get(), color.y()), f(get(), color.z())}}; + } else if (type == ParameterType::IMAGE){ + auto image = get(); + auto newImage = Image{std::shared_ptr(new double[image.width * image.height * CHANNELS]), image.width, image.height}; + + for (unsigned int i = 0; i < image.width; i++){ + for (unsigned int j = 0; j < image.height; j++){ + auto oldColor = image.read(i, j); + newImage.write(i, j, blt::vec3d{f(oldColor.x(), color.x()), f(oldColor.y(), color.y()), f(oldColor.z(), color.z())}); + } + } + + return Parameter{std::move(newImage)}; + } + } + + template + Parameter apply(Op f, unsigned int variable) const { + if (type == ParameterType::SCALAR) + return Parameter{f(get(), (double) variable)}; + else if (type == ParameterType::COLOR) { + auto color = get(); + return Parameter{blt::vec3d{f(color.x(), (double) variable), f(color.y(), (double)variable), f(color.z(), (double)variable)}}; + } else if (type == ParameterType::VARIABLE){ + return Parameter{f(get(), variable)}; + } else if (type == ParameterType::IMAGE){ + auto image = get(); + auto newImage = Image{std::shared_ptr(new double[image.width * image.height * CHANNELS]), image.width, image.height}; + + for (unsigned int i = 0; i < image.width; i++){ + for (unsigned int j = 0; j < image.height; j++){ + auto oldColor = image.read(i, j); + newImage.write(i, j, blt::vec3d{f(oldColor.x(), (double)variable), f(oldColor.y(), (double)variable), f(oldColor.z(), (double)variable)}); + } + } + + return Parameter{std::move(newImage)}; + } + } + + template + Parameter apply(Op f, const Image& image) const { + if (type == ParameterType::IMAGE){ + auto ourImage = get(); + if (ourImage.width != image.width || ourImage.height != image.height){ + BLT_ERROR("Unable to apply to images of differing sizes!"); + throw std::runtime_error("Unable to apply to images of differing sizes!"); + } + auto newImage = Image{std::shared_ptr(new double[ourImage.width * ourImage.height * CHANNELS]), ourImage.width, ourImage.height}; + + for (unsigned int i = 0; i < ourImage.width; i++){ + for (unsigned int j = 0; j < ourImage.height; j++){ + auto oldColor = ourImage.read(i, j); + auto newColor = image.read(i, j); + newImage.write(i, j, blt::vec3d{f(oldColor.x(), (double)newColor.x()), f(oldColor.y(), (double)newColor.y()), f(oldColor.z(), (double)newColor.z())}); + } + } + + return Parameter{std::move(newImage)}; + } else { + BLT_WARN("Please apply non-images to images instead of images to non-images"); + } + } + + template + inline Parameter apply(Op f, const Parameter& param) const { + if (param.type == ParameterType::SCALAR) + return apply(f, param.get()); + else if (type == ParameterType::COLOR) + return apply(f, param.get()); + else if (type == ParameterType::VARIABLE) + return apply(f, param.get()); + else + return apply(f, param.get()); + } +}; + +} + + +#endif //PARKSNREC_UTIL_H