Change random values of the S and V in HSV colors.
To avoid generation of the extremely light or dark colors we use now generated values from the range [0.65; 0.1]
This commit is contained in:
YuSanka 2021-12-09 14:16:17 +01:00
parent 7880c20330
commit 27883caa08
3 changed files with 176 additions and 158 deletions

View file

@ -1,6 +1,5 @@
#include "libslic3r/libslic3r.h" #include "libslic3r/libslic3r.h"
#include "DoubleSlider.hpp" #include "DoubleSlider.hpp"
#include "DoubleSlider_Utils.hpp"
#include "libslic3r/GCode.hpp" #include "libslic3r/GCode.hpp"
#include "GUI.hpp" #include "GUI.hpp"
#include "GUI_App.hpp" #include "GUI_App.hpp"
@ -27,7 +26,6 @@
#include <cmath> #include <cmath>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <random>
#include "Field.hpp" #include "Field.hpp"
#include "format.hpp" #include "format.hpp"
#include "NotificationManager.hpp" #include "NotificationManager.hpp"
@ -2562,7 +2560,7 @@ std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int
if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) { if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) {
#if 1 #if 1
if (ticks.empty()) if (ticks.empty())
return get_opposite_color((*m_colors)[0]); return color_generator.get_opposite_color((*m_colors)[0]);
auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick); auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick);
if (before_tick_it == ticks.end()) if (before_tick_it == ticks.end())
@ -2571,24 +2569,24 @@ std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int
if (--before_tick_it; before_tick_it->type == ColorChange) if (--before_tick_it; before_tick_it->type == ColorChange)
break; break;
if (before_tick_it->type == ColorChange) if (before_tick_it->type == ColorChange)
return get_opposite_color(before_tick_it->color); return color_generator.get_opposite_color(before_tick_it->color);
return get_opposite_color((*m_colors)[0]); return color_generator.get_opposite_color((*m_colors)[0]);
} }
if (before_tick_it == ticks.begin()) if (before_tick_it == ticks.begin())
{ {
const std::string& frst_color = (*m_colors)[0]; const std::string& frst_color = (*m_colors)[0];
if (before_tick_it->type == ColorChange) if (before_tick_it->type == ColorChange)
return get_opposite_color(frst_color, before_tick_it->color); return color_generator.get_opposite_color(frst_color, before_tick_it->color);
auto next_tick_it = before_tick_it; auto next_tick_it = before_tick_it;
while (next_tick_it != ticks.end()) while (next_tick_it != ticks.end())
if (++next_tick_it; next_tick_it->type == ColorChange) if (++next_tick_it; next_tick_it->type == ColorChange)
break; break;
if (next_tick_it->type == ColorChange) if (next_tick_it->type == ColorChange)
return get_opposite_color(frst_color, next_tick_it->color); return color_generator.get_opposite_color(frst_color, next_tick_it->color);
return get_opposite_color(frst_color); return color_generator.get_opposite_color(frst_color);
} }
std::string frst_color = ""; std::string frst_color = "";
@ -2609,13 +2607,13 @@ std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int
if (before_tick_it->type == ColorChange) { if (before_tick_it->type == ColorChange) {
if (frst_color.empty()) if (frst_color.empty())
return get_opposite_color(before_tick_it->color); return color_generator.get_opposite_color(before_tick_it->color);
return get_opposite_color(before_tick_it->color, frst_color); return color_generator.get_opposite_color(before_tick_it->color, frst_color);
} }
if (frst_color.empty()) if (frst_color.empty())
return get_opposite_color((*m_colors)[0]); return color_generator.get_opposite_color((*m_colors)[0]);
return get_opposite_color((*m_colors)[0], frst_color); return color_generator.get_opposite_color((*m_colors)[0], frst_color);
#else #else
const std::vector<std::string>& colors = ColorPrintColors::get(); const std::vector<std::string>& colors = ColorPrintColors::get();
if (ticks.empty()) if (ticks.empty())

View file

@ -3,6 +3,7 @@
#include "libslic3r/CustomGCode.hpp" #include "libslic3r/CustomGCode.hpp"
#include "wxExtensions.hpp" #include "wxExtensions.hpp"
#include "DoubleSlider_Utils.hpp"
#include <wx/window.h> #include <wx/window.h>
#include <wx/control.h> #include <wx/control.h>
@ -118,6 +119,7 @@ class TickCodeInfo
// int m_default_color_idx = 0; // int m_default_color_idx = 0;
std::vector<std::string>* m_colors {nullptr}; std::vector<std::string>* m_colors {nullptr};
ColorGenerator color_generator;
std::string get_color_for_tick(TickCode tick, Type type, const int extruder); std::string get_color_for_tick(TickCode tick, Type type, const int extruder);

View file

