Add support for CMYKW and RGBKW in texture mapping zones

This commit is contained in:
sentientstardust
2026-05-08 15:11:19 +01:00
parent ed260a8055
commit b42f3666a4
11 changed files with 449 additions and 32 deletions

View File

@@ -46,8 +46,8 @@ Zoomed-out G-code preview:
- **Load OBJ files with image textures or vertex colors** - slice in full image resolution, no need to subdivide your model or bake vertex colors first
### Fast multicolor printing
- When printing image textures with this fork, only a single color is used per layer (not dependent on texture color). You can print many different models at once without increasing the number of tool changes.
### Print with only one tool change per layer
- When printing image textures with this technique, only a single filament color is used per layer (not dependent on texture color). You can print many different models at once without increasing the number of tool changes.
![More Test Prints](https://gradients.garden/gitlab_images/test_prints.jpeg)

View File

@@ -5941,9 +5941,11 @@ static bool texture_mapping_component_is_black_for_gcode(size_t
int filament_color_mode,
const std::vector<std::array<float, 3>> &component_colors)
{
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorBW))) {
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorCMYK):
case int(TextureMappingZone::FilamentColorRGBK):
case int(TextureMappingZone::FilamentColorCMYKW):
case int(TextureMappingZone::FilamentColorRGBKW):
if (component_idx == 3)
return true;
break;
@@ -6872,7 +6874,7 @@ static std::array<float, 4> raw_offset_preview_rgba_for_gcode(const std::vector<
static std::vector<std::string> raw_filament_color_mode_channel_keys_for_gcode(int filament_color_mode, size_t component_count)
{
std::vector<std::string> keys;
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorBW))) {
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB):
keys = { "R", "G", "B" };
break;
@@ -6894,6 +6896,12 @@ static std::vector<std::string> raw_filament_color_mode_channel_keys_for_gcode(i
case int(TextureMappingZone::FilamentColorBW):
keys = { "K", "W" };
break;
case int(TextureMappingZone::FilamentColorCMYKW):
keys = { "C", "M", "Y", "K", "W" };
break;
case int(TextureMappingZone::FilamentColorRGBKW):
keys = { "R", "G", "B", "K", "W" };
break;
default:
break;
}
@@ -7130,6 +7138,24 @@ static std::vector<size_t> semantic_component_indices_for_gcode(const std::vecto
case int(TextureMappingZone::FilamentColorRGBW):
semantic_colors = { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } }, { { 1.f, 1.f, 1.f } } };
break;
case int(TextureMappingZone::FilamentColorCMYKW):
semantic_colors = {
{ { 0.f, 1.f, 1.f } },
{ { 1.f, 0.f, 1.f } },
{ { 1.f, 1.f, 0.f } },
{ { 0.f, 0.f, 0.f } },
{ { 1.f, 1.f, 1.f } }
};
break;
case int(TextureMappingZone::FilamentColorRGBKW):
semantic_colors = {
{ { 1.f, 0.f, 0.f } },
{ { 0.f, 1.f, 0.f } },
{ { 0.f, 0.f, 1.f } },
{ { 0.f, 0.f, 0.f } },
{ { 1.f, 1.f, 1.f } }
};
break;
default:
return {};
}
@@ -7141,7 +7167,7 @@ static std::vector<std::array<float, 3>> fixed_color_generic_solver_component_co
{
switch (std::clamp(filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW))) {
int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB):
return { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } } };
case int(TextureMappingZone::FilamentColorCMY):
@@ -7154,6 +7180,10 @@ static std::vector<std::array<float, 3>> fixed_color_generic_solver_component_co
return { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } }, { { 0.f, 0.f, 0.f } } };
case int(TextureMappingZone::FilamentColorRGBW):
return { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } }, { { 1.f, 1.f, 1.f } } };
case int(TextureMappingZone::FilamentColorCMYKW):
return { { { 0.f, 1.f, 1.f } }, { { 1.f, 0.f, 1.f } }, { { 1.f, 1.f, 0.f } }, { { 0.f, 0.f, 0.f } }, { { 1.f, 1.f, 1.f } } };
case int(TextureMappingZone::FilamentColorRGBKW):
return { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } }, { { 0.f, 0.f, 0.f } }, { { 1.f, 1.f, 1.f } } };
default:
return {};
}
@@ -7167,7 +7197,7 @@ static std::vector<float> optimized_primary_component_weights_for_target_for_gco
{
const int clamped_mode = std::clamp(filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW));
int(TextureMappingZone::FilamentColorRGBKW));
if (clamped_mode == int(TextureMappingZone::FilamentColorAny))
return {};
@@ -7237,6 +7267,33 @@ static std::vector<float> optimized_primary_component_weights_for_target_for_gco
return weights;
}
if (clamped_mode == int(TextureMappingZone::FilamentColorCMYKW)) {
if (component_count != 5)
return {};
const float chroma = std::max(0.f, 1.f - darkness - whiteness);
const float c = chroma <= EPSILON ? 0.f : 1.f - safe_div(r - whiteness, chroma);
const float m = chroma <= EPSILON ? 0.f : 1.f - safe_div(g - whiteness, chroma);
const float y = chroma <= EPSILON ? 0.f : 1.f - safe_div(b - whiteness, chroma);
weights[component_index_for_role(0)] = print_visibility_strength(c);
weights[component_index_for_role(1)] = print_visibility_strength(m);
weights[component_index_for_role(2)] = print_visibility_strength(y);
weights[component_index_for_role(3)] = print_visibility_strength(darkness);
weights[component_index_for_role(4)] = print_visibility_strength(whiteness);
return weights;
}
if (clamped_mode == int(TextureMappingZone::FilamentColorRGBKW)) {
if (component_count != 5)
return {};
const float chroma = std::max(0.f, 1.f - darkness - whiteness);
weights[component_index_for_role(0)] = print_visibility_strength(safe_div(r - whiteness, chroma));
weights[component_index_for_role(1)] = print_visibility_strength(safe_div(g - whiteness, chroma));
weights[component_index_for_role(2)] = print_visibility_strength(safe_div(b - whiteness, chroma));
weights[component_index_for_role(3)] = print_visibility_strength(darkness);
weights[component_index_for_role(4)] = print_visibility_strength(whiteness);
return weights;
}
if (component_count != 4)
return {};
@@ -8217,7 +8274,7 @@ std::optional<Point> GCode::texture_mapping_seam_hiding_point(const ExtrusionLoo
const int texture_filament_color_mode = std::clamp(zone->filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW));
int(TextureMappingZone::FilamentColorRGBKW));
const bool raw_texture_mapping_mode =
zone->texture_mapping_mode == int(TextureMappingZone::TextureMappingRawValues);
const bool texture_force_sequential_filaments = zone->force_sequential_filaments;
@@ -9372,7 +9429,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
const int texture_filament_color_mode = std::clamp(
zone->filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW));
int(TextureMappingZone::FilamentColorRGBKW));
const bool texture_force_sequential_filaments = zone->force_sequential_filaments;
const int generic_solver_lookup_mode = std::clamp(zone->generic_solver_lookup_mode,
int(TextureMappingZone::GenericSolverClosestMix),

View File

@@ -37,7 +37,9 @@ struct PrimeTowerTextureRenderSettings
RGB,
RGBK,
RGBW,
BW
BW,
CMYKW,
RGBKW
};
bool enabled = false;
@@ -207,6 +209,18 @@ private:
std::array<float, 3>{1.f, 1.f, 1.f}};
case BW:
return {std::array<float, 3>{0.f, 0.f, 0.f}, std::array<float, 3>{1.f, 1.f, 1.f}};
case CMYKW:
return {std::array<float, 3>{0.f, 1.f, 1.f},
std::array<float, 3>{1.f, 0.f, 1.f},
std::array<float, 3>{1.f, 1.f, 0.f},
std::array<float, 3>{0.f, 0.f, 0.f},
std::array<float, 3>{1.f, 1.f, 1.f}};
case RGBKW:
return {std::array<float, 3>{1.f, 0.f, 0.f},
std::array<float, 3>{0.f, 1.f, 0.f},
std::array<float, 3>{0.f, 0.f, 1.f},
std::array<float, 3>{0.f, 0.f, 0.f},
std::array<float, 3>{1.f, 1.f, 1.f}};
default: return {};
}
}
@@ -357,6 +371,26 @@ private:
default:
break;
}
if (component_count == 5) {
const float chroma = std::max(0.f, 1.f - darkness - whiteness);
if (mode == int(TextureMappingZone::FilamentColorCMYKW)) {
const float c = chroma <= 1e-6f ? 0.f : 1.f - safe_div(r - whiteness, chroma);
const float m = chroma <= 1e-6f ? 0.f : 1.f - safe_div(g - whiteness, chroma);
const float y = chroma <= 1e-6f ? 0.f : 1.f - safe_div(b - whiteness, chroma);
return {print_visibility_strength(c),
print_visibility_strength(m),
print_visibility_strength(y),
print_visibility_strength(darkness),
print_visibility_strength(whiteness)};
}
if (mode == int(TextureMappingZone::FilamentColorRGBKW)) {
return {print_visibility_strength(safe_div(r - whiteness, chroma)),
print_visibility_strength(safe_div(g - whiteness, chroma)),
print_visibility_strength(safe_div(b - whiteness, chroma)),
print_visibility_strength(darkness),
print_visibility_strength(whiteness)};
}
}
if (component_count != 4)
return {};
if (mode == int(TextureMappingZone::FilamentColorCMYK)) {
@@ -530,6 +564,29 @@ private:
print_visibility_strength(gray <= 0.5f ? 2.f * gray : 1.f)};
break;
}
case CMYKW: {
const float chroma = std::max(0.f, 1.f - darkness - whiteness);
const float c = chroma <= 1e-6f ? 0.f : 1.f - safe_div(r - whiteness, chroma);
const float m = chroma <= 1e-6f ? 0.f : 1.f - safe_div(g - whiteness, chroma);
const float y = chroma <= 1e-6f ? 0.f : 1.f - safe_div(b - whiteness, chroma);
ideals = {{{0.f, 1.f, 1.f}, {1.f, 0.f, 1.f}, {1.f, 1.f, 0.f}, {0.f, 0.f, 0.f}, {1.f, 1.f, 1.f}}};
weights = {print_visibility_strength(c),
print_visibility_strength(m),
print_visibility_strength(y),
print_visibility_strength(darkness),
print_visibility_strength(whiteness)};
break;
}
case RGBKW: {
const float chroma = std::max(0.f, 1.f - darkness - whiteness);
ideals = {{{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}, {0.f, 0.f, 0.f}, {1.f, 1.f, 1.f}}};
weights = {print_visibility_strength(safe_div(r - whiteness, chroma)),
print_visibility_strength(safe_div(g - whiteness, chroma)),
print_visibility_strength(safe_div(b - whiteness, chroma)),
print_visibility_strength(darkness),
print_visibility_strength(whiteness)};
break;
}
default:
ideals = {{{0.f, 1.f, 1.f}, {1.f, 0.f, 1.f}, {1.f, 1.f, 0.f}, {0.f, 0.f, 0.f}}};
weights = {print_visibility_strength(1.f - r),

View File

@@ -137,6 +137,10 @@ static std::vector<std::array<float, 3>> prime_tower_semantic_colors_for_print(i
return {{{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}, {1.f, 1.f, 1.f}}};
case PrimeTowerTextureRenderSettings::BW:
return {{{0.f, 0.f, 0.f}, {1.f, 1.f, 1.f}}};
case PrimeTowerTextureRenderSettings::CMYKW:
return {{{0.f, 1.f, 1.f}, {1.f, 0.f, 1.f}, {1.f, 1.f, 0.f}, {0.f, 0.f, 0.f}, {1.f, 1.f, 1.f}}};
case PrimeTowerTextureRenderSettings::RGBKW:
return {{{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}, {0.f, 0.f, 0.f}, {1.f, 1.f, 1.f}}};
default:
return {};
}
@@ -210,6 +214,8 @@ static int prime_tower_auto_color_mode_for_print(const ToolOrdering &tool_orderi
PrimeTowerTextureRenderSettings::CMYW,
PrimeTowerTextureRenderSettings::RGBK,
PrimeTowerTextureRenderSettings::RGBW,
PrimeTowerTextureRenderSettings::CMYKW,
PrimeTowerTextureRenderSettings::RGBKW,
PrimeTowerTextureRenderSettings::CMY,
PrimeTowerTextureRenderSettings::RGB,
PrimeTowerTextureRenderSettings::BW
@@ -236,7 +242,7 @@ static int prime_tower_auto_color_mode_for_print(const ToolOrdering &tool_orderi
static int prime_tower_texture_zone_color_mode_for_print(int filament_color_mode)
{
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorBW))) {
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB): return PrimeTowerTextureRenderSettings::RGB;
case int(TextureMappingZone::FilamentColorCMY): return PrimeTowerTextureRenderSettings::CMY;
case int(TextureMappingZone::FilamentColorCMYK): return PrimeTowerTextureRenderSettings::CMYK;
@@ -244,6 +250,8 @@ static int prime_tower_texture_zone_color_mode_for_print(int filament_color_mode
case int(TextureMappingZone::FilamentColorRGBK): return PrimeTowerTextureRenderSettings::RGBK;
case int(TextureMappingZone::FilamentColorRGBW): return PrimeTowerTextureRenderSettings::RGBW;
case int(TextureMappingZone::FilamentColorBW): return PrimeTowerTextureRenderSettings::BW;
case int(TextureMappingZone::FilamentColorCMYKW): return PrimeTowerTextureRenderSettings::CMYKW;
case int(TextureMappingZone::FilamentColorRGBKW): return PrimeTowerTextureRenderSettings::RGBKW;
default: return PrimeTowerTextureRenderSettings::GenericSolver;
}
}
@@ -258,6 +266,8 @@ static int prime_tower_texture_mapping_color_mode_for_print(int prime_tower_colo
case PrimeTowerTextureRenderSettings::RGBK: return int(TextureMappingZone::FilamentColorRGBK);
case PrimeTowerTextureRenderSettings::RGBW: return int(TextureMappingZone::FilamentColorRGBW);
case PrimeTowerTextureRenderSettings::BW: return int(TextureMappingZone::FilamentColorBW);
case PrimeTowerTextureRenderSettings::CMYKW: return int(TextureMappingZone::FilamentColorCMYKW);
case PrimeTowerTextureRenderSettings::RGBKW: return int(TextureMappingZone::FilamentColorRGBKW);
default: return int(TextureMappingZone::FilamentColorAny);
}
}
@@ -3468,6 +3478,10 @@ void Print::_make_wipe_tower()
texture.color_mode = PrimeTowerTextureRenderSettings::RGBW;
else if (mode == "bw")
texture.color_mode = PrimeTowerTextureRenderSettings::BW;
else if (mode == "cmykw")
texture.color_mode = PrimeTowerTextureRenderSettings::CMYKW;
else if (mode == "rgbkw")
texture.color_mode = PrimeTowerTextureRenderSettings::RGBKW;
else
texture.color_mode = PrimeTowerTextureRenderSettings::CMYK;

