obj color match "keep color" append missing color simplification

This commit is contained in:
Rad
2026-03-11 17:49:17 +01:00
parent d339f82e37
commit 95f6cb2574
4 changed files with 185 additions and 62 deletions

View File

@@ -26,12 +26,12 @@ int OBJCOLOR_ITEM_WIDTH() { return objcolor_scale(30); }
static const wxColour g_text_color = wxColour(107, 107, 107, 255);
const int HEADER_BORDER = 5;
const int CONTENT_BORDER = 3;
const int PANEL_WIDTH = 370;
const int COLOR_LABEL_WIDTH = 180;
const int PANEL_WIDTH = 430;
const int COLOR_LABEL_WIDTH = 165;
#undef ICON_SIZE
#define ICON_SIZE wxSize(FromDIP(16), FromDIP(16))
#define MIN_OBJCOLOR_DIALOG_WIDTH FromDIP(400)
#define MIN_OBJCOLOR_DIALOG_WIDTH FromDIP(460)
#define FIX_SCROLL_HEIGTH FromDIP(400)
#define BTN_SIZE wxSize(FromDIP(58), FromDIP(24))
#define BTN_GAP FromDIP(20)
@@ -399,7 +399,7 @@ void ObjColorPanel::update_filament_ids()
const int existing_filament_count = static_cast<int>(m_colours.size());
std::map<int, int> appended_filament_id_map;
if (m_is_add_filament) {
if (!m_new_add_colors.empty()) {
std::vector<int> selected_appended_indices;
selected_appended_indices.reserve(m_cluster_map_filaments.size());
for (int mapped_filament_id : m_cluster_map_filaments) {
@@ -471,8 +471,8 @@ wxBoxSizer *ObjColorPanel::create_add_btn_sizer(wxWindow *parent)
StateColor calc_btn_bd(std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
StateColor calc_btn_text(std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Normal));
// create btn
m_quick_add_btn = new Button(parent, _L("Append"));
m_quick_add_btn->SetToolTip(_L("Add consumable extruder after existing extruders."));
m_quick_add_btn = new Button(parent, _L("Append all"));
m_quick_add_btn->SetToolTip(_L("Add all clustered colors after the existing filaments."));
auto cur_btn = m_quick_add_btn;
cur_btn->SetFont(Label::Body_13);
cur_btn->SetMinSize(wxSize(FromDIP(60), FromDIP(20)));
@@ -497,7 +497,7 @@ wxBoxSizer *ObjColorPanel::create_reset_btn_sizer(wxWindow *parent)
StateColor calc_btn_text(std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Normal));
// create btn
m_quick_reset_btn = new Button(parent, _L("Reset"));
m_quick_add_btn->SetToolTip(_L("Reset mapped extruders."));
m_quick_reset_btn->SetToolTip(_L("Reset mapped extruders."));
auto cur_btn = m_quick_reset_btn;
cur_btn->SetFont(Label::Body_13);
cur_btn->SetMinSize(wxSize(FromDIP(60), FromDIP(20)));
@@ -574,7 +574,7 @@ ComboBox *ObjColorPanel::CreateEditorCtrl(wxWindow *parent, int id) // wxRect la
void ObjColorPanel::deal_approximate_match_btn()
{
if (m_is_add_filament) {
if (!m_new_add_colors.empty()) {
deal_reset_btn();
}
@@ -606,6 +606,93 @@ void ObjColorPanel::deal_approximate_match_btn()
m_result_icon_list[i]->bitmap_combox->SetSelection(new_index);
m_cluster_map_filaments[i] = new_index;
}
update_keep_color_buttons();
}
bool ObjColorPanel::colors_are_equal(const wxColour &lhs, const wxColour &rhs)
{
return lhs.Red() == rhs.Red() && lhs.Green() == rhs.Green() && lhs.Blue() == rhs.Blue() && lhs.Alpha() == rhs.Alpha();
}
int ObjColorPanel::find_filament_selection_by_color(const wxColour &color) const
{
for (size_t i = 0; i < m_colours.size(); ++i) {
if (colors_are_equal(m_colours[i], color)) {
return static_cast<int>(i + 1);
}
}
for (size_t i = 0; i < m_new_add_colors.size(); ++i) {
if (colors_are_equal(m_new_add_colors[i], color)) {
return static_cast<int>(m_colours.size() + i + 1);
}
}
return 0;
}
int ObjColorPanel::append_new_filament_option(const wxColour &color)
{
if (m_colours.size() + m_new_add_colors.size() >= g_max_color) {
return 0;
}
m_new_add_colors.emplace_back(color);
const int selection = static_cast<int>(m_colours.size() + m_new_add_colors.size());
auto * bitmap = get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(selection), m_combox_icon_width, m_combox_icon_height);
for (auto *item : m_result_icon_list) {
if (item->bitmap_combox == nullptr) {
continue;
}
item->bitmap_combox->Append(wxString::Format("%d", item->bitmap_combox->GetCount()), *bitmap);
item->bitmap_combox->SetItemTooltip(item->bitmap_combox->GetCount() - 1, color.GetAsString(wxC2S_HTML_SYNTAX));
}
return selection;
}
void ObjColorPanel::update_keep_color_buttons()
{
for (size_t i = 0; i < m_result_icon_list.size(); ++i) {
auto *item = m_result_icon_list[i];
if (item->keep_color_btn == nullptr) {
continue;
}
const bool has_cluster_color = i < m_cluster_colours.size();
const bool show_keep_color = has_cluster_color && find_filament_selection_by_color(m_cluster_colours[i]) == 0;
item->keep_color_btn->Show(show_keep_color);
item->keep_color_btn->Enable(show_keep_color);
}
if (m_scrolledWindow != nullptr) {
m_scrolledWindow->Layout();
}
Layout();
}
void ObjColorPanel::deal_keep_color_btn(int id)
{
if (id < 0 || id >= static_cast<int>(m_cluster_colours.size())) {
return;
}
int selection = find_filament_selection_by_color(m_cluster_colours[id]);
if (selection == 0) {
selection = append_new_filament_option(m_cluster_colours[id]);
}
if (selection == 0) {
m_warning_text->SetLabelText(_L("Warning: The count of newly added and \ncurrent extruders exceeds 16."));
return;
}
m_result_icon_list[id]->bitmap_combox->SetSelection(selection);
m_cluster_map_filaments[id] = selection;
m_warning_text->SetLabelText(_L("Note: The color has been selected, you can choose OK \nto continue or manually adjust it."));
update_keep_color_buttons();
}
void ObjColorPanel::show_sizer(wxSizer *sizer, bool show)
@@ -639,17 +726,16 @@ void ObjColorPanel::redraw_part_table() {
int id = i;
wxPanel *row_panel = new wxPanel(m_scrolledWindow);
row_panel->SetBackgroundColour((i+1) % 2 == 0 ? *wxWHITE : wxColour(238, 238, 238));
auto row_sizer = new wxGridSizer(1, 2, 1, 3);
auto row_sizer = new wxBoxSizer(wxHORIZONTAL);
row_panel->SetSizer(row_sizer);
row_panel->SetMinSize(wxSize(FromDIP(PANEL_WIDTH), -1));
row_panel->SetMaxSize(wxSize(FromDIP(PANEL_WIDTH), -1));
auto cluster_color_icon_sizer = create_color_icon_and_rgba_sizer(row_panel, id, m_cluster_colours[id]);
row_sizer->Add(cluster_color_icon_sizer, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, FromDIP(CONTENT_BORDER));
// result_combox
create_result_button_sizer(row_panel, id);
row_sizer->Add(m_result_icon_list[id]->bitmap_combox, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL, 0);
row_sizer->Add(cluster_color_icon_sizer, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
row_sizer->AddStretchSpacer();
row_sizer->Add(create_result_button_sizer(row_panel, id), 0, wxALIGN_CENTER_VERTICAL, 0);
m_row_sizer_list.emplace_back(row_sizer);
m_gridsizer->Add(row_panel, 0, wxALIGN_LEFT | wxALL, FromDIP(HEADER_BORDER));
@@ -660,6 +746,7 @@ void ObjColorPanel::redraw_part_table() {
// m_color_cluster_icon_list//m_color_cluster_text_list
update_color_icon_and_rgba_sizer(i, m_cluster_colours[i]);
}
update_keep_color_buttons();
m_scrolledWindow->Refresh();
}
@@ -674,7 +761,7 @@ void ObjColorPanel::draw_table()
for (size_t ii = 0; ii < row; ii++) {
wxPanel *row_panel = new wxPanel(m_scrolledWindow);
row_panel->SetBackgroundColour(ii % 2 == 0 ? *wxWHITE : wxColour(238, 238, 238));
auto row_sizer = new wxGridSizer(1, 2, 1, 5);
auto row_sizer = new wxBoxSizer(wxHORIZONTAL);
row_panel->SetSizer(row_sizer);
row_panel->SetMinSize(wxSize(FromDIP(PANEL_WIDTH), -1));
@@ -682,19 +769,19 @@ void ObjColorPanel::draw_table()
if (ii == 0) {
wxStaticText *colors_left_title = new wxStaticText(row_panel, wxID_ANY, _L("Cluster colors"));
colors_left_title->SetFont(Label::Head_14);
row_sizer->Add(colors_left_title, 0, wxALIGN_CENTER | wxALL, FromDIP(HEADER_BORDER));
row_sizer->Add(colors_left_title, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(40));
row_sizer->AddStretchSpacer();
wxStaticText *colors_middle_title = new wxStaticText(row_panel, wxID_ANY, _L("Map Filament"));
colors_middle_title->SetFont(Label::Head_14);
row_sizer->Add(colors_middle_title, 0, wxALIGN_CENTER | wxALL, FromDIP(HEADER_BORDER));
row_sizer->Add(colors_middle_title, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(HEADER_BORDER));
} else {
int id = ii - 1;
if (id < m_cluster_colours.size()) {
auto cluster_color_icon_sizer = create_color_icon_and_rgba_sizer(row_panel, id, m_cluster_colours[id]);
row_sizer->Add(cluster_color_icon_sizer, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL, FromDIP(CONTENT_BORDER));
// result_combox
create_result_button_sizer(row_panel, id);
row_sizer->Add(m_result_icon_list[id]->bitmap_combox, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL, FromDIP(CONTENT_BORDER));
row_sizer->Add(cluster_color_icon_sizer, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10));
row_sizer->AddStretchSpacer();
row_sizer->Add(create_result_button_sizer(row_panel, id), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(CONTENT_BORDER));
}
}
row_height = row_panel->GetSize().GetHeight();
@@ -717,6 +804,7 @@ void ObjColorPanel::draw_table()
m_scrolledWindow->EnableScrolling(false, true);
m_scrolledWindow->ShowScrollbars(wxSHOW_SB_NEVER, wxSHOW_SB_DEFAULT);//wxSHOW_SB_ALWAYS
m_scrolledWindow->SetScrollRate(20, 20);
update_keep_color_buttons();
}
void ObjColorPanel::deal_algo(char cluster_number, bool redraw_ui)
@@ -761,64 +849,83 @@ void ObjColorPanel::deal_default_strategy()
void ObjColorPanel::deal_add_btn()
{
if (m_colours.size() > g_max_color) { return; }
if (m_colours.size() >= g_max_color) { return; }
deal_reset_btn();
std::vector<wxBitmap *> new_icons;
auto new_color_size = m_cluster_colors_from_algo.size();
new_icons.reserve(new_color_size);
m_new_add_colors.clear();
m_new_add_colors.reserve(new_color_size);
int new_index = m_colours.size() + 1;
bool is_exceed = false;
for (size_t i = 0; i < new_color_size; i++) {
if (m_colours.size() + new_icons.size() >= g_max_color) {
std::vector<int> appended_selections;
appended_selections.reserve(m_cluster_colors_from_algo.size());
for (size_t i = 0; i < m_cluster_colors_from_algo.size(); i++) {
const wxColour cur_color = convert_to_wxColour(m_cluster_colors_from_algo[i]);
const int selection = append_new_filament_option(cur_color);
if (selection == 0) {
is_exceed = true;
break;
}
wxColour cur_color = convert_to_wxColour(m_cluster_colors_from_algo[i]);
m_new_add_colors.emplace_back(cur_color);
new_icons.emplace_back(get_extruder_color_icon(cur_color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(),
std::to_string(new_index), m_combox_icon_width, m_combox_icon_height));
new_index++;
}
new_index = m_colours.size() + 1;
for (size_t i = 0; i < m_result_icon_list.size(); i++) {
auto item = m_result_icon_list[i];
for (size_t k = 0; k < new_icons.size(); k++) {
item->bitmap_combox->Append(wxString::Format("%d", item->bitmap_combox->GetCount()), *new_icons[k]);
item->bitmap_combox->SetItemTooltip(item->bitmap_combox->GetCount() -1,m_new_add_colors[k].GetAsString(wxC2S_HTML_SYNTAX));
}
item->bitmap_combox->SetSelection(new_index);
m_cluster_map_filaments[i] = new_index;
new_index++;
appended_selections.emplace_back(selection);
}
if (is_exceed) {
deal_approximate_match_btn();
m_warning_text->SetLabelText(_L("Warning: The count of newly added and \ncurrent extruders exceeds 16."));
return;
}
m_is_add_filament = true;
for (size_t i = 0; i < m_cluster_colours.size() && i < appended_selections.size(); i++) {
m_result_icon_list[i]->bitmap_combox->SetSelection(appended_selections[i]);
m_cluster_map_filaments[i] = appended_selections[i];
}
update_keep_color_buttons();
}
void ObjColorPanel::deal_reset_btn()
{
for (auto item : m_result_icon_list) {
for (size_t i = 0; i < m_result_icon_list.size(); ++i) {
auto *item = m_result_icon_list[i];
// delete redundant bitmap
while (item->bitmap_combox->GetCount() > m_colours.size()+ 1) {
item->bitmap_combox->DeleteOneItem(item->bitmap_combox->GetCount() - 1);
}
item->bitmap_combox->SetSelection(0);
if (i < m_cluster_map_filaments.size()) {
m_cluster_map_filaments[i] = 0;
}
}
m_is_add_filament = false;
m_new_add_colors.clear();
m_warning_text->SetLabelText("");
update_keep_color_buttons();
}
void ObjColorPanel::create_result_button_sizer(wxWindow *parent, int id)
wxBoxSizer *ObjColorPanel::create_result_button_sizer(wxWindow *parent, int id)
{
for (size_t i = m_result_icon_list.size(); i < id + 1; i++) {
m_result_icon_list.emplace_back(new ButtonState());
}
m_result_icon_list[id]->bitmap_combox = CreateEditorCtrl(parent,id);
auto *result_sizer = new wxBoxSizer(wxHORIZONTAL);
result_sizer->Add(m_result_icon_list[id]->bitmap_combox, 0, wxALIGN_CENTER_VERTICAL, 0);
StateColor calc_btn_bg(std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed), std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
StateColor calc_btn_bd(std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
StateColor calc_btn_text(std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Normal));
auto *keep_color_btn = new Button(parent, _L("Keep color"));
keep_color_btn->SetToolTip(_L("Add this cluster color as a new filament."));
keep_color_btn->SetFont(Label::Body_13);
keep_color_btn->SetMinSize(wxSize(FromDIP(88), FromDIP(24)));
keep_color_btn->SetCornerRadius(FromDIP(12));
keep_color_btn->SetBackgroundColor(calc_btn_bg);
keep_color_btn->SetBorderColor(calc_btn_bd);
keep_color_btn->SetTextColor(calc_btn_text);
keep_color_btn->Bind(wxEVT_BUTTON, [this, id](wxCommandEvent &) {
deal_keep_color_btn(id);
});
m_result_icon_list[id]->keep_color_btn = keep_color_btn;
result_sizer->AddSpacer(FromDIP(8));
result_sizer->Add(keep_color_btn, 0, wxALIGN_CENTER_VERTICAL, 0);
return result_sizer;
}
wxBoxSizer *ObjColorPanel::create_color_icon_and_rgba_sizer(wxWindow *parent, int id, const wxColour& color)

View File

@@ -31,8 +31,9 @@ public:
void update_filament_ids();
struct ButtonState
{
ComboBox* bitmap_combox{nullptr};
bool is_map{false};//int id{0};
ComboBox *bitmap_combox{nullptr};
Button * keep_color_btn{nullptr};
bool is_map{false}; // int id{0};
};
private:
wxBoxSizer *create_approximate_match_btn_sizer(wxWindow *parent);
@@ -40,7 +41,7 @@ private:
wxBoxSizer *create_reset_btn_sizer(wxWindow *parent);
wxBoxSizer *create_extruder_icon_and_rgba_sizer(wxWindow *parent, int id, const wxColour& color);
std::string get_color_str(const wxColour &color);
void create_result_button_sizer(wxWindow *parent, int id);
wxBoxSizer *create_result_button_sizer(wxWindow *parent, int id);
wxBoxSizer *create_color_icon_and_rgba_sizer(wxWindow *parent, int id, const wxColour& color);
void update_color_icon_and_rgba_sizer(int id, const wxColour &color);
ComboBox* CreateEditorCtrl(wxWindow *parent,int id);
@@ -48,10 +49,15 @@ private:
void show_sizer(wxSizer *sizer, bool show);
void redraw_part_table();
void deal_approximate_match_btn();
void deal_keep_color_btn(int id);
void deal_add_btn();
void deal_reset_btn();
void deal_algo(char cluster_number,bool redraw_ui =false);
void deal_default_strategy();
int find_filament_selection_by_color(const wxColour &color) const;
int append_new_filament_option(const wxColour &color);
void update_keep_color_buttons();
static bool colors_are_equal(const wxColour &lhs, const wxColour &rhs);
private:
//view ui
wxScrolledWindow * m_scrolledWindow = nullptr;
@@ -66,7 +72,7 @@ private:
std::vector<wxButton*> m_extruder_icon_list;
std::vector<wxButton*> m_color_cluster_icon_list;//need modeify
std::vector<wxStaticText*> m_color_cluster_text_list;//need modeify
std::vector<wxGridSizer*> m_row_sizer_list; // control show or not
std::vector<wxSizer*> m_row_sizer_list; // control show or not
std::vector<ButtonState*> m_result_icon_list;
int m_last_cluster_num{-1};
const int m_combox_width{50};
@@ -83,13 +89,11 @@ private:
std::vector<wxColour> m_colours;//from project and show right
std::vector<int> m_cluster_map_filaments;//show middle
std::vector<wxColour> m_cluster_colours;//from_algo and show left
bool m_can_add_filament{true};
std::vector<wxColour> m_new_add_colors;
//algo result
std::vector<Slic3r::RGBA> m_cluster_colors_from_algo;
std::vector<int> m_cluster_labels_from_algo;
//result
bool m_is_add_filament{false};
unsigned char& m_first_extruder_id;
std::vector<unsigned char> &m_filament_ids;
};
@@ -111,4 +115,4 @@ private:
unsigned char & m_first_extruder_id;
};
#endif // _WIPE_TOWER_DIALOG_H_
#endif // _WIPE_TOWER_DIALOG_H_