@ -1,25 +1,28 @@
#include <stdio.h> #include <stdio.h>
#include <random>
#include "wx/colour.h" #include "wx/colour.h"
// 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 class ColorGenerator
{
typedef struct { // 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 r; // a fraction between 0 and 1
double g; // a fraction between 0 and 1 double g; // a fraction between 0 and 1
double b; // a fraction between 0 and 1 double b; // a fraction between 0 and 1
} rgb; } rgb;
typedef struct { typedef struct {
double h; // angle in degrees double h; // angle in degrees
double s; // a fraction between 0 and 1 double s; // a fraction between 0 and 1
double v; // a fraction between 0 and 1 double v; // a fraction between 0 and 1
} hsv; } hsv;
static hsv rgb2hsv(rgb in); //static hsv rgb2hsv(rgb in);
static rgb hsv2rgb(hsv in); //static rgb hsv2rgb(hsv in);
hsv rgb2hsv(rgb in) hsv rgb2hsv(rgb in)
{ {
hsv out; hsv out;
double min, max, delta; double min, max, delta;
@ -37,46 +40,47 @@ hsv rgb2hsv(rgb in)
out.h = 0; // undefined, maybe nan? out.h = 0; // undefined, maybe nan?
return out; return out;
} }
if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash if (max > 0.0) { // NOTE: if Max is == 0, this divide would cause a crash
out.s = (delta / max); // s out.s = (delta / max); // s
} else { }
else {
// if max is 0, then r = g = b = 0 // if max is 0, then r = g = b = 0
// s = 0, h is undefined // s = 0, h is undefined
out.s = 0.0; out.s = 0.0;
out.h = NAN; // its now undefined out.h = NAN; // its now undefined
return out; return out;
} }
if( in.r >= max ) // > is bogus, just keeps compilor happy if (in.r >= max) // > is bogus, just keeps compilor happy
out.h = ( in.g - in.b ) / delta; // between yellow & magenta out.h = (in.g - in.b) / delta; // between yellow & magenta
else else
if( in.g >= max ) if (in.g >= max)
out.h = 2.0 + ( in.b - in.r ) / delta; // between cyan & yellow out.h = 2.0 + (in.b - in.r) / delta; // between cyan & yellow
else else
out.h = 4.0 + ( in.r - in.g ) / delta; // between magenta & cyan out.h = 4.0 + (in.r - in.g) / delta; // between magenta & cyan
out.h *= 60.0; // degrees out.h *= 60.0; // degrees
if( out.h < 0.0 ) if (out.h < 0.0)
out.h += 360.0; out.h += 360.0;
return out; return out;
} }
hsv rgb2hsv(const std::string& str_clr_in) hsv rgb2hsv(const std::string& str_clr_in)
{ {
wxColour clr(str_clr_in); wxColour clr(str_clr_in);
rgb in = { clr.Red() / 255.0, clr.Green() / 255.0, clr.Blue() / 255.0 }; rgb in = { clr.Red() / 255.0, clr.Green() / 255.0, clr.Blue() / 255.0 };
return rgb2hsv(in); return rgb2hsv(in);
} }
rgb hsv2rgb(hsv in) rgb hsv2rgb(hsv in)
{ {
double hh, p, q, t, ff; double hh, p, q, t, ff;
long i; long i;
rgb out; rgb out;
if(in.s <= 0.0) { // < is bogus, just shuts up warnings if (in.s <= 0.0) { // < is bogus, just shuts up warnings
out.r = in.v; out.r = in.v;
out.g = in.v; out.g = in.v;
out.b = in.v; out.b = in.v;
@ -91,7 +95,7 @@ rgb hsv2rgb(hsv in)
q = in.v * (1.0 - (in.s * ff)); q = in.v * (1.0 - (in.s * ff));
t = in.v * (1.0 - (in.s * (1.0 - ff))); t = in.v * (1.0 - (in.s * (1.0 - ff)));
switch(i) { switch (i) {
case 0: case 0:
out.r = in.v; out.r = in.v;
out.g = t; out.g = t;
@ -126,15 +130,28 @@ rgb hsv2rgb(hsv in)
break; break;
} }
return out; return out;
} }
double rand_val() std::random_device rd;
{
return 0.1 * (10 - rand() % 8);
}
std::string get_opposite_color(const std::string& color) 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<double> distrib(0.65, 1.0);
return distrib(rand_generator);
}
std::string get_opposite_color(const std::string& color)
{
std::string opp_color = ""; std::string opp_color = "";
hsv hsv_clr = rgb2hsv(color); hsv hsv_clr = rgb2hsv(color);
@ -148,10 +165,10 @@ std::string get_opposite_color(const std::string& color)
opp_color = clr_str.ToStdString(); opp_color = clr_str.ToStdString();
return opp_color; return opp_color;
} }
std::string get_opposite_color(const std::string& color_frst, const std::string& color_scnd) std::string get_opposite_color(const std::string& color_frst, const std::string& color_scnd)
{ {
std::string opp_color = ""; std::string opp_color = "";
hsv hsv_frst = rgb2hsv(color_frst); hsv hsv_frst = rgb2hsv(color_frst);
@ -170,4 +187,5 @@ std::string get_opposite_color(const std::string& color_frst, const std::string&
opp_color = clr_str.ToStdString(); opp_color = clr_str.ToStdString();
return opp_color; return opp_color;
} }
};