View File

@@ -265,6 +265,10 @@ static const char *vertex_color_mode_name_for_error(int filament_color_mode)
return "RGBW";
case int(TextureMappingZone::FilamentColorBW):
return "BW";
case int(TextureMappingZone::FilamentColorCMYKW):
return "CMYKW";
case int(TextureMappingZone::FilamentColorRGBKW):
return "RGBKW";
default:
return "Generic Solver (slow)";
}
@@ -304,7 +308,7 @@ static std::vector<std::string> collect_texture_mapping_vertex_color_mode_mismat
const int filament_color_mode = std::clamp(zone->filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW));
int(TextureMappingZone::FilamentColorRGBKW));
const size_t expected_count = TextureMappingManager::expected_component_count(zone->texture_mapping_mode,
filament_color_mode);
if (expected_count == 0)

View File

@@ -394,7 +394,7 @@ static std::vector<RGB> semantic_colors(int filament_color_mode)
{
switch (clamp_int(filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW))) {
int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB): return {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}};
case int(TextureMappingZone::FilamentColorCMY): return {{0, 255, 255}, {255, 0, 255}, {255, 255, 0}};
case int(TextureMappingZone::FilamentColorCMYK): return {{0, 255, 255}, {255, 0, 255}, {255, 255, 0}, {0, 0, 0}};
@@ -402,6 +402,8 @@ static std::vector<RGB> semantic_colors(int filament_color_mode)
case int(TextureMappingZone::FilamentColorRGBK): return {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {0, 0, 0}};
case int(TextureMappingZone::FilamentColorRGBW): return {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 255}};
case int(TextureMappingZone::FilamentColorBW): return {{0, 0, 0}, {255, 255, 255}};
case int(TextureMappingZone::FilamentColorCMYKW): return {{0, 255, 255}, {255, 0, 255}, {255, 255, 0}, {0, 0, 0}, {255, 255, 255}};
case int(TextureMappingZone::FilamentColorRGBKW): return {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {0, 0, 0}, {255, 255, 255}};
default: return {};
}
}
@@ -497,7 +499,7 @@ static int mapping_mode_from_name(const std::string &name)
static std::string color_model_name(int mode)
{
switch (clamp_int(mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorBW))) {
switch (clamp_int(mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB): return "rgb";
case int(TextureMappingZone::FilamentColorCMY): return "cmy";
case int(TextureMappingZone::FilamentColorCMYK): return "cmyk";
@@ -505,6 +507,8 @@ static std::string color_model_name(int mode)
case int(TextureMappingZone::FilamentColorRGBK): return "rgbk";
case int(TextureMappingZone::FilamentColorRGBW): return "rgbw";
case int(TextureMappingZone::FilamentColorBW): return "bw";
case int(TextureMappingZone::FilamentColorCMYKW): return "cmykw";
case int(TextureMappingZone::FilamentColorRGBKW): return "rgbkw";
default: return "any";
}
}
@@ -518,6 +522,8 @@ static int color_model_from_name(const std::string &name)
if (name == "rgbk") return int(TextureMappingZone::FilamentColorRGBK);
if (name == "rgbw") return int(TextureMappingZone::FilamentColorRGBW);
if (name == "bw") return int(TextureMappingZone::FilamentColorBW);
if (name == "cmykw") return int(TextureMappingZone::FilamentColorCMYKW);
if (name == "rgbkw") return int(TextureMappingZone::FilamentColorRGBKW);
return int(TextureMappingZone::FilamentColorAny);
}
@@ -620,7 +626,7 @@ static std::string normalized_prime_tower_color_mode_name(std::string name)
if (name == "generic" || name == "generic_solver" || name == "solver")
return "generic_solver";
if (name == "rgb" || name == "cmy" || name == "cmyk" || name == "cmyw" ||
name == "rgbk" || name == "rgbw" || name == "bw")
name == "rgbk" || name == "rgbw" || name == "bw" || name == "cmykw" || name == "rgbkw")
return name;
return "auto";
}
@@ -1344,7 +1350,7 @@ size_t TextureMappingManager::expected_component_count(int mapping_mode, int fil
switch (clamp_int(filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW))) {
int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB):
case int(TextureMappingZone::FilamentColorCMY):
return 3;
@@ -1355,6 +1361,9 @@ size_t TextureMappingManager::expected_component_count(int mapping_mode, int fil
return 4;
case int(TextureMappingZone::FilamentColorBW):
return 2;
case int(TextureMappingZone::FilamentColorCMYKW):
case int(TextureMappingZone::FilamentColorRGBKW):
return 5;
default:
return 0;
}

