mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-02 06:47:04 +00:00
Blend mixed slots in the machine-send and AMS-sync thumbnails
This commit is contained in:
@@ -4,7 +4,10 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "EncodedFilament.hpp"
|
||||
#include "FilamentBitmapUtils.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "libslic3r/FilamentMixer.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
@@ -265,4 +268,65 @@ wxBitmap create_filament_bitmap(const std::vector<wxColour>& colors, const wxSiz
|
||||
}
|
||||
}
|
||||
|
||||
void recompute_mixed_slot_colors(std::vector<wxColour>& colors,
|
||||
const Slic3r::DynamicPrintConfig& cfg)
|
||||
{
|
||||
const auto* is_mixed_opt = cfg.option<ConfigOptionBools>("filament_is_mixed");
|
||||
const auto* comp_opt = cfg.option<ConfigOptionStrings>("filament_mixed_components");
|
||||
const auto* ratio_opt = cfg.option<ConfigOptionStrings>("filament_mixed_sublayer_ratios");
|
||||
const auto* grad_opt = cfg.option<ConfigOptionBools>("filament_mixed_gradient");
|
||||
if (!is_mixed_opt || !comp_opt) return;
|
||||
|
||||
const size_t n = is_mixed_opt->values.size();
|
||||
if (colors.size() < n) colors.resize(n);
|
||||
|
||||
const auto* colour_opt = cfg.option<ConfigOptionStrings>("filament_colour");
|
||||
const auto kFallback = wxColour(128, 128, 128, 255);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
if (!is_mixed_opt->values[i]) continue;
|
||||
|
||||
if (i >= comp_opt->values.size()) { colors[i] = kFallback; continue; }
|
||||
auto comp_ids = Slic3r::parse_mixed_components(comp_opt->values[i]);
|
||||
if (comp_ids.empty()) { colors[i] = kFallback; continue; }
|
||||
|
||||
bool is_gradient = grad_opt && i < grad_opt->values.size() && grad_opt->values[i];
|
||||
std::vector<unsigned int> use_ids = comp_ids;
|
||||
std::vector<int> weights;
|
||||
|
||||
if (is_gradient && comp_ids.size() >= 2) {
|
||||
use_ids = { comp_ids.front(), comp_ids.back() };
|
||||
weights = { 5000, 5000 };
|
||||
} else {
|
||||
auto ratios_d = Slic3r::parse_mixed_ratios(
|
||||
(ratio_opt && i < ratio_opt->values.size()) ? ratio_opt->values[i] : std::string{},
|
||||
comp_ids.size());
|
||||
weights.reserve(comp_ids.size());
|
||||
for (double r : ratios_d)
|
||||
weights.push_back(static_cast<int>(std::lround(r * 10000.0)));
|
||||
}
|
||||
|
||||
std::vector<std::string> hex_colors;
|
||||
hex_colors.reserve(use_ids.size());
|
||||
bool any_invalid = false;
|
||||
for (unsigned int id : use_ids) {
|
||||
if (id == 0 || id > colors.size()) { any_invalid = true; break; }
|
||||
wxColour c = colors[id - 1];
|
||||
if (c.IsOk() && (c.Red() > 0 || c.Green() > 0 || c.Blue() > 0)) {
|
||||
hex_colors.push_back(wxString::Format("#%02X%02X%02X", c.Red(), c.Green(), c.Blue()).ToStdString());
|
||||
} else if (colour_opt && (id - 1) < colour_opt->values.size()) {
|
||||
hex_colors.push_back(colour_opt->values[id - 1]);
|
||||
} else {
|
||||
any_invalid = true; break;
|
||||
}
|
||||
}
|
||||
if (any_invalid) { colors[i] = kFallback; continue; }
|
||||
|
||||
std::string hex = Slic3r::blend_color_multi(hex_colors, weights);
|
||||
wxColour blended(hex);
|
||||
if (!blended.IsOk()) blended = kFallback;
|
||||
colors[i] = wxColour(blended.Red(), blended.Green(), blended.Blue(), 255);
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
@@ -7,6 +7,10 @@
|
||||
#include <wx/gdicmn.h>
|
||||
#include <vector>
|
||||
|
||||
// Orca: forward-declare so the header is self-contained outside libslic3r_gui's
|
||||
// force-included pch (the GUI test suite includes it directly).
|
||||
namespace Slic3r { class DynamicPrintConfig; }
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
// Fills a rect with a west->east linear gradient by drawing solid 1px columns.
|
||||
@@ -28,6 +32,12 @@ wxBitmap create_filament_bitmap(const std::vector<wxColour>& colors,
|
||||
const wxSize& size,
|
||||
bool force_gradient = false);
|
||||
|
||||
// Recompute blended representative colors for mixed (virtual) filament slots.
|
||||
// Reads mixed-filament config keys from cfg and writes back into colors[i]
|
||||
// for every slot where filament_is_mixed[i] is true.
|
||||
void recompute_mixed_slot_colors(std::vector<wxColour>& colors,
|
||||
const Slic3r::DynamicPrintConfig& cfg);
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif // slic3r_GUI_FilamentBitmapUtils_hpp_
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Thread.hpp"
|
||||
#include "libslic3r/Color.hpp"
|
||||
#include "FilamentBitmapUtils.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_Preview.hpp"
|
||||
@@ -5693,10 +5694,15 @@ void SelectMachineDialog::clone_thumbnail_data() {
|
||||
m_preview_colors_in_thumbnail.resize(m_materialList.size());
|
||||
}
|
||||
while (iter != m_materialList.end()) {
|
||||
int id = iter->first;
|
||||
Material * item = iter->second;
|
||||
MaterialItem *m = item->item;
|
||||
m_preview_colors_in_thumbnail[id] = m->m_material_coloul;
|
||||
// Orca: key the preview colours by filament slot, as m_cur_colors_in_thumbnail and
|
||||
// SyncAmsInfoDialog already do, so recompute_mixed_slot_colors() below can look a mixed
|
||||
// slot's component colours up by id (BBS keys this array by list position).
|
||||
if (item->id >= m_preview_colors_in_thumbnail.size()) {
|
||||
m_preview_colors_in_thumbnail.resize(item->id + 1);
|
||||
}
|
||||
m_preview_colors_in_thumbnail[item->id] = m->m_material_coloul;
|
||||
if (item->id < m_cur_colors_in_thumbnail.size()) {
|
||||
m_cur_colors_in_thumbnail[item->id] = m->m_ams_coloul;
|
||||
}
|
||||
@@ -5706,6 +5712,20 @@ void SelectMachineDialog::clone_thumbnail_data() {
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
// Expand color arrays to cover mixed (virtual) slots and compute their blended colors
|
||||
const auto& cfg = wxGetApp().preset_bundle->project_config;
|
||||
size_t total = 0;
|
||||
if (auto* opt = cfg.option<ConfigOptionBools>("filament_is_mixed"))
|
||||
total = opt->values.size();
|
||||
size_t target = std::max(total, m_cur_colors_in_thumbnail.size());
|
||||
if (m_cur_colors_in_thumbnail.size() < target)
|
||||
m_cur_colors_in_thumbnail.resize(target);
|
||||
if (m_preview_colors_in_thumbnail.size() < target)
|
||||
m_preview_colors_in_thumbnail.resize(target);
|
||||
recompute_mixed_slot_colors(m_preview_colors_in_thumbnail, cfg);
|
||||
recompute_mixed_slot_colors(m_cur_colors_in_thumbnail, cfg);
|
||||
|
||||
//copy data
|
||||
auto &data = m_cur_input_thumbnail_data;
|
||||
m_preview_thumbnail_data.reset();
|
||||
@@ -5880,6 +5900,10 @@ void SelectMachineDialog::change_default_normal(int old_filament_id, wxColour te
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Recompute mixed slot colors after physical slot color change
|
||||
const auto& cfg = wxGetApp().preset_bundle->project_config;
|
||||
recompute_mixed_slot_colors(m_cur_colors_in_thumbnail, cfg);
|
||||
|
||||
ThumbnailData& data = m_cur_input_thumbnail_data;
|
||||
ThumbnailData& no_light_data = m_cur_no_light_thumbnail_data;
|
||||
if (data.width > 0 && data.height > 0 && data.width == no_light_data.width && data.height == no_light_data.height) {
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "DeviceCore/DevManager.h"
|
||||
#include "DeviceCore/DevMapping.h"
|
||||
#include "DeviceCore/DevStorage.h"
|
||||
#include "FilamentBitmapUtils.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
@@ -2943,6 +2944,20 @@ void SyncAmsInfoDialog::clone_thumbnail_data()
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
// Expand color arrays to cover mixed (virtual) slots and compute their blended colors
|
||||
const auto& cfg = wxGetApp().preset_bundle->project_config;
|
||||
size_t total = 0;
|
||||
if (auto* opt = cfg.option<ConfigOptionBools>("filament_is_mixed"))
|
||||
total = opt->values.size();
|
||||
size_t target = std::max(total, m_cur_colors_in_thumbnail.size());
|
||||
if (m_cur_colors_in_thumbnail.size() < target)
|
||||
m_cur_colors_in_thumbnail.resize(target);
|
||||
if (m_preview_colors_in_thumbnail.size() < target)
|
||||
m_preview_colors_in_thumbnail.resize(target);
|
||||
recompute_mixed_slot_colors(m_preview_colors_in_thumbnail, cfg);
|
||||
recompute_mixed_slot_colors(m_cur_colors_in_thumbnail, cfg);
|
||||
|
||||
// copy data
|
||||
auto &data = m_cur_input_thumbnail_data;
|
||||
m_preview_thumbnail_data.reset();
|
||||
@@ -3131,6 +3146,10 @@ void SyncAmsInfoDialog::change_default_normal(int old_filament_id, wxColour temp
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Recompute mixed slot colors after physical slot color change
|
||||
const auto& cfg = wxGetApp().preset_bundle->project_config;
|
||||
recompute_mixed_slot_colors(m_cur_colors_in_thumbnail, cfg);
|
||||
|
||||
ThumbnailData &data = m_cur_input_thumbnail_data;
|
||||
ThumbnailData &no_light_data = m_cur_no_light_thumbnail_data;
|
||||
if (data.width > 0 && data.height > 0 && data.width == no_light_data.width && data.height == no_light_data.height) {
|
||||
|
||||
Reference in New Issue
Block a user