NEW: support to edit bed stl and texture for third-party printers

Jira:STUDIO-4209
some codes are referenced form PrusaSlicer,thanks enricoturri1966 for the original commit

commit cf380fb456
Author: enricoturri1966 <enricoturri@seznam.cz>
Date:   Tue Sep 21 13:51:57 2021 +0200
    Tech ENABLE_OUT_OF_BED_DETECTION_IMPROVEMENTS - Out of bed detection for circular printbeds
...

Change-Id: I1b1e2ff045286566d4fb9f2d8ad4faa1f135f60c
(cherry picked from commit 284bca9f1f4cdb9eb405e8205cd50666a2b0b2a0)
This commit is contained in:
zhou.xu
2023-09-14 10:41:47 +08:00
committed by Lane.Wei
parent 384b0793ff
commit 487c86e915
11 changed files with 319 additions and 228 deletions

View File

@@ -35,7 +35,7 @@ static std::string get_option_label(BedShape::Parameter param)
}
}
void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter param)
void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter param, bool can_edit)
{
ConfigOptionDef def;
t_config_option_key key;
@@ -47,6 +47,7 @@ void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter para
def.max = 1200;
def.label = get_option_label(param);
def.tooltip = L("Size in X and Y of the rectangular plate.");
def.readonly = !can_edit;
key = "rect_size";
break;
case Parameter::RectOrigin:
@@ -56,6 +57,7 @@ void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter para
def.max = 600;
def.label = get_option_label(param);
def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle.");
def.readonly = !can_edit;
key = "rect_origin";
break;
case Parameter::Diameter:
@@ -64,6 +66,7 @@ void BedShape::append_option_line(ConfigOptionsGroupShp optgroup, Parameter para
def.sidetext = L("mm");
def.label = get_option_label(param);
def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center.");
def.readonly = !can_edit;
key = "diameter";
break;
default:
@@ -128,22 +131,23 @@ void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup)
}
}
void BedShapeDialog::build_dialog(const ConfigOptionPoints& default_pt, const ConfigOptionString& custom_texture, const ConfigOptionString& custom_model)
void BedShapeDialog::build_dialog(const ConfigOptionPoints &default_pt, const ConfigOptionString &custom_texture, const ConfigOptionString &custom_model, bool can_edit)
{
SetFont(wxGetApp().normal_font());
m_panel = new BedShapePanel(this);
this->SetBackgroundColour(*wxWHITE);
m_panel = new BedShapePanel(this);
m_panel->set_edit_state(can_edit);
m_panel->build_panel(default_pt, custom_texture, custom_model);
auto main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(m_panel, 1, wxEXPAND);
main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
auto main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(m_panel, 1, wxEXPAND);
main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
wxGetApp().UpdateDlgDarkUI(this);
SetSizer(main_sizer);
SetMinSize(GetSize());
main_sizer->SetSizeHints(this);
SetSizer(main_sizer);
SetMinSize(GetSize());
main_sizer->SetSizeHints(this);
this->Bind(wxEVT_CLOSE_WINDOW, ([this](wxCloseEvent& evt) {
EndModal(wxID_CANCEL);
@@ -178,6 +182,7 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
auto sbsizer = new wxStaticBoxSizer(wxVERTICAL, this, _L("Shape"));
sbsizer->GetStaticBox()->SetFont(wxGetApp().bold_font());
sbsizer->GetStaticBox()->Enable(m_can_edit);
wxGetApp().UpdateDarkUI(sbsizer->GetStaticBox());
// shape options
@@ -187,13 +192,12 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
sbsizer->Add(m_shape_options_book);
auto optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Rectangle));
BedShape::append_option_line(optgroup, BedShape::Parameter::RectSize);
BedShape::append_option_line(optgroup, BedShape::Parameter::RectSize,m_can_edit);
// BBS hide
//BedShape::append_option_line(optgroup, BedShape::Parameter::RectOrigin);
BedShape::append_option_line(optgroup, BedShape::Parameter::RectOrigin, m_can_edit);
activate_options_page(optgroup);
// BBS hide
/* optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Circle));
/* optgroup = init_shape_options_page(BedShape::get_name(BedShape::PageType::Circle));
BedShape::append_option_line(optgroup, BedShape::Parameter::Diameter);
activate_options_page(optgroup);
@@ -219,9 +223,6 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
wxPanel* texture_panel = init_texture_panel();
wxPanel* model_panel = init_model_panel();
// BBS hide
texture_panel->Hide();
model_panel->Hide();
Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent& e) { update_shape(); }));
@@ -251,6 +252,7 @@ void BedShapePanel::build_panel(const ConfigOptionPoints& default_pt, const Conf
ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(const wxString& title)
{
wxPanel* panel = new wxPanel(m_shape_options_book);
panel->SetBackgroundColour(*wxWHITE);
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _L("Settings"));
optgroup->label_width = 10;
@@ -271,83 +273,64 @@ void BedShapePanel::activate_options_page(ConfigOptionsGroupShp options_group)
options_group->parent()->SetSizerAndFit(options_group->sizer);
}
wxPanel* BedShapePanel::init_texture_panel()
wxPanel *BedShapePanel::init_texture_panel()
{
wxPanel* panel = new wxPanel(this);
panel->SetBackgroundColour(*wxWHITE);
wxPanel *panel = new wxPanel(this);
wxGetApp().UpdateDarkUI(panel, true);
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _L("Texture"));
optgroup->label_width = 10;
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
update_shape();
};
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { update_shape(); };
Line line{ "", "" };
Line line{"", ""};
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Disabled), std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
StateColor btn_bd_white(std::pair<wxColour, int>(*wxWHITE, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
Button* load_btn = new Button(parent, _L("Load..."));
load_btn->SetBackgroundColor(btn_bg_white);
load_btn->SetBorderColor(btn_bd_white);
load_btn->SetBackgroundColour(*wxWHITE);
wxSizer* load_sizer = new wxBoxSizer(wxHORIZONTAL);
line.widget = [this](wxWindow *parent) {
wxButton *load_btn = new wxButton(parent, wxID_ANY, _L("Load..."));
load_btn->Enable(m_can_edit);
wxSizer * load_sizer = new wxBoxSizer(wxHORIZONTAL);
load_sizer->Add(load_btn, 1, wxEXPAND);
wxStaticText* filename_lbl = new wxStaticText(parent, wxID_ANY, _(NONE));
wxStaticText *filename_lbl = new wxStaticText(parent, wxID_ANY, _(NONE));
wxSizer* filename_sizer = new wxBoxSizer(wxHORIZONTAL);
wxSizer *filename_sizer = new wxBoxSizer(wxHORIZONTAL);
filename_sizer->Add(filename_lbl, 1, wxEXPAND);
Button* remove_btn = new Button(parent, _L("Remove"));
remove_btn->SetBackgroundColor(btn_bg_white);
remove_btn->SetBorderColor(btn_bd_white);
remove_btn->SetBackgroundColour(*wxWHITE);
wxSizer* remove_sizer = new wxBoxSizer(wxHORIZONTAL);
wxButton *remove_btn = new wxButton(parent, wxID_ANY, _L("Remove"));
wxSizer * remove_sizer = new wxBoxSizer(wxHORIZONTAL);
remove_sizer->Add(remove_btn, 1, wxEXPAND);
wxGetApp().UpdateDarkUI(load_btn);
wxGetApp().UpdateDarkUI(remove_btn);
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(filename_sizer, 1, wxEXPAND);
sizer->Add(load_sizer, 1, wxEXPAND);
sizer->Add(remove_sizer, 1, wxEXPAND | wxTOP, 2);
load_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e) { load_texture(); }));
remove_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e) {
m_custom_texture = NONE;
update_shape();
}));
load_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent &e) { load_texture(); }));
remove_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent &e) {
m_custom_texture = NONE;
update_shape();
}));
filename_lbl->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent& e) {
e.SetText(_(boost::filesystem::path(m_custom_texture).filename().string()));
wxStaticText* lbl = dynamic_cast<wxStaticText*>(e.GetEventObject());
if (lbl != nullptr) {
bool exists = (m_custom_texture == NONE) || boost::filesystem::exists(m_custom_texture);
lbl->SetForegroundColour(exists ? /*wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)*/wxGetApp().get_label_clr_default() : wxColor(*wxRED));
filename_lbl->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent &e) {
e.SetText(_(boost::filesystem::path(m_custom_texture).filename().string()));
wxStaticText *lbl = dynamic_cast<wxStaticText *>(e.GetEventObject());
if (lbl != nullptr) {
bool exists = (m_custom_texture == NONE) || boost::filesystem::exists(m_custom_texture);
lbl->SetForegroundColour(exists ? wxGetApp().get_label_clr_default() : wxColor(*wxRED));
wxString tooltip_text = "";
if (m_custom_texture != NONE) {
if (!exists)
tooltip_text += _L("Not found:") + " ";
wxString tooltip_text = "";
if (m_custom_texture != NONE) {
if (!exists) tooltip_text += _L("Not found:") + " ";
tooltip_text += _(m_custom_texture);
}
tooltip_text += _(m_custom_texture);
}
wxToolTip* tooltip = lbl->GetToolTip();
if ((tooltip == nullptr) || (tooltip->GetTip() != tooltip_text))
lbl->SetToolTip(tooltip_text);
}
}));
remove_btn->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent& e) { e.Enable(m_custom_texture != NONE); }));
wxToolTip *tooltip = lbl->GetToolTip();
if ((tooltip == nullptr) || (tooltip->GetTip() != tooltip_text)) lbl->SetToolTip(tooltip_text);
}
}));
remove_btn->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent &e) { e.Enable(m_custom_texture != NONE); }));
parent->SetBackgroundColour(*wxWHITE);
return sizer;
};
optgroup->append_line(line);
@@ -358,84 +341,64 @@ wxPanel* BedShapePanel::init_texture_panel()
return panel;
}
wxPanel* BedShapePanel::init_model_panel()
wxPanel *BedShapePanel::init_model_panel()
{
wxPanel* panel = new wxPanel(this);
panel->SetBackgroundColour(*wxWHITE);
wxPanel *panel = new wxPanel(this);
wxGetApp().UpdateDarkUI(panel, true);
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(panel, _L("Model"));
optgroup->label_width = 10;
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
update_shape();
};
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { update_shape(); };
Line line{ "", "" };
Line line{"", ""};
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Disabled), std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Hovered),
std::pair<wxColour, int>(*wxWHITE, StateColor::Normal));
StateColor btn_bd_white(std::pair<wxColour, int>(*wxWHITE, StateColor::Disabled), std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
Button* load_btn = new Button(parent, _L("Load..."));
load_btn->SetBackgroundColor(btn_bg_white);
load_btn->SetBorderColor(btn_bd_white);
load_btn->SetBackgroundColour(*wxWHITE);
wxSizer* load_sizer = new wxBoxSizer(wxHORIZONTAL);
line.widget = [this](wxWindow *parent) {
wxButton *load_btn = new wxButton(parent, wxID_ANY, _L("Load..."));
load_btn->Enable(m_can_edit);
wxSizer * load_sizer = new wxBoxSizer(wxHORIZONTAL);
load_sizer->Add(load_btn, 1, wxEXPAND);
wxStaticText* filename_lbl = new wxStaticText(parent, wxID_ANY, _(NONE));
wxSizer* filename_sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText *filename_lbl = new wxStaticText(parent, wxID_ANY, _(NONE));
wxSizer * filename_sizer = new wxBoxSizer(wxHORIZONTAL);
filename_sizer->Add(filename_lbl, 1, wxEXPAND);
Button* remove_btn = new Button(parent, _L("Remove"));
remove_btn->SetBackgroundColor(btn_bg_white);
remove_btn->SetBorderColor(btn_bd_white);
remove_btn->SetBackgroundColour(*wxWHITE);
wxSizer* remove_sizer = new wxBoxSizer(wxHORIZONTAL);
wxButton *remove_btn = new wxButton(parent, wxID_ANY, _L("Remove"));
wxSizer * remove_sizer = new wxBoxSizer(wxHORIZONTAL);
remove_sizer->Add(remove_btn, 1, wxEXPAND);
wxGetApp().UpdateDarkUI(load_btn);
wxGetApp().UpdateDarkUI(remove_btn);
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(filename_sizer, 1, wxEXPAND);
sizer->Add(load_sizer, 1, wxEXPAND);
sizer->Add(remove_sizer, 1, wxEXPAND | wxTOP, 2);
load_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e) { load_model(); }));
load_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent &e) { load_model(); }));
remove_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e) {
m_custom_model = NONE;
update_shape();
}));
remove_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent &e) {
m_custom_model = NONE;
update_shape();
}));
filename_lbl->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent& e) {
e.SetText(_(boost::filesystem::path(m_custom_model).filename().string()));
wxStaticText* lbl = dynamic_cast<wxStaticText*>(e.GetEventObject());
if (lbl != nullptr) {
bool exists = (m_custom_model == NONE) || boost::filesystem::exists(m_custom_model);
lbl->SetForegroundColour(exists ? /*wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)*/wxGetApp().get_label_clr_default() : wxColor(*wxRED));
filename_lbl->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent &e) {
e.SetText(_(boost::filesystem::path(m_custom_model).filename().string()));
wxStaticText *lbl = dynamic_cast<wxStaticText *>(e.GetEventObject());
if (lbl != nullptr) {
bool exists = (m_custom_model == NONE) || boost::filesystem::exists(m_custom_model);
lbl->SetForegroundColour(exists ? wxGetApp().get_label_clr_default() : wxColor(*wxRED));
wxString tooltip_text = "";
if (m_custom_model != NONE) {
if (!exists)
tooltip_text += _L("Not found:") + " ";
wxString tooltip_text = "";
if (m_custom_model != NONE) {
if (!exists) tooltip_text += _L("Not found:") + " ";
tooltip_text += _(m_custom_model);
}
tooltip_text += _(m_custom_model);
}
wxToolTip* tooltip = lbl->GetToolTip();
if ((tooltip == nullptr) || (tooltip->GetTip() != tooltip_text))
lbl->SetToolTip(tooltip_text);
}
}));
remove_btn->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent& e) { e.Enable(m_custom_model != NONE); }));
wxToolTip *tooltip = lbl->GetToolTip();
if ((tooltip == nullptr) || (tooltip->GetTip() != tooltip_text)) lbl->SetToolTip(tooltip_text);
}
}));
remove_btn->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent &e) { e.Enable(m_custom_model != NONE); }));
parent->SetBackgroundColour(*wxWHITE);
return sizer;
};
optgroup->append_line(line);
@@ -480,34 +443,46 @@ void BedShapePanel::update_shape()
auto opt_group = m_optgroups[page_idx];
switch (static_cast<BedShape::PageType>(page_idx)) {
case BedShape::PageType::Rectangle:
{
case BedShape::PageType::Rectangle: {
m_is_valid = true;
Vec2d rect_size(Vec2d::Zero());
Vec2d rect_origin(Vec2d::Zero());
Vec2d rect_origin(Vec2d::Zero());
try { rect_size = boost::any_cast<Vec2d>(opt_group->get_value("rect_size")); }
catch (const std::exception& /* e */) { return; }
try {
rect_size = boost::any_cast<Vec2d>(opt_group->get_value("rect_size"));
} catch (const std::exception & /* e */) {
return;
}
// BBS
//try { rect_origin = boost::any_cast<Vec2d>(opt_group->get_value("rect_origin")); }
//catch (const std::exception & /* e */) { return; }
auto x = rect_size(0);
auto y = rect_size(1);
// empty strings or '-' or other things
if (x == 0 || y == 0) return;
double x0 = 0.0;
double y0 = 0.0;
double x1 = x;
double y1 = y;
try {
rect_origin = boost::any_cast<Vec2d>(opt_group->get_value("rect_origin"));
} catch (const std::exception & /* e */) {
return;
}
auto dx = rect_origin(0);
auto dy = rect_origin(1);
auto x = rect_size(0);
auto y = rect_size(1);
// empty strings or '-' or other things
if (x == 0 || y == 0) {
m_is_valid = false;
return;
}
double x0 = 0.0;
double y0 = 0.0;
double x1 = x;
double y1 = y;
x0 -= dx;
x1 -= dx;
y0 -= dy;
y1 -= dy;
auto dx = rect_origin(0);
auto dy = rect_origin(1);
if (dx >= x || dy >= y) {
m_is_valid = false;
return;
}
x0 -= dx;
x1 -= dx;
y0 -= dy;
y1 -= dy;
m_shape = { Vec2d(x0, y0),
Vec2d(x1, y0),
Vec2d(x1, y1),