View File

@@ -52,7 +52,9 @@ struct TextureMappingZone
FilamentColorCMYW = 4,
FilamentColorRGBK = 5,
FilamentColorRGBW = 6,
FilamentColorBW = 7
FilamentColorBW = 7,
FilamentColorCMYKW = 8,
FilamentColorRGBKW = 9
};
enum GenericSolverLookupMode : uint8_t {

View File

@@ -314,6 +314,10 @@ static std::string raw_atlas_color_mode_name_for_keys(const std::vector<std::str
return "RGBW";
if (all_standard && keys.size() == 2 && has_key("K") && has_key("W"))
return "BW";
if (all_standard && keys.size() == 5 && has_key("C") && has_key("M") && has_key("Y") && has_key("K") && has_key("W"))
return "CMYKW";
if (all_standard && keys.size() == 5 && has_key("R") && has_key("G") && has_key("B") && has_key("K") && has_key("W"))
return "RGBKW";
if (all_standard && !joined.empty())
return joined;
@@ -8025,6 +8029,66 @@ void GLGizmoTrueColorPainting::sync_rgb_from_rgbw()
m_rgb_color[2] = mixed.b();
}
void GLGizmoTrueColorPainting::sync_cmykw_from_rgb()
{
const std::vector<ColorRGBA> colors = {
ColorRGBA(0.f, 1.f, 1.f, 1.f),
ColorRGBA(1.f, 0.f, 1.f, 1.f),
ColorRGBA(1.f, 1.f, 0.f, 1.f),
ColorRGBA(0.f, 0.f, 0.f, 1.f),
ColorRGBA(1.f, 1.f, 1.f, 1.f)
};
const std::vector<float> weights = closest_color_mix_weights(colors, ColorRGBA(m_rgb_color[0], m_rgb_color[1], m_rgb_color[2], 1.f));
for (size_t idx = 0; idx < m_cmykw_color.size() && idx < weights.size(); ++idx)
m_cmykw_color[idx] = weights[idx];
}
void GLGizmoTrueColorPainting::sync_rgb_from_cmykw()
{
const std::vector<ColorRGBA> colors = {
ColorRGBA(0.f, 1.f, 1.f, 1.f),
ColorRGBA(1.f, 0.f, 1.f, 1.f),
ColorRGBA(1.f, 1.f, 0.f, 1.f),
ColorRGBA(0.f, 0.f, 0.f, 1.f),
ColorRGBA(1.f, 1.f, 1.f, 1.f)
};
const std::vector<float> weights(m_cmykw_color.begin(), m_cmykw_color.end());
const ColorRGBA mixed = color_mix_from_weights(colors, weights, ColorRGBA(1.f, 1.f, 1.f, 1.f));
m_rgb_color[0] = mixed.r();
m_rgb_color[1] = mixed.g();
m_rgb_color[2] = mixed.b();
}
void GLGizmoTrueColorPainting::sync_rgbkw_from_rgb()
{
const std::vector<ColorRGBA> colors = {
ColorRGBA(1.f, 0.f, 0.f, 1.f),
ColorRGBA(0.f, 1.f, 0.f, 1.f),
ColorRGBA(0.f, 0.f, 1.f, 1.f),
ColorRGBA(0.f, 0.f, 0.f, 1.f),
ColorRGBA(1.f, 1.f, 1.f, 1.f)
};
const std::vector<float> weights = closest_color_mix_weights(colors, ColorRGBA(m_rgb_color[0], m_rgb_color[1], m_rgb_color[2], 1.f));
for (size_t idx = 0; idx < m_rgbkw_color.size() && idx < weights.size(); ++idx)
m_rgbkw_color[idx] = weights[idx];
}
void GLGizmoTrueColorPainting::sync_rgb_from_rgbkw()
{
const std::vector<ColorRGBA> colors = {
ColorRGBA(1.f, 0.f, 0.f, 1.f),
ColorRGBA(0.f, 1.f, 0.f, 1.f),
ColorRGBA(0.f, 0.f, 1.f, 1.f),
ColorRGBA(0.f, 0.f, 0.f, 1.f),
ColorRGBA(1.f, 1.f, 1.f, 1.f)
};
const std::vector<float> weights(m_rgbkw_color.begin(), m_rgbkw_color.end());
const ColorRGBA mixed = color_mix_from_weights(colors, weights, ColorRGBA(1.f, 1.f, 1.f, 1.f));
m_rgb_color[0] = mixed.r();
m_rgb_color[1] = mixed.g();
m_rgb_color[2] = mixed.b();
}
void GLGizmoTrueColorPainting::sync_bw_from_rgb()
{
const float r = std::clamp(m_rgb_color[0], 0.f, 1.f);
@@ -8115,6 +8179,12 @@ void GLGizmoTrueColorPainting::sync_active_color_mode_from_rgb(bool update_filam
case ColorInputMode::BW:
sync_bw_from_rgb();
break;
case ColorInputMode::CMYKW:
sync_cmykw_from_rgb();
break;
case ColorInputMode::RGBKW:
sync_rgbkw_from_rgb();
break;
}
}
@@ -8262,6 +8332,60 @@ bool GLGizmoTrueColorPainting::render_rgbw_picker(float item_width)
return changed;
}
bool GLGizmoTrueColorPainting::render_cmykw_picker(float item_width)
{
bool changed = false;
ImGui::PushItemWidth(item_width);
ImGuiColorEditFlags flags = ImGuiColorEditFlags_DisplayRGB |
ImGuiColorEditFlags_InputRGB |
ImGuiColorEditFlags_NoInputs;
if (ImGui::ColorEdit3("##true_color_cmykw_visual", m_rgb_color.data(), flags)) {
sync_cmykw_from_rgb();
changed = true;
}
bool cmykw_changed = false;
cmykw_changed |= ImGui::SliderFloat("Cyan", &m_cmykw_color[0], 0.f, 1.f, "%.2f");
cmykw_changed |= ImGui::SliderFloat("Magenta", &m_cmykw_color[1], 0.f, 1.f, "%.2f");
cmykw_changed |= ImGui::SliderFloat("Yellow", &m_cmykw_color[2], 0.f, 1.f, "%.2f");
cmykw_changed |= ImGui::SliderFloat("Black", &m_cmykw_color[3], 0.f, 1.f, "%.2f");
cmykw_changed |= ImGui::SliderFloat("White", &m_cmykw_color[4], 0.f, 1.f, "%.2f");
ImGui::PopItemWidth();
if (cmykw_changed) {
sync_rgb_from_cmykw();
changed = true;
}
return changed;
}
bool GLGizmoTrueColorPainting::render_rgbkw_picker(float item_width)
{
bool changed = false;
ImGui::PushItemWidth(item_width);
ImGuiColorEditFlags flags = ImGuiColorEditFlags_DisplayRGB |
ImGuiColorEditFlags_InputRGB |
ImGuiColorEditFlags_NoInputs;
if (ImGui::ColorEdit3("##true_color_rgbkw_visual", m_rgb_color.data(), flags)) {
sync_rgbkw_from_rgb();
changed = true;
}
bool rgbkw_changed = false;
rgbkw_changed |= ImGui::SliderFloat("Red", &m_rgbkw_color[0], 0.f, 1.f, "%.2f");
rgbkw_changed |= ImGui::SliderFloat("Green", &m_rgbkw_color[1], 0.f, 1.f, "%.2f");
rgbkw_changed |= ImGui::SliderFloat("Blue", &m_rgbkw_color[2], 0.f, 1.f, "%.2f");
rgbkw_changed |= ImGui::SliderFloat("Black", &m_rgbkw_color[3], 0.f, 1.f, "%.2f");
rgbkw_changed |= ImGui::SliderFloat("White", &m_rgbkw_color[4], 0.f, 1.f, "%.2f");
ImGui::PopItemWidth();
if (rgbkw_changed) {
sync_rgb_from_rgbkw();
changed = true;
}
return changed;
}
bool GLGizmoTrueColorPainting::render_bw_picker(float item_width)
{
bool changed = false;
@@ -8378,7 +8502,9 @@ void GLGizmoTrueColorPainting::on_render_input_window(float x, float y, float bo
"CMYW",
"RGBK",
"RGBW",
"BW"
"BW",
"CMYKW",
"RGBKW"
};
const int mode_count = int(sizeof(mode_labels) / sizeof(mode_labels[0]));
int mode = std::clamp(int(m_color_input_mode), 0, mode_count - 1);
@@ -8435,6 +8561,12 @@ void GLGizmoTrueColorPainting::on_render_input_window(float x, float y, float bo
case ColorInputMode::BW:
color_changed = render_bw_picker(slider_width);
break;
case ColorInputMode::CMYKW:
color_changed = render_cmykw_picker(slider_width);
break;
case ColorInputMode::RGBKW:
color_changed = render_rgbkw_picker(slider_width);
break;
}
if (color_changed)
update_triangle_selectors_color();

View File

@@ -220,7 +220,9 @@ private:
CMYW,
RGBK,
RGBW,
BW
BW,
CMYKW,
RGBKW
};
bool on_init() override;
@@ -257,6 +259,10 @@ private:
void sync_rgb_from_rgbk();
void sync_rgbw_from_rgb();
void sync_rgb_from_rgbw();
void sync_cmykw_from_rgb();
void sync_rgb_from_cmykw();
void sync_rgbkw_from_rgb();
void sync_rgb_from_rgbkw();
void sync_bw_from_rgb();
void sync_rgb_from_bw();
void ensure_filament_mix_colors();
@@ -269,6 +275,8 @@ private:
bool render_cmyw_picker(float item_width);
bool render_rgbk_picker(float item_width);
bool render_rgbw_picker(float item_width);
bool render_cmykw_picker(float item_width);
bool render_rgbkw_picker(float item_width);
bool render_bw_picker(float item_width);
bool render_filament_colors_picker(float item_width);
@@ -279,6 +287,8 @@ private:
std::array<float, 4> m_rgbk_color { 0.f, 0.f, 0.f, 1.f };
std::array<float, 4> m_rgbw_color { 0.f, 0.f, 0.f, 1.f };
std::array<float, 2> m_bw_color { 1.f, 0.f };
std::array<float, 5> m_cmykw_color { 0.f, 0.f, 0.f, 0.f, 1.f };
std::array<float, 5> m_rgbkw_color { 0.f, 0.f, 0.f, 0.f, 1.f };
std::vector<ColorRGBA> m_filament_mix_colors;
std::vector<float> m_filament_mix;
float m_brush_hardness = 1.f;

