diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index 3ab0342d2c..8ee2d442ba 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -2279,12 +2279,12 @@ int CLI::run(int argc, char **argv) else colors.push_back("#FFFFFF"); - std::vector> colors_out(colors.size()); - unsigned char rgb_color[3] = {}; + std::vector colors_out(colors.size()); + ColorRGBA rgb_color; for (const std::string& color : colors) { - Slic3r::GUI::BitmapCache::parse_color(color, rgb_color); + Slic3r::decode_color(color, rgb_color); size_t color_idx = &color - &colors.front(); - colors_out[color_idx] = { float(rgb_color[0]) / 255.f, float(rgb_color[1]) / 255.f, float(rgb_color[2]) / 255.f, 1.f }; + colors_out[color_idx] = rgb_color; } int gl_major, gl_minor, gl_verbos; @@ -2357,15 +2357,12 @@ int CLI::run(int argc, char **argv) //glvolume_collection.volumes.back()->geometry_id = key.geometry_id; std::string color = filament_color?filament_color->get_at(extruder_id - 1):"#00FF00"; - unsigned char rgb_color[3] = {}; - Slic3r::GUI::BitmapCache::parse_color(color, rgb_color); - glvolume_collection.volumes.back()->set_render_color( float(rgb_color[0]) / 255.f, float(rgb_color[1]) / 255.f, float(rgb_color[2]) / 255.f, 1.f); + ColorRGBA rgb_color; + Slic3r::decode_color(color, rgb_color); + glvolume_collection.volumes.back()->set_render_color(rgb_color); - std::array new_color; - new_color[0] = float(rgb_color[0]) / 255.f; - new_color[1] = float(rgb_color[1]) / 255.f; - new_color[2] = float(rgb_color[2]) / 255.f; - new_color[3] = 1.f; + ColorRGBA new_color; + new_color = rgb_color; glvolume_collection.volumes.back()->set_color(new_color); glvolume_collection.volumes.back()->printable = model_instance.printable; } diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 3cfb82b073..0a840db87f 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -56,6 +56,8 @@ set(lisbslic3r_sources Clipper2Utils.cpp Clipper2Utils.hpp ClipperZUtils.hpp + Color.cpp + Color.hpp Config.cpp Config.hpp CurveAnalyzer.cpp diff --git a/src/libslic3r/Color.cpp b/src/libslic3r/Color.cpp new file mode 100644 index 0000000000..b911d170e3 --- /dev/null +++ b/src/libslic3r/Color.cpp @@ -0,0 +1,412 @@ +#include "libslic3r.h" +#include "Color.hpp" + +#include + +static const float INV_255 = 1.0f / 255.0f; + +namespace Slic3r { + +// Conversion from RGB to HSV color space +// The input RGB values are in the range [0, 1] +// The output HSV values are in the ranges h = [0, 360], and s, v = [0, 1] +static void RGBtoHSV(float r, float g, float b, float& h, float& s, float& v) +{ + assert(0.0f <= r && r <= 1.0f); + assert(0.0f <= g && g <= 1.0f); + assert(0.0f <= b && b <= 1.0f); + + const float max_comp = std::max(std::max(r, g), b); + const float min_comp = std::min(std::min(r, g), b); + const float delta = max_comp - min_comp; + + if (delta > 0.0f) { + if (max_comp == r) + h = 60.0f * (std::fmod(((g - b) / delta), 6.0f)); + else if (max_comp == g) + h = 60.0f * (((b - r) / delta) + 2.0f); + else if (max_comp == b) + h = 60.0f * (((r - g) / delta) + 4.0f); + + s = (max_comp > 0.0f) ? delta / max_comp : 0.0f; + } + else { + h = 0.0f; + s = 0.0f; + } + v = max_comp; + + while (h < 0.0f) { h += 360.0f; } + while (h > 360.0f) { h -= 360.0f; } + + assert(0.0f <= s && s <= 1.0f); + assert(0.0f <= v && v <= 1.0f); + assert(0.0f <= h && h <= 360.0f); +} + +// Conversion from HSV to RGB color space +// The input HSV values are in the ranges h = [0, 360], and s, v = [0, 1] +// The output RGB values are in the range [0, 1] +static void HSVtoRGB(float h, float s, float v, float& r, float& g, float& b) +{ + assert(0.0f <= s && s <= 1.0f); + assert(0.0f <= v && v <= 1.0f); + assert(0.0f <= h && h <= 360.0f); + + const float chroma = v * s; + const float h_prime = std::fmod(h / 60.0f, 6.0f); + const float x = chroma * (1.0f - std::abs(std::fmod(h_prime, 2.0f) - 1.0f)); + const float m = v - chroma; + + if (0.0f <= h_prime && h_prime < 1.0f) { + r = chroma; + g = x; + b = 0.0f; + } + else if (1.0f <= h_prime && h_prime < 2.0f) { + r = x; + g = chroma; + b = 0.0f; + } + else if (2.0f <= h_prime && h_prime < 3.0f) { + r = 0.0f; + g = chroma; + b = x; + } + else if (3.0f <= h_prime && h_prime < 4.0f) { + r = 0.0f; + g = x; + b = chroma; + } + else if (4.0f <= h_prime && h_prime < 5.0f) { + r = x; + g = 0.0f; + b = chroma; + } + else if (5.0f <= h_prime && h_prime < 6.0f) { + r = chroma; + g = 0.0f; + b = x; + } + else { + r = 0.0f; + g = 0.0f; + b = 0.0f; + } + + r += m; + g += m; + b += m; + + assert(0.0f <= r && r <= 1.0f); + assert(0.0f <= g && g <= 1.0f); + assert(0.0f <= b && b <= 1.0f); +} + +class Randomizer +{ + std::random_device m_rd; + +public: + float random_float(float min, float max) { + std::mt19937 rand_generator(m_rd()); + std::uniform_real_distribution distrib(min, max); + return distrib(rand_generator); + } +}; + +ColorRGB::ColorRGB(float r, float g, float b) +: m_data({ std::clamp(r, 0.0f, 1.0f), std::clamp(g, 0.0f, 1.0f), std::clamp(b, 0.0f, 1.0f) }) +{ +} + +ColorRGB::ColorRGB(unsigned char r, unsigned char g, unsigned char b) +: m_data({ std::clamp(r * INV_255, 0.0f, 1.0f), std::clamp(g * INV_255, 0.0f, 1.0f), std::clamp(b * INV_255, 0.0f, 1.0f) }) +{ +} + +bool ColorRGB::operator < (const ColorRGB& other) const +{ + for (size_t i = 0; i < 3; ++i) { + if (m_data[i] < other.m_data[i]) + return true; + } + + return false; +} + +bool ColorRGB::operator > (const ColorRGB& other) const +{ + for (size_t i = 0; i < 3; ++i) { + if (m_data[i] > other.m_data[i]) + return true; + } + + return false; +} + +ColorRGB ColorRGB::operator + (const ColorRGB& other) const +{ + ColorRGB ret; + for (size_t i = 0; i < 3; ++i) { + ret.m_data[i] = std::clamp(m_data[i] + other.m_data[i], 0.0f, 1.0f); + } + return ret; +} + +ColorRGB ColorRGB::operator * (float value) const +{ + assert(value >= 0.0f); + ColorRGB ret; + for (size_t i = 0; i < 3; ++i) { + ret.m_data[i] = std::clamp(value * m_data[i], 0.0f, 1.0f); + } + return ret; +} + +ColorRGBA::ColorRGBA(float r, float g, float b, float a) +: m_data({ std::clamp(r, 0.0f, 1.0f), std::clamp(g, 0.0f, 1.0f), std::clamp(b, 0.0f, 1.0f), std::clamp(a, 0.0f, 1.0f) }) +{ +} + +ColorRGBA::ColorRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +: m_data({ std::clamp(r * INV_255, 0.0f, 1.0f), std::clamp(g * INV_255, 0.0f, 1.0f), std::clamp(b * INV_255, 0.0f, 1.0f), std::clamp(a * INV_255, 0.0f, 1.0f) }) +{ +} + +bool ColorRGBA::operator < (const ColorRGBA& other) const +{ + for (size_t i = 0; i < 3; ++i) { + if (m_data[i] < other.m_data[i]) + return true; + } + + return false; +} + +bool ColorRGBA::operator > (const ColorRGBA& other) const +{ + for (size_t i = 0; i < 3; ++i) { + if (m_data[i] > other.m_data[i]) + return true; + } + + return false; +} + +ColorRGBA ColorRGBA::operator + (const ColorRGBA& other) const +{ + ColorRGBA ret; + for (size_t i = 0; i < 3; ++i) { + ret.m_data[i] = std::clamp(m_data[i] + other.m_data[i], 0.0f, 1.0f); + } + return ret; +} + +ColorRGBA ColorRGBA::operator * (float value) const +{ + assert(value >= 0.0f); + ColorRGBA ret; + for (size_t i = 0; i < 3; ++i) { + ret.m_data[i] = std::clamp(value * m_data[i], 0.0f, 1.0f); + } + ret.m_data[3] = this->m_data[3]; + return ret; +} + +ColorRGB operator * (float value, const ColorRGB& other) { return other * value; } +ColorRGBA operator * (float value, const ColorRGBA& other) { return other * value; } + +ColorRGB lerp(const ColorRGB& a, const ColorRGB& b, float t) +{ + assert(0.0f <= t && t <= 1.0f); + return (1.0f - t) * a + t * b; +} + +ColorRGBA lerp(const ColorRGBA& a, const ColorRGBA& b, float t) +{ + assert(0.0f <= t && t <= 1.0f); + return (1.0f - t) * a + t * b; +} + +ColorRGB complementary(const ColorRGB& color) +{ + return { 1.0f - color.r(), 1.0f - color.g(), 1.0f - color.b() }; +} + +ColorRGBA complementary(const ColorRGBA& color) +{ + return { 1.0f - color.r(), 1.0f - color.g(), 1.0f - color.b(), color.a() }; +} + +ColorRGB saturate(const ColorRGB& color, float factor) +{ + float h, s, v; + RGBtoHSV(color.r(), color.g(), color.b(), h, s, v); + s = std::clamp(s * factor, 0.0f, 1.0f); + float r, g, b; + HSVtoRGB(h, s, v, r, g, b); + return { r, g, b }; +} + +ColorRGBA saturate(const ColorRGBA& color, float factor) +{ + return to_rgba(saturate(to_rgb(color), factor), color.a()); +} + +ColorRGB opposite(const ColorRGB& color) +{ + float h, s, v; + RGBtoHSV(color.r(), color.g(), color.b(), h, s, v); + + h += 65.0f; // 65 instead 60 to avoid circle values + if (h > 360.0f) + h -= 360.0f; + + Randomizer rnd; + s = rnd.random_float(0.65f, 1.0f); + v = rnd.random_float(0.65f, 1.0f); + + float r, g, b; + HSVtoRGB(h, s, v, r, g, b); + return { r, g, b }; +} + +ColorRGB opposite(const ColorRGB& a, const ColorRGB& b) +{ + float ha, sa, va; + RGBtoHSV(a.r(), a.g(), a.b(), ha, sa, va); + float hb, sb, vb; + RGBtoHSV(b.r(), b.g(), b.b(), hb, sb, vb); + + float delta_h = std::abs(ha - hb); + float start_h = (delta_h > 180.0f) ? std::min(ha, hb) : std::max(ha, hb); + + start_h += 5.0f; // to avoid circle change of colors for 120 deg + if (delta_h < 180.0f) + delta_h = 360.0f - delta_h; + + Randomizer rnd; + float out_h = start_h + 0.5f * delta_h; + if (out_h > 360.0f) + out_h -= 360.0f; + float out_s = rnd.random_float(0.65f, 1.0f); + float out_v = rnd.random_float(0.65f, 1.0f); + + float out_r, out_g, out_b; + HSVtoRGB(out_h, out_s, out_v, out_r, out_g, out_b); + return { out_r, out_g, out_b }; +} + +bool can_decode_color(const std::string &color) +{ + return (color.size() == 7 && color.front() == '#') || (color.size() == 9 && color.front() == '#'); +} + +bool decode_color(const std::string& color_in, ColorRGB& color_out) +{ + ColorRGBA rgba; + if (!decode_color(color_in, rgba)) + return false; + + color_out = to_rgb(rgba); + return true; +} + +bool decode_color(const std::string& color_in, ColorRGBA& color_out) +{ + auto hex_digit_to_int = [](const char c) { + return + (c >= '0' && c <= '9') ? int(c - '0') : + (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 : + (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; + }; + + color_out = ColorRGBA::BLACK(); + if (can_decode_color(color_in)) { + const char *c = color_in.data() + 1; + if (color_in.size() == 7) { + for (unsigned int i = 0; i < 3; ++i) { + const int digit1 = hex_digit_to_int(*c++); + const int digit2 = hex_digit_to_int(*c++); + if (digit1 != -1 && digit2 != -1) + color_out.set(i, float(digit1 * 16 + digit2) * INV_255); + } + } else { + for (unsigned int i = 0; i < 4; ++i) { + const int digit1 = hex_digit_to_int(*c++); + const int digit2 = hex_digit_to_int(*c++); + if (digit1 != -1 && digit2 != -1) + color_out.set(i, float(digit1 * 16 + digit2) * INV_255); + } + } + } else + return false; + + assert(0.0f <= color_out.r() && color_out.r() <= 1.0f); + assert(0.0f <= color_out.g() && color_out.g() <= 1.0f); + assert(0.0f <= color_out.b() && color_out.b() <= 1.0f); + assert(0.0f <= color_out.a() && color_out.a() <= 1.0f); + return true; +} + +bool decode_colors(const std::vector& colors_in, std::vector& colors_out) +{ + colors_out = std::vector(colors_in.size(), ColorRGB::BLACK()); + for (size_t i = 0; i < colors_in.size(); ++i) { + if (!decode_color(colors_in[i], colors_out[i])) + return false; + } + return true; +} + +bool decode_colors(const std::vector& colors_in, std::vector& colors_out) +{ + colors_out = std::vector(colors_in.size(), ColorRGBA::BLACK()); + for (size_t i = 0; i < colors_in.size(); ++i) { + if (!decode_color(colors_in[i], colors_out[i])) + return false; + } + return true; +} + +std::string encode_color(const ColorRGB& color) +{ + char buffer[64]; + ::sprintf(buffer, "#%02X%02X%02X", color.r_uchar(), color.g_uchar(), color.b_uchar()); + return std::string(buffer); +} + +std::string encode_color(const ColorRGBA& color) { return encode_color(to_rgb(color)); } + +ColorRGB to_rgb(const ColorRGBA& other_rgba) { return { other_rgba.r(), other_rgba.g(), other_rgba.b() }; } +ColorRGBA to_rgba(const ColorRGB& other_rgb) { return { other_rgb.r(), other_rgb.g(), other_rgb.b(), 1.0f }; } +ColorRGBA to_rgba(const ColorRGB& other_rgb, float alpha) { return { other_rgb.r(), other_rgb.g(), other_rgb.b(), alpha }; } + +ColorRGBA picking_decode(unsigned int id) +{ + return { + float((id >> 0) & 0xff) * INV_255, // red + float((id >> 8) & 0xff) * INV_255, // green + float((id >> 16) & 0xff) * INV_255, // blue + float(picking_checksum_alpha_channel(id & 0xff, (id >> 8) & 0xff, (id >> 16) & 0xff)) * INV_255 // checksum for validating against unwanted alpha blending and multi sampling + }; +} + +unsigned int picking_encode(unsigned char r, unsigned char g, unsigned char b) { return r + (g << 8) + (b << 16); } + +unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue) +{ + // 8 bit hash for the color + unsigned char b = ((((37 * red) + green) & 0x0ff) * 37 + blue) & 0x0ff; + // Increase enthropy by a bit reversal + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + // Flip every second bit to increase the enthropy even more. + b ^= 0x55; + return b; +} + +} // namespace Slic3r + diff --git a/src/libslic3r/Color.hpp b/src/libslic3r/Color.hpp new file mode 100644 index 0000000000..fce0c67e00 --- /dev/null +++ b/src/libslic3r/Color.hpp @@ -0,0 +1,170 @@ +#ifndef slic3r_Color_hpp_ +#define slic3r_Color_hpp_ + +#include +#include + +namespace Slic3r { + +class ColorRGB +{ + std::array m_data{1.0f, 1.0f, 1.0f}; + +public: + ColorRGB() = default; + ColorRGB(float r, float g, float b); + ColorRGB(unsigned char r, unsigned char g, unsigned char b); + ColorRGB(const ColorRGB& other) = default; + + ColorRGB& operator = (const ColorRGB& other) { m_data = other.m_data; return *this; } + + bool operator == (const ColorRGB& other) const { return m_data == other.m_data; } + bool operator != (const ColorRGB& other) const { return !operator==(other); } + bool operator < (const ColorRGB& other) const; + bool operator > (const ColorRGB& other) const; + + ColorRGB operator + (const ColorRGB& other) const; + ColorRGB operator * (float value) const; + + const float* const data() const { return m_data.data(); } + + float r() const { return m_data[0]; } + float g() const { return m_data[1]; } + float b() const { return m_data[2]; } + + void r(float r) { m_data[0] = std::clamp(r, 0.0f, 1.0f); } + void g(float g) { m_data[1] = std::clamp(g, 0.0f, 1.0f); } + void b(float b) { m_data[2] = std::clamp(b, 0.0f, 1.0f); } + + void set(unsigned int comp, float value) { + assert(0 <= comp && comp <= 2); + m_data[comp] = std::clamp(value, 0.0f, 1.0f); + } + + unsigned char r_uchar() const { return static_cast(m_data[0] * 255.0f); } + unsigned char g_uchar() const { return static_cast(m_data[1] * 255.0f); } + unsigned char b_uchar() const { return static_cast(m_data[2] * 255.0f); } + + static const ColorRGB BLACK() { return { 0.0f, 0.0f, 0.0f }; } + static const ColorRGB BLUE() { return { 0.0f, 0.0f, 1.0f }; } + static const ColorRGB BLUEISH() { return { 0.5f, 0.5f, 1.0f }; } + static const ColorRGB DARK_GRAY() { return { 0.25f, 0.25f, 0.25f }; } + static const ColorRGB DARK_YELLOW() { return { 0.5f, 0.5f, 0.0f }; } + static const ColorRGB GRAY() { return { 0.5f, 0.5f, 0.5f }; } + static const ColorRGB GREEN() { return { 0.0f, 1.0f, 0.0f }; } + static const ColorRGB GREENISH() { return { 0.5f, 1.0f, 0.5f }; } + static const ColorRGB LIGHT_GRAY() { return { 0.75f, 0.75f, 0.75f }; } + static const ColorRGB ORANGE() { return { 0.92f, 0.50f, 0.26f }; } + static const ColorRGB RED() { return { 1.0f, 0.0f, 0.0f }; } + static const ColorRGB REDISH() { return { 1.0f, 0.5f, 0.5f }; } + static const ColorRGB YELLOW() { return { 1.0f, 1.0f, 0.0f }; } + static const ColorRGB WHITE() { return { 1.0f, 1.0f, 1.0f }; } + + static const ColorRGB X() { return { 0.75f, 0.0f, 0.0f }; } + static const ColorRGB Y() { return { 0.0f, 0.75f, 0.0f }; } + static const ColorRGB Z() { return { 0.0f, 0.0f, 0.75f }; } +}; + +class ColorRGBA +{ + std::array m_data{ 1.0f, 1.0f, 1.0f, 1.0f }; + +public: + ColorRGBA() = default; + ColorRGBA(float r, float g, float b, float a); + ColorRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a); + ColorRGBA(const ColorRGBA& other) = default; + + ColorRGBA& operator = (const ColorRGBA& other) { m_data = other.m_data; return *this; } + + bool operator == (const ColorRGBA& other) const { return m_data == other.m_data; } + bool operator != (const ColorRGBA& other) const { return !operator==(other); } + bool operator < (const ColorRGBA& other) const; + bool operator > (const ColorRGBA& other) const; + + ColorRGBA operator + (const ColorRGBA& other) const; + ColorRGBA operator * (float value) const; + + const float* const data() const { return m_data.data(); } + + float r() const { return m_data[0]; } + float g() const { return m_data[1]; } + float b() const { return m_data[2]; } + float a() const { return m_data[3]; } + + void r(float r) { m_data[0] = std::clamp(r, 0.0f, 1.0f); } + void g(float g) { m_data[1] = std::clamp(g, 0.0f, 1.0f); } + void b(float b) { m_data[2] = std::clamp(b, 0.0f, 1.0f); } + void a(float a) { m_data[3] = std::clamp(a, 0.0f, 1.0f); } + + void set(unsigned int comp, float value) { + assert(0 <= comp && comp <= 3); + m_data[comp] = std::clamp(value, 0.0f, 1.0f); + } + + unsigned char r_uchar() const { return static_cast(m_data[0] * 255.0f); } + unsigned char g_uchar() const { return static_cast(m_data[1] * 255.0f); } + unsigned char b_uchar() const { return static_cast(m_data[2] * 255.0f); } + unsigned char a_uchar() const { return static_cast(m_data[3] * 255.0f); } + + bool is_transparent() const { return m_data[3] < 1.0f; } + + static const ColorRGBA BLACK() { return { 0.0f, 0.0f, 0.0f, 1.0f }; } + static const ColorRGBA BLUE() { return { 0.0f, 0.0f, 1.0f, 1.0f }; } + static const ColorRGBA BLUEISH() { return { 0.5f, 0.5f, 1.0f, 1.0f }; } + static const ColorRGBA DARK_GRAY() { return { 0.25f, 0.25f, 0.25f, 1.0f }; } + static const ColorRGBA DARK_YELLOW() { return { 0.5f, 0.5f, 0.0f, 1.0f }; } + static const ColorRGBA GRAY() { return { 0.5f, 0.5f, 0.5f, 1.0f }; } + static const ColorRGBA GREEN() { return { 0.0f, 1.0f, 0.0f, 1.0f }; } + static const ColorRGBA GREENISH() { return { 0.5f, 1.0f, 0.5f, 1.0f }; } + static const ColorRGBA LIGHT_GRAY() { return { 0.75f, 0.75f, 0.75f, 1.0f }; } + static const ColorRGBA ORANGE() { return { 0.923f, 0.504f, 0.264f, 1.0f }; } + static const ColorRGBA RED() { return { 1.0f, 0.0f, 0.0f, 1.0f }; } + static const ColorRGBA REDISH() { return { 1.0f, 0.5f, 0.5f, 1.0f }; } + static const ColorRGBA YELLOW() { return { 1.0f, 1.0f, 0.0f, 1.0f }; } + static const ColorRGBA WHITE() { return { 1.0f, 1.0f, 1.0f, 1.0f }; } + + static const ColorRGBA X() { return { 0.75f, 0.0f, 0.0f, 1.0f }; } + static const ColorRGBA Y() { return { 0.0f, 0.75f, 0.0f, 1.0f }; } + static const ColorRGBA Z() { return { 0.0f, 0.0f, 0.75f, 1.0f }; } +}; + +extern ColorRGB operator * (float value, const ColorRGB& other); +extern ColorRGBA operator * (float value, const ColorRGBA& other); + +extern ColorRGB lerp(const ColorRGB& a, const ColorRGB& b, float t); +extern ColorRGBA lerp(const ColorRGBA& a, const ColorRGBA& b, float t); + +extern ColorRGB complementary(const ColorRGB& color); +extern ColorRGBA complementary(const ColorRGBA& color); + +extern ColorRGB saturate(const ColorRGB& color, float factor); +extern ColorRGBA saturate(const ColorRGBA& color, float factor); + +extern ColorRGB opposite(const ColorRGB& color); +extern ColorRGB opposite(const ColorRGB& a, const ColorRGB& b); + +extern bool can_decode_color(const std::string& color); + +extern bool decode_color(const std::string& color_in, ColorRGB& color_out); +extern bool decode_color(const std::string& color_in, ColorRGBA& color_out); + +extern bool decode_colors(const std::vector& colors_in, std::vector& colors_out); +extern bool decode_colors(const std::vector& colors_in, std::vector& colors_out); + +extern std::string encode_color(const ColorRGB& color); +extern std::string encode_color(const ColorRGBA& color); + +extern ColorRGB to_rgb(const ColorRGBA& other_rgba); +extern ColorRGBA to_rgba(const ColorRGB& other_rgb); +extern ColorRGBA to_rgba(const ColorRGB& other_rgb, float alpha); + +extern ColorRGBA picking_decode(unsigned int id); +extern unsigned int picking_encode(unsigned char r, unsigned char g, unsigned char b); +// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components +// were not interpolated by alpha blending or multi sampling. +extern unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue); + +} // namespace Slic3r + +#endif /* slic3r_Color_hpp_ */ diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index a7b6e050eb..0c29cdc195 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -26,9 +26,11 @@ #endif static const float GROUND_Z = -0.04f; -static const std::array DEFAULT_MODEL_COLOR = { 0.3255f, 0.337f, 0.337f, 1.0f }; -static const std::array DEFAULT_MODEL_COLOR_DARK = { 0.255f, 0.255f, 0.283f, 1.0f }; -static const std::array PICKING_MODEL_COLOR = { 0.0f, 0.0f, 0.0f, 1.0f }; +static const Slic3r::ColorRGBA DEFAULT_MODEL_COLOR = { 0.3255f, 0.337f, 0.337f, 1.0f }; +static const Slic3r::ColorRGBA DEFAULT_MODEL_COLOR_DARK = { 0.255f, 0.255f, 0.283f, 1.0f }; +static const Slic3r::ColorRGBA PICKING_MODEL_COLOR = Slic3r::ColorRGBA::BLACK(); +static const Slic3r::ColorRGBA DEFAULT_SOLID_GRID_COLOR = { 0.9f, 0.9f, 0.9f, 1.0f }; +static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0.9f, 0.6f }; namespace Slic3r { namespace GUI { @@ -137,22 +139,22 @@ const float Bed3D::Axes::DefaultStemLength = 25.0f; const float Bed3D::Axes::DefaultTipRadius = 2.5f * Bed3D::Axes::DefaultStemRadius; const float Bed3D::Axes::DefaultTipLength = 5.0f; -std::array Bed3D::AXIS_X_COLOR = decode_color_to_float_array("#FF0000"); -std::array Bed3D::AXIS_Y_COLOR = decode_color_to_float_array("#00FF00"); -std::array Bed3D::AXIS_Z_COLOR = decode_color_to_float_array("#0000FF"); +ColorRGBA Bed3D::AXIS_X_COLOR = ColorRGBA::X(); +ColorRGBA Bed3D::AXIS_Y_COLOR = ColorRGBA::Y(); +ColorRGBA Bed3D::AXIS_Z_COLOR = ColorRGBA::Z(); void Bed3D::update_render_colors() { - Bed3D::AXIS_X_COLOR = GLColor(RenderColor::colors[RenderCol_Axis_X]); - Bed3D::AXIS_Y_COLOR = GLColor(RenderColor::colors[RenderCol_Axis_Y]); - Bed3D::AXIS_Z_COLOR = GLColor(RenderColor::colors[RenderCol_Axis_Z]); + Bed3D::AXIS_X_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Axis_X]); + Bed3D::AXIS_Y_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Axis_Y]); + Bed3D::AXIS_Z_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Axis_Z]); } void Bed3D::load_render_colors() { - RenderColor::colors[RenderCol_Axis_X] = IMColor(Bed3D::AXIS_X_COLOR); - RenderColor::colors[RenderCol_Axis_Y] = IMColor(Bed3D::AXIS_Y_COLOR); - RenderColor::colors[RenderCol_Axis_Z] = IMColor(Bed3D::AXIS_Z_COLOR); + RenderColor::colors[RenderCol_Axis_X] = ImGuiWrapper::to_ImVec4(Bed3D::AXIS_X_COLOR); + RenderColor::colors[RenderCol_Axis_Y] = ImGuiWrapper::to_ImVec4(Bed3D::AXIS_Y_COLOR); + RenderColor::colors[RenderCol_Axis_Z] = ImGuiWrapper::to_ImVec4(Bed3D::AXIS_Z_COLOR); } void Bed3D::Axes::render() const @@ -724,10 +726,7 @@ void Bed3D::render_default(bool bottom) const /*if (!picking) { // draw grid glsafe(::glLineWidth(1.5f * m_scale_factor)); - if (has_model && !bottom) - glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 1.0f)); - else - glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f)); + glsafe(::glColor4fv(has_model && !bottom ? DEFAULT_SOLID_GRID_COLOR.data() : DEFAULT_TRANSPARENT_GRID_COLOR.data())); glsafe(::glVertexPointer(3, GL_FLOAT, default_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data())); glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count())); }*/ diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index f6daadddf1..d1af27f425 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -42,9 +42,9 @@ public: class Bed3D { public: - static std::array AXIS_X_COLOR; - static std::array AXIS_Y_COLOR; - static std::array AXIS_Z_COLOR; + static ColorRGBA AXIS_X_COLOR; + static ColorRGBA AXIS_Y_COLOR; + static ColorRGBA AXIS_Z_COLOR; static void update_render_colors(); static void load_render_colors(); diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index be821f64fe..f94bba6c4f 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -70,36 +70,27 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char #endif // HAS_GLSAFE // BBS -std::vector> get_extruders_colors() +std::vector get_extruders_colors() { - unsigned char rgba_color[4] = {}; - std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); - std::vector> colors_out(colors.size()); + Slic3r::ColorRGBA rgba_color; + std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); + std::vector colors_out(colors.size()); for (const std::string &color : colors) { - Slic3r::GUI::BitmapCache::parse_color4(color, rgba_color); + Slic3r::decode_color(color, rgba_color); size_t color_idx = &color - &colors.front(); - colors_out[color_idx] = { - float(rgba_color[0]) / 255.f, - float(rgba_color[1]) / 255.f, - float(rgba_color[2]) / 255.f, - float(rgba_color[3]) / 255.f, - }; + colors_out[color_idx] = rgba_color; } return colors_out; } float FullyTransparentMaterialThreshold = 0.1f; float FullTransparentModdifiedToFixAlpha = 0.3f; -std::array adjust_color_for_rendering(const std::array &colors) + +Slic3r::ColorRGBA adjust_color_for_rendering(const Slic3r::ColorRGBA &colors) { - if (colors[3] < FullyTransparentMaterialThreshold) { // completely transparent - std::array new_color; - new_color[0] = 1; - new_color[1] = 1; - new_color[2] = 1; - new_color[3] = FullTransparentModdifiedToFixAlpha; - return new_color; - } + if (colors.a() < FullyTransparentMaterialThreshold) { // completely transparent + return {1, 1, 1, FullTransparentModdifiedToFixAlpha}; + } return colors; } @@ -383,21 +374,21 @@ void GLVolume::SinkingContours::update() m_model.reset(); } -std::array GLVolume::DISABLED_COLOR = { 0.25f, 0.25f, 0.25f, 1.0f }; -std::array GLVolume::SLA_SUPPORT_COLOR = { 0.75f, 0.75f, 0.75f, 1.0f }; -std::array GLVolume::SLA_PAD_COLOR = { 0.0f, 0.2f, 0.0f, 1.0f }; +ColorRGBA GLVolume::DISABLED_COLOR = ColorRGBA::DARK_GRAY(); +ColorRGBA GLVolume::SLA_SUPPORT_COLOR = ColorRGBA::LIGHT_GRAY(); +ColorRGBA GLVolume::SLA_PAD_COLOR = { 0.0f, 0.2f, 0.0f, 1.0f }; // BBS -std::array GLVolume::NEUTRAL_COLOR = { 0.8f, 0.8f, 0.8f, 1.0f }; -std::array GLVolume::UNPRINTABLE_COLOR = { 0.0f, 0.0f, 0.0f, 0.5f }; +ColorRGBA GLVolume::NEUTRAL_COLOR = { 0.8f, 0.8f, 0.8f, 1.0f }; +ColorRGBA GLVolume::UNPRINTABLE_COLOR = { 0.0f, 0.0f, 0.0f, 0.5f }; -std::array GLVolume::MODEL_MIDIFIER_COL = {1.0f, 1.0f, 0.0f, 0.6f}; -std::array GLVolume::MODEL_NEGTIVE_COL = {0.3f, 0.3f, 0.3f, 0.4f}; -std::array GLVolume::SUPPORT_ENFORCER_COL = {0.3f, 0.3f, 1.0f, 0.4f}; -std::array GLVolume::SUPPORT_BLOCKER_COL = {1.0f, 0.3f, 0.3f, 0.4f}; +ColorRGBA GLVolume::MODEL_MIDIFIER_COL = {1.0f, 1.0f, 0.0f, 0.6f}; +ColorRGBA GLVolume::MODEL_NEGTIVE_COL = {0.3f, 0.3f, 0.3f, 0.4f}; +ColorRGBA GLVolume::SUPPORT_ENFORCER_COL = {0.3f, 0.3f, 1.0f, 0.4f}; +ColorRGBA GLVolume::SUPPORT_BLOCKER_COL = {1.0f, 0.3f, 0.3f, 0.4f}; -std::array GLVolume::MODEL_HIDDEN_COL = {0.f, 0.f, 0.f, 0.3f}; +ColorRGBA GLVolume::MODEL_HIDDEN_COL = {0.f, 0.f, 0.f, 0.3f}; -std::array, 5> GLVolume::MODEL_COLOR = { { +std::array GLVolume::MODEL_COLOR = { { { 1.0f, 1.0f, 0.0f, 1.f }, { 1.0f, 0.5f, 0.5f, 1.f }, { 0.5f, 1.0f, 0.5f, 1.f }, @@ -407,25 +398,25 @@ std::array, 5> GLVolume::MODEL_COLOR = { { void GLVolume::update_render_colors() { - GLVolume::DISABLED_COLOR = GLColor(RenderColor::colors[RenderCol_Model_Disable]); - GLVolume::NEUTRAL_COLOR = GLColor(RenderColor::colors[RenderCol_Model_Neutral]); - GLVolume::MODEL_COLOR[0] = GLColor(RenderColor::colors[RenderCol_Modifier]); - GLVolume::MODEL_COLOR[1] = GLColor(RenderColor::colors[RenderCol_Negtive_Volume]); - GLVolume::MODEL_COLOR[2] = GLColor(RenderColor::colors[RenderCol_Support_Enforcer]); - GLVolume::MODEL_COLOR[3] = GLColor(RenderColor::colors[RenderCol_Support_Blocker]); - GLVolume::UNPRINTABLE_COLOR = GLColor(RenderColor::colors[RenderCol_Model_Unprintable]); + GLVolume::DISABLED_COLOR = GUI::ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Model_Disable]); + GLVolume::NEUTRAL_COLOR = GUI::ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Model_Neutral]); + GLVolume::MODEL_COLOR[0] = GUI::ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Modifier]); + GLVolume::MODEL_COLOR[1] = GUI::ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Negtive_Volume]); + GLVolume::MODEL_COLOR[2] = GUI::ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Support_Enforcer]); + GLVolume::MODEL_COLOR[3] = GUI::ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Support_Blocker]); + GLVolume::UNPRINTABLE_COLOR = GUI::ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Model_Unprintable]); } void GLVolume::load_render_colors() { - RenderColor::colors[RenderCol_Model_Disable] = IMColor(GLVolume::DISABLED_COLOR); - RenderColor::colors[RenderCol_Model_Neutral] = IMColor(GLVolume::NEUTRAL_COLOR); - RenderColor::colors[RenderCol_Modifier] = IMColor(GLVolume::MODEL_COLOR[0]); - RenderColor::colors[RenderCol_Negtive_Volume] = IMColor(GLVolume::MODEL_COLOR[1]); - RenderColor::colors[RenderCol_Support_Enforcer] = IMColor(GLVolume::MODEL_COLOR[2]); - RenderColor::colors[RenderCol_Support_Blocker] = IMColor(GLVolume::MODEL_COLOR[3]); - RenderColor::colors[RenderCol_Model_Unprintable]= IMColor(GLVolume::UNPRINTABLE_COLOR); + RenderColor::colors[RenderCol_Model_Disable] = GUI::ImGuiWrapper::to_ImVec4(GLVolume::DISABLED_COLOR); + RenderColor::colors[RenderCol_Model_Neutral] = GUI::ImGuiWrapper::to_ImVec4(GLVolume::NEUTRAL_COLOR); + RenderColor::colors[RenderCol_Modifier] = GUI::ImGuiWrapper::to_ImVec4(GLVolume::MODEL_COLOR[0]); + RenderColor::colors[RenderCol_Negtive_Volume] = GUI::ImGuiWrapper::to_ImVec4(GLVolume::MODEL_COLOR[1]); + RenderColor::colors[RenderCol_Support_Enforcer] = GUI::ImGuiWrapper::to_ImVec4(GLVolume::MODEL_COLOR[2]); + RenderColor::colors[RenderCol_Support_Blocker] = GUI::ImGuiWrapper::to_ImVec4(GLVolume::MODEL_COLOR[3]); + RenderColor::colors[RenderCol_Model_Unprintable] = GUI::ImGuiWrapper::to_ImVec4(GLVolume::UNPRINTABLE_COLOR); } GLVolume::GLVolume(float r, float g, float b, float a) @@ -459,25 +450,11 @@ GLVolume::GLVolume(float r, float g, float b, float a) mmuseg_ts = 0; } -void GLVolume::set_color(const std::array& rgba) -{ - color = rgba; -} // BBS float GLVolume::explosion_ratio = 1.0; float GLVolume::last_explosion_ratio = 1.0; -void GLVolume::set_render_color(float r, float g, float b, float a) -{ - render_color = { r, g, b, a }; -} - -void GLVolume::set_render_color(const std::array& rgba) -{ - render_color = rgba; -} - void GLVolume::set_render_color() { bool outside = is_outside || is_below_printbed(); @@ -514,57 +491,45 @@ void GLVolume::set_render_color() #endif else { //to make black not too hard too see - std::array new_color = adjust_color_for_rendering(color); + ColorRGBA new_color = adjust_color_for_rendering(color); set_render_color(new_color); } } if (force_transparent) { - if (color[3] < FullyTransparentMaterialThreshold) { - render_color[3] = FullTransparentModdifiedToFixAlpha; + if (color.a() < FullyTransparentMaterialThreshold) { + render_color.a(FullTransparentModdifiedToFixAlpha); } else { - render_color[3] = color[3]; + render_color.a(color.a()); } } //BBS set unprintable color if (!printable) { - render_color[0] = UNPRINTABLE_COLOR[0]; - render_color[1] = UNPRINTABLE_COLOR[1]; - render_color[2] = UNPRINTABLE_COLOR[2]; - render_color[3] = UNPRINTABLE_COLOR[3]; + render_color = UNPRINTABLE_COLOR; } //BBS set invisible color if (!visible) { - render_color[0] = MODEL_HIDDEN_COL[0]; - render_color[1] = MODEL_HIDDEN_COL[1]; - render_color[2] = MODEL_HIDDEN_COL[2]; - render_color[3] = MODEL_HIDDEN_COL[3]; + render_color = MODEL_HIDDEN_COL; } } -std::array color_from_model_volume(const ModelVolume& model_volume) +ColorRGBA color_from_model_volume(const ModelVolume& model_volume) { - std::array color = {0.0f, 0.0f, 0.0f, 1.0f}; - if (model_volume.is_negative_volume()) { + ColorRGBA color; + if (model_volume.is_negative_volume()) return GLVolume::MODEL_NEGTIVE_COL; - } - else if (model_volume.is_modifier()) { + else if (model_volume.is_modifier()) #if ENABLE_MODIFIERS_ALWAYS_TRANSPARENT return GLVolume::MODEL_MIDIFIER_COL; #else - color[0] = 0.2f; - color[1] = 1.0f; - color[2] = 0.2f; + color = { 0.2f, 1.0f, 0.2f, 1.0f }; #endif // ENABLE_MODIFIERS_ALWAYS_TRANSPARENT - } - else if (model_volume.is_support_blocker()) { + else if (model_volume.is_support_blocker()) return GLVolume::SUPPORT_BLOCKER_COL; - } - else if (model_volume.is_support_enforcer()) { + else if (model_volume.is_support_enforcer()) return GLVolume::SUPPORT_ENFORCER_COL; - } return color; } @@ -713,12 +678,12 @@ void GLVolume::render(bool with_outline) const if (color_volume) { GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); - std::vector> colors = get_extruders_colors(); + std::vector colors = get_extruders_colors(); //when force_transparent, we need to keep the alpha - if (force_native_color && (render_color[3] < 1.0)) { - for (int index = 0; index < colors.size(); index ++) - colors[index][3] = render_color[3]; + if (force_native_color && (render_color.is_transparent())) { + for (int index = 0; index < colors.size(); index++) + colors[index].a(render_color.a()); } glsafe(::glMultMatrixd(world_matrix().data())); for (int idx = 0; idx < mmuseg_ivas.size(); idx++) { @@ -733,20 +698,20 @@ void GLVolume::render(bool with_outline) const int extruder_id = mv->extruder_id(); //shader->set_uniform("uniform_color", colors[extruder_id - 1]); //to make black not too hard too see - std::array new_color = adjust_color_for_rendering(colors[extruder_id - 1]); + ColorRGBA new_color = adjust_color_for_rendering(colors[extruder_id - 1]); shader->set_uniform("uniform_color", new_color); } else { if (idx <= colors.size()) { //shader->set_uniform("uniform_color", colors[idx - 1]); //to make black not too hard too see - std::array new_color = adjust_color_for_rendering(colors[idx - 1]); + ColorRGBA new_color = adjust_color_for_rendering(colors[idx - 1]); shader->set_uniform("uniform_color", new_color); } else { //shader->set_uniform("uniform_color", colors[0]); //to make black not too hard too see - std::array new_color = adjust_color_for_rendering(colors[0]); + ColorRGBA new_color = adjust_color_for_rendering(colors[0]); shader->set_uniform("uniform_color", new_color); } } @@ -794,7 +759,7 @@ void GLVolume::render(bool with_outline) const shader->stop_using(); outline_shader->start_using(); //float scale_ratio = 1.02f; - std::array outline_color = { 0.0f, 1.0f, 0.0f, 1.0f }; + ColorRGBA outline_color = { 0.0f, 1.0f, 0.0f, 1.0f }; outline_shader->set_uniform("uniform_color", outline_color);*/ #if 0 //dump stencil buffer @@ -868,7 +833,7 @@ void GLVolume::render(bool with_outline) const glStencilFunc(GL_NOTEQUAL, 0xff, 0xFF); glStencilMask(0x00); float scale = 1.02f; - std::array body_color = { 1.0f, 1.0f, 1.0f, 1.0f }; //red + ColorRGBA body_color = { 1.0f, 1.0f, 1.0f, 1.0f }; //red shader->set_uniform("uniform_color", body_color); shader->set_uniform("is_outline", true); @@ -900,7 +865,7 @@ void GLVolume::render(bool with_outline) const } //BBS add render for simple case -void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector>& extruder_colors) const +void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector& extruder_colors) const { if (this->is_left_handed()) glFrontFace(GL_CW); @@ -947,20 +912,20 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj if (idx == 0) { int extruder_id = model_volume->extruder_id(); //to make black not too hard too see - std::array new_color = adjust_color_for_rendering(extruder_colors[extruder_id - 1]); + ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[extruder_id - 1]); shader->set_uniform("uniform_color", new_color); } else { if (idx <= extruder_colors.size()) { //shader->set_uniform("uniform_color", extruder_colors[idx - 1]); //to make black not too hard too see - std::array new_color = adjust_color_for_rendering(extruder_colors[idx - 1]); + ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[idx - 1]); shader->set_uniform("uniform_color", new_color); } else { //shader->set_uniform("uniform_color", extruder_colors[0]); //to make black not too hard too see - std::array new_color = adjust_color_for_rendering(extruder_colors[0]); + ColorRGBA new_color = adjust_color_for_rendering(extruder_colors[0]); shader->set_uniform("uniform_color", new_color); } } @@ -999,7 +964,7 @@ void GLVolume::render_sinking_contours() m_sinking_contours.render(); } -GLWipeTowerVolume::GLWipeTowerVolume(const std::vector>& colors) +GLWipeTowerVolume::GLWipeTowerVolume(const std::vector& colors) : GLVolume() { m_colors = colors; @@ -1022,7 +987,7 @@ void GLWipeTowerVolume::render(bool with_outline) const GLShaderProgram* shader = GUI::wxGetApp().get_current_shader(); for (int i = 0; i < m_colors.size(); i++) { if (shader) { - std::array new_color = adjust_color_for_rendering(m_colors[i]); + ColorRGBA new_color = adjust_color_for_rendering(m_colors[i]); shader->set_uniform("uniform_color", new_color); } this->iva_per_colors[i].render(); @@ -1035,7 +1000,7 @@ void GLWipeTowerVolume::render(bool with_outline) const bool GLWipeTowerVolume::IsTransparent() { for (size_t i = 0; i < m_colors.size(); i++) { - if (m_colors[i][3] < 1.0f) { + if (m_colors[i].is_transparent()) { return true; } } @@ -1070,8 +1035,8 @@ int GLVolumeCollection::load_object_volume( const int extruder_id = model_volume->extruder_id(); const ModelInstance *instance = model_object->instances[instance_idx]; const TriangleMesh &mesh = model_volume->mesh(); - std::array color = GLVolume::MODEL_COLOR[((color_by == "volume") ? volume_idx : obj_idx) % 4]; - color[3] = model_volume->is_model_part() ? 0.7f : 0.4f; + ColorRGBA color = GLVolume::MODEL_COLOR[((color_by == "volume") ? volume_idx : obj_idx) % 4]; + color.a(model_volume->is_model_part() ? 0.7f : 0.4f); this->volumes.emplace_back(new GLVolume(color)); GLVolume& v = *this->volumes.back(); v.set_color(color_from_model_volume(*model_volume)); @@ -1164,8 +1129,8 @@ int GLVolumeCollection::load_wipe_tower_preview( if (height == 0.0f) height = 0.1f; - std::vector> extruder_colors = get_extruders_colors(); - std::vector> colors; + std::vector extruder_colors = get_extruders_colors(); + std::vector colors; GUI::PartPlateList& ppl = GUI::wxGetApp().plater()->get_partplate_list(); std::vector plate_extruders = ppl.get_plate(plate_idx)->get_extruders(true); TriangleMesh wipe_tower_shell = make_cube(width, depth, height); @@ -1185,7 +1150,7 @@ int GLVolumeCollection::load_wipe_tower_preview( // Orca: make it transparent for(auto& color : colors) - color[3] = 0.66f; + color.a(0.66f); volumes.emplace_back(new GLWipeTowerVolume(colors)); GLWipeTowerVolume& v = *dynamic_cast(volumes.back()); v.iva_per_colors.resize(colors.size()); @@ -1208,14 +1173,14 @@ int GLVolumeCollection::load_wipe_tower_preview( return int(volumes.size() - 1); } -GLVolume* GLVolumeCollection::new_toolpath_volume(const std::array& rgba, size_t reserve_vbo_floats) +GLVolume* GLVolumeCollection::new_toolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats) { GLVolume *out = new_nontoolpath_volume(rgba, reserve_vbo_floats); out->is_extrusion_path = true; return out; } -GLVolume* GLVolumeCollection::new_nontoolpath_volume(const std::array& rgba, size_t reserve_vbo_floats) +GLVolume* GLVolumeCollection::new_nontoolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats) { GLVolume *out = new GLVolume(rgba); out->is_extrusion_path = false; @@ -1232,7 +1197,7 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo for (unsigned int i = 0; i < (unsigned int)volumes.size(); ++i) { GLVolume* volume = volumes[i]; - bool is_transparent = (volume->render_color[3] < 1.0f); + bool is_transparent = volume->render_color.is_transparent(); auto tempGlwipeTowerVolume = dynamic_cast(volume); if (tempGlwipeTowerVolume) { is_transparent = tempGlwipeTowerVolume->IsTransparent(); @@ -1539,83 +1504,53 @@ void GLVolumeCollection::reset_outside_state() void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig *config, bool is_update_alpha) { - static const float inv_255 = 1.0f / 255.0f; + + using ColorItem = std::pair; + std::vector colors; - struct Color - { - std::string text; - unsigned char rgba[4]; - - Color() - : text("") - { - rgba[0] = 255; - rgba[1] = 255; - rgba[2] = 255; - rgba[3] = 255; - } - - void set(const std::string& text, unsigned char* rgba) - { - this->text = text; - ::memcpy((void*)this->rgba, (const void*)rgba, 4 * sizeof(unsigned char)); - } - }; - - if (config == nullptr) - return; - - unsigned char rgba[4]; - std::vector colors; - - if (static_cast(config->opt_int("printer_technology")) == ptSLA) - { + if (static_cast(config->opt_int("printer_technology")) == ptSLA) { const std::string& txt_color = config->opt_string("material_colour").empty() ? print_config_def.get("material_colour")->get_default_value()->value : config->opt_string("material_colour"); - if (Slic3r::GUI::BitmapCache::parse_color4(txt_color, rgba)) { - colors.resize(1); - colors[0].set(txt_color, rgba); - } + ColorRGBA rgba; + if (decode_color(txt_color, rgba)) + colors.push_back({ txt_color, rgba }); } - else - { + else { const ConfigOptionStrings* filamemts_opt = dynamic_cast(config->option("filament_colour")); if (filamemts_opt == nullptr) return; - unsigned int colors_count = (unsigned int)filamemts_opt->values.size(); + size_t colors_count = (size_t)filamemts_opt->values.size(); if (colors_count == 0) return; colors.resize(colors_count); for (unsigned int i = 0; i < colors_count; ++i) { - const std::string& txt_color = config->opt_string("filament_colour", i); - if (Slic3r::GUI::BitmapCache::parse_color4(txt_color, rgba)) - colors[i].set(txt_color, rgba); + ColorRGBA rgba; + const std::string& fil_color = config->opt_string("filament_colour", i); + if (decode_color(fil_color, rgba)) + colors[i] = { fil_color, rgba }; } } for (GLVolume* volume : volumes) { - if (volume == nullptr || volume->is_modifier || volume->is_wipe_tower || (volume->volume_idx() < 0)) + if (volume == nullptr || volume->is_modifier || volume->is_wipe_tower || volume->volume_idx() < 0) continue; int extruder_id = volume->extruder_id - 1; if (extruder_id < 0 || (int)colors.size() <= extruder_id) extruder_id = 0; - const Color& color = colors[extruder_id]; - if (!color.text.empty()) { - for (int i = 0; i < 4; ++i) { - if (is_update_alpha == false) { - if (i < 3) { - volume->color[i] = (float) color.rgba[i] * inv_255; - } - continue; - } - volume->color[i] = (float) color.rgba[i] * inv_255; - } - } + const ColorItem& color = colors[extruder_id]; + if (!color.first.empty()) { + if (!is_update_alpha) { + float old_a = color.second.a(); + volume->color = color.second; + volume->color.a(old_a); + } + volume->color = color.second; + } } } @@ -1625,7 +1560,7 @@ void GLVolumeCollection::set_transparency(float alpha) if (volume == nullptr || volume->is_modifier || volume->is_wipe_tower || (volume->volume_idx() < 0)) continue; - volume->color[3] = alpha; + volume->color.a(alpha); } } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index c850884da8..b9030ac4f7 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -7,6 +7,7 @@ #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/Geometry.hpp" +#include "libslic3r/Color.hpp" // BBS #include "libslic3r/ObjectID.hpp" @@ -30,10 +31,10 @@ #define glsafe(cmd) cmd #define glcheck() #endif // HAS_GLSAFE -extern std::vector> get_extruders_colors(); -extern float FullyTransparentMaterialThreshold; -extern float FullTransparentModdifiedToFixAlpha; -extern std::array adjust_color_for_rendering(const std::array &colors); +extern std::vector get_extruders_colors(); +extern float FullyTransparentMaterialThreshold; +extern float FullTransparentModdifiedToFixAlpha; +extern Slic3r::ColorRGBA adjust_color_for_rendering(const Slic3r::ColorRGBA &colors); namespace Slic3r { @@ -54,7 +55,7 @@ enum ModelInstanceEPrintVolumeState : unsigned char; using ModelObjectPtrs = std::vector; // Return appropriate color based on the ModelVolume. -std::array color_from_model_volume(const ModelVolume& model_volume); +extern ColorRGBA color_from_model_volume(const ModelVolume& model_volume); // A container for interleaved arrays of 3D vertices and normals, // possibly indexed by triangles and / or quads. @@ -261,17 +262,17 @@ class GLVolume { public: std::string name; - static std::array DISABLED_COLOR; - static std::array SLA_SUPPORT_COLOR; - static std::array SLA_PAD_COLOR; - static std::array NEUTRAL_COLOR; - static std::array UNPRINTABLE_COLOR; - static std::array, 5> MODEL_COLOR; - static std::array MODEL_MIDIFIER_COL; - static std::array MODEL_NEGTIVE_COL; - static std::array SUPPORT_ENFORCER_COL; - static std::array SUPPORT_BLOCKER_COL; - static std::array MODEL_HIDDEN_COL; + static ColorRGBA DISABLED_COLOR; + static ColorRGBA SLA_SUPPORT_COLOR; + static ColorRGBA SLA_PAD_COLOR; + static ColorRGBA NEUTRAL_COLOR; + static ColorRGBA UNPRINTABLE_COLOR; + static std::array MODEL_COLOR; + static ColorRGBA MODEL_MIDIFIER_COL; + static ColorRGBA MODEL_NEGTIVE_COL; + static ColorRGBA SUPPORT_ENFORCER_COL; + static ColorRGBA SUPPORT_BLOCKER_COL; + static ColorRGBA MODEL_HIDDEN_COL; static void update_render_colors(); static void load_render_colors(); @@ -288,7 +289,7 @@ public: }; GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f); - GLVolume(const std::array& rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {} + GLVolume(const ColorRGBA& color) : GLVolume(color.r(), color.g(), color.b(), color.a()) {} virtual ~GLVolume() = default; // BBS @@ -329,9 +330,9 @@ protected: public: // Color of the triangles / quads held by this volume. - std::array color; + ColorRGBA color; // Color used to render this volume. - std::array render_color; + ColorRGBA render_color; struct CompositeID { CompositeID(int object_id, int volume_id, int instance_id) : object_id(object_id), volume_id(volume_id), instance_id(instance_id) {} @@ -426,9 +427,8 @@ public: return out; } - void set_color(const std::array& rgba); - void set_render_color(float r, float g, float b, float a); - void set_render_color(const std::array& rgba); + void set_color(const ColorRGBA& rgba) { color = rgba; } + void set_render_color(const ColorRGBA& rgba) { render_color = rgba; } // Sets render color in dependence of current state void set_render_color(); // set color according to model volume @@ -525,7 +525,7 @@ public: virtual void render(bool with_outline = false) const; //BBS: add simple render function for thumbnail - void simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector>& extruder_colors) const; + void simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_objects, std::vector& extruder_colors) const; void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); } void release_geometry() { this->indexed_vertex_array.release_geometry(); } @@ -556,14 +556,14 @@ public: // BBS class GLWipeTowerVolume : public GLVolume { public: - GLWipeTowerVolume(const std::vector>& colors); + GLWipeTowerVolume(const std::vector& colors); virtual void render(bool with_outline = false) const; std::vector iva_per_colors; bool IsTransparent(); private: - std::vector> m_colors; + std::vector m_colors; }; typedef std::vector GLVolumePtrs; @@ -657,8 +657,8 @@ public: int load_wipe_tower_preview( int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized); - GLVolume* new_toolpath_volume(const std::array& rgba, size_t reserve_vbo_floats = 0); - GLVolume* new_nontoolpath_volume(const std::array& rgba, size_t reserve_vbo_floats = 0); + GLVolume* new_toolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0); + GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0); int get_selection_support_threshold_angle(bool&) const; // Render the volumes by OpenGL. diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index 74f5efbe6e..e8f21416af 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -2,6 +2,7 @@ #include "I18N.hpp" #include "libslic3r/Utils.hpp" +#include "libslic3r/Color.hpp" #include "GUI.hpp" #include "GUI_App.hpp" #include "MainFrame.hpp" @@ -127,10 +128,10 @@ wxString CopyrightsDialog::get_html_text() wxColour bgr_clr = wxGetApp().get_window_default_clr();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); const auto text_clr = wxGetApp().get_label_clr_default();// wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); - const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); - const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); + const auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue())); + const auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue())); - const wxString copyright_str = _(L("Copyright")) + "© "; + const wxString copyright_str = _L("Copyright") + "© "; wxString text = wxString::Format( "" diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 999d09a7c5..a0edea0711 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -431,46 +431,5 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi return wxImage_to_wxBitmap_with_alpha(std::move(image), scale); } -bool BitmapCache::parse_color(const std::string& scolor, unsigned char* rgb_out) -{ - if (scolor.size() == 9) { - unsigned char rgba[4]; - parse_color4(scolor, rgba); - rgb_out[0] = rgba[0]; - rgb_out[1] = rgba[1]; - rgb_out[2] = rgba[2]; - return true; - } - rgb_out[0] = rgb_out[1] = rgb_out[2] = 0; - if (scolor.size() != 7 || scolor.front() != '#') - return false; - const char* c = scolor.data() + 1; - for (size_t i = 0; i < 3; ++i) { - int digit1 = hex_digit_to_int(*c++); - int digit2 = hex_digit_to_int(*c++); - if (digit1 == -1 || digit2 == -1) - return false; - rgb_out[i] = (unsigned char)(digit1 * 16 + digit2); - } - - return true; -} - -bool BitmapCache::parse_color4(const std::string& scolor, unsigned char* rgba_out) -{ - rgba_out[0] = rgba_out[1] = rgba_out[2] = 0; rgba_out[3] = 255; - if ((scolor.size() != 7 && scolor.size() != 9) || scolor.front() != '#') - return false; - const char* c = scolor.data() + 1; - for (size_t i = 0; i < scolor.size() / 2; ++i) { - int digit1 = hex_digit_to_int(*c++); - int digit2 = hex_digit_to_int(*c++); - if (digit1 == -1 || digit2 == -1) - return false; - rgba_out[i] = (unsigned char)(digit1 * 16 + digit2); - } - return true; -} - } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/BitmapCache.hpp b/src/slic3r/GUI/BitmapCache.hpp index 4803fa961d..a5748acac2 100644 --- a/src/slic3r/GUI/BitmapCache.hpp +++ b/src/slic3r/GUI/BitmapCache.hpp @@ -9,9 +9,11 @@ #include #endif +#include "libslic3r/Color.hpp" struct NSVGimage; -namespace Slic3r { namespace GUI { +namespace Slic3r { +namespace GUI { class BitmapCache { @@ -44,12 +46,9 @@ public: wxBitmap* load_svg(const std::string &bitmap_key, unsigned width = 0, unsigned height = 0, const bool grayscale = false, const bool dark_mode = false, const std::string& new_color = "", const float scale_in_center = 0.f); wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false); - wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3], bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE, suppress_scaling, border_width, dark_mode); } + wxBitmap mksolid(size_t width, size_t height, const ColorRGB& rgb, bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false) { return mksolid(width, height, rgb.r_uchar(), rgb.g_uchar(), rgb.b_uchar(), wxALPHA_OPAQUE, suppress_scaling, border_width, dark_mode); } wxBitmap mkclear(size_t width, size_t height) { return mksolid(width, height, 0, 0, 0, wxALPHA_TRANSPARENT); } - static bool parse_color(const std::string& scolor, unsigned char* rgb_out); - static bool parse_color4(const std::string& scolor, unsigned char* rgba_out); - private: std::map m_map; double m_gs = 0.2; // value, used for image.ConvertToGreyscale(m_gs, m_gs, m_gs) diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 572fb829f5..a34a7cd46e 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -36,6 +36,7 @@ #include "libslic3r/Config.hpp" #include "libslic3r/libslic3r.h" #include "libslic3r/Model.hpp" +#include "libslic3r/Color.hpp" #include "GUI.hpp" #include "GUI_App.hpp" #include "GUI_Utils.hpp" @@ -777,9 +778,9 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector* are not compatible with some installed printers."), materials->technology == T_FFF ? _L("Filaments") : _L("SLA materials")); wxString text; if (all_printers) { diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 091a60b45f..3565a40b95 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -1619,8 +1619,7 @@ boost::any& ColourPicker::get_value() if (colour == wxTransparentColour) m_value = std::string(""); else { - auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), colour.Red(), colour.Green(), colour.Blue()); - m_value = clr_str.ToStdString(); + m_value = encode_color(ColorRGB(colour.Red(), colour.Green(), colour.Blue())); } return m_value; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3d0e4f2b9c..082e7b84df 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -90,42 +90,6 @@ static EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(EMoveType::Retract) + id); } -static std::array decode_color(const std::string& color) { - static const float INV_255 = 1.0f / 255.0f; - - std::array ret = { 0.0f, 0.0f, 0.0f, 1.0f }; - const char* c = color.data() + 1; - if (color.size() == 7 && color.front() == '#') { - for (size_t j = 0; j < 3; ++j) { - int digit1 = hex_digit_to_int(*c++); - int digit2 = hex_digit_to_int(*c++); - if (digit1 == -1 || digit2 == -1) - break; - - ret[j] = float(digit1 * 16 + digit2) * INV_255; - } - } - else if (color.size() == 9 && color.front() == '#') { - for (size_t j = 0; j < 4; ++j) { - int digit1 = hex_digit_to_int(*c++); - int digit2 = hex_digit_to_int(*c++); - if (digit1 == -1 || digit2 == -1) - break; - - ret[j] = float(digit1 * 16 + digit2) * INV_255; - } - } - return ret; -} - -static std::vector> decode_colors(const std::vector& colors) { - std::vector> output(colors.size(), { 0.0f, 0.0f, 0.0f, 1.0f }); - for (size_t i = 0; i < colors.size(); ++i) { - output[i] = decode_color(colors[i]); - } - return output; -} - // Round to a bin with minimum two digits resolution. // Equivalent to conversion to string with sprintf(buf, "%.2g", value) and conversion back to float, but faster. static float round_to_bin(const float value) @@ -263,7 +227,7 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessorResult::MoveVertex& move move.volumetric_rate(), move.layer_duration, move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); } -GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) const +ColorRGBA GCodeViewer::Extrusions::Range::get_color_at(float value) const { // Input value scaled to the colors range const float step = step_size(); @@ -280,15 +244,8 @@ GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) con const size_t color_low_idx = std::clamp(static_cast(global_t), 0, color_max_idx); const size_t color_high_idx = std::clamp(color_low_idx + 1, 0, color_max_idx); - // Compute how far the value is between the low and high colors so that they can be interpolated - const float local_t = std::clamp(global_t - static_cast(color_low_idx), 0.0f, 1.0f); - // Interpolate between the low and high colors to find exactly which color the input value should get - Color ret = { 0.0f, 0.0f, 0.0f, 1.0f }; - for (unsigned int i = 0; i < 3; ++i) { - ret[i] = lerp(Range_Colors[color_low_idx][i], Range_Colors[color_high_idx][i], local_t); - } - return ret; + return lerp(Range_Colors[color_low_idx], Range_Colors[color_high_idx], global_t - static_cast(color_low_idx)); } float GCodeViewer::Extrusions::Range::step_size() const { @@ -584,11 +541,11 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, f return ret; }; - static const ImVec4 LINE_NUMBER_COLOR = ImGuiWrapper::COL_ORANGE_LIGHT; + static const ImVec4 LINE_NUMBER_COLOR = ImGuiWrapper::COL_ORANGE_LIGHT; static const ImVec4 SELECTION_RECT_COLOR = ImGuiWrapper::COL_ORANGE_DARK; - static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f }; - static const ImVec4 PARAMETERS_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; - static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f }; + static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f }; + static const ImVec4 PARAMETERS_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; + static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f }; if (!m_visible || !wxGetApp().show_gcode_window() || m_filename.empty() || m_lines_ends.empty() || curr_line_id == 0) return; @@ -728,7 +685,7 @@ if (has_render_path) gcode_window.render(legend_height + 2, std::max(10.f, (float)canvas_height - 40), (float)canvas_width - (float)right_margin, static_cast(gcode_ids[current.last])); } -const std::vector GCodeViewer::Extrusion_Role_Colors {{ +const std::vector GCodeViewer::Extrusion_Role_Colors{ { { 0.90f, 0.70f, 0.70f, 1.0f }, // erNone { 1.00f, 0.90f, 0.30f, 1.0f }, // erPerimeter { 1.00f, 0.49f, 0.22f, 1.0f }, // erExternalPerimeter @@ -750,7 +707,7 @@ const std::vector GCodeViewer::Extrusion_Role_Colors {{ { 0.37f, 0.82f, 0.58f, 1.0f } // erCustom }}; -const std::vector GCodeViewer::Options_Colors {{ +const std::vector GCodeViewer::Options_Colors{ { { 0.803f, 0.135f, 0.839f, 1.0f }, // Retractions { 0.287f, 0.679f, 0.810f, 1.0f }, // Unretractions { 0.900f, 0.900f, 0.900f, 1.0f }, // Seams @@ -760,7 +717,7 @@ const std::vector GCodeViewer::Options_Colors {{ { 0.886f, 0.825f, 0.262f, 1.0f } // CustomGCodes }}; -const std::vector GCodeViewer::Travel_Colors {{ +const std::vector GCodeViewer::Travel_Colors{ { { 0.219f, 0.282f, 0.609f, 1.0f }, // Move { 0.112f, 0.422f, 0.103f, 1.0f }, // Extrude { 0.505f, 0.064f, 0.028f, 1.0f } // Retract @@ -768,7 +725,7 @@ const std::vector GCodeViewer::Travel_Colors {{ // Normal ranges // blue to red -const std::vector GCodeViewer::Range_Colors{{ +const std::vector GCodeViewer::Range_Colors{ { decode_color_to_float_array("#0b2c7a"), // bluish decode_color_to_float_array("#135985"), decode_color_to_float_array("#1c8891"), @@ -782,8 +739,8 @@ const std::vector GCodeViewer::Range_Colors{{ decode_color_to_float_array("#942616") // reddish }}; -const GCodeViewer::Color GCodeViewer::Wipe_Color = { 1.0f, 1.0f, 0.0f, 1.0f }; -const GCodeViewer::Color GCodeViewer::Neutral_Color = { 0.25f, 0.25f, 0.25f, 1.0f }; +const ColorRGBA GCodeViewer::Wipe_Color = ColorRGBA::YELLOW(); +const ColorRGBA GCodeViewer::Neutral_Color = ColorRGBA::DARK_GRAY(); GCodeViewer::GCodeViewer() { @@ -1140,13 +1097,13 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v if (m_view_type == EViewType::Tool && !gcode_result.extruder_colors.empty()) { // update tool colors from config stored in the gcode - m_tools.m_tool_colors = decode_colors(gcode_result.extruder_colors); + decode_colors(gcode_result.extruder_colors, m_tools.m_tool_colors); m_tools.m_tool_visibles = std::vector(m_tools.m_tool_colors.size()); for (auto item: m_tools.m_tool_visibles) item = true; } else { // update tool colors - m_tools.m_tool_colors = decode_colors(str_tool_colors); + decode_colors(str_tool_colors, m_tools.m_tool_colors); m_tools.m_tool_visibles = std::vector(m_tools.m_tool_colors.size()); for (auto item : m_tools.m_tool_visibles) item = true; } @@ -1154,9 +1111,11 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v for (int i = 0; i < m_tools.m_tool_colors.size(); i++) { m_tools.m_tool_colors[i] = adjust_color_for_rendering(m_tools.m_tool_colors[i]); } - // ensure there are enough colors defined + ColorRGBA default_color; + decode_color("#FF8000", default_color); + // ensure there are enough colors defined while (m_tools.m_tool_colors.size() < std::max(size_t(1), gcode_result.extruders_count)) { - m_tools.m_tool_colors.push_back(decode_color("#FF8000")); + m_tools.m_tool_colors.push_back(default_color); m_tools.m_tool_visibles.push_back(true); } @@ -1247,7 +1206,7 @@ void GCodeViewer::reset() m_paths_bounding_box = BoundingBoxf3(); m_max_bounding_box = BoundingBoxf3(); m_max_print_height = 0.0f; - m_tools.m_tool_colors = std::vector(); + m_tools.m_tool_colors = std::vector(); m_tools.m_tool_visibles = std::vector(); m_extruders_count = 0; m_extruder_ids = std::vector(); @@ -1904,7 +1863,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const return; // collect color information to generate materials - std::vector colors; + std::vector colors; for (const RenderPath& path : t_buffer.render_paths) { colors.push_back(path.color); } @@ -1926,10 +1885,10 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const fprintf(fp, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SoftFever_VERSION); unsigned int colors_count = 1; - for (const Color& color : colors) { + for (const ColorRGBA& color : colors) { fprintf(fp, "\nnewmtl material_%d\n", colors_count++); fprintf(fp, "Ka 1 1 1\n"); - fprintf(fp, "Kd %g %g %g\n", color[0], color[1], color[2]); + fprintf(fp, "Kd %g %g %g\n", color.r(), color.g(), color.b()); fprintf(fp, "Ks 0 0 0\n"); } @@ -1990,7 +1949,7 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const } size_t i = 0; - for (const Color& color : colors) { + for (const ColorRGBA& color : colors) { // save material triangles to file fprintf(fp, "\nusemtl material_%zu\n", i + 1); fprintf(fp, "# triangles material %zu\n", i + 1); @@ -3231,7 +3190,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized, bool force_p for (GLVolume* volume : m_shells.volumes.volumes) { volume->zoom_to_volumes = false; - volume->color[3] = 0.5f; + volume->color.a(0.5f); volume->force_native_color = true; volume->set_render_color(); //BBS: add shell bounding box logic @@ -3254,7 +3213,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": enter, m_buffers size %1%!")%m_buffers.size(); auto extrusion_color = [this](const Path& path) { - Color color; + ColorRGBA color; switch (m_view_type) { case EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } @@ -3269,7 +3228,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool case EViewType::Tool: { color = m_tools.m_tool_colors[path.extruder_id]; break; } case EViewType::ColorPrint: { if (path.cp_color_id >= static_cast(m_tools.m_tool_colors.size())) - color = { 0.5f, 0.5f, 0.5f, 1.0f }; + color = ColorRGBA::GRAY(); else { color = m_tools.m_tool_colors[path.cp_color_id]; color = adjust_color_for_rendering(color); @@ -3282,7 +3241,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool color = {id, role, id, 1.0f}; break; } - default: { color = { 1.0f, 1.0f, 1.0f, 1.0f }; break; } + default: { color = ColorRGBA::WHITE(); break; } } return color; @@ -3515,7 +3474,7 @@ m_no_render_path = false; if (m_sequential_view.current.last < sub_path.first.s_id || sub_path.last.s_id < m_sequential_view.current.first) continue; - Color color; + ColorRGBA color; switch (path.type) { case EMoveType::Tool_change: @@ -4168,7 +4127,8 @@ void GCodeViewer::render_all_plates_stats(const std::vector filament_diameters = gcode_result_list.front()->filament_diameters; std::vector filament_densities = gcode_result_list.front()->filament_densities; - std::vector filament_colors = decode_colors(wxGetApp().plater()->get_extruder_colors_from_plater_config(gcode_result_list.back())); + std::vector filament_colors; + decode_colors(wxGetApp().plater()->get_extruder_colors_from_plater_config(gcode_result_list.back()), filament_colors); for (int i = 0; i < filament_colors.size(); i++) { filament_colors[i] = adjust_color_for_rendering(filament_colors[i]); @@ -4213,13 +4173,13 @@ void GCodeViewer::render_all_plates_stats(const std::vector>& columns_offsets) + auto append_item = [icon_size, &imgui, imperial_units, &window_padding, &draw_list, this](const ColorRGBA& color, const std::vector>& columns_offsets) { // render icon ImVec2 pos = ImVec2(ImGui::GetCursorScreenPos().x + window_padding * 3, ImGui::GetCursorScreenPos().y); draw_list->AddRectFilled({ pos.x + 1.0f * m_scale, pos.y + 3.0f * m_scale }, { pos.x + icon_size - 1.0f * m_scale, pos.y + icon_size + 1.0f * m_scale }, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + ImGuiWrapper::to_ImU32(color)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(20.0 * m_scale, 6.0 * m_scale)); @@ -4425,7 +4385,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv auto append_item = [icon_size, &imgui, imperial_units, &window_padding, &draw_list, this]( EItemType type, - const Color& color, + const ColorRGBA& color, const std::vector>& columns_offsets, bool checkbox = true, bool visible = true, @@ -4437,21 +4397,21 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv default: case EItemType::Rect: { draw_list->AddRectFilled({ pos.x + 1.0f * m_scale, pos.y + 3.0f * m_scale }, { pos.x + icon_size - 1.0f * m_scale, pos.y + icon_size + 1.0f * m_scale }, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + ImGuiWrapper::to_ImU32(color)); break; } case EItemType::Circle: { ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size + 5.0f)); - draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16); + draw_list->AddCircleFilled(center, 0.5f * icon_size, ImGuiWrapper::to_ImU32(color), 16); break; } case EItemType::Hexagon: { ImVec2 center(0.5f * (pos.x + pos.x + icon_size), 0.5f * (pos.y + pos.y + icon_size + 5.0f)); - draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 6); + draw_list->AddNgonFilled(center, 0.5f * icon_size, ImGuiWrapper::to_ImU32(color), 6); break; } case EItemType::Line: { - draw_list->AddLine({ pos.x + 1, pos.y + icon_size + 2 }, { pos.x + icon_size - 1, pos.y + 4 }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); + draw_list->AddLine({ pos.x + 1, pos.y + icon_size + 2 }, { pos.x + icon_size - 1, pos.y + 4 }, ImGuiWrapper::to_ImU32(color), 3.0f); break; case EItemType::None: break; @@ -4567,7 +4527,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv }; auto color_print_ranges = [this](unsigned char extruder_id, const std::vector& custom_gcode_per_print_z) { - std::vector>> ret; + std::vector>> ret; ret.reserve(custom_gcode_per_print_z.size()); for (const auto& item : custom_gcode_per_print_z) { @@ -4587,7 +4547,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv // to avoid duplicate values, check adding values if (ret.empty() || !(ret.back().second.first == previous_z && ret.back().second.second == current_z)) - ret.push_back({ decode_color(item.color), { previous_z, current_z } }); + { + ColorRGBA color; + decode_color(item.color, color); + ret.push_back({ color, { previous_z, current_z } }); + } } return ret; @@ -4834,7 +4798,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } auto append_option_item = [this, append_item](EMoveType type, std::vector offsets) { - auto append_option_item_with_type = [this, offsets, append_item](EMoveType type, const Color& color, const std::string& label, bool visible) { + auto append_option_item_with_type = [this, offsets, append_item](EMoveType type, const ColorRGBA& color, const std::string& label, bool visible) { append_item(EItemType::Rect, color, {{ label , offsets[0] }}, true, visible, [this, type, visible]() { m_buffers[buffer_id(type)].visible = !m_buffers[buffer_id(type)].visible; // update buffers' render paths @@ -4958,7 +4922,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv if (need_scrollable) ImGui::BeginChild("color_prints", { -1.0f, child_height }, false); if (m_extruder_ids.size() == 1) { // single extruder use case - const std::vector>> cp_values = color_print_ranges(0, custom_gcode_per_print_z); + const std::vector>> cp_values = color_print_ranges(0, custom_gcode_per_print_z); const int items_cnt = static_cast(cp_values.size()); auto extruder_idx = m_extruder_ids[0]; if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode @@ -4990,7 +4954,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv // shows only extruders actually used size_t i = 0; for (auto extruder_idx : m_extruder_ids) { - const std::vector>> cp_values = color_print_ranges(extruder_idx, custom_gcode_per_print_z); + const std::vector>> cp_values = color_print_ranges(extruder_idx, custom_gcode_per_print_z); const int items_cnt = static_cast(cp_values.size()); if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode const bool filament_visible = m_tools.m_tool_visibles[extruder_idx]; @@ -5119,8 +5083,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv }; EType type; int extruder_id; - Color color1; - Color color2; + ColorRGBA color1; + ColorRGBA color2; Times times; std::pair used_filament {0.0f, 0.0f}; }; @@ -5131,7 +5095,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv //BBS: replace model custom gcode with current plate custom gcode std::vector custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z; - std::vector last_color(m_extruders_count); + std::vector last_color(m_extruders_count); for (size_t i = 0; i < m_extruders_count; ++i) { last_color[i] = m_tools.m_tool_colors[i]; } @@ -5143,8 +5107,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv case CustomGCode::PausePrint: { auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); if (it != custom_gcode_per_print_z.end()) { - items.push_back({ PartialTime::EType::Print, it->extruder, last_color[it->extruder - 1], Color(), time_rec.second }); - items.push_back({ PartialTime::EType::Pause, it->extruder, Color(), Color(), time_rec.second }); + items.push_back({ PartialTime::EType::Print, it->extruder, last_color[it->extruder - 1], ColorRGBA::BLACK(), time_rec.second }); + items.push_back({ PartialTime::EType::Pause, it->extruder, ColorRGBA::BLACK(), ColorRGBA::BLACK(), time_rec.second }); custom_gcode_per_print_z.erase(it); } break; @@ -5152,14 +5116,16 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv case CustomGCode::ColorChange: { auto it = std::find_if(custom_gcode_per_print_z.begin(), custom_gcode_per_print_z.end(), [time_rec](const CustomGCode::Item& item) { return item.type == time_rec.first; }); if (it != custom_gcode_per_print_z.end()) { - items.push_back({ PartialTime::EType::Print, it->extruder, last_color[it->extruder - 1], Color(), time_rec.second, get_used_filament_from_volume(used_filaments[color_change_idx++], it->extruder-1) }); - items.push_back({ PartialTime::EType::ColorChange, it->extruder, last_color[it->extruder - 1], decode_color(it->color), time_rec.second }); - last_color[it->extruder - 1] = decode_color(it->color); + items.push_back({ PartialTime::EType::Print, it->extruder, last_color[it->extruder - 1], ColorRGBA::BLACK(), time_rec.second, get_used_filament_from_volume(used_filaments[color_change_idx++], it->extruder - 1) }); + ColorRGBA color; + decode_color(it->color, color); + items.push_back({ PartialTime::EType::ColorChange, it->extruder, last_color[it->extruder - 1], color, time_rec.second }); + last_color[it->extruder - 1] = color; last_extruder_id = it->extruder; custom_gcode_per_print_z.erase(it); } else - items.push_back({ PartialTime::EType::Print, last_extruder_id, last_color[last_extruder_id - 1], Color(), time_rec.second, get_used_filament_from_volume(used_filaments[color_change_idx++], last_extruder_id -1) }); + items.push_back({ PartialTime::EType::Print, last_extruder_id, last_color[last_extruder_id - 1], ColorRGBA::BLACK(), time_rec.second, get_used_filament_from_volume(used_filaments[color_change_idx++], last_extruder_id - 1) }); break; } @@ -5170,7 +5136,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv return items; }; - auto append_color_change = [&imgui](const Color& color1, const Color& color2, const std::array& offsets, const Times& times) { + auto append_color_change = [&imgui](const ColorRGBA& color1, const ColorRGBA& color2, const std::array& offsets, const Times& times) { imgui.text(_u8L("Color change")); ImGui::SameLine(); @@ -5180,16 +5146,16 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv pos.x -= 0.5f * ImGui::GetStyle().ItemSpacing.x; draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, - ImGui::GetColorU32({ color1[0], color1[1], color1[2], 1.0f })); + ImGuiWrapper::to_ImU32(color1)); pos.x += icon_size; draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, - ImGui::GetColorU32({ color2[0], color2[1], color2[2], 1.0f })); + ImGuiWrapper::to_ImU32(color2)); ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(times.second - times.first))); }; - auto append_print = [&imgui, imperial_units](const Color& color, const std::array& offsets, const Times& times, std::pair used_filament) { + auto append_print = [&imgui, imperial_units](const ColorRGBA& color, const std::array& offsets, const Times& times, std::pair used_filament) { imgui.text(_u8L("Print")); ImGui::SameLine(); @@ -5199,7 +5165,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv pos.x -= 0.5f * ImGui::GetStyle().ItemSpacing.x; draw_list->AddRectFilled({ pos.x + 1.0f, pos.y + 1.0f }, { pos.x + icon_size - 1.0f, pos.y + icon_size - 1.0f }, - ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f })); + ImGuiWrapper::to_ImU32(color)); ImGui::SameLine(offsets[0]); imgui.text(short_time(get_time_dhms(times.second))); @@ -5713,7 +5679,7 @@ void GCodeViewer::log_memory_used(const std::string& label, int64_t additional) } } -GCodeViewer::Color GCodeViewer::option_color(EMoveType move_type) const +ColorRGBA GCodeViewer::option_color(EMoveType move_type) const { switch (move_type) { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 818f3a3e5e..4c0f080974 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -34,7 +34,6 @@ static const float SLIDER_BOTTOM_MARGIN = 64.0f; class GCodeViewer { using IBufferType = unsigned short; - using Color = std::array; using VertexBuffer = std::vector; using MultiVertexBuffer = std::vector; using IndexBuffer = std::vector; @@ -43,12 +42,12 @@ class GCodeViewer using InstanceIdBuffer = std::vector; using InstancesOffsets = std::vector; - static const std::vector Extrusion_Role_Colors; - static const std::vector Options_Colors; - static const std::vector Travel_Colors; - static const std::vector Range_Colors; - static const Color Wipe_Color; - static const Color Neutral_Color; + static const std::vector Extrusion_Role_Colors; + static const std::vector Options_Colors; + static const std::vector Travel_Colors; + static const std::vector Range_Colors; + static const ColorRGBA Wipe_Color; + static const ColorRGBA Neutral_Color; enum class EOptionsColors : unsigned char { @@ -133,7 +132,7 @@ class GCodeViewer // vbo id unsigned int vbo{ 0 }; // Color to apply to the instances - Color color; + ColorRGBA color; }; std::vector ranges; @@ -256,7 +255,7 @@ class GCodeViewer // Index of the parent tbuffer unsigned char tbuffer_id; // Render path property - Color color; + ColorRGBA color; // Index of the buffer in TBuffer::indices unsigned int ibuffer_id; // Render path content @@ -276,12 +275,10 @@ class GCodeViewer bool operator() (const RenderPath &l, const RenderPath &r) const { if (l.tbuffer_id < r.tbuffer_id) return true; - for (int i = 0; i < 3; ++i) { - if (l.color[i] < r.color[i]) - return true; - else if (l.color[i] > r.color[i]) - return false; - } + if (l.color < r.color) + return true; + else if (l.color > r.color) + return false; return l.ibuffer_id < r.ibuffer_id; } }; @@ -312,7 +309,7 @@ class GCodeViewer struct Model { GLModel model; - Color color; + ColorRGBA color; InstanceVBuffer instances; GLModel::InitializationData data; @@ -416,7 +413,7 @@ class GCodeViewer void reset(bool log = false) { min = FLT_MAX; max = -FLT_MAX; count = 0; log_scale = log; } float step_size() const; - Color get_color_at(float value) const; + ColorRGBA get_color_at(float value) const; float get_value_at_step(int step) const; }; @@ -519,7 +516,7 @@ Range layer_duration_log; TBuffer* buffer{ nullptr }; unsigned int ibo{ 0 }; unsigned int vbo{ 0 }; - Color color; + ColorRGBA color; ~SequentialRangeCap(); bool is_renderable() const { return buffer != nullptr; } @@ -717,7 +714,7 @@ public: struct ETools { - std::vector m_tool_colors; + std::vector m_tool_colors; std::vector m_tool_visibles; }; @@ -920,7 +917,7 @@ private: } bool is_visible(const Path& path) const { return is_visible(path.role); } void log_memory_used(const std::string& label, int64_t additional = 0) const; - Color option_color(EMoveType move_type) const; + ColorRGBA option_color(EMoveType move_type) const; }; } // namespace GUI diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 036e7cbb34..15c343d585 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -78,23 +78,25 @@ static constexpr const float TRACKBALLSIZE = 0.8f; -float GLCanvas3D::DEFAULT_BG_LIGHT_COLOR[3] = { 0.906f, 0.906f, 0.906f }; -float GLCanvas3D::DEFAULT_BG_LIGHT_COLOR_DARK[3] = { 0.329f, 0.329f, 0.353f }; -float GLCanvas3D::ERROR_BG_LIGHT_COLOR[3] = { 0.753f, 0.192f, 0.039f }; -float GLCanvas3D::ERROR_BG_LIGHT_COLOR_DARK[3] = { 0.753f, 0.192f, 0.039f }; +static Slic3r::ColorRGB DEFAULT_BG_LIGHT_COLOR = {0.906f, 0.906f, 0.906f}; +static Slic3r::ColorRGB DEFAULT_BG_LIGHT_COLOR_DARK = {0.329f, 0.329f, 0.353f}; +static Slic3r::ColorRGB ERROR_BG_LIGHT_COLOR = {0.753f, 0.192f, 0.039f}; +static Slic3r::ColorRGB ERROR_BG_LIGHT_COLOR_DARK = {0.753f, 0.192f, 0.039f}; void GLCanvas3D::update_render_colors() { - GLCanvas3D::DEFAULT_BG_LIGHT_COLOR[0] = RenderColor::colors[RenderCol_3D_Background].x; - GLCanvas3D::DEFAULT_BG_LIGHT_COLOR[1] = RenderColor::colors[RenderCol_3D_Background].y; - GLCanvas3D::DEFAULT_BG_LIGHT_COLOR[2] = RenderColor::colors[RenderCol_3D_Background].z; + DEFAULT_BG_LIGHT_COLOR = { + RenderColor::colors[RenderCol_3D_Background].x, + RenderColor::colors[RenderCol_3D_Background].y, + RenderColor::colors[RenderCol_3D_Background].z, + }; } void GLCanvas3D::load_render_colors() { - RenderColor::colors[RenderCol_3D_Background] = ImVec4(GLCanvas3D::DEFAULT_BG_LIGHT_COLOR[0], - GLCanvas3D::DEFAULT_BG_LIGHT_COLOR[1], - GLCanvas3D::DEFAULT_BG_LIGHT_COLOR[2], + RenderColor::colors[RenderCol_3D_Background] = ImVec4(DEFAULT_BG_LIGHT_COLOR.r(), + DEFAULT_BG_LIGHT_COLOR.g(), + DEFAULT_BG_LIGHT_COLOR.b(), 1.0f); } @@ -967,8 +969,8 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons void GLCanvas3D::SequentialPrintClearance::render() { - std::array FILL_COLOR = { 0.7f, 0.7f, 1.0f, 0.5f }; - std::array NO_FILL_COLOR = { 0.75f, 0.75f, 0.75f, 0.75f }; + const ColorRGBA FILL_COLOR = { 0.7f, 0.7f, 1.0f, 0.5f }; + const ColorRGBA NO_FILL_COLOR = { 0.75f, 0.75f, 0.75f, 0.75f }; GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); if (shader == nullptr) @@ -2068,7 +2070,7 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, { GLShaderProgram* shader = wxGetApp().get_shader("thumbnail"); ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects; - std::vector> colors = ::get_extruders_colors(); + std::vector colors = ::get_extruders_colors(); switch (OpenGLManager::get_framebuffers_type()) { case OpenGLManager::EFramebufferType::Arb: @@ -2130,8 +2132,8 @@ void GLCanvas3D::set_selected_visible(bool visible) for (unsigned int i : m_selection.get_volume_idxs()) { GLVolume* volume = const_cast(m_selection.get_volume(i)); volume->visible = visible; - volume->color[3] = visible ? 1.f : GLVolume::MODEL_HIDDEN_COL[3]; - volume->render_color[3] = volume->color[3]; + volume->color.a(visible ? 1.f : GLVolume::MODEL_HIDDEN_COL.a()); + volume->render_color.a(volume->color.a()); volume->force_native_color = !visible; } } @@ -5526,7 +5528,7 @@ static void debug_output_thumbnail(const ThumbnailData& thumbnail_data) #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, - PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, + PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking) { //BBS modify visible calc function @@ -5563,9 +5565,7 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const return ret; }; - static std::array curr_color; - static const std::array orange = { 0.923f, 0.504f, 0.264f, 1.0f }; - static const std::array gray = { 0.64f, 0.64f, 0.64f, 1.0f }; + static ColorRGBA curr_color; GLVolumePtrs visible_volumes; @@ -5702,12 +5702,9 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const shader->set_uniform("emission_factor", 0.1f); for (GLVolume* vol : visible_volumes) { //BBS set render color for thumbnails - curr_color[0] = vol->color[0]; - curr_color[1] = vol->color[1]; - curr_color[2] = vol->color[2]; - curr_color[3] = vol->color[3]; + curr_color = vol->color; - std::array new_color = adjust_color_for_rendering(curr_color); + ColorRGBA new_color = adjust_color_for_rendering(curr_color); shader->set_uniform("uniform_color", new_color); shader->set_uniform("volume_world_matrix", vol->world_matrix()); //BBS set all volume to orange @@ -5739,7 +5736,7 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const } void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, + PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking) { thumbnail_data.set(w, h); @@ -5847,7 +5844,7 @@ void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, uns } void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, + PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking) { thumbnail_data.set(w, h); @@ -5949,7 +5946,7 @@ void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, // glsafe(::glDisable(GL_MULTISAMPLE)); } -void GLCanvas3D::render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList &partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type) +void GLCanvas3D::render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList &partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type) { // check that thumbnail size does not exceed the default framebuffer size const Size& cnv_size = get_canvas_size(); @@ -6519,21 +6516,22 @@ void GLCanvas3D::_picking_pass() int volume_id = -1; int gizmo_id = -1; - GLubyte color[4] = { 0, 0, 0, 0 }; + std::array color = { 0, 0, 0, 0 }; const Size& cnv_size = get_canvas_size(); bool inside = 0 <= m_mouse.position(0) && m_mouse.position(0) < cnv_size.get_width() && 0 <= m_mouse.position(1) && m_mouse.position(1) < cnv_size.get_height(); if (inside) { - glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color)); + glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position.y() - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color.data())); if (picking_checksum_alpha_channel(color[0], color[1], color[2]) == color[3]) { // Only non-interpolated colors are valid, those have their lowest three bits zeroed. // we reserve color = (0,0,0) for occluders (as the printbed) // volumes' id are shifted by 1 // see: _render_volumes_for_picking() + unsigned int id = picking_encode(color[0], color[1], color[2]); //BBS: remove the bed picking logic - //volume_id = color[0] + (color[1] << 8) + (color[2] << 16) - 1; - volume_id = color[0] + (color[1] << 8) + (color[2] << 16); + //volume_id = id - 1; + volume_id = id; // gizmos' id are instead properly encoded by the color - gizmo_id = color[0] + (color[1] << 8) + (color[2] << 16); + gizmo_id = id; } } else @@ -6676,21 +6674,21 @@ void GLCanvas3D::_render_background() const ::glBegin(GL_QUADS); - float* background_color = m_is_dark ? DEFAULT_BG_LIGHT_COLOR_DARK : DEFAULT_BG_LIGHT_COLOR; - float* error_background_color = m_is_dark ? ERROR_BG_LIGHT_COLOR_DARK : ERROR_BG_LIGHT_COLOR; + ColorRGB background_color = m_is_dark ? DEFAULT_BG_LIGHT_COLOR_DARK : DEFAULT_BG_LIGHT_COLOR; + ColorRGB error_background_color = m_is_dark ? ERROR_BG_LIGHT_COLOR_DARK : ERROR_BG_LIGHT_COLOR; if (use_error_color) - ::glColor3fv(error_background_color); + ::glColor3fv(error_background_color.data()); else - ::glColor3fv(background_color); + ::glColor3fv(background_color.data()); ::glVertex2f(-1.0f, -1.0f); ::glVertex2f(1.0f, -1.0f); if (use_error_color) - ::glColor3fv(error_background_color); + ::glColor3fv(error_background_color.data()); else - ::glColor3fv(background_color); + ::glColor3fv(background_color.data()); ::glVertex2f(1.0f, 1.0f); ::glVertex2f(-1.0f, 1.0f); @@ -7249,8 +7247,6 @@ void GLCanvas3D::_render_style_editor() void GLCanvas3D::_render_volumes_for_picking() const { - static const GLfloat INV_255 = 1.0f / 255.0f; - // do not cull backfaces to show broken geometry, if any glsafe(::glDisable(GL_CULL_FACE)); @@ -7266,13 +7262,9 @@ void GLCanvas3D::_render_volumes_for_picking() const // we reserve color = (0,0,0) for occluders (as the printbed) // so we shift volumes' id by 1 to get the proper color //BBS: remove the bed picking logic - unsigned int id = volume.second.first; - //unsigned int id = 1 + volume.second.first; - unsigned int r = (id & (0x000000FF << 0)) << 0; - unsigned int g = (id & (0x000000FF << 8)) >> 8; - unsigned int b = (id & (0x000000FF << 16)) >> 16; - unsigned int a = picking_checksum_alpha_channel(r, g, b); - glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255)); + const unsigned int id = volume.second.first; + //const unsigned int id = 1 + volume.second.first; + glsafe(::glColor4fv(picking_decode(id).data())); volume.first->render(); } } @@ -7870,15 +7862,15 @@ void GLCanvas3D::_render_paint_toolbar() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImGuiContext& context = *GImGui; bool disabled = !wxGetApp().plater()->can_fillcolor(); - unsigned char rgb[3]; + ColorRGBA rgba; for (int i = 0; i < extruder_num; i++) { if (i > 0) ImGui::SameLine(); - Slic3r::GUI::BitmapCache::parse_color(colors[i], rgb); - ImGui::PushStyleColor(ImGuiCol_Button, ImColor(rgb[0], rgb[1], rgb[2]).Value); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImColor(rgb[0], rgb[1], rgb[2]).Value); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImColor(rgb[0], rgb[1], rgb[2]).Value); + decode_color(colors[i], rgba); + ImGui::PushStyleColor(ImGuiCol_Button, ImGuiWrapper::to_ImVec4(rgba)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGuiWrapper::to_ImVec4(rgba)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGuiWrapper::to_ImVec4(rgba)); if (disabled) ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); if (ImGui::Button(("##filament_button" + std::to_string(i)).c_str(), button_size)) { @@ -7899,9 +7891,9 @@ void GLCanvas3D::_render_paint_toolbar() const } const float text_offset_y = 4.0f * em_unit * f_scale; - for (int i = 0; i < extruder_num; i++){ - Slic3r::GUI::BitmapCache::parse_color(colors[i], rgb); - float gray = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]; + for (int i = 0; i < extruder_num; i++) { + decode_color(colors[i], rgba); + float gray = 0.299 * rgba.r_uchar() + 0.587 * rgba.g_uchar() + 0.114 * rgba.b_uchar(); ImVec4 text_color = gray < 80 ? ImVec4(1.0f, 1.0f, 1.0f, 1.0f) : ImVec4(0, 0, 0, 1.0f); imgui.push_bold_font(); @@ -8375,7 +8367,7 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume) if (!print->has_skirt() && !print->has_brim()) return; - const std::array color = { 0.5f, 1.0f, 0.5f, 1.0f }; // greenish + const ColorRGBA color = ColorRGBA::GREENISH(); // number of skirt layers size_t total_layer_count = 0; @@ -8421,7 +8413,8 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume) void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume& build_volume, const std::vector& str_tool_colors, const std::vector& color_print_values) { - std::vector> tool_colors = _parse_colors(str_tool_colors); + std::vector tool_colors; + decode_colors(str_tool_colors, tool_colors); struct Ctxt { @@ -8430,20 +8423,20 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c bool has_perimeters; bool has_infill; bool has_support; - const std::vector>* tool_colors; + const std::vector* tool_colors; bool is_single_material_print; int filaments_cnt; const std::vector* color_print_values; - static const std::array& color_perimeters() { static std::array color = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow - static const std::array& color_infill() { static std::array color = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish - static const std::array& color_support() { static std::array color = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish - static const std::array& color_pause_or_custom_code() { static std::array color = { 0.5f, 0.5f, 0.5f, 1.f }; return color; } // gray + static ColorRGBA color_perimeters() { return ColorRGBA::YELLOW(); } + static ColorRGBA color_infill() { return ColorRGBA::REDISH(); } + static ColorRGBA color_support() { return ColorRGBA::GREENISH(); } + static ColorRGBA color_pause_or_custom_code() { return ColorRGBA::GRAY(); } // For cloring by a tool, return a parsed color. bool color_by_tool() const { return tool_colors != nullptr; } size_t number_tools() const { return color_by_tool() ? tool_colors->size() : 0; } - const std::array& color_tool(size_t tool) const { return (*tool_colors)[tool]; } + const ColorRGBA& color_tool(size_t tool) const { return (*tool_colors)[tool]; } // For coloring by a color_print(M600), return a parsed color. bool color_by_color_print() const { return color_print_values!=nullptr; } @@ -8583,7 +8576,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c //FIXME Improve the heuristics for a grain size. size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1)); tbb::spin_mutex new_volume_mutex; - auto new_volume = [this, &new_volume_mutex](const std::array& color) { + auto new_volume = [this, &new_volume_mutex](const ColorRGBA& color) { // Allocate the volume before locking. GLVolume *volume = new GLVolume(color); volume->is_extrusion_path = true; @@ -8725,21 +8718,22 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con if (!print->is_step_done(psWipeTower)) return; - std::vector> tool_colors = _parse_colors(str_tool_colors); + std::vector tool_colors; + decode_colors(str_tool_colors, tool_colors); struct Ctxt { const Print *print; - const std::vector>* tool_colors; + const std::vector* tool_colors; Vec2f wipe_tower_pos; float wipe_tower_angle; - static const std::array& color_support() { static std::array color = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish + static ColorRGBA color_support() { return ColorRGBA::GREENISH(); } // For cloring by a tool, return a parsed color. bool color_by_tool() const { return tool_colors != nullptr; } size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() : 0; } - const std::array& color_tool(size_t tool) const { return (*tool_colors)[tool]; } + const ColorRGBA& color_tool(size_t tool) const { return (*tool_colors)[tool]; } int volume_idx(int tool, int feature) const { return this->color_by_tool() ? std::min(this->number_tools() - 1, std::max(tool, 0)) : feature; } @@ -8779,7 +8773,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con size_t n_items = print->wipe_tower_data().tool_changes.size() + (ctxt.priming.empty() ? 0 : 1); size_t grain_size = std::max(n_items / 128, size_t(1)); tbb::spin_mutex new_volume_mutex; - auto new_volume = [this, &new_volume_mutex](const std::array& color) { + auto new_volume = [this, &new_volume_mutex](const ColorRGBA& color) { auto *volume = new GLVolume(color); volume->is_extrusion_path = true; tbb::spin_mutex::scoped_lock lock; @@ -8898,7 +8892,7 @@ void GLCanvas3D::_load_sla_shells() return; auto add_volume = [this](const SLAPrintObject &object, int volume_id, const SLAPrintObject::Instance& instance, - const TriangleMesh& mesh, const std::array& color, bool outside_printer_detection_enabled) { + const TriangleMesh& mesh, const ColorRGBA& color, bool outside_printer_detection_enabled) { m_volumes.volumes.emplace_back(new GLVolume(color)); GLVolume& v = *m_volumes.volumes.back(); #if ENABLE_SMOOTH_NORMALS @@ -8970,28 +8964,6 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning) _set_warning_notification(warning, show); } -std::vector> GLCanvas3D::_parse_colors(const std::vector& colors) -{ - static const float INV_255 = 1.0f / 255.0f; - - std::vector> output(colors.size(), { 1.0f, 1.0f, 1.0f, 1.0f }); - for (size_t i = 0; i < colors.size(); ++i) { - const std::string& color = colors[i]; - const char* c = color.data() + 1; - if (color.size() == 7 && color.front() == '#') { - for (size_t j = 0; j < 3; ++j) { - int digit1 = hex_digit_to_int(*c++); - int digit2 = hex_digit_to_int(*c++); - if (digit1 == -1 || digit2 == -1) - break; - - output[i][j] = float(digit1 * 16 + digit2) * INV_255; - } - } - } - return output; -} - void GLCanvas3D::_set_warning_notification(EWarning warning, bool state) { enum ErrorType{ diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index fb1780c7bc..7f03f00f3c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -199,14 +199,6 @@ class GLCanvas3D static const double DefaultCameraZoomToBedMarginFactor; static const double DefaultCameraZoomToPlateMarginFactor; - - static float DEFAULT_BG_LIGHT_COLOR[3]; - static float ERROR_BG_LIGHT_COLOR[3]; - static float DEFAULT_BG_LIGHT_COLOR_LIGHT[3]; - static float ERROR_BG_LIGHT_COLOR_LIGHT[3]; - static float DEFAULT_BG_LIGHT_COLOR_DARK[3]; - static float ERROR_BG_LIGHT_COLOR_DARK[3]; - static void update_render_colors(); static void load_render_colors(); @@ -857,15 +849,15 @@ public: void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, const GLVolumeCollection& volumes, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); static void render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, - const GLVolumeCollection& volumes, std::vector>& extruder_colors, + const GLVolumeCollection& volumes, std::vector& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); // render thumbnail using an off-screen framebuffer static void render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, + PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); // render thumbnail using an off-screen framebuffer when GLEW_EXT_framebuffer_object is supported static void render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, - PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, + PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false); //BBS use gcoder viewer render calibration thumbnails @@ -1155,7 +1147,7 @@ private: bool _render_orient_menu(float left, float right, float bottom, float top); bool _render_arrange_menu(float left, float right, float bottom, float top); // render thumbnail using the default framebuffer - void render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type); + void render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type); void _update_volumes_hover_state(); @@ -1201,8 +1193,6 @@ private: // BBS FIXME float get_overlay_window_width() { return 0; /*LayersEditing::get_overlay_window_width();*/ } - - static std::vector> _parse_colors(const std::vector& colors); }; } // namespace GUI diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 422b654080..fa804efc2f 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -165,7 +165,7 @@ bool GLModel::init_from_file(const std::string& filename) return true; } -void GLModel::set_color(int entity_id, const std::array& color) +void GLModel::set_color(int entity_id, const ColorRGBA& color) { for (size_t i = 0; i < m_render_data.size(); ++i) { if (entity_id == -1 || static_cast(i) == entity_id) diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index d47c56fd93..62722b18cf 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -3,6 +3,7 @@ #include "libslic3r/Point.hpp" #include "libslic3r/BoundingBox.hpp" +#include "libslic3r/Color.hpp" #include #include @@ -33,7 +34,7 @@ namespace GUI { unsigned int vbo_id{ 0 }; unsigned int ibo_id{ 0 }; size_t indices_count{ 0 }; - std::array color{ 1.0f, 1.0f, 1.0f, 1.0f }; + ColorRGBA color; }; struct InitializationData @@ -44,7 +45,7 @@ namespace GUI { std::vector positions; std::vector normals; std::vector indices; - std::array color{ 1.0f, 1.0f, 1.0f, 1.0f }; + ColorRGBA color; }; std::vector entities; @@ -74,7 +75,7 @@ namespace GUI { bool init_from_file(const std::string& filename); // if entity_id == -1 set the color of all entities - void set_color(int entity_id, const std::array& color); + void set_color(int entity_id, const ColorRGBA& color); void reset(); void render() const; diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index 9c1e936525..32b3d59601 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -4,6 +4,7 @@ #include "3DScene.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/format.hpp" +#include "libslic3r/Color.hpp" #include #include @@ -206,154 +207,114 @@ void GLShaderProgram::stop_using() const glsafe(::glUseProgram(0)); } -bool GLShaderProgram::set_uniform(const char* name, int value) const +void GLShaderProgram::set_uniform(int id, int value) const { - int id = get_uniform_location(name); - if (id >= 0) { - glsafe(::glUniform1i(id, static_cast(value))); - return true; - } - return false; + if (id >= 0) + glsafe(::glUniform1i(id, value)); } -bool GLShaderProgram::set_uniform(const char* name, bool value) const +void GLShaderProgram::set_uniform(int id, bool value) const { - return set_uniform(name, value ? 1 : 0); + set_uniform(id, value ? 1 : 0); } -bool GLShaderProgram::set_uniform(const char* name, float value) const +void GLShaderProgram::set_uniform(int id, float value) const { - int id = get_uniform_location(name); - if (id >= 0) { - glsafe(::glUniform1f(id, static_cast(value))); - return true; - } - return false; + if (id >= 0) + glsafe(::glUniform1f(id, value)); } -bool GLShaderProgram::set_uniform(const char* name, double value) const +void GLShaderProgram::set_uniform(int id, double value) const { - return set_uniform(name, static_cast(value)); + set_uniform(id, static_cast(value)); } -bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +void GLShaderProgram::set_uniform(int id, const std::array& value) const { - int id = get_uniform_location(name); - if (id >= 0) { + if (id >= 0) glsafe(::glUniform2iv(id, 1, static_cast(value.data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +void GLShaderProgram::set_uniform(int id, const std::array& value) const { - int id = get_uniform_location(name); - if (id >= 0) { + if (id >= 0) glsafe(::glUniform3iv(id, 1, static_cast(value.data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +void GLShaderProgram::set_uniform(int id, const std::array& value) const { - int id = get_uniform_location(name); - if (id >= 0) { + if (id >= 0) glsafe(::glUniform4iv(id, 1, static_cast(value.data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +void GLShaderProgram::set_uniform(int id, const std::array& value) const { - int id = get_uniform_location(name); - if (id >= 0) { + if (id >= 0) glsafe(::glUniform2fv(id, 1, static_cast(value.data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +void GLShaderProgram::set_uniform(int id, const std::array& value) const { - int id = get_uniform_location(name); - if (id >= 0) { + if (id >= 0) glsafe(::glUniform3fv(id, 1, static_cast(value.data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const std::array& value) const +void GLShaderProgram::set_uniform(int id, const std::array& value) const { - int id = get_uniform_location(name); - if (id >= 0) { + if (id >= 0) glsafe(::glUniform4fv(id, 1, static_cast(value.data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const float* value, size_t size) const +void GLShaderProgram::set_uniform(int id, const float* value, size_t size) const { - if (size == 1) - return set_uniform(name, value[0]); - else if (size < 5) { - int id = get_uniform_location(name); - if (id >= 0) { - if (size == 2) - glsafe(::glUniform2fv(id, 1, static_cast(value))); - else if (size == 3) - glsafe(::glUniform3fv(id, 1, static_cast(value))); - else - glsafe(::glUniform4fv(id, 1, static_cast(value))); - - return true; - } - } - return false; -} - -bool GLShaderProgram::set_uniform(const char* name, const Transform3f& value) const -{ - int id = get_uniform_location(name); if (id >= 0) { + if (size == 1) + set_uniform(id, value[0]); + else if (size == 2) + glsafe(::glUniform2fv(id, 1, static_cast(value))); + else if (size == 3) + glsafe(::glUniform3fv(id, 1, static_cast(value))); + else if (size == 4) + glsafe(::glUniform4fv(id, 1, static_cast(value))); + } +} + +void GLShaderProgram::set_uniform(int id, const Transform3f& value) const +{ + if (id >= 0) glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, static_cast(value.matrix().data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const Transform3d& value) const +void GLShaderProgram::set_uniform(int id, const Transform3d& value) const { - return set_uniform(name, value.cast()); + set_uniform(id, value.cast()); } -bool GLShaderProgram::set_uniform(const char* name, const Matrix3f& value) const +void GLShaderProgram::set_uniform(int id, const Matrix3f& value) const { - int id = get_uniform_location(name); - if (id >= 0) { + if (id >= 0) glsafe(::glUniformMatrix3fv(id, 1, GL_FALSE, static_cast(value.data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const Vec3f& value) const +void GLShaderProgram::set_uniform(int id, const Vec3f& value) const { - int id = get_uniform_location(name); - if (id >= 0) { + if (id >= 0) glsafe(::glUniform3fv(id, 1, static_cast(value.data()))); - return true; - } - return false; } -bool GLShaderProgram::set_uniform(const char* name, const Vec3d& value) const +void GLShaderProgram::set_uniform(int id, const Vec3d& value) const { - return set_uniform(name, static_cast(value.cast())); + set_uniform(id, static_cast(value.cast())); +} + +void GLShaderProgram::set_uniform(int id, const ColorRGB& value) const +{ + set_uniform(id, value.data(), 3); +} + +void GLShaderProgram::set_uniform(int id, const ColorRGBA& value) const +{ + set_uniform(id, value.data(), 4); } int GLShaderProgram::get_attrib_location(const char* name) const diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index d7b92000df..975c12c24a 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -9,6 +9,8 @@ namespace Slic3r { +class ColorRGB; +class ColorRGBA; class GLShaderProgram { public: @@ -44,22 +46,43 @@ public: void start_using() const; void stop_using() const; - bool set_uniform(const char* name, int value) const; - bool set_uniform(const char* name, bool value) const; - bool set_uniform(const char* name, float value) const; - bool set_uniform(const char* name, double value) const; - bool set_uniform(const char* name, const std::array& value) const; - bool set_uniform(const char* name, const std::array& value) const; - bool set_uniform(const char* name, const std::array& value) const; - bool set_uniform(const char* name, const std::array& value) const; - bool set_uniform(const char* name, const std::array& value) const; - bool set_uniform(const char* name, const std::array& value) const; - bool set_uniform(const char* name, const float* value, size_t size) const; - bool set_uniform(const char* name, const Transform3f& value) const; - bool set_uniform(const char* name, const Transform3d& value) const; - bool set_uniform(const char* name, const Matrix3f& value) const; - bool set_uniform(const char* name, const Vec3f& value) const; - bool set_uniform(const char* name, const Vec3d& value) const; + void set_uniform(const char* name, int value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, bool value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, float value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, double value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const std::array& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const float* value, size_t size) const { set_uniform(get_uniform_location(name), value, size); } + void set_uniform(const char* name, const Transform3f& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const Transform3d& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const Matrix3f& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const Vec3f& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const Vec3d& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const ColorRGB& value) const { set_uniform(get_uniform_location(name), value); } + void set_uniform(const char* name, const ColorRGBA& value) const { set_uniform(get_uniform_location(name), value); } + + void set_uniform(int id, int value) const; + void set_uniform(int id, bool value) const; + void set_uniform(int id, float value) const; + void set_uniform(int id, double value) const; + void set_uniform(int id, const std::array& value) const; + void set_uniform(int id, const std::array& value) const; + void set_uniform(int id, const std::array& value) const; + void set_uniform(int id, const std::array& value) const; + void set_uniform(int id, const std::array& value) const; + void set_uniform(int id, const std::array& value) const; + void set_uniform(int id, const float* value, size_t size) const; + void set_uniform(int id, const Transform3f& value) const; + void set_uniform(int id, const Transform3d& value) const; + void set_uniform(int id, const Matrix3f& value) const; + void set_uniform(int id, const Vec3f& value) const; + void set_uniform(int id, const Vec3d& value) const; + void set_uniform(int id, const ColorRGB& value) const; + void set_uniform(int id, const ColorRGBA& value) const; // returns -1 if not found int get_attrib_location(const char* name) const; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index dcbf17321a..3e6b699878 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -56,6 +56,7 @@ #include "libslic3r/Thread.hpp" #include "libslic3r/miniz_extension.hpp" #include "libslic3r/Utils.hpp" +#include "libslic3r/Color.hpp" #include "GUI.hpp" #include "GUI_Utils.hpp" @@ -3228,8 +3229,7 @@ void GUI_App::set_label_clr_modified(const wxColour& clr) if (m_color_label_modified == clr) return; m_color_label_modified = clr; - auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue()); - std::string str = clr_str.ToStdString(); + const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue())); app_config->save(); */ } @@ -3242,8 +3242,7 @@ void GUI_App::set_label_clr_sys(const wxColour& clr) if (m_color_label_sys == clr) return; m_color_label_sys = clr; - auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue()); - std::string str = clr_str.ToStdString(); + const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue())); app_config->save(); */ } diff --git a/src/slic3r/GUI/GUI_Colors.hpp b/src/slic3r/GUI/GUI_Colors.hpp index 32a0399181..0395e997c0 100644 --- a/src/slic3r/GUI/GUI_Colors.hpp +++ b/src/slic3r/GUI/GUI_Colors.hpp @@ -2,6 +2,7 @@ #define slic3r_GUI_Colors_hpp_ #include "imgui/imgui.h" +#include "libslic3r/Color.hpp" enum RenderCol_ { RenderCol_3D_Background = 0, @@ -38,13 +39,6 @@ public: static ImVec4 colors[RenderCol_Count]; }; const char* GetRenderColName(RenderCol idx); -inline std::array GLColor(ImVec4 color) { - return {color.x, color.y, color.z, color.w }; -} - -inline ImVec4 IMColor(std::array color) { - return ImVec4(color[0], color[1], color[2], color[3]); -} } diff --git a/src/slic3r/GUI/GUI_ObjectTable.cpp b/src/slic3r/GUI/GUI_ObjectTable.cpp index 3f194ec4e6..eda7c15b71 100644 --- a/src/slic3r/GUI/GUI_ObjectTable.cpp +++ b/src/slic3r/GUI/GUI_ObjectTable.cpp @@ -2812,13 +2812,13 @@ int ObjectTablePanel::init_filaments_and_colors() } unsigned int i = 0; - unsigned char rgb[3]; + ColorRGB rgb; while (i < m_filaments_count) { const std::string& txt_color = global_config->opt_string("filament_colour", i); if (i < color_count) { - if (Slic3r::GUI::BitmapCache::parse_color(txt_color, rgb)) + if (decode_color(txt_color, rgb)) { - m_filaments_colors[i] = wxColour(rgb[0], rgb[1], rgb[2]); + m_filaments_colors[i] = wxColour(rgb.r_uchar(), rgb.g_uchar(), rgb.b_uchar()); } else { diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index bf2c4277b8..ab3d2fd794 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -23,6 +23,7 @@ #include "Event.hpp" #include "../libslic3r/libslic3r_version.h" #include "../libslic3r/Utils.hpp" +#include "libslic3r/Color.hpp" class wxCheckBox; @@ -39,28 +40,10 @@ inline int hex_to_int(const char c) return (c >= '0' && c <= '9') ? int(c - '0') : (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 : (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; } -static std::array decode_color_to_float_array(const std::string color) +static ColorRGBA decode_color_to_float_array(const std::string color) { - // set alpha to 1.0f by default - std::array ret = {0, 0, 0, 1.0f}; - const char * c = color.data() + 1; - if (color.size() == 7 && color.front() == '#') { - for (size_t j = 0; j < 3; ++j) { - int digit1 = hex_to_int(*c++); - int digit2 = hex_to_int(*c++); - if (digit1 == -1 || digit2 == -1) break; - ret[j] = float(digit1 * 16 + digit2) / 255.0f; - } - } - else if (color.size() == 9 && color.front() == '#') { - for (size_t j = 0; j < 4; ++j) { - int digit1 = hex_to_int(*c++); - int digit2 = hex_to_int(*c++); - if (digit1 == -1 || digit2 == -1) break; - - ret[j] = float(digit1 * 16 + digit2) / 255.0f; - } - } + ColorRGBA ret = ColorRGBA::BLACK(); + decode_color(color, ret); return ret; } @@ -470,14 +453,6 @@ public: std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics); -inline int hex_digit_to_int(const char c) -{ - return - (c >= '0' && c <= '9') ? int(c - '0') : - (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 : - (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; -} - class TaskTimer { std::chrono::milliseconds start_timer; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp index ba97805013..bc1ff411a1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp @@ -28,8 +28,6 @@ const float UndefFloat = -999.f; // connector colors -using ColorRGBA = std::array; - static const ColorRGBA BLACK() { return {0.0f, 0.0f, 0.0f, 1.0f}; } static const ColorRGBA BLUE() { return {0.0f, 0.0f, 1.0f, 1.0f}; } static const ColorRGBA BLUEISH() { return {0.5f, 0.5f, 1.0f, 1.0f}; } @@ -103,8 +101,8 @@ static void rotate_z_3d(std::array& verts, float radian_angle) const double GLGizmoAdvancedCut::Offset = 10.0; const double GLGizmoAdvancedCut::Margin = 20.0; -const std::array GLGizmoAdvancedCut::GrabberColor = { 1.0, 1.0, 0.0, 1.0 }; -const std::array GLGizmoAdvancedCut::GrabberHoverColor = { 0.7, 0.7, 0.0, 1.0}; +const ColorRGBA GLGizmoAdvancedCut::GrabberColor = { 1.0f, 1.0f, 0.0f, 1.0f }; +const ColorRGBA GLGizmoAdvancedCut::GrabberHoverColor = { 0.7f, 0.7f, 0.0f, 1.0f }; GLGizmoAdvancedCut::GLGizmoAdvancedCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoRotate3D(parent, icon_filename, sprite_id, nullptr) @@ -525,11 +523,7 @@ void GLGizmoAdvancedCut::on_render_for_picking() float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0); #endif - std::array color = picking_color_component(0); - m_move_grabber.color[0] = color[0]; - m_move_grabber.color[1] = color[1]; - m_move_grabber.color[2] = color[2]; - m_move_grabber.color[3] = color[3]; + m_move_grabber.color = picking_color_component(0); m_move_grabber.render_for_picking(mean_size); glsafe(::glEnable(GL_DEPTH_TEST)); @@ -564,7 +558,7 @@ void GLGizmoAdvancedCut::on_render_for_picking() const Transform3d view_model_matrix = translate_tf * m_rotate_matrix * scale_tf; - std::array color = picking_color_component(i+1); + ColorRGBA color = picking_color_component(i+1); render_connector_model(m_shapes[connectors[i].attribs], color, view_model_matrix, true); } } @@ -919,7 +913,7 @@ void GLGizmoAdvancedCut::render_cut_plane_and_grabbers() // m_move_grabber.hover_color = GrabberHoverColor; // m_move_grabber.render(m_hover_id == get_group_id(), (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0)); bool hover = (m_hover_id == get_group_id()); - std::array render_color; + ColorRGBA render_color; if (hover) { render_color = GrabberHoverColor; } @@ -1036,7 +1030,7 @@ void GLGizmoAdvancedCut::render_cut_line() glDisable(GL_LINE_STIPPLE); } -void GLGizmoAdvancedCut::render_connector_model(GLModel &model, const std::array &color, Transform3d view_model_matrix, bool for_picking) +void GLGizmoAdvancedCut::render_connector_model(GLModel &model, const ColorRGBA &color, Transform3d view_model_matrix, bool for_picking) { glPushMatrix(); GLShaderProgram *shader = nullptr; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp index 5cb9e765cc..38abb30c3f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp @@ -27,8 +27,8 @@ struct Rotate_data { private: static const double Offset; static const double Margin; - static const std::array GrabberColor; - static const std::array GrabberHoverColor; + static const ColorRGBA GrabberColor; + static const ColorRGBA GrabberHoverColor; mutable double m_movement; mutable double m_height; // height of cut plane to heatbed @@ -201,7 +201,7 @@ private: void render_connectors(); void render_clipper_cut(); void render_cut_line(); - void render_connector_model(GLModel &model, const std::array& color, Transform3d view_model_matrix, bool for_picking = false); + void render_connector_model(GLModel &model, const ColorRGBA& color, Transform3d view_model_matrix, bool for_picking = false); void clear_selection(); void init_connector_shapes(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index b1d98d3dc2..75efc8902b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -21,51 +21,51 @@ const float GLGizmoBase::Grabber::FixedGrabberSize = 16.0f; const float GLGizmoBase::Grabber::FixedRadiusSize = 80.0f; -std::array GLGizmoBase::DEFAULT_BASE_COLOR = { 0.625f, 0.625f, 0.625f, 1.0f }; -std::array GLGizmoBase::DEFAULT_DRAG_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; -std::array GLGizmoBase::DEFAULT_HIGHLIGHT_COLOR = { 1.0f, 0.38f, 0.0f, 1.0f }; -std::array, 3> GLGizmoBase::AXES_HOVER_COLOR = {{ +ColorRGBA GLGizmoBase::DEFAULT_BASE_COLOR = { 0.625f, 0.625f, 0.625f, 1.0f }; +ColorRGBA GLGizmoBase::DEFAULT_DRAG_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; +ColorRGBA GLGizmoBase::DEFAULT_HIGHLIGHT_COLOR = {1.0f, 0.38f, 0.0f, 1.0f}; +std::array GLGizmoBase::AXES_HOVER_COLOR = {{ { 0.7f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.7f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.7f, 1.0f } }}; -std::array, 3> GLGizmoBase::AXES_COLOR = { { +std::array GLGizmoBase::AXES_COLOR = {{ { 1.0, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }}; -std::array GLGizmoBase::CONSTRAINED_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f }; -std::array GLGizmoBase::FLATTEN_COLOR = { 0.96f, 0.93f, 0.93f, 0.5f }; -std::array GLGizmoBase::FLATTEN_HOVER_COLOR = { 1.0f, 1.0f, 1.0f, 0.75f }; +ColorRGBA GLGizmoBase::CONSTRAINED_COLOR = {0.5f, 0.5f, 0.5f, 1.0f}; +ColorRGBA GLGizmoBase::FLATTEN_COLOR = {0.96f, 0.93f, 0.93f, 0.5f}; +ColorRGBA GLGizmoBase::FLATTEN_HOVER_COLOR = {1.0f, 1.0f, 1.0f, 0.75f}; // new style color -std::array GLGizmoBase::GRABBER_NORMAL_COL = {1.0f, 1.0f, 1.0f, 1.0f}; -std::array GLGizmoBase::GRABBER_HOVER_COL = {0.863f, 0.125f, 0.063f, 1.0f}; -std::array GLGizmoBase::GRABBER_UNIFORM_COL = {0, 1.0, 1.0, 1.0f}; -std::array GLGizmoBase::GRABBER_UNIFORM_HOVER_COL = {0, 0.7, 0.7, 1.0f}; +ColorRGBA GLGizmoBase::GRABBER_NORMAL_COL = {1.0f, 1.0f, 1.0f, 1.0f}; +ColorRGBA GLGizmoBase::GRABBER_HOVER_COL = {0.863f, 0.125f, 0.063f, 1.0f}; +ColorRGBA GLGizmoBase::GRABBER_UNIFORM_COL = {0, 1.0, 1.0, 1.0f}; +ColorRGBA GLGizmoBase::GRABBER_UNIFORM_HOVER_COL = {0, 0.7, 0.7, 1.0f}; void GLGizmoBase::update_render_colors() { GLGizmoBase::AXES_COLOR = { { - GLColor(RenderColor::colors[RenderCol_Grabber_X]), - GLColor(RenderColor::colors[RenderCol_Grabber_Y]), - GLColor(RenderColor::colors[RenderCol_Grabber_Z]) + ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Grabber_X]), + ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Grabber_Y]), + ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Grabber_Z]) } }; - GLGizmoBase::FLATTEN_COLOR = GLColor(RenderColor::colors[RenderCol_Flatten_Plane]); - GLGizmoBase::FLATTEN_HOVER_COLOR = GLColor(RenderColor::colors[RenderCol_Flatten_Plane_Hover]); + GLGizmoBase::FLATTEN_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Flatten_Plane]); + GLGizmoBase::FLATTEN_HOVER_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Flatten_Plane_Hover]); } void GLGizmoBase::load_render_colors() { - RenderColor::colors[RenderCol_Grabber_X] = IMColor(GLGizmoBase::AXES_COLOR[0]); - RenderColor::colors[RenderCol_Grabber_Y] = IMColor(GLGizmoBase::AXES_COLOR[1]); - RenderColor::colors[RenderCol_Grabber_Z] = IMColor(GLGizmoBase::AXES_COLOR[2]); - RenderColor::colors[RenderCol_Flatten_Plane] = IMColor(GLGizmoBase::FLATTEN_COLOR); - RenderColor::colors[RenderCol_Flatten_Plane_Hover] = IMColor(GLGizmoBase::FLATTEN_HOVER_COLOR); + RenderColor::colors[RenderCol_Grabber_X] = ImGuiWrapper::to_ImVec4(GLGizmoBase::AXES_COLOR[0]); + RenderColor::colors[RenderCol_Grabber_Y] = ImGuiWrapper::to_ImVec4(GLGizmoBase::AXES_COLOR[1]); + RenderColor::colors[RenderCol_Grabber_Z] = ImGuiWrapper::to_ImVec4(GLGizmoBase::AXES_COLOR[2]); + RenderColor::colors[RenderCol_Flatten_Plane] = ImGuiWrapper::to_ImVec4(GLGizmoBase::FLATTEN_COLOR); + RenderColor::colors[RenderCol_Flatten_Plane_Hover] = ImGuiWrapper::to_ImVec4(GLGizmoBase::FLATTEN_HOVER_COLOR); } GLGizmoBase::Grabber::Grabber() @@ -80,7 +80,7 @@ GLGizmoBase::Grabber::Grabber() void GLGizmoBase::Grabber::render(bool hover, float size) const { - std::array render_color; + ColorRGBA render_color; if (hover) { render_color = hover_color; } @@ -113,7 +113,7 @@ const GLModel& GLGizmoBase::Grabber::get_cube() const return cube; } -void GLGizmoBase::Grabber::render(float size, const std::array& render_color, bool picking) const +void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking) const { if (! cube_initialized) { // This cannot be done in constructor, OpenGL is not yet @@ -179,10 +179,6 @@ void GLGizmoBase::set_hover_id(int id) } } -void GLGizmoBase::set_highlight_color(const std::array& color) -{ - m_highlight_color = color; -} void GLGizmoBase::enable_grabber(unsigned int id) { @@ -265,22 +261,13 @@ void GLGizmoBase::GizmoImguiSetNextWIndowPos(float &x, float y, int flag, float m_imgui->set_next_window_pos(x, y, flag, pivot_x, pivot_y); } -std::array GLGizmoBase::picking_color_component(unsigned int id) const +ColorRGBA GLGizmoBase::picking_color_component(unsigned int id) const { - static const float INV_255 = 1.0f / 255.0f; - id = BASE_ID - id; - if (m_group_id > -1) id -= m_group_id; - // color components are encoded to match the calculation of volume_id made into GLCanvas3D::_picking_pass() - return std::array { - float((id >> 0) & 0xff) * INV_255, // red - float((id >> 8) & 0xff) * INV_255, // green - float((id >> 16) & 0xff) * INV_255, // blue - float(picking_checksum_alpha_channel(id & 0xff, (id >> 8) & 0xff, (id >> 16) & 0xff))* INV_255 // checksum for validating against unwanted alpha blending and multi sampling - }; + return picking_decode(id); } void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const @@ -316,8 +303,7 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) { if (m_grabbers[i].enabled) { - std::array color = picking_color_component(i); - m_grabbers[i].color = color; + m_grabbers[i].color = picking_color_component(i); m_grabbers[i].render_for_picking(mean_size); } } @@ -354,23 +340,5 @@ std::string GLGizmoBase::get_name(bool include_shortcut) const return out; } - - -// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components -// were not interpolated by alpha blending or multi sampling. -unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue) -{ - // 8 bit hash for the color - unsigned char b = ((((37 * red) + green) & 0x0ff) * 37 + blue) & 0x0ff; - // Increase enthropy by a bit reversal - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; - // Flip every second bit to increase the enthropy even more. - b ^= 0x55; - return b; -} - - } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index c725809bba..1dea8f08d4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -2,6 +2,7 @@ #define slic3r_GLGizmoBase_hpp_ #include "libslic3r/Point.hpp" +#include "libslic3r/Color.hpp" #include "slic3r/GUI/I18N.hpp" #include "slic3r/GUI/GLModel.hpp" @@ -38,18 +39,18 @@ public: static float INV_ZOOM; //BBS colors - static std::array DEFAULT_BASE_COLOR; - static std::array DEFAULT_DRAG_COLOR; - static std::array DEFAULT_HIGHLIGHT_COLOR; - static std::array, 3> AXES_COLOR; - static std::array, 3> AXES_HOVER_COLOR; - static std::array CONSTRAINED_COLOR; - static std::array FLATTEN_COLOR; - static std::array FLATTEN_HOVER_COLOR; - static std::array GRABBER_NORMAL_COL; - static std::array GRABBER_HOVER_COL; - static std::array GRABBER_UNIFORM_COL; - static std::array GRABBER_UNIFORM_HOVER_COL; + static ColorRGBA DEFAULT_BASE_COLOR; + static ColorRGBA DEFAULT_DRAG_COLOR; + static ColorRGBA DEFAULT_HIGHLIGHT_COLOR; + static std::array AXES_COLOR; + static std::array AXES_HOVER_COLOR; + static ColorRGBA CONSTRAINED_COLOR; + static ColorRGBA FLATTEN_COLOR; + static ColorRGBA FLATTEN_HOVER_COLOR; + static ColorRGBA GRABBER_NORMAL_COL; + static ColorRGBA GRABBER_HOVER_COL; + static ColorRGBA GRABBER_UNIFORM_COL; + static ColorRGBA GRABBER_UNIFORM_HOVER_COL; static void update_render_colors(); static void load_render_colors(); @@ -65,8 +66,8 @@ protected: Vec3d center; Vec3d angles; - std::array color; - std::array hover_color; + ColorRGBA color; + ColorRGBA hover_color; bool enabled; bool dragging; @@ -80,7 +81,7 @@ protected: const GLModel& get_cube() const; private: - void render(float size, const std::array& render_color, bool picking) const; + void render(float size, const ColorRGBA& render_color, bool picking) const; GLModel cube; bool cube_initialized = false; @@ -114,9 +115,9 @@ protected: unsigned int m_sprite_id; int m_hover_id; bool m_dragging; - std::array m_base_color; - std::array m_drag_color; - std::array m_highlight_color; + ColorRGBA m_base_color; + ColorRGBA m_drag_color; + ColorRGBA m_highlight_color; mutable std::vector m_grabbers; ImGuiWrapper* m_imgui; bool m_first_input_window_render; @@ -169,7 +170,7 @@ public: int get_hover_id() const { return m_hover_id; } void set_hover_id(int id); - void set_highlight_color(const std::array& color); + void set_highlight_color(const ColorRGBA& color) { m_highlight_color = color; } void enable_grabber(unsigned int id); void disable_grabber(unsigned int id); @@ -219,7 +220,7 @@ protected: void GizmoImguiSetNextWIndowPos(float &x, float y, int flag, float pivot_x = 0.0f, float pivot_y = 0.0f); // Returns the picking color for the given id, based on the BASE_ID constant // No check is made for clashing with other picking color (i.e. GLVolumes) - std::array picking_color_component(unsigned int id) const; + ColorRGBA picking_color_component(unsigned int id) const; void render_grabbers(const BoundingBoxf3& box) const; void render_grabbers(float size) const; void render_grabbers_for_picking(const BoundingBoxf3& box) const; @@ -235,11 +236,6 @@ private: int count = 0; }; - -// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components -// were not interpolated by alpha blending or multi sampling. -extern unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue); - } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index d5008725e4..0e5d1c7308 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -23,7 +23,8 @@ namespace GUI { const double GLGizmoCut::Offset = 10.0; const double GLGizmoCut::Margin = 20.0; -const std::array GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0, 1.0 }; +static const ColorRGBA GRABBER_COLOR = ColorRGBA::ORANGE(); +static const ColorRGBA PLANE_COLOR = { 0.8f, 0.8f, 0.8f, 0.5f }; GLGizmoCut::GLGizmoCut(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) @@ -103,7 +104,7 @@ void GLGizmoCut::on_render() // Draw the cutting plane ::glBegin(GL_QUADS); - ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); + ::glColor4fv(PLANE_COLOR.data()); ::glVertex3f(min_x, min_y, plane_center.z()); ::glVertex3f(max_x, min_y, plane_center.z()); ::glVertex3f(max_x, max_y, plane_center.z()); @@ -134,7 +135,7 @@ void GLGizmoCut::on_render() shader->start_using(); shader->set_uniform("emission_factor", 0.1f); - m_grabbers[0].color = GrabberColor; + m_grabbers[0].color = GRABBER_COLOR; m_grabbers[0].render(m_hover_id == 0, (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0)); shader->stop_using(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index 0d745fe3cb..cf7c7ac042 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -13,7 +13,6 @@ class GLGizmoCut : public GLGizmoBase { static const double Offset; static const double Margin; - static const std::array GrabberColor; double m_cut_z{ 0.0 }; double m_max_z{ 0.0 }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index c095c0915e..49622d84c5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -640,7 +640,7 @@ void GLGizmoFdmSupports::update_from_model_object(bool first_update) m_volume_timestamps.clear(); int volume_id = -1; - std::vector> ebt_colors; + std::vector ebt_colors; ebt_colors.push_back(GLVolume::NEUTRAL_COLOR); ebt_colors.push_back(TriangleSelectorGUI::enforcers_color); ebt_colors.push_back(TriangleSelectorGUI::blockers_color); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 39bc98d7fb..8f73379e71 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -114,7 +114,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift())); glsafe(::glMultMatrixd(instance_matrix.data())); - std::array render_color; + ColorRGBA render_color; const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes; size_t cache_size = drain_holes.size(); @@ -127,8 +127,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons // First decide about the color of the point. if (picking) { - std::array color = picking_color_component(i); - render_color = color; + render_color = picking_color_component(i); } else { if (size_t(m_hover_id) == i) { @@ -140,11 +139,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons render_color = {1.f, 0.f, 0.f, .5f}; } else { // neigher hover nor picking - - render_color[0] = point_selected ? 1.0f : 1.f; - render_color[1] = point_selected ? 0.3f : 1.f; - render_color[2] = point_selected ? 0.3f : 1.f; - render_color[3] = 0.5f; + render_color = point_selected ? ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f) : ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f); } } @@ -544,14 +539,11 @@ RENDER_AGAIN: } m_imgui->disabled_begin(! m_enable_hollowing); - float max_tooltip_width = ImGui::GetFontSize() * 20.0f; ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("offset")); ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x); ImGui::PushItemWidth(window_width - settings_sliders_left); - m_imgui->slider_float("##offset", &offset, offset_min, offset_max, "%.1f mm"); - if (m_imgui->get_last_slider_status().hovered) - m_imgui->tooltip((_utf8(opts[0].second->tooltip)).c_str(), max_tooltip_width); + m_imgui->slider_float("##offset", &offset, offset_min, offset_max, "%.1f mm", 1.0f, true, _L(opts[0].second->tooltip)); bool slider_clicked = m_imgui->get_last_slider_status().clicked; // someone clicked the slider bool slider_edited =m_imgui->get_last_slider_status().edited; // someone is dragging the slider @@ -561,9 +553,7 @@ RENDER_AGAIN: ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("quality")); ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x); - m_imgui->slider_float("##quality", &quality, quality_min, quality_max, "%.1f"); - if (m_imgui->get_last_slider_status().hovered) - m_imgui->tooltip((_utf8(opts[1].second->tooltip)).c_str(), max_tooltip_width); + m_imgui->slider_float("##quality", &quality, quality_min, quality_max, "%.1f", 1.0f, true, _L(opts[1].second->tooltip)); slider_clicked |= m_imgui->get_last_slider_status().clicked; slider_edited |= m_imgui->get_last_slider_status().edited; @@ -574,9 +564,7 @@ RENDER_AGAIN: ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("closing_distance")); ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x); - m_imgui->slider_float("##closing_distance", &closing_d, closing_d_min, closing_d_max, "%.1f mm"); - if (m_imgui->get_last_slider_status().hovered) - m_imgui->tooltip((_utf8(opts[2].second->tooltip)).c_str(), max_tooltip_width); + m_imgui->slider_float("##closing_distance", &closing_d, closing_d_min, closing_d_max, "%.1f mm", 1.0f, true, _L(opts[2].second->tooltip)); slider_clicked |= m_imgui->get_last_slider_status().clicked; slider_edited |= m_imgui->get_last_slider_status().edited; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 517e880d93..3dbb020fe6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -58,11 +58,11 @@ bool GLGizmoMmuSegmentation::on_is_activable() const } //BBS: use the global one in 3DScene.cpp -/*static std::vector> get_extruders_colors() +/*static std::vector get_extruders_colors() { unsigned char rgb_color[3] = {}; std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); - std::vector> colors_out(colors.size()); + std::vector colors_out(colors.size()); for (const std::string &color : colors) { Slic3r::GUI::BitmapCache::parse_color(color, rgb_color); size_t color_idx = &color - &colors.front(); @@ -276,18 +276,14 @@ bool GLGizmoMmuSegmentation::on_key_down_select_tool_type(int keyCode) { return true; } -static void render_extruders_combo(const std::string &label, - const std::vector &extruders, - const std::vector> &extruders_colors, - size_t &selection_idx) +static void render_extruders_combo(const std::string& label, + const std::vector& extruders, + const std::vector& extruders_colors, + size_t& selection_idx) { assert(!extruders_colors.empty()); assert(extruders_colors.size() == extruders_colors.size()); - auto convert_to_imu32 = [](const std::array &color) -> ImU32 { - return IM_COL32(uint8_t(color[0] * 255.f), uint8_t(color[1] * 255.f), uint8_t(color[2] * 255.f), uint8_t(color[3] * 255.f)); - }; - size_t selection_out = selection_idx; // It is necessary to use BeginGroup(). Otherwise, when using SameLine() is called, then other items will be drawn inside the combobox. ImGui::BeginGroup(); @@ -303,7 +299,7 @@ static void render_extruders_combo(const std::string &labe ImGui::SameLine(); ImGuiStyle &style = ImGui::GetStyle(); float height = ImGui::GetTextLineHeight(); - ImGui::GetWindowDrawList()->AddRectFilled(start_position, ImVec2(start_position.x + height + height / 2, start_position.y + height), convert_to_imu32(extruders_colors[extruder_idx])); + ImGui::GetWindowDrawList()->AddRectFilled(start_position, ImVec2(start_position.x + height + height / 2, start_position.y + height), ImGuiWrapper::to_ImU32(extruders_colors[extruder_idx])); ImGui::GetWindowDrawList()->AddRect(start_position, ImVec2(start_position.x + height + height / 2, start_position.y + height), IM_COL32_BLACK); ImGui::SetCursorScreenPos(ImVec2(start_position.x + height + height / 2 + style.FramePadding.x, start_position.y)); @@ -321,7 +317,7 @@ static void render_extruders_combo(const std::string &labe ImVec2 p = ImGui::GetCursorScreenPos(); float height = ImGui::GetTextLineHeight(); - ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + height + height / 2, p.y + height), convert_to_imu32(extruders_colors[selection_idx])); + ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + height + height / 2, p.y + height), ImGuiWrapper::to_ImU32(extruders_colors[selection_idx])); ImGui::GetWindowDrawList()->AddRect(p, ImVec2(p.x + height + height / 2, p.y + height), IM_COL32_BLACK); ImGui::SetCursorScreenPos(ImVec2(p.x + height + height / 2 + style.FramePadding.x, p.y)); @@ -448,8 +444,8 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott const float item_spacing = m_imgui->scaled(0.8f); size_t n_extruder_colors = std::min((size_t)EnforcerBlockerType::ExtruderMax, m_extruders_colors.size()); for (int extruder_idx = 0; extruder_idx < n_extruder_colors; extruder_idx++) { - const std::array &extruder_color = m_extruders_colors[extruder_idx]; - ImVec4 color_vec(extruder_color[0], extruder_color[1], extruder_color[2], extruder_color[3]); + const ColorRGBA &extruder_color = m_extruders_colors[extruder_idx]; + ImVec4 color_vec = ImGuiWrapper::to_ImVec4(extruder_color); std::string color_label = std::string("##extruder color ") + std::to_string(extruder_idx); std::string item_text = std::to_string(extruder_idx + 1); const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true); @@ -486,7 +482,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott if (extruder_idx < 9 && ImGui::IsItemHovered()) m_imgui->tooltip(_L("Shortcut Key ") + std::to_string(extruder_idx + 1), max_tooltip_width); // draw filament id - float gray = 0.299 * extruder_color[0] + 0.587 * extruder_color[1] + 0.114 * extruder_color[2]; + float gray = 0.299 * extruder_color.r() + 0.587 * extruder_color.g() + 0.114 * extruder_color.b(); ImGui::SameLine(button_offset + (button_size.x - label_size.x) / 2.f); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {10.0,15.0}); if (gray * 255.f < 80.f) @@ -811,7 +807,7 @@ void GLGizmoMmuSegmentation::init_model_triangle_selectors() continue; int extruder_idx = (mv->extruder_id() > 0) ? mv->extruder_id() - 1 : 0; - std::vector> ebt_colors; + std::vector ebt_colors; ebt_colors.push_back(m_extruders_colors[size_t(extruder_idx)]); ebt_colors.insert(ebt_colors.end(), m_extruders_colors.begin(), m_extruders_colors.end()); @@ -833,7 +829,7 @@ void GLGizmoMmuSegmentation::update_triangle_selectors_colors() TriangleSelectorPatch* selector = dynamic_cast(m_triangle_selectors[i].get()); int extruder_idx = m_volumes_extruder_idxs[i]; int extruder_color_idx = std::max(0, extruder_idx - 1); - std::vector> ebt_colors; + std::vector ebt_colors; ebt_colors.push_back(m_extruders_colors[extruder_color_idx]); ebt_colors.insert(ebt_colors.end(), m_extruders_colors.begin(), m_extruders_colors.end()); selector->set_ebt_colors(ebt_colors); @@ -871,7 +867,7 @@ PainterGizmoType GLGizmoMmuSegmentation::get_painter_type() const } // BBS -std::array GLGizmoMmuSegmentation::get_cursor_hover_color() const +ColorRGBA GLGizmoMmuSegmentation::get_cursor_hover_color() const { if (m_selected_extruder_idx < m_extruders_colors.size()) return m_extruders_colors[m_selected_extruder_idx]; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp index 6b5cde25c7..e7ec8d7bc2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp @@ -87,7 +87,7 @@ public: protected: // BBS - std::array get_cursor_hover_color() const override; + ColorRGBA get_cursor_hover_color() const override; void on_set_state() override; EnforcerBlockerType get_left_button_state_type() const override { return EnforcerBlockerType(m_selected_extruder_idx + 1); } @@ -107,7 +107,7 @@ protected: // BBS size_t m_selected_extruder_idx = 0; - std::vector> m_extruders_colors; + std::vector m_extruders_colors; std::vector m_volumes_extruder_idxs; // BBS diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 747d8ec89e..62fc1dc6ff 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -170,7 +170,7 @@ void GLGizmoMove3D::on_render_for_picking() //get picking colors only for (unsigned int i = 0; i < (unsigned int) m_grabbers.size(); ++i) { if (m_grabbers[i].enabled) { - std::array color = picking_color_component(i); + ColorRGBA color = picking_color_component(i); m_grabbers[i].color = color; } } @@ -224,7 +224,7 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box double size = 0.75 * GLGizmoBase::Grabber::FixedGrabberSize * GLGizmoBase::INV_ZOOM; - std::array color = m_grabbers[axis].color; + ColorRGBA color = m_grabbers[axis].color; if (!picking && m_hover_id != -1) { if (m_hover_id == axis) { color = m_grabbers[axis].hover_color; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index f682d249ec..7e68b73730 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -177,7 +177,7 @@ void GLGizmoPainterBase::render_cursor_circle() const glsafe(::glLineWidth(1.5f)); // BBS - std::array render_color = this->get_cursor_hover_color(); + ColorRGBA render_color = this->get_cursor_hover_color(); if (m_button_down == Button::Left) render_color = this->get_cursor_sphere_left_button_color(); else if (m_button_down == Button::Right) @@ -225,7 +225,7 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const glFrontFace(GL_CW); // BBS - std::array render_color = this->get_cursor_hover_color(); + ColorRGBA render_color = this->get_cursor_hover_color(); if (m_button_down == Button::Left) render_color = this->get_cursor_sphere_left_button_color(); else if (m_button_down == Button::Right) @@ -1002,13 +1002,16 @@ TriangleSelector::ClippingPlane GLGizmoPainterBase::get_clipping_plane_in_volume return TriangleSelector::ClippingPlane({float(normal_transformed.x()), float(normal_transformed.y()), float(normal_transformed.z()), offset_transformed}); } -std::array TriangleSelectorGUI::get_seed_fill_color(const std::array &base_color) +ColorRGBA TriangleSelectorGUI::enforcers_color = {0.5f, 1.f, 0.5f, 1.f}; +ColorRGBA TriangleSelectorGUI::blockers_color = {1.f, 0.5f, 0.5f, 1.f}; + +ColorRGBA TriangleSelectorGUI::get_seed_fill_color(const ColorRGBA& base_color) { // BBS return { - base_color[0] * 1.25f < 1.f ? base_color[0] * 1.25f : 1.f, - base_color[1] * 1.25f < 1.f ? base_color[1] * 1.25f : 1.f, - base_color[2] * 1.25f < 1.f ? base_color[2] * 1.25f : 1.f, + base_color.r() * 1.25f < 1.f ? base_color.r() * 1.25f : 1.f, + base_color.g() * 1.25f < 1.f ? base_color.g() * 1.25f : 1.f, + base_color.b() * 1.25f < 1.f ? base_color.b() * 1.25f : 1.f, 1.f}; } @@ -1036,7 +1039,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) for (auto &iva : m_iva_seed_fills) if (iva.has_VBOs()) { size_t color_idx = &iva - &m_iva_seed_fills.front(); - const std::array &color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color : + const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color : color_idx == 2 ? blockers_color : GLVolume::NEUTRAL_COLOR); shader->set_uniform("uniform_color", color); @@ -1166,18 +1169,18 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui) for (size_t buffer_idx = 0; buffer_idx < m_triangle_patches.size(); ++buffer_idx) { if (this->has_VBOs(buffer_idx)) { const TrianglePatch& patch = m_triangle_patches[buffer_idx]; - std::array color; + ColorRGBA color; if (patch.is_fragment() && !patch.neighbor_types.empty()) { size_t color_idx = (size_t)*patch.neighbor_types.begin(); color = m_ebt_colors[color_idx]; - color[3] = 0.85; + color.a(0.85); } else { size_t color_idx = (size_t)patch.type; color = m_ebt_colors[color_idx]; } //to make black not too hard too see - std::array new_color = adjust_color_for_rendering(color); + ColorRGBA new_color = adjust_color_for_rendering(color); shader->set_uniform("uniform_color", new_color); //shader->set_uniform("uniform_color", color); //BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", buffer_idx %1%: new_color[%2%, %3%, %4%, %5%]")%buffer_idx%new_color[0]%new_color[1]%new_color[2]%new_color[3]; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index d2f69ad2ae..de92a426c6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -84,8 +84,8 @@ public: }; // BBS - static constexpr std::array enforcers_color{ 0.5f, 1.f, 0.5f, 1.f }; - static constexpr std::array blockers_color{ 1.f, 0.5f, 0.5f, 1.f }; + static ColorRGBA enforcers_color; + static ColorRGBA blockers_color; #ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG void render_debug(ImGuiWrapper* imgui); @@ -98,7 +98,7 @@ protected: // BBS bool m_paint_changed = true; - static std::array get_seed_fill_color(const std::array &base_color); + static ColorRGBA get_seed_fill_color(const ColorRGBA &base_color); private: void update_render_data(); @@ -128,7 +128,7 @@ struct TrianglePatch { class TriangleSelectorPatch : public TriangleSelectorGUI { public: - explicit TriangleSelectorPatch(const TriangleMesh& mesh, const std::vector> ebt_colors, float edge_limit = 0.6f) + explicit TriangleSelectorPatch(const TriangleMesh& mesh, const std::vector ebt_colors, float edge_limit = 0.6f) : TriangleSelectorGUI(mesh, edge_limit), m_ebt_colors(ebt_colors) {} virtual ~TriangleSelectorPatch() = default; @@ -141,7 +141,7 @@ public: void update_selector_triangles(); void update_triangles_per_patch(); - void set_ebt_colors(const std::vector> ebt_colors) { m_ebt_colors = ebt_colors; } + void set_ebt_colors(const std::vector ebt_colors) { m_ebt_colors = ebt_colors; } void set_filter_state(bool is_filter_state); constexpr static float GapAreaMin = 0.f; @@ -195,7 +195,7 @@ protected: std::vector m_vertices_VBO_ids; std::vector m_triangle_indices_VBO_ids; - std::vector> m_ebt_colors; + std::vector m_ebt_colors; bool m_filter_state = false; @@ -247,10 +247,10 @@ protected: virtual void update_model_object() = 0; virtual void update_from_model_object(bool first_update) = 0; - virtual std::array get_cursor_sphere_left_button_color() const { return {0.f, 0.f, 1.f, 0.25f}; } - virtual std::array get_cursor_sphere_right_button_color() const { return {1.f, 0.f, 0.f, 0.25f}; } + virtual ColorRGBA get_cursor_sphere_left_button_color() const { return {0.f, 0.f, 1.f, 0.25f}; } + virtual ColorRGBA get_cursor_sphere_right_button_color() const { return {1.f, 0.f, 0.f, 0.25f}; } // BBS - virtual std::array get_cursor_hover_color() const { return { 0.f, 0.f, 0.f, 0.25f }; } + virtual ColorRGBA get_cursor_hover_color() const { return { 0.f, 0.f, 0.f, 0.25f }; } virtual EnforcerBlockerType get_left_button_state_type() const { return EnforcerBlockerType::ENFORCER; } virtual EnforcerBlockerType get_right_button_state_type() const { return EnforcerBlockerType::BLOCKER; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 65479b064e..124e370a36 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -331,7 +331,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick //float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0); //double size = m_dragging ? (double)m_grabbers[0].get_dragging_half_size(mean_size) : (double)m_grabbers[0].get_half_size(mean_size); - std::array color = m_grabbers[0].color; + ColorRGBA color = m_grabbers[0].color; if (!picking && m_hover_id != -1) { color = m_grabbers[0].hover_color; //color[0] = 1.0f - color[0]; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index d0fae7c033..9de9d2c903 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -388,7 +388,7 @@ void GLGizmoSeam::update_from_model_object(bool first_update) m_triangle_selectors.clear(); int volume_id = -1; - std::vector> ebt_colors; + std::vector ebt_colors; ebt_colors.push_back(GLVolume::NEUTRAL_COLOR); ebt_colors.push_back(TriangleSelectorGUI::enforcers_color); ebt_colors.push_back(TriangleSelectorGUI::blockers_color); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 73ed826fc6..94175aef9d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -137,7 +137,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) glsafe(::glTranslated(0.0, 0.0, z_shift)); glsafe(::glMultMatrixd(instance_matrix.data())); - std::array render_color; + ColorRGBA render_color; for (size_t i = 0; i < cache_size; ++i) { const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i]; const bool& point_selected = m_editing_mode ? m_editing_cache[i].selected : false; @@ -219,10 +219,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking) // Now render the drain holes: if (has_holes && ! picking) { - render_color[0] = 0.7f; - render_color[1] = 0.7f; - render_color[2] = 0.7f; - render_color[3] = 0.7f; + render_color = { 0.7f, 0.7f, 0.7f, 0.7f }; const_cast(&m_cylinder)->set_color(-1, render_color); if (shader) shader->set_uniform("emission_factor", 0.5f); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoText.cpp b/src/slic3r/GUI/Gizmos/GLGizmoText.cpp index 553b477b32..c50c80ea36 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoText.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoText.cpp @@ -445,7 +445,7 @@ void GLGizmoText::on_render() m_grabbers[0].center = m_mouse_position_world; m_grabbers[0].enabled = true; - std::array color = picking_color_component(0); + ColorRGBA color = picking_color_component(0); m_grabbers[0].color = color; m_grabbers[0].render_for_picking(mean_size); } @@ -490,7 +490,7 @@ void GLGizmoText::on_render_for_picking() float mean_size = (float) (GLGizmoBase::Grabber::FixedGrabberSize); m_grabbers[0].center = m_mouse_position_world; m_grabbers[0].enabled = true; - std::array color = picking_color_component(0); + ColorRGBA color = picking_color_component(0); m_grabbers[0].color = color; m_grabbers[0].render_for_picking(mean_size); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 4e29d10afb..fc6decbaa8 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -221,8 +221,8 @@ void InstancesHider::render_cut() const if (mv->is_model_part()) glsafe(::glColor3f(0.8f, 0.3f, 0.0f)); else { - const std::array& c = color_from_model_volume(*mv); - glsafe(::glColor4f(c[0], c[1], c[2], c[3])); + const ColorRGBA color = color_from_model_volume(*mv); + glsafe(::glColor4fv(color.data())); } glsafe(::glPushAttrib(GL_DEPTH_TEST)); glsafe(::glDisable(GL_DEPTH_TEST)); diff --git a/src/slic3r/GUI/IMSlider.cpp b/src/slic3r/GUI/IMSlider.cpp index 7987ea7862..c0293aefa2 100644 --- a/src/slic3r/GUI/IMSlider.cpp +++ b/src/slic3r/GUI/IMSlider.cpp @@ -586,8 +586,8 @@ void IMSlider::draw_colored_band(const ImRect& groove, const ImRect& slideable_r }; //draw main colored band const int default_color_idx = m_mode == MultiAsSingle ? std::max(m_only_extruder - 1, 0) : 0; - std::arrayrgba = decode_color_to_float_array(m_extruder_colors[default_color_idx]); - ImU32 band_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f); + ColorRGBA rgba = decode_color_to_float_array(m_extruder_colors[default_color_idx]); + ImU32 band_clr = ImGuiWrapper::to_ImU32(rgba); draw_main_band(band_clr); static float tick_pos; @@ -605,8 +605,8 @@ void IMSlider::draw_colored_band(const ImRect& groove, const ImRect& slideable_r const std::string clr_str = m_mode == SingleExtruder ? tick_it->color : get_color_for_tool_change_tick(tick_it); if (!clr_str.empty()) { - std::arrayrgba = decode_color_to_float_array(clr_str); - ImU32 band_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f); + ColorRGBA rgba = decode_color_to_float_array(clr_str); + ImU32 band_clr = ImGuiWrapper::to_ImU32(rgba); if (tick_it->tick == 0) draw_main_band(band_clr); else @@ -1323,9 +1323,9 @@ void IMSlider::render_add_menu() } else if (begin_menu(_u8L("Change Filament").c_str())) { for (int i = 0; i < extruder_num; i++) { - std::array rgba = decode_color_to_float_array(m_extruder_colors[i]); - ImU32 icon_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f); - if (rgba[3] == 0) + ColorRGBA rgba = decode_color_to_float_array(m_extruder_colors[i]); + ImU32 icon_clr = ImGuiWrapper::to_ImU32(rgba); + if (rgba.a() == 0) icon_clr = 0; if (menu_item_with_icon((_u8L("Filament ") + std::to_string(i + 1)).c_str(), "", ImVec2(14, 14) * m_scale, icon_clr, false, true, &hovered)) add_code_as_tick(ToolChange, i + 1); if (hovered) { show_tooltip(_u8L("Change filament at the beginning of this layer.")); } @@ -1373,8 +1373,8 @@ void IMSlider::render_edit_menu(const TickCode& tick) } else if (begin_menu(_u8L("Change Filament").c_str())) { for (int i = 0; i < extruder_num; i++) { - std::array rgba = decode_color_to_float_array(m_extruder_colors[i]); - ImU32 icon_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f); + ColorRGBA rgba = decode_color_to_float_array(m_extruder_colors[i]); + ImU32 icon_clr = ImGuiWrapper::to_ImU32(rgba); if (menu_item_with_icon((_u8L("Filament ") + std::to_string(i + 1)).c_str(), "", ImVec2(14, 14) * m_scale, icon_clr)) add_code_as_tick(ToolChange, i + 1); } end_menu(); diff --git a/src/slic3r/GUI/IMSlider_Utils.hpp b/src/slic3r/GUI/IMSlider_Utils.hpp index bfe5545a3b..e69de29bb2 100644 --- a/src/slic3r/GUI/IMSlider_Utils.hpp +++ b/src/slic3r/GUI/IMSlider_Utils.hpp @@ -1,198 +0,0 @@ -#ifndef slic3r_IMSlider_Utils_hpp_ -#define slic3r_IMSlider_Utils_hpp_ - -#include -#include - -#include "wx/colour.h" - -//double epsilon() { return 0.0011; } - -class ColorGenerator -{ - // Some of next code is borrowed from https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both - typedef struct { - double r; // a fraction between 0 and 1 - double g; // a fraction between 0 and 1 - double b; // a fraction between 0 and 1 - } rgb; - - typedef struct { - double h; // angle in degrees - double s; // a fraction between 0 and 1 - double v; // a fraction between 0 and 1 - } hsv; - - //static hsv rgb2hsv(rgb in); - //static rgb hsv2rgb(hsv in); - - hsv rgb2hsv(rgb in) - { - hsv out; - double min, max, delta; - - min = in.r < in.g ? in.r : in.g; - min = min < in.b ? min : in.b; - - max = in.r > in.g ? in.r : in.g; - max = max > in.b ? max : in.b; - - out.v = max; // v - delta = max - min; - if (delta < 0.00001) - { - out.s = 0; - out.h = 0; // undefined, maybe nan? - return out; - } - if (max > 0.0) { // NOTE: if Max is == 0, this divide would cause a crash - out.s = (delta / max); // s - } - else { - // if max is 0, then r = g = b = 0 - // s = 0, h is undefined - out.s = 0.0; - out.h = NAN; // its now undefined - return out; - } - if (in.r >= max) // > is bogus, just keeps compilor happy - out.h = (in.g - in.b) / delta; // between yellow & magenta - else - if (in.g >= max) - out.h = 2.0 + (in.b - in.r) / delta; // between cyan & yellow - else - out.h = 4.0 + (in.r - in.g) / delta; // between magenta & cyan - - out.h *= 60.0; // degrees - - if (out.h < 0.0) - out.h += 360.0; - - return out; - } - - hsv rgb2hsv(const std::string& str_clr_in) - { - wxColour clr(str_clr_in); - rgb in = { clr.Red() / 255.0, clr.Green() / 255.0, clr.Blue() / 255.0 }; - return rgb2hsv(in); - } - - - rgb hsv2rgb(hsv in) - { - double hh, p, q, t, ff; - long i; - rgb out; - - if (in.s <= 0.0) { // < is bogus, just shuts up warnings - out.r = in.v; - out.g = in.v; - out.b = in.v; - return out; - } - hh = in.h; - if (hh >= 360.0) hh -= 360.0;//hh = 0.0; - hh /= 60.0; - i = (long)hh; - ff = hh - i; - p = in.v * (1.0 - in.s); - q = in.v * (1.0 - (in.s * ff)); - t = in.v * (1.0 - (in.s * (1.0 - ff))); - - switch (i) { - case 0: - out.r = in.v; - out.g = t; - out.b = p; - break; - case 1: - out.r = q; - out.g = in.v; - out.b = p; - break; - case 2: - out.r = p; - out.g = in.v; - out.b = t; - break; - - case 3: - out.r = p; - out.g = q; - out.b = in.v; - break; - case 4: - out.r = t; - out.g = p; - out.b = in.v; - break; - case 5: - default: - out.r = in.v; - out.g = p; - out.b = q; - break; - } - return out; - } - - std::random_device rd; - -public: - - ColorGenerator() {} - ~ColorGenerator() {} - - double rand_val() - { - std::mt19937 rand_generator(rd()); - - // this value will be used for Saturation and Value - // to avoid extremely light/dark colors, take this value from range [0.65; 1.0] - std::uniform_real_distribution distrib(0.65, 1.0); - return distrib(rand_generator); - } - - - std::string get_opposite_color(const std::string& color) - { - std::string opp_color = ""; - - hsv hsv_clr = rgb2hsv(color); - hsv_clr.h += 65; // 65 instead 60 to avoid circle values - hsv_clr.s = rand_val(); - hsv_clr.v = rand_val(); - - rgb rgb_opp_color = hsv2rgb(hsv_clr); - - wxString clr_str = wxString::Format(wxT("#%02X%02X%02X"), (unsigned char)(rgb_opp_color.r * 255), (unsigned char)(rgb_opp_color.g * 255), (unsigned char)(rgb_opp_color.b * 255)); - opp_color = clr_str.ToStdString(); - - return opp_color; - } - - std::string get_opposite_color(const std::string& color_frst, const std::string& color_scnd) - { - std::string opp_color = ""; - - hsv hsv_frst = rgb2hsv(color_frst); - hsv hsv_scnd = rgb2hsv(color_scnd); - - double delta_h = fabs(hsv_frst.h - hsv_scnd.h); - double start_h = delta_h > 180 ? std::min(hsv_scnd.h, hsv_frst.h) : std::max(hsv_scnd.h, hsv_frst.h); - start_h += 5; // to avoid circle change of colors for 120 deg - if (delta_h < 180) - delta_h = 360 - delta_h; - - hsv hsv_opp = hsv{ start_h + 0.5 * delta_h, rand_val(), rand_val() }; - rgb rgb_opp_color = hsv2rgb(hsv_opp); - - wxString clr_str = wxString::Format(wxT("#%02X%02X%02X"), (unsigned char)(rgb_opp_color.r * 255), (unsigned char)(rgb_opp_color.g * 255), (unsigned char)(rgb_opp_color.b * 255)); - opp_color = clr_str.ToStdString(); - - return opp_color; - } -}; - -#endif \ No newline at end of file diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 05ef3a4c95..f061cd7970 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -27,6 +27,7 @@ #include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" +#include "libslic3r/Color.hpp" #include "libslic3r/Shape/TextShape.hpp" #include "3DScene.hpp" #include "GUI.hpp" @@ -127,11 +128,11 @@ static const std::map font_icons_extra_large = { const ImVec4 ImGuiWrapper::COL_GREY_DARK = { 0.333f, 0.333f, 0.333f, 1.0f }; const ImVec4 ImGuiWrapper::COL_GREY_LIGHT = { 0.4f, 0.4f, 0.4f, 1.0f }; const ImVec4 ImGuiWrapper::COL_ORANGE_DARK = { 0.757f, 0.404f, 0.216f, 1.0f }; -const ImVec4 ImGuiWrapper::COL_ORANGE_LIGHT = { 1.0f, 0.49f, 0.216f, 1.0f }; +const ImVec4 ImGuiWrapper::COL_ORANGE_LIGHT = to_ImVec4(ColorRGBA::ORANGE()); const ImVec4 ImGuiWrapper::COL_WINDOW_BACKGROUND = { 0.1f, 0.1f, 0.1f, 0.8f }; const ImVec4 ImGuiWrapper::COL_BUTTON_BACKGROUND = COL_ORANGE_DARK; const ImVec4 ImGuiWrapper::COL_BUTTON_HOVERED = COL_ORANGE_LIGHT; -const ImVec4 ImGuiWrapper::COL_BUTTON_ACTIVE = ImGuiWrapper::COL_BUTTON_HOVERED; +const ImVec4 ImGuiWrapper::COL_BUTTON_ACTIVE = COL_BUTTON_HOVERED; //BBS @@ -1776,6 +1777,26 @@ bool ImGuiWrapper::want_any_input() const return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput; } +ImU32 ImGuiWrapper::to_ImU32(const ColorRGBA& color) +{ + return ImGui::GetColorU32({ color.r(), color.g(), color.b(), color.a() }); +} + +ImVec4 ImGuiWrapper::to_ImVec4(const ColorRGBA& color) +{ + return { color.r(), color.g(), color.b(), color.a() }; +} + +ColorRGBA ImGuiWrapper::from_ImU32(const ImU32& color) +{ + return from_ImVec4(ImGui::ColorConvertU32ToFloat4(color)); +} + +ColorRGBA ImGuiWrapper::from_ImVec4(const ImVec4& color) +{ + return { color.x, color.y, color.z, color.w }; +} + #ifdef __APPLE__ static const ImWchar ranges_keyboard_shortcuts[] = { diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 052ea00e5e..5f37c16eb7 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -11,9 +11,12 @@ #include "libslic3r/Point.hpp" #include "libslic3r/GCode/ThumbnailData.hpp" -namespace Slic3r {namespace Search { +namespace Slic3r { +class ColorRGBA; +namespace Search { struct OptionViewParameters; -}} +} // namespace Search +} // namespace Slic3r class wxString; class wxMouseEvent; @@ -181,6 +184,11 @@ public: void reset_requires_extra_frame() { m_requires_extra_frame = false; } #endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT + static ImU32 to_ImU32(const ColorRGBA& color); + static ImVec4 to_ImVec4(const ColorRGBA& color); + static ColorRGBA from_ImU32(const ImU32& color); + static ColorRGBA from_ImVec4(const ImVec4& color); + static const ImVec4 COL_GREY_DARK; static const ImVec4 COL_GREY_LIGHT; static const ImVec4 COL_ORANGE_DARK; diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index cceb1b5d88..8a91b80b8f 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -14,6 +14,7 @@ #include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" +#include "libslic3r/Color.hpp" #include "GUI.hpp" #include "I18N.hpp" //#include "ConfigWizard.hpp" @@ -264,9 +265,9 @@ static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxStrin wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); wxFont monospace = wxGetApp().code_font(); wxColour text_clr = wxGetApp().get_label_clr_default(); - wxColour bgr_clr = parent->GetBackgroundColour(); //wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); - auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); + wxColour bgr_clr = parent->GetBackgroundColour(); + auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue())); + auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue())); const int font_size = font.GetPointSize(); int size[] = { font_size, font_size, font_size, font_size, font_size, font_size, font_size }; html->SetFonts(font.GetFaceName(), monospace.GetFaceName(), size); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index bd86ceaa3d..546fd65546 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -64,17 +64,17 @@ namespace GUI { class Bed3D; -std::array PartPlate::SELECT_COLOR = { 0.2666f, 0.2784f, 0.2784f, 1.0f }; //{ 0.4196f, 0.4235f, 0.4235f, 1.0f }; -std::array PartPlate::UNSELECT_COLOR = { 0.82f, 0.82f, 0.82f, 1.0f }; -std::array PartPlate::UNSELECT_DARK_COLOR = { 0.384f, 0.384f, 0.412f, 1.0f }; -std::array PartPlate::DEFAULT_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f }; -std::array PartPlate::LINE_TOP_COLOR = { 0.89f, 0.89f, 0.89f, 1.0f }; -std::array PartPlate::LINE_TOP_DARK_COLOR = { 0.431f, 0.431f, 0.463f, 1.0f }; -std::array PartPlate::LINE_TOP_SEL_COLOR = { 0.5294f, 0.5451, 0.5333f, 1.0f}; -std::array PartPlate::LINE_TOP_SEL_DARK_COLOR = { 0.298f, 0.298f, 0.3333f, 1.0f}; -std::array PartPlate::LINE_BOTTOM_COLOR = { 0.8f, 0.8f, 0.8f, 0.4f }; -std::array PartPlate::HEIGHT_LIMIT_TOP_COLOR = { 0.6f, 0.6f, 1.0f, 1.0f }; -std::array PartPlate::HEIGHT_LIMIT_BOTTOM_COLOR = { 0.4f, 0.4f, 1.0f, 1.0f }; +ColorRGBA PartPlate::SELECT_COLOR = { 0.2666f, 0.2784f, 0.2784f, 1.0f }; //{ 0.4196f, 0.4235f, 0.4235f, 1.0f }; +ColorRGBA PartPlate::UNSELECT_COLOR = { 0.82f, 0.82f, 0.82f, 1.0f }; +ColorRGBA PartPlate::UNSELECT_DARK_COLOR = { 0.384f, 0.384f, 0.412f, 1.0f }; +ColorRGBA PartPlate::DEFAULT_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f }; +ColorRGBA PartPlate::LINE_TOP_COLOR = { 0.89f, 0.89f, 0.89f, 1.0f }; +ColorRGBA PartPlate::LINE_TOP_DARK_COLOR = { 0.431f, 0.431f, 0.463f, 1.0f }; +ColorRGBA PartPlate::LINE_TOP_SEL_COLOR = { 0.5294f, 0.5451, 0.5333f, 1.0f}; +ColorRGBA PartPlate::LINE_TOP_SEL_DARK_COLOR = { 0.298f, 0.298f, 0.3333f, 1.0f}; +ColorRGBA PartPlate::LINE_BOTTOM_COLOR = { 0.8f, 0.8f, 0.8f, 0.4f }; +ColorRGBA PartPlate::HEIGHT_LIMIT_TOP_COLOR = { 0.6f, 0.6f, 1.0f, 1.0f }; +ColorRGBA PartPlate::HEIGHT_LIMIT_BOTTOM_COLOR = { 0.4f, 0.4f, 1.0f, 1.0f }; // get text extent with wxMemoryDC void get_text_extent(const wxString &msg, wxCoord &w, wxCoord &h, wxFont *font) @@ -116,20 +116,20 @@ wxFont* find_font(const std::string& text_str, int max_size = 32) } void PartPlate::update_render_colors() { - PartPlate::SELECT_COLOR = GLColor(RenderColor::colors[RenderCol_Plate_Selected]); - PartPlate::UNSELECT_COLOR = GLColor(RenderColor::colors[RenderCol_Plate_Unselected]); - PartPlate::DEFAULT_COLOR = GLColor(RenderColor::colors[RenderCol_Plate_Default]); - PartPlate::LINE_TOP_COLOR = GLColor(RenderColor::colors[RenderCol_Plate_Line_Top]); - PartPlate::LINE_BOTTOM_COLOR = GLColor(RenderColor::colors[RenderCol_Plate_Line_Bottom]); + PartPlate::SELECT_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Plate_Selected]); + PartPlate::UNSELECT_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Plate_Unselected]); + PartPlate::DEFAULT_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Plate_Default]); + PartPlate::LINE_TOP_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Plate_Line_Top]); + PartPlate::LINE_BOTTOM_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_Plate_Line_Bottom]); } void PartPlate::load_render_colors() { - RenderColor::colors[RenderCol_Plate_Selected] = IMColor(SELECT_COLOR); - RenderColor::colors[RenderCol_Plate_Unselected] = IMColor(UNSELECT_COLOR); - RenderColor::colors[RenderCol_Plate_Default] = IMColor(DEFAULT_COLOR); - RenderColor::colors[RenderCol_Plate_Line_Top] = IMColor(LINE_TOP_COLOR); - RenderColor::colors[RenderCol_Plate_Line_Bottom] = IMColor(LINE_BOTTOM_COLOR); + RenderColor::colors[RenderCol_Plate_Selected] = ImGuiWrapper::to_ImVec4(SELECT_COLOR); + RenderColor::colors[RenderCol_Plate_Unselected] = ImGuiWrapper::to_ImVec4(UNSELECT_COLOR); + RenderColor::colors[RenderCol_Plate_Default] = ImGuiWrapper::to_ImVec4(DEFAULT_COLOR); + RenderColor::colors[RenderCol_Plate_Line_Top] = ImGuiWrapper::to_ImVec4(LINE_TOP_COLOR); + RenderColor::colors[RenderCol_Plate_Line_Bottom] = ImGuiWrapper::to_ImVec4(LINE_BOTTOM_COLOR); } @@ -708,9 +708,9 @@ void PartPlate::render_exclude_area(bool force_default_color) const { return; unsigned int triangles_vcount = m_exclude_triangles.get_vertices_count(); - std::array select_color{ 0.765f, 0.7686f, 0.7686f, 1.0f }; - std::array unselect_color{ 0.9f, 0.9f, 0.9f, 1.0f }; - std::array default_color{ 0.9f, 0.9f, 0.9f, 1.0f }; + ColorRGBA select_color{ 0.765f, 0.7686f, 0.7686f, 1.0f }; + ColorRGBA unselect_color{ 0.9f, 0.9f, 0.9f, 1.0f }; + ColorRGBA default_color{ 0.9f, 0.9f, 0.9f, 1.0f }; // draw exclude area glsafe(::glDepthMask(GL_FALSE)); @@ -729,7 +729,7 @@ void PartPlate::render_exclude_area(bool force_default_color) const { } -/*void PartPlate::render_background_for_picking(const float* render_color) const +/*void PartPlate::render_background_for_picking(const ColorRGBA render_color) const { unsigned int triangles_vcount = m_triangles.get_vertices_count(); @@ -1000,13 +1000,13 @@ void PartPlate::render_only_numbers(bool bottom) const } } -void PartPlate::render_rectangle_for_picking(const GeometryBuffer &buffer, const float* render_color) const +void PartPlate::render_rectangle_for_picking(const GeometryBuffer &buffer, const ColorRGBA render_color) const { unsigned int triangles_vcount = buffer.get_vertices_count(); //glsafe(::glDepthMask(GL_FALSE)); glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - glsafe(::glColor4fv(render_color)); + glsafe(::glColor4fv(render_color.data())); glsafe(::glNormal3d(0.0f, 0.0f, 1.0f)); glsafe(::glVertexPointer(3, GL_FLOAT, buffer.get_vertex_data_size(), (GLvoid*)buffer.get_vertices_data())); glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount)); @@ -1058,14 +1058,14 @@ void PartPlate::render_label(GLCanvas3D& canvas) const { } -void PartPlate::render_grabber(const float* render_color, bool use_lighting) const +void PartPlate::render_grabber(const ColorRGBA render_color, bool use_lighting) const { BoundingBoxf3* bounding_box = const_cast(&m_bounding_box); const Vec3d& center = m_grabber_box.center(); if (use_lighting) glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glColor4fv(render_color)); + glsafe(::glColor4fv(render_color.data())); glsafe(::glPushMatrix()); glsafe(::glTranslated(center(0), center(1), center(2))); @@ -1138,7 +1138,7 @@ void PartPlate::render_face(float x_size, float y_size) const glsafe(::glEnd()); } -void PartPlate::render_arrows(const float* render_color, bool use_lighting) const +void PartPlate::render_arrows(const ColorRGBA render_color, bool use_lighting) const { #if 0 if (m_quadric == nullptr) @@ -1176,7 +1176,7 @@ void PartPlate::render_arrows(const float* render_color, bool use_lighting) cons #endif } -void PartPlate::render_left_arrow(const float* render_color, bool use_lighting) const +void PartPlate::render_left_arrow(const ColorRGBA render_color, bool use_lighting) const { #if 0 if (m_quadric == nullptr) @@ -1203,7 +1203,7 @@ void PartPlate::render_left_arrow(const float* render_color, bool use_lighting) glsafe(::glDisable(GL_LIGHTING)); #endif } -void PartPlate::render_right_arrow(const float* render_color, bool use_lighting) const +void PartPlate::render_right_arrow(const ColorRGBA render_color, bool use_lighting) const { #if 0 if (m_quadric == nullptr) @@ -1233,58 +1233,40 @@ void PartPlate::render_right_arrow(const float* render_color, bool use_lighting) void PartPlate::on_render_for_picking() const { //glsafe(::glDisable(GL_DEPTH_TEST)); int hover_id = 0; - std::array color = picking_color_component(hover_id); - m_grabber_color[0] = color[0]; - m_grabber_color[1] = color[1]; - m_grabber_color[2] = color[2]; - m_grabber_color[3] = color[3]; + ColorRGBA color = picking_color_component(hover_id); + m_grabber_color = color; //render_grabber(m_grabber_color, false); render_rectangle_for_picking(m_triangles, m_grabber_color); hover_id = 1; - color = picking_color_component(hover_id); - m_grabber_color[0] = color[0]; - m_grabber_color[1] = color[1]; - m_grabber_color[2] = color[2]; - m_grabber_color[3] = color[3]; + color = picking_color_component(hover_id); + m_grabber_color = color; //render_left_arrow(m_grabber_color, false); render_rectangle_for_picking(m_del_icon, m_grabber_color); hover_id = 2; - color = picking_color_component(hover_id); - m_grabber_color[0] = color[0]; - m_grabber_color[1] = color[1]; - m_grabber_color[2] = color[2]; - m_grabber_color[3] = color[3]; + color = picking_color_component(hover_id); + m_grabber_color = color; render_rectangle_for_picking(m_orient_icon, m_grabber_color); hover_id = 3; - color = picking_color_component(hover_id); - m_grabber_color[0] = color[0]; - m_grabber_color[1] = color[1]; - m_grabber_color[2] = color[2]; - m_grabber_color[3] = color[3]; + color = picking_color_component(hover_id); + m_grabber_color = color; render_rectangle_for_picking(m_arrange_icon, m_grabber_color); hover_id = 4; - color = picking_color_component(hover_id); - m_grabber_color[0] = color[0]; - m_grabber_color[1] = color[1]; - m_grabber_color[2] = color[2]; - m_grabber_color[3] = color[3]; + color = picking_color_component(hover_id); + m_grabber_color = color; //render_right_arrow(m_grabber_color, false); render_rectangle_for_picking(m_lock_icon, m_grabber_color); hover_id = 5; - color = picking_color_component(hover_id); - m_grabber_color[0] = color[0]; - m_grabber_color[1] = color[1]; - m_grabber_color[2] = color[2]; - m_grabber_color[3] = color[3]; + color = picking_color_component(hover_id); + m_grabber_color = color; if (m_partplate_list->render_plate_settings) render_rectangle_for_picking(m_plate_settings_icon, m_grabber_color); } -std::array PartPlate::picking_color_component(int idx) const +ColorRGBA PartPlate::picking_color_component(int idx) const { static const float INV_255 = 1.0f / 255.0f; unsigned int id = PLATE_BASE_ID - this->m_plate_index * GRABBER_COUNT - idx; - return std::array { + return ColorRGBA { float((id >> 0) & 0xff)* INV_255, // red float((id >> 8) & 0xff)* INV_255, // greeen float((id >> 16) & 0xff)* INV_255, // blue diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index e2b2a3bf1d..fc3da75315 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -139,7 +139,7 @@ private: mutable unsigned int m_plate_idx_vbo_id{ 0 }; GLTexture m_texture; - mutable float m_grabber_color[4]; + mutable ColorRGBA m_grabber_color; float m_scale_factor{ 1.0f }; GLUquadricObject* m_quadric; int m_hover_id; @@ -175,23 +175,23 @@ private: void render_logo(bool bottom, bool render_cali = true) const; void render_logo_texture(GLTexture& logo_texture, const GeometryBuffer& logo_buffer, bool bottom, unsigned int vbo_id) const; void render_exclude_area(bool force_default_color) const; - //void render_background_for_picking(const float* render_color) const; + //void render_background_for_picking(const ColorRGBA render_color) const; void render_grid(bool bottom) const; void render_height_limit(PartPlate::HeightLimitMode mode = HEIGHT_LIMIT_BOTH) const; void render_label(GLCanvas3D& canvas) const; - void render_grabber(const float* render_color, bool use_lighting) const; + void render_grabber(const ColorRGBA render_color, bool use_lighting) const; void render_face(float x_size, float y_size) const; - void render_arrows(const float* render_color, bool use_lighting) const; - void render_left_arrow(const float* render_color, bool use_lighting) const; - void render_right_arrow(const float* render_color, bool use_lighting) const; + void render_arrows(const ColorRGBA render_color, bool use_lighting) const; + void render_left_arrow(const ColorRGBA render_color, bool use_lighting) const; + void render_right_arrow(const ColorRGBA render_color, bool use_lighting) const; void render_icon_texture(int position_id, int tex_coords_id, const GeometryBuffer &buffer, GLTexture &texture, unsigned int &vbo_id) const; void show_tooltip(const std::string tooltip); void render_icons(bool bottom, bool only_name = false, int hover_id = -1); void render_only_numbers(bool bottom) const; void render_plate_name_texture(int position_id, int tex_coords_id); - void render_rectangle_for_picking(const GeometryBuffer &buffer, const float* render_color) const; + void render_rectangle_for_picking(const GeometryBuffer &buffer, const ColorRGBA render_color) const; void on_render_for_picking() const; - std::array picking_color_component(int idx) const; + ColorRGBA picking_color_component(int idx) const; void release_opengl_resource(); public: @@ -199,17 +199,17 @@ public: static const unsigned int PLATE_NAME_HOVER_ID = 6; static const unsigned int GRABBER_COUNT = 7; - static std::array SELECT_COLOR; - static std::array UNSELECT_COLOR; - static std::array UNSELECT_DARK_COLOR; - static std::array DEFAULT_COLOR; - static std::array LINE_BOTTOM_COLOR; - static std::array LINE_TOP_COLOR; - static std::array LINE_TOP_DARK_COLOR; - static std::array LINE_TOP_SEL_COLOR; - static std::array LINE_TOP_SEL_DARK_COLOR; - static std::array HEIGHT_LIMIT_BOTTOM_COLOR; - static std::array HEIGHT_LIMIT_TOP_COLOR; + static ColorRGBA SELECT_COLOR; + static ColorRGBA UNSELECT_COLOR; + static ColorRGBA UNSELECT_DARK_COLOR; + static ColorRGBA DEFAULT_COLOR; + static ColorRGBA LINE_BOTTOM_COLOR; + static ColorRGBA LINE_TOP_COLOR; + static ColorRGBA LINE_TOP_DARK_COLOR; + static ColorRGBA LINE_TOP_SEL_COLOR; + static ColorRGBA LINE_TOP_SEL_DARK_COLOR; + static ColorRGBA HEIGHT_LIMIT_BOTTOM_COLOR; + static ColorRGBA HEIGHT_LIMIT_TOP_COLOR; static void update_render_colors(); static void load_render_colors(); diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index f00b5c4612..c58150b12a 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -24,6 +24,7 @@ #include "libslic3r/libslic3r.h" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/PresetBundle.hpp" +#include "libslic3r/Color.hpp" #include "GUI.hpp" #include "GUI_App.hpp" diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 2119632d38..1d581aef9b 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -3,6 +3,7 @@ #include "libslic3r/Utils.hpp" #include "libslic3r/Thread.hpp" +#include "libslic3r/Color.hpp" #include "GUI.hpp" #include "GUI_App.hpp" #include "GUI_Preview.hpp" @@ -3643,7 +3644,6 @@ void SelectMachineDialog::set_default_normal() //init MaterialItem auto extruders = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_used_extruders(); - BitmapCache bmcache; MaterialHash::iterator iter = m_materialList.begin(); while (iter != m_materialList.end()) { @@ -3661,10 +3661,10 @@ void SelectMachineDialog::set_default_normal() for (auto i = 0; i < extruders.size(); i++) { auto extruder = extruders[i] - 1; auto colour = wxGetApp().preset_bundle->project_config.opt_string("filament_colour", (unsigned int) extruder); - unsigned char rgb[4]; - bmcache.parse_color4(colour, rgb); + ColorRGBA rgb; + decode_color(colour, rgb); - auto colour_rgb = wxColour((int) rgb[0], (int) rgb[1], (int) rgb[2], (int) rgb[3]); + auto colour_rgb = wxColour((int) rgb.r_uchar(), (int) rgb.g_uchar(), (int) rgb.b_uchar(), (int) rgb.a_uchar()); if (extruder >= materials.size() || extruder < 0 || extruder >= display_materials.size()) continue; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index c9e8fb9b4c..8628fdd5e1 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -23,7 +23,9 @@ #include #include -static const std::array UNIFORM_SCALE_COLOR = { 0.923f, 0.504f, 0.264f, 1.0f }; +static const Slic3r::ColorRGBA UNIFORM_SCALE_COLOR = Slic3r::ColorRGBA::ORANGE(); +static const Slic3r::ColorRGBA SOLID_PLANE_COLOR = {0.0f, 174.0f / 255.0f, 66.0f / 255.0f, 1.0f}; +static const Slic3r::ColorRGBA TRANSPARENT_PLANE_COLOR = { 0.8f, 0.8f, 0.8f, 0.5f }; namespace Slic3r { namespace GUI { @@ -572,11 +574,11 @@ void Selection::clear() for (unsigned int i : m_list) { GLVolume& volume = *(*m_volumes)[i]; volume.selected = false; - bool transparent = volume.color[3] < 1.0f; - if (transparent) + bool is_transparent = volume.color.is_transparent(); + if (is_transparent) volume.force_transparent = true; volume.set_render_color(); - if (transparent) + if (is_transparent) volume.force_transparent = false; } #else @@ -2212,12 +2214,9 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons glsafe(::glEnd()); } -static std::array get_color(Axis axis) +static ColorRGBA get_color(Axis axis) { - return { GLGizmoBase::AXES_COLOR[axis][0], - GLGizmoBase::AXES_COLOR[axis][1], - GLGizmoBase::AXES_COLOR[axis][2], - GLGizmoBase::AXES_COLOR[axis][3] }; + return GLGizmoBase::AXES_COLOR[axis]; }; void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const @@ -2351,10 +2350,8 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); ::glBegin(GL_QUADS); - if ((camera_on_top && type == 1) || (!camera_on_top && type == 2)) - ::glColor4f(0.0f, 174.0f / 255.0f, 66.0f / 255.0f, 1.0f); - else - ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); + ::glColor4fv((camera_on_top && type == 1) || (!camera_on_top && type == 2) ? + SOLID_PLANE_COLOR.data() : TRANSPARENT_PLANE_COLOR.data()); ::glVertex3f(min_x, min_y, z1); ::glVertex3f(max_x, min_y, z1); ::glVertex3f(max_x, max_y, z1); @@ -2362,10 +2359,8 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co glsafe(::glEnd()); ::glBegin(GL_QUADS); - if ((camera_on_top && type == 2) || (!camera_on_top && type == 1)) - ::glColor4f(0.0f, 174.0f / 255.0f, 66.0f / 255.0f, 1.0f); - else - ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f); + ::glColor4fv((camera_on_top && type == 2) || (!camera_on_top && type == 1) ? + SOLID_PLANE_COLOR.data() : TRANSPARENT_PLANE_COLOR.data()); ::glVertex3f(min_x, min_y, z2); ::glVertex3f(max_x, min_y, z2); ::glVertex3f(max_x, max_y, z2); diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 5f192f3635..b93c00f767 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -8,6 +8,7 @@ #include "libslic3r/BlacklistedLibraryCheck.hpp" #include "libslic3r/Platform.hpp" #include "libslic3r/Utils.hpp" +#include "libslic3r/Color.hpp" #include "slic3r/GUI/format.hpp" #include "slic3r/Utils/Http.hpp" @@ -591,9 +592,8 @@ SendSystemInfoDialog::SendSystemInfoDialog(wxWindow* parent) wxColour bgr_clr = wxGetApp().get_window_default_clr(); SetBackgroundColour(bgr_clr); const auto text_clr = wxGetApp().get_label_clr_default(); - auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); - auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); - + auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue())); + auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue())); auto *topSizer = new wxBoxSizer(wxVERTICAL); auto *vsizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/slic3r/GUI/SysInfoDialog.cpp b/src/slic3r/GUI/SysInfoDialog.cpp index ce7f01f140..c3ff06873d 100644 --- a/src/slic3r/GUI/SysInfoDialog.cpp +++ b/src/slic3r/GUI/SysInfoDialog.cpp @@ -15,6 +15,7 @@ #include "MainFrame.hpp" #include "wxExtensions.hpp" #include "../libslic3r/BlacklistedLibraryCheck.hpp" +#include "../libslic3r/Color.hpp" #include "format.hpp" #ifdef _WIN32 @@ -114,8 +115,8 @@ SysInfoDialog::SysInfoDialog() // main_info_text wxFont font = get_default_font(this); const auto text_clr = wxGetApp().get_label_clr_default();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); - auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); - auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); + auto text_clr_str = encode_color(ColorRGB(text_clr.Red(), text_clr.Green(), text_clr.Blue())); + auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue())); const int fs = font.GetPointSize() - 1; int size[] = { static_cast(fs*1.5), static_cast(fs*1.4), static_cast(fs*1.3), fs, fs, fs, fs }; diff --git a/src/slic3r/GUI/TickCode.cpp b/src/slic3r/GUI/TickCode.cpp index 158afe7a1f..267752c544 100644 --- a/src/slic3r/GUI/TickCode.cpp +++ b/src/slic3r/GUI/TickCode.cpp @@ -4,28 +4,39 @@ namespace Slic3r { namespace GUI { std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int extruder) { + auto opposite_one_color = [](const std::string& color) { + ColorRGB rgb; + decode_color(color, rgb); + return encode_color(opposite(rgb)); + }; + auto opposite_two_colors = [](const std::string& a, const std::string& b) { + ColorRGB rgb1; decode_color(a, rgb1); + ColorRGB rgb2; decode_color(b, rgb2); + return encode_color(opposite(rgb1, rgb2)); + }; + if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) { #if 1 - if (ticks.empty()) return color_generator.get_opposite_color((*m_colors)[0]); + if (ticks.empty()) return opposite_one_color((*m_colors)[0]); auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick); if (before_tick_it == ticks.end()) { while (before_tick_it != ticks.begin()) if (--before_tick_it; before_tick_it->type == ColorChange) break; - if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(before_tick_it->color); - return color_generator.get_opposite_color((*m_colors)[0]); + if (before_tick_it->type == ColorChange) return opposite_one_color(before_tick_it->color); + return opposite_one_color((*m_colors)[0]); } if (before_tick_it == ticks.begin()) { const std::string &frst_color = (*m_colors)[0]; - if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, before_tick_it->color); + if (before_tick_it->type == ColorChange) return opposite_two_colors(frst_color, before_tick_it->color); auto next_tick_it = before_tick_it; while (next_tick_it != ticks.end()) if (++next_tick_it; next_tick_it->type == ColorChange) break; - if (next_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, next_tick_it->color); + if (next_tick_it->type == ColorChange) return opposite_two_colors(frst_color, next_tick_it->color); - return color_generator.get_opposite_color(frst_color); + return opposite_one_color(frst_color); } std::string frst_color = ""; @@ -44,12 +55,12 @@ std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int if (--before_tick_it; before_tick_it->type == ColorChange) break; if (before_tick_it->type == ColorChange) { - if (frst_color.empty()) return color_generator.get_opposite_color(before_tick_it->color); - return color_generator.get_opposite_color(before_tick_it->color, frst_color); + if (frst_color.empty()) return opposite_one_color(before_tick_it->color); + return opposite_two_colors(before_tick_it->color, frst_color); } - if (frst_color.empty()) return color_generator.get_opposite_color((*m_colors)[0]); - return color_generator.get_opposite_color((*m_colors)[0], frst_color); + if (frst_color.empty()) return opposite_one_color((*m_colors)[0]); + return opposite_two_colors((*m_colors)[0], frst_color); #else const std::vector &colors = ColorPrintColors::get(); if (ticks.empty()) return colors[0]; diff --git a/src/slic3r/GUI/TickCode.hpp b/src/slic3r/GUI/TickCode.hpp index 8616d7565a..14785dee55 100644 --- a/src/slic3r/GUI/TickCode.hpp +++ b/src/slic3r/GUI/TickCode.hpp @@ -2,7 +2,7 @@ #define slic3r_GUI_TickCode_hpp_ #include "libslic3r/CustomGCode.hpp" -#include "IMSlider_Utils.hpp" +#include "libslic3r/Color.hpp" #include namespace Slic3r { @@ -29,7 +29,6 @@ class TickCodeInfo bool m_use_default_colors = false; std::vector* m_colors{ nullptr };// reference to IMSlider::m_extruder_colors - ColorGenerator color_generator; std::string get_color_for_tick(TickCode tick, Type type, const int extruder); diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index a5868b377b..a04152f004 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -11,6 +11,7 @@ #include "libslic3r/PrintConfig.hpp" #include "libslic3r/PresetBundle.hpp" +#include "libslic3r/Color.hpp" #include "format.hpp" #include "GUI_App.hpp" #include "Plater.hpp" @@ -60,8 +61,7 @@ static std::string get_icon_name(Preset::Type type, PrinterTechnology pt) { static std::string def_text_color() { wxColour def_colour = wxGetApp().get_label_clr_default();//wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); - auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), def_colour.Red(), def_colour.Green(), def_colour.Blue()); - return clr_str.ToStdString(); + return encode_color(ColorRGB(def_colour.Red(), def_colour.Green(), def_colour.Blue())); } static std::string grey = "#808080"; static std::string orange = "#ed6b21"; @@ -126,8 +126,8 @@ wxBitmap ModelNode::get_bitmap(const wxString& color) const int icon_height = lround(1.6 * em); BitmapCache bmp_cache; - unsigned char rgb[3]; - BitmapCache::parse_color(into_u8(color), rgb); + ColorRGB rgb; + decode_color(into_u8(color), rgb); // there is no need to scale created solid bitmap #ifndef __linux__ return bmp_cache.mksolid(icon_width, icon_height, rgb, true); diff --git a/src/slic3r/GUI/WipeTowerDialog.cpp b/src/slic3r/GUI/WipeTowerDialog.cpp index 4646afc897..55d47c1b84 100644 --- a/src/slic3r/GUI/WipeTowerDialog.cpp +++ b/src/slic3r/GUI/WipeTowerDialog.cpp @@ -7,6 +7,7 @@ #include "I18N.hpp" #include "GUI_App.hpp" #include "MsgDialog.hpp" +#include "libslic3r/Color.hpp" #include "Widgets/Button.hpp" #include "slic3r/Utils/ColorSpaceConvert.hpp" #include "MainFrame.hpp" @@ -407,9 +408,9 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector& matrix, con m_number_of_extruders = (int)(sqrt(matrix.size())+0.001); for (const std::string& color : extruder_colours) { - //unsigned char rgb[3]; - //Slic3r::GUI::BitmapCache::parse_color(color, rgb); - m_colours.push_back(wxColor(color)); + Slic3r::ColorRGB rgb; + Slic3r::decode_color(color, rgb); + m_colours.push_back(wxColor(rgb.r_uchar(), rgb.g_uchar(), rgb.b_uchar())); } // Create two switched panels with their own sizers diff --git a/src/slic3r/Utils/CalibUtils.cpp b/src/slic3r/Utils/CalibUtils.cpp index 6561bedfe7..62ad2a36f8 100644 --- a/src/slic3r/Utils/CalibUtils.cpp +++ b/src/slic3r/Utils/CalibUtils.cpp @@ -909,9 +909,9 @@ void CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f //draw thumbnails { GLVolumeCollection glvolume_collection; - std::vector> colors_out(1); + std::vector colors_out(1); unsigned char rgb_color[4] = {255, 255, 255, 255}; - std::array new_color {1.0f, 1.0f, 1.0f, 1.0f}; + ColorRGBA new_color {1.0f, 1.0f, 1.0f, 1.0f}; colors_out.push_back(new_color); ThumbnailData* thumbnail_data = &plate_data_list[0]->plate_thumbnail; @@ -927,7 +927,7 @@ void CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f for (int instance_idx = 0; instance_idx < (int)model_object.instances.size(); ++ instance_idx) { const ModelInstance &model_instance = *model_object.instances[instance_idx]; glvolume_collection.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, "volume", true, false, true); - glvolume_collection.volumes.back()->set_render_color( new_color[0], new_color[1], new_color[2], new_color[3]); + glvolume_collection.volumes.back()->set_render_color(new_color); glvolume_collection.volumes.back()->set_color(new_color); //glvolume_collection.volumes.back()->printable = model_instance.printable; }