diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c06d19cb9..bf1d24e8a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -184,7 +184,7 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T // Disable linear advance for the wipe tower operations. - gcode += "M900 K0\n"; + gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); // Move over the wipe tower. // Retract for a tool change, using the toolchange retract value and setting the priming extra length. gcode += gcodegen.retract(true); @@ -289,7 +289,7 @@ std::string WipeTowerIntegration::prime(GCode &gcodegen) if (&m_priming != nullptr && ! m_priming.extrusions.empty()) { // Disable linear advance for the wipe tower operations. - gcode += "M900 K0\n"; + gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); // Let the tool change be executed by the wipe tower class. // Inform the G-code writer about the changes done behind its back. gcode += m_priming.gcode; diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/src/libslic3r/GCode/WipeTowerPrusaMM.cpp index 829fe1bb9..34065a491 100644 --- a/src/libslic3r/GCode/WipeTowerPrusaMM.cpp +++ b/src/libslic3r/GCode/WipeTowerPrusaMM.cpp @@ -40,7 +40,7 @@ namespace PrusaMultiMaterial { class Writer { public: - Writer(float layer_height, float line_width) : + Writer(float layer_height, float line_width, GCodeFlavor flavor) : m_current_pos(std::numeric_limits::max(), std::numeric_limits::max()), m_current_z(0.f), m_current_feedrate(0.f), @@ -48,7 +48,8 @@ public: m_extrusion_flow(0.f), m_preview_suppressed(false), m_elapsed_time(0.f), - m_default_analyzer_line_width(line_width) + m_default_analyzer_line_width(line_width), + m_gcode_flavor(flavor) { // adds tag for analyzer: char buf[64]; @@ -333,7 +334,10 @@ public: Writer& set_extruder_trimpot(int current) { char buf[128]; - sprintf(buf, "M907 E%d\n", current); + if (m_gcode_flavor == gcfRepRap) + sprintf(buf, "M906 E%d\n", current); + else + sprintf(buf, "M907 E%d\n", current); m_gcode += buf; return *this; }; @@ -407,6 +411,7 @@ private: int current_temp = -1; const float m_default_analyzer_line_width; float m_used_filament_length = 0.f; + GCodeFlavor m_gcode_flavor; std::string set_format_X(float x) { @@ -510,7 +515,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime( const float prime_section_width = std::min(240.f / tools.size(), 60.f); box_coordinates cleaning_box(xy(5.f, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f); - PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width); + PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width, m_gcode_flavor); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) @@ -612,7 +617,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo (tool != (unsigned int)(-1) ? /*m_layer_info->depth*/wipe_area+m_depth_traversed-0.5*m_perimeter_width : m_wipe_tower_depth-m_perimeter_width)); - PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width); + PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width, m_gcode_flavor); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) @@ -631,7 +636,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo // Increase the extruder driver current to allow fast ramming. if (m_set_extruder_trimpot) - writer.set_extruder_trimpot(550); + writer.set_extruder_trimpot(750); // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool. if (tool != (unsigned int)-1){ // This is not the last change. @@ -693,7 +698,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, flo m_wipe_tower_width, m_wipe_tower_depth); - PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width); + PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width, m_gcode_flavor); writer.set_extrusion_flow(m_extrusion_flow * 1.1f) .set_z(m_z_pos) // Let the writer know the current Z position as a base for Z-hop. .set_initial_tool(m_current_tool) @@ -1022,7 +1027,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer() // Otherwise the caller would likely travel to the wipe tower in vain. assert(! this->layer_finished()); - PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width); + PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width, m_gcode_flavor); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) diff --git a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp index 2b5fa2241..90f50b57a 100644 --- a/src/libslic3r/GCode/WipeTowerPrusaMM.hpp +++ b/src/libslic3r/GCode/WipeTowerPrusaMM.hpp @@ -8,6 +8,7 @@ #include #include "WipeTower.hpp" +#include "PrintConfig.hpp" namespace Slic3r @@ -46,7 +47,7 @@ public: // wipe_area -- space available for one toolchange in mm WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction, float cooling_tube_length, float parking_pos_retraction, float extra_loading_move, - float bridging, bool set_extruder_trimpot, + float bridging, bool set_extruder_trimpot, GCodeFlavor flavor, const std::vector>& wiping_matrix, unsigned int initial_tool) : m_wipe_tower_pos(x, y), m_wipe_tower_width(width), @@ -60,6 +61,7 @@ public: m_extra_loading_move(extra_loading_move), m_bridging(bridging), m_set_extruder_trimpot(set_extruder_trimpot), + m_gcode_flavor(flavor), m_current_tool(initial_tool), wipe_volumes(wiping_matrix) {} @@ -223,6 +225,7 @@ private: bool m_set_extruder_trimpot = false; bool m_retain_speed_override = true; bool m_adhesion = true; + GCodeFlavor m_gcode_flavor; float m_perimeter_width = 0.4f * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill. float m_extrusion_flow = 0.038f; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter. diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 0637ba7f0..d743a9b23 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -126,7 +126,6 @@ bool Print::invalidate_state_by_config_options(const std::vector #include #include +#include #include #include "libslic3r/Utils.hpp" @@ -81,11 +82,17 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt for (const auto &model : models) { if (! filter(model)) { continue; } - wxBitmap bitmap(GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str())), wxBITMAP_TYPE_PNG); + wxBitmap bitmap; + int bitmap_width = 0; + const wxString bitmap_file = GUI::from_u8(Slic3r::var((boost::format("printers/%1%_%2%.png") % vendor.id % model.id).str())); + if (wxFileExists(bitmap_file)) { + bitmap.LoadFile(bitmap_file, wxBITMAP_TYPE_PNG); + bitmap_width = bitmap.GetWidth(); + } auto *title = new wxStaticText(this, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); title->SetFont(font_name); - const int wrap_width = std::max((int)MODEL_MIN_WRAP, bitmap.GetWidth()); + const int wrap_width = std::max((int)MODEL_MIN_WRAP, bitmap_width); title->Wrap(wrap_width); current_row_width += wrap_width; @@ -647,7 +654,7 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) SetMinSize(bg.GetSize()); const wxSize size = GetTextExtent("m"); - em = size.x; + em_w = size.x; em_h = size.y; // Add logo bitmap. @@ -775,7 +782,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) unsigned y = 0; for (size_t i = 0; i < items.size(); i++) { const Item& item = items[i]; - unsigned x = em/2 + item.indent * em; + unsigned x = em_w/2 + item.indent * em_w; if (i == item_active || item_hover >= 0 && i == (size_t)item_hover) { dc.DrawBitmap(bullet_blue, x, y + yoff_icon, false); @@ -783,7 +790,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) else if (i < item_active) { dc.DrawBitmap(bullet_black, x, y + yoff_icon, false); } else if (i > item_active) { dc.DrawBitmap(bullet_white, x, y + yoff_icon, false); } - x += + bullet_w + em/2; + x += + bullet_w + em_w/2; const auto text_size = dc.GetTextExtent(item.label); dc.DrawText(item.label, x, y + yoff_text); @@ -794,6 +801,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt) if (GetMinSize().x < index_width) { CallAfter([this, index_width]() { SetMinSize(wxSize(index_width, GetMinSize().y)); + Refresh(); }); } } @@ -1073,7 +1081,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) 9*disp_rect.width / 10, 9*disp_rect.height / 10); - const int width_hint = p->index->GetSize().GetWidth() + p->page_fff->get_width() + 300; // XXX: magic constant, I found no better solution + const int width_hint = p->index->GetSize().GetWidth() + p->page_fff->get_width() + 30 * p->em(); // XXX: magic constant, I found no better solution if (width_hint < window_rect.width) { window_rect.x += (window_rect.width - width_hint) / 2; window_rect.width = width_hint; diff --git a/src/slic3r/GUI/ConfigWizard_private.hpp b/src/slic3r/GUI/ConfigWizard_private.hpp index df7602adf..792b92015 100644 --- a/src/slic3r/GUI/ConfigWizard_private.hpp +++ b/src/slic3r/GUI/ConfigWizard_private.hpp @@ -211,6 +211,7 @@ public: void clear(); + int em() const { return em_w; } private: struct Item { @@ -221,7 +222,7 @@ private: bool operator==(ConfigWizardPage *page) const { return this->page == page; } }; - int em; + int em_w; int em_h; const wxBitmap bg; @@ -234,7 +235,7 @@ private: ssize_t item_hover; size_t last_page; - int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em) + em; } + int item_height() const { return std::max(bullet_black.GetSize().GetHeight(), em_w) + em_w; } void on_paint(wxPaintEvent &evt); void on_mouse_move(wxMouseEvent &evt); @@ -286,6 +287,8 @@ struct ConfigWizard::priv void on_custom_setup(bool custom_wanted); void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater); + + int em() const { return index->em(); } }; diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 41805702b..3537f98e4 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -139,6 +139,8 @@ public: bool checked_tab(Tab* tab); void load_current_presets(); + wxString current_language_code() { return m_wxLocale != nullptr ? m_wxLocale->GetCanonicalName() : wxString("en_US"); } + virtual bool OnExceptionInMainLoop(); #ifdef __APPLE__ diff --git a/src/slic3r/GUI/RammingChart.cpp b/src/slic3r/GUI/RammingChart.cpp index 41e5cdfe7..6f71e8616 100644 --- a/src/slic3r/GUI/RammingChart.cpp +++ b/src/slic3r/GUI/RammingChart.cpp @@ -141,6 +141,9 @@ void Chart::mouse_double_clicked(wxMouseEvent& event) { void Chart::recalculate_line() { + m_line_to_draw.clear(); + m_total_volume = 0.f; + std::vector points; for (auto& but : m_buttons) { points.push_back(wxPoint(math_to_screen(but.get_pos()))); @@ -150,92 +153,88 @@ void Chart::recalculate_line() { break; } } - std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; }); - - m_line_to_draw.clear(); - m_total_volume = 0.f; - - - // Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods - const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point - // false - second ---- || ------- - const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points - std::vector diag(N+1); - std::vector mu(N+1); - std::vector lambda(N+1); - std::vector h(N+1); - std::vector rhs(N+1); - - // let's fill in inner equations - for (int i=1;i<=N;++i) h[i] = points[i].x-points[i-1].x; - std::fill(diag.begin(),diag.end(),2.f); - for (int i=1;i<=N-1;++i) { - mu[i] = h[i]/(h[i]+h[i+1]); - lambda[i] = 1.f - mu[i]; - rhs[i] = 6 * ( float(points[i+1].y-points[i].y )/(h[i+1]*(points[i+1].x-points[i-1].x)) - - float(points[i].y -points[i-1].y)/(h[i] *(points[i+1].x-points[i-1].x)) ); - } - - // now fill in the first and last equations, according to boundary conditions: - if (boundary_first_derivative) { - const float endpoints_derivative = 0; - lambda[0] = 1; - mu[N] = 1; - rhs[0] = (6.f/h[1]) * (float(points[0].y-points[1].y)/(points[0].x-points[1].x) - endpoints_derivative); - rhs[N] = (6.f/h[N]) * (endpoints_derivative - float(points[N-1].y-points[N].y)/(points[N-1].x-points[N].x)); - } - else { - lambda[0] = 0; - mu[N] = 0; - rhs[0] = 0; - rhs[N] = 0; - } + + // The calculation wouldn't work in case the ramming is to be turned off completely. + if (points.size()>1) { + std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; }); + + // Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods + const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point + // false - second ---- || ------- + const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points + std::vector diag(N+1); + std::vector mu(N+1); + std::vector lambda(N+1); + std::vector h(N+1); + std::vector rhs(N+1); - // the trilinear system is ready to be solved: - for (int i=1;i<=N;++i) { - float multiple = mu[i]/diag[i-1]; // let's subtract proper multiple of above equation - diag[i]-= multiple * lambda[i-1]; - rhs[i] -= multiple * rhs[i-1]; - } - // now the back substitution (vector mu contains invalid values from now on): - rhs[N] = rhs[N]/diag[N]; - for (int i=N-1;i>=0;--i) - rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i]; - - - - - unsigned int i=1; - float y=0.f; - for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) { - if (splines) { - if (i=0;--i) + rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i]; + + unsigned int i=1; + float y=0.f; + for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) { + if (splines) { + if (i x) + y = points[0].y; + else + if (points[N].x < x) + y = points[N].y; + else + y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) + + (points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] + + (points[i].y -rhs[i] *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i]; + m_line_to_draw.push_back(y); } - if (points[0].x > x) - y = points[0].y; - else - if (points[N].x < x) - y = points[N].y; - else - y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) + - (points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] + - (points[i].y -rhs[i] *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i]; - m_line_to_draw.push_back(y); + else { + float x_math = screen_to_math(wxPoint(x,0)).m_x; + if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math) + ++i; + m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y); + } + + m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1); + m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1); + m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight()); } - else { - float x_math = screen_to_math(wxPoint(x,0)).m_x; - if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math) - ++i; - m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y); - } - - - m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1); - m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1); - m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight()); } - + wxPostEvent(this->GetParent(), wxCommandEvent(EVT_WIPE_TOWER_CHART_CHANGED)); Refresh(); }