View File

@@ -35,8 +35,8 @@ constexpr float k_preview_clip_padding = 2.f * k_preview_offset;
constexpr float k_polygon_offset_factor = -1.f;
constexpr float k_polygon_offset_units = -1.f;
constexpr float k_epsilon = 1e-6f;
constexpr unsigned int k_simulated_texture_preview_max_edge = 1024;
constexpr size_t k_simulated_texture_preview_max_pixels = 1024ull * 1024ull;
constexpr unsigned int k_simulated_texture_preview_max_edge = 2048;
constexpr size_t k_simulated_texture_preview_max_pixels = 2048ull * 2048ull;
constexpr const char *TEXTURE_MAPPING_BACKGROUND_COLOR_CONFIG_KEY = "texture_mapping_background_color";
struct TexturePreviewMixCandidate
@@ -556,7 +556,7 @@ std::vector<std::string> raw_filament_color_mode_channel_keys_for_texture_previe
std::vector<std::string> keys;
switch (std::clamp(filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW))) {
int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB):
keys = { "R", "G", "B" };
break;
@@ -578,6 +578,12 @@ std::vector<std::string> raw_filament_color_mode_channel_keys_for_texture_previe
case int(TextureMappingZone::FilamentColorBW):
keys = { "K", "W" };
break;
case int(TextureMappingZone::FilamentColorCMYKW):
keys = { "C", "M", "Y", "K", "W" };
break;
case int(TextureMappingZone::FilamentColorRGBKW):
keys = { "R", "G", "B", "K", "W" };
break;
default:
break;
}
@@ -771,6 +777,24 @@ std::vector<size_t> semantic_component_indices_for_texture_preview(const std::ve
case int(TextureMappingZone::FilamentColorRGBW):
semantic_colors = { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } }, { { 1.f, 1.f, 1.f } } };
break;
case int(TextureMappingZone::FilamentColorCMYKW):
semantic_colors = {
{ { 0.f, 1.f, 1.f } },
{ { 1.f, 0.f, 1.f } },
{ { 1.f, 1.f, 0.f } },
{ { 0.f, 0.f, 0.f } },
{ { 1.f, 1.f, 1.f } }
};
break;
case int(TextureMappingZone::FilamentColorRGBKW):
semantic_colors = {
{ { 1.f, 0.f, 0.f } },
{ { 0.f, 1.f, 0.f } },
{ { 0.f, 0.f, 1.f } },
{ { 0.f, 0.f, 0.f } },
{ { 1.f, 1.f, 1.f } }
};
break;
default:
return {};
}
@@ -782,7 +806,7 @@ std::vector<std::array<float, 3>> fixed_color_generic_solver_component_colors(in
{
switch (std::clamp(filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW))) {
int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB):
return { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } } };
case int(TextureMappingZone::FilamentColorCMY):
@@ -795,6 +819,10 @@ std::vector<std::array<float, 3>> fixed_color_generic_solver_component_colors(in
return { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } }, { { 0.f, 0.f, 0.f } } };
case int(TextureMappingZone::FilamentColorRGBW):
return { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } }, { { 1.f, 1.f, 1.f } } };
case int(TextureMappingZone::FilamentColorCMYKW):
return { { { 0.f, 1.f, 1.f } }, { { 1.f, 0.f, 1.f } }, { { 1.f, 1.f, 0.f } }, { { 0.f, 0.f, 0.f } }, { { 1.f, 1.f, 1.f } } };
case int(TextureMappingZone::FilamentColorRGBKW):
return { { { 1.f, 0.f, 0.f } }, { { 0.f, 1.f, 0.f } }, { { 0.f, 0.f, 1.f } }, { { 0.f, 0.f, 0.f } }, { { 1.f, 1.f, 1.f } } };
default:
return {};
}
@@ -827,7 +855,7 @@ bool texture_preview_uses_generic_solver(const TexturePreviewSimulationSettings
const int clamped_mode = std::clamp(settings.filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW));
int(TextureMappingZone::FilamentColorRGBKW));
size_t expected_component_count = 0;
switch (clamped_mode) {
case int(TextureMappingZone::FilamentColorRGB):
@@ -843,6 +871,10 @@ bool texture_preview_uses_generic_solver(const TexturePreviewSimulationSettings
case int(TextureMappingZone::FilamentColorBW):
expected_component_count = 2;
break;
case int(TextureMappingZone::FilamentColorCMYKW):
case int(TextureMappingZone::FilamentColorRGBKW):
expected_component_count = 5;
break;
default:
return true;
}
@@ -1183,7 +1215,7 @@ std::vector<float> optimized_primary_component_weights_for_target(const std::arr
{
const int clamped_mode = std::clamp(filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW));
int(TextureMappingZone::FilamentColorRGBKW));
if (clamped_mode == int(TextureMappingZone::FilamentColorAny))
return {};
@@ -1249,6 +1281,33 @@ std::vector<float> optimized_primary_component_weights_for_target(const std::arr
return weights;
}
if (clamped_mode == int(TextureMappingZone::FilamentColorCMYKW)) {
if (component_count != 5)
return {};
const float chroma = std::max(0.f, 1.f - darkness - whiteness);
const float c = chroma <= k_epsilon ? 0.f : 1.f - safe_div(r - whiteness, chroma);
const float m = chroma <= k_epsilon ? 0.f : 1.f - safe_div(g - whiteness, chroma);
const float y = chroma <= k_epsilon ? 0.f : 1.f - safe_div(b - whiteness, chroma);
weights[component_index_for_role(0)] = print_visibility_strength(c * chroma);
weights[component_index_for_role(1)] = print_visibility_strength(m * chroma);
weights[component_index_for_role(2)] = print_visibility_strength(y * chroma);
weights[component_index_for_role(3)] = print_visibility_strength(darkness);
weights[component_index_for_role(4)] = clamp01(std::pow(whiteness, 1.35f));
return weights;
}
if (clamped_mode == int(TextureMappingZone::FilamentColorRGBKW)) {
if (component_count != 5)
return {};
const float chroma = std::max(0.f, 1.f - darkness - whiteness);
weights[component_index_for_role(0)] = print_visibility_strength(safe_div(r - whiteness, chroma) * chroma);
weights[component_index_for_role(1)] = print_visibility_strength(safe_div(g - whiteness, chroma) * chroma);
weights[component_index_for_role(2)] = print_visibility_strength(safe_div(b - whiteness, chroma) * chroma);
weights[component_index_for_role(3)] = print_visibility_strength(darkness);
weights[component_index_for_role(4)] = clamp01(std::pow(whiteness, 1.35f));
return weights;
}
if (component_count != 4)
return {};
@@ -1420,7 +1479,7 @@ std::optional<TexturePreviewSimulationSettings> texture_preview_simulation_setti
int(TextureMappingZone::TextureMappingRawValues));
settings.filament_color_mode = std::clamp(zone->filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW));
int(TextureMappingZone::FilamentColorRGBKW));
settings.force_sequential_filaments = zone->force_sequential_filaments;
settings.limit_texture_resolution = zone->preview_limit_resolution;
settings.compact_offset_mode = zone->compact_offset_mode;

View File

@@ -612,12 +612,49 @@ static wxArrayString texture_mapping_color_mode_choices()
choices.Add(_L("RGBK"));
choices.Add(_L("RGBW"));
choices.Add(_L("BW"));
choices.Add(_L("5+ toolheads:"));
choices.Add(_L("CMYKW"));
choices.Add(_L("RGBKW"));
return choices;
}
static int texture_mapping_five_toolhead_marker_selection()
{
return 8;
}
static int texture_mapping_color_mode_selection(int filament_color_mode)
{
const int clamped_mode = std::clamp(filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorRGBKW));
switch (clamped_mode) {
case int(TextureMappingZone::FilamentColorCMYKW): return 9;
case int(TextureMappingZone::FilamentColorRGBKW): return 10;
default: return clamped_mode;
}
}
static int texture_mapping_color_mode_from_selection(int selection, int fallback)
{
switch (selection) {
case 0: return int(TextureMappingZone::FilamentColorAny);
case 1: return int(TextureMappingZone::FilamentColorRGB);
case 2: return int(TextureMappingZone::FilamentColorCMY);
case 3: return int(TextureMappingZone::FilamentColorCMYK);
case 4: return int(TextureMappingZone::FilamentColorCMYW);
case 5: return int(TextureMappingZone::FilamentColorRGBK);
case 6: return int(TextureMappingZone::FilamentColorRGBW);
case 7: return int(TextureMappingZone::FilamentColorBW);
case 9: return int(TextureMappingZone::FilamentColorCMYKW);
case 10: return int(TextureMappingZone::FilamentColorRGBKW);
default: return std::clamp(fallback, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorRGBKW));
}
}
static std::vector<wxString> texture_mapping_channel_labels(int filament_color_mode)
{
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorBW))) {
switch (std::clamp(filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorRGBKW))) {
case int(TextureMappingZone::FilamentColorRGB):
return {_L("Red"), _L("Green"), _L("Blue")};
case int(TextureMappingZone::FilamentColorCMY):
@@ -632,6 +669,10 @@ static std::vector<wxString> texture_mapping_channel_labels(int filament_color_m
return {_L("Red"), _L("Green"), _L("Blue"), _L("White")};
case int(TextureMappingZone::FilamentColorBW):
return {_L("Black"), _L("White")};
case int(TextureMappingZone::FilamentColorCMYKW):
return {_L("Cyan"), _L("Magenta"), _L("Yellow"), _L("Black"), _L("White")};
case int(TextureMappingZone::FilamentColorRGBKW):
return {_L("Red"), _L("Green"), _L("Blue"), _L("Black"), _L("White")};
default:
return {};
}
@@ -1348,8 +1389,23 @@ public:
prime_color_modes.Add(_L("RGBK"));
prime_color_modes.Add(_L("RGBW"));
prime_color_modes.Add(_L("BW"));
prime_color_modes.Add(_L("5+ toolheads:"));
prime_color_modes.Add(_L("CMYKW"));
prime_color_modes.Add(_L("RGBKW"));
m_prime_tower_color_mode_choice = new wxChoice(global_page, wxID_ANY, wxDefaultPosition, wxDefaultSize, prime_color_modes);
m_prime_tower_color_mode_choice->SetSelection(prime_tower_color_mode_selection(m_global_settings.prime_tower_color_mode));
int last_prime_tower_color_mode_selection = m_prime_tower_color_mode_choice->GetSelection();
m_prime_tower_color_mode_choice->Bind(wxEVT_CHOICE,
[this, last_prime_tower_color_mode_selection](wxCommandEvent &) mutable {
if (m_prime_tower_color_mode_choice == nullptr)
return;
const int selection = m_prime_tower_color_mode_choice->GetSelection();
if (selection == prime_tower_five_toolhead_marker_selection()) {
m_prime_tower_color_mode_choice->SetSelection(last_prime_tower_color_mode_selection);
return;
}
last_prime_tower_color_mode_selection = selection;
});
color_mode_row->Add(m_prime_tower_color_mode_choice, 1, wxALIGN_CENTER_VERTICAL);
global_root->Add(color_mode_row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, gap);
@@ -1555,10 +1611,17 @@ private:
case 6: return "rgbk";
case 7: return "rgbw";
case 8: return "bw";
case 10: return "cmykw";
case 11: return "rgbkw";
default: return "auto";
}
}
static int prime_tower_five_toolhead_marker_selection()
{
return 9;
}
static int prime_tower_color_mode_selection(const std::string &mode)
{
const std::string normalized = TextureMappingGlobalSettings::normalize_color_mode_name(mode);
@@ -1570,6 +1633,8 @@ private:
if (normalized == "rgbk") return 6;
if (normalized == "rgbw") return 7;
if (normalized == "bw") return 8;
if (normalized == "cmykw") return 10;
if (normalized == "rgbkw") return 11;
return 0;
}
@@ -5489,7 +5554,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
auto *mode_row = new wxWrapSizer(wxHORIZONTAL, wxWRAPSIZER_DEFAULT_FLAGS);
mode_row->Add(new wxStaticText(editor, wxID_ANY, _L("Filament colors")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
auto *mode_choice = new wxChoice(editor, wxID_ANY, wxDefaultPosition, wxDefaultSize, texture_mapping_color_mode_choices());
mode_choice->SetSelection(std::clamp(entry.filament_color_mode, int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorBW)));
mode_choice->SetSelection(texture_mapping_color_mode_selection(entry.filament_color_mode));
mode_row->Add(mode_choice, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
auto *preview_colors_chk = new wxCheckBox(editor, wxID_ANY, _L("Preview Result Colors"));
preview_colors_chk->SetValue(entry.preview_simulate_colors);
@@ -5535,7 +5600,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
updated.component_a = ids.empty() ? 1 : ids.front();
updated.component_b = ids.size() > 1 ? ids[1] : updated.component_a;
updated.filament_color_mode = mode_choice != nullptr ?
std::clamp(mode_choice->GetSelection(), int(TextureMappingZone::FilamentColorAny), int(TextureMappingZone::FilamentColorBW)) :
texture_mapping_color_mode_from_selection(mode_choice->GetSelection(), updated.filament_color_mode) :
updated.filament_color_mode;
updated.preview_simulate_colors = preview_colors_chk != nullptr && preview_colors_chk->GetValue();
updated.contrast_pct = contrast_spin != nullptr ? std::clamp(float(contrast_spin->GetValue()), 25.f, 300.f) : updated.contrast_pct;
@@ -5576,14 +5641,22 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
for (wxCheckBox *chk : filament_checks)
if (chk != nullptr)
chk->Bind(wxEVT_CHECKBOX, [apply_controls](wxCommandEvent &) { apply_controls(); });
mode_choice->Bind(wxEVT_CHOICE, [this, zone_index, mgr_ptr, num_physical, physical_colors, filament_checks, mode_choice, apply_controls](wxCommandEvent &) {
int last_mode_selection = mode_choice->GetSelection();
mode_choice->Bind(wxEVT_CHOICE, [this, zone_index, mgr_ptr, num_physical, physical_colors, filament_checks, mode_choice, apply_controls, last_mode_selection](wxCommandEvent &) mutable {
if (mode_choice != nullptr) {
const int selection = mode_choice->GetSelection();
if (selection == texture_mapping_five_toolhead_marker_selection()) {
mode_choice->SetSelection(last_mode_selection);
return;
}
last_mode_selection = selection;
}
if (zone_index < mgr_ptr->zones().size()) {
TextureMappingZone &zone = mgr_ptr->zones()[zone_index];
if (zone.auto_adjust_filament_selection) {
TextureMappingZone adjusted = zone;
adjusted.filament_color_mode = std::clamp(mode_choice != nullptr ? mode_choice->GetSelection() : zone.filament_color_mode,
int(TextureMappingZone::FilamentColorAny),
int(TextureMappingZone::FilamentColorBW));
adjusted.filament_color_mode = texture_mapping_color_mode_from_selection(
mode_choice != nullptr ? mode_choice->GetSelection() : -1, zone.filament_color_mode);
TextureMappingManager::auto_adjust_texture_component_ids(adjusted, num_physical, physical_colors);
const std::vector<unsigned int> adjusted_ids = texture_mapping_selected_ids(adjusted, num_physical);
for (size_t idx = 0; idx < filament_checks.size(); ++idx)