From 8cdcac6ad86a9186df489705aca1a18787ac89ea Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 9 Oct 2019 09:28:50 +0200 Subject: [PATCH 01/45] First implementations for an extension of color change feature : Added context menu for "plus" button on DoubleSlider --- src/slic3r/GUI/GUI_Preview.cpp | 19 ++++ src/slic3r/GUI/wxExtensions.cpp | 179 +++++++++++++++++++++++++++----- src/slic3r/GUI/wxExtensions.hpp | 21 ++++ 3 files changed, 192 insertions(+), 27 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index b6350bcab..98f6a8ee6 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -583,6 +583,25 @@ void Preview::create_double_slider() m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100); m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); + /* + auto extruder_selector = new wxComboBox(this, wxID_ANY); + extruder_selector->Append("Whole print"); + int extruder_cnt = wxGetApp().extruders_edited_cnt(); + int i = 0; + while (i < extruder_cnt) + { + i++; + extruder_selector->Append(wxString::Format("Extruder %d", i)); + } + extruder_selector->SetSelection(0); + + auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(extruder_selector, 0, wxEXPAND, 0); + sizer->Add(m_slider, 1, wxEXPAND, 0); + + m_double_slider_sizer->Add(sizer, 0, wxEXPAND, 0); + */ + // sizer, m_canvas_widget m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 0109f6a29..10139ac2d 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2451,10 +2451,16 @@ std::vector DoubleSlider::GetTicksValues() const const int val_size = m_values.size(); if (!m_values.empty()) - for (int tick : m_ticks) { - if (tick > val_size) + // #ys_FIXME_COLOR + // for (int tick : m_ticks) { + // if (tick > val_size) + // break; + // values.push_back(m_values[tick]); + // } + for (const TICK_CODE& tick : m_ticks_) { + if (tick.tick > val_size) break; - values.push_back(m_values[tick]); + values.push_back(m_values[tick.tick]); } return values; @@ -2465,19 +2471,36 @@ void DoubleSlider::SetTicksValues(const std::vector& heights) if (m_values.empty()) return; - const bool was_empty = m_ticks.empty(); + // #ys_FIXME_COLOR + // const bool was_empty = m_ticks.empty(); + // + // m_ticks.clear(); + // for (auto h : heights) { + // auto it = std::lower_bound(m_values.begin(), m_values.end(), h - epsilon()); + // + // if (it == m_values.end()) + // continue; + // + // m_ticks.insert(it-m_values.begin()); + // } + // + // if (!was_empty && m_ticks.empty()) + // // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one + // wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); - m_ticks.clear(); + const bool was_empty = m_ticks_.empty(); + + m_ticks_.clear(); for (auto h : heights) { auto it = std::lower_bound(m_values.begin(), m_values.end(), h - epsilon()); if (it == m_values.end()) continue; - m_ticks.insert(it-m_values.begin()); + m_ticks_.insert(it-m_values.begin()); } - if (!was_empty && m_ticks.empty()) + if (!was_empty && m_ticks_.empty()) // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } @@ -2552,7 +2575,10 @@ void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoin return; wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); - if (m_ticks.find(tick) != m_ticks.end()) + // #ys_FIXME_COLOR + // if (m_ticks.find(tick) != m_ticks.end()) + // icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); + if (m_ticks_.find(tick) != m_ticks_.end()) icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); wxCoord x_draw, y_draw; @@ -2695,9 +2721,13 @@ void DoubleSlider::draw_ticks(wxDC& dc) int height, width; get_size(&width, &height); const wxCoord mid = is_horizontal() ? 0.5*height : 0.5*width; - for (auto tick : m_ticks) + // #ys_FIXME_COLOR + // for (auto tick : m_ticks) + for (auto tick : m_ticks_) { - const wxCoord pos = get_position_from_value(tick); + // #ys_FIXME_COLOR + // const wxCoord pos = get_position_from_value(tick); + const wxCoord pos = get_position_from_value(tick.tick); is_horizontal() ? dc.DrawLine(pos, mid-14, pos, mid-9) : dc.DrawLine(mid - 14, pos/* - 1*/, mid - 9, pos/* - 1*/); @@ -2727,7 +2757,9 @@ void DoubleSlider::draw_colored_band(wxDC& dc) main_band.SetBottom(height - SLIDER_MARGIN + 1); } - if (m_ticks.empty()) { + // #ys_FIXME_COLOR + // if (m_ticks.empty()) { + if (m_ticks_.empty()) { dc.SetPen(GetParent()->GetBackgroundColour()); dc.SetBrush(GetParent()->GetBackgroundColour()); dc.DrawRectangle(main_band); @@ -2743,11 +2775,15 @@ void DoubleSlider::draw_colored_band(wxDC& dc) dc.DrawRectangle(main_band); size_t i = 1; - for (auto tick : m_ticks) + // #ys_FIXME_COLOR + // for (auto tick : m_ticks) + for (auto tick : m_ticks_) { if (i == colors_cnt) i = 0; - const wxCoord pos = get_position_from_value(tick); + // #ys_FIXME_COLOR + //const wxCoord pos = get_position_from_value(tick); + const wxCoord pos = get_position_from_value(tick.tick); is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) : main_band.SetBottom(pos-1); @@ -2780,7 +2816,9 @@ void DoubleSlider::draw_one_layer_icon(wxDC& dc) void DoubleSlider::draw_revert_icon(wxDC& dc) { - if (m_ticks.empty() || !m_is_enabled_tick_manipulation) + // #ys_FIXME_COLOR + // if (m_ticks.empty() || !m_is_enabled_tick_manipulation) + if (m_ticks_.empty() || !m_is_enabled_tick_manipulation) return; int width, height; @@ -2832,16 +2870,24 @@ bool DoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) int DoubleSlider::is_point_near_tick(const wxPoint& pt) { - for (auto tick : m_ticks) { - const wxCoord pos = get_position_from_value(tick); + // #ys_FIXME_COLOR + // for (auto tick : m_ticks) { + for (auto tick : m_ticks_) { + // #ys_FIXME_COLOR + // const wxCoord pos = get_position_from_value(tick); + const wxCoord pos = get_position_from_value(tick.tick); if (is_horizontal()) { if (pos - 4 <= pt.x && pt.x <= pos + 4) - return tick; + // #ys_FIXME_COLOR + // return tick; + return tick.tick; } else { if (pos - 4 <= pt.y && pt.y <= pos + 4) - return tick; + // #ys_FIXME_COLOR + // return tick; + return tick.tick; } } return -1; @@ -2893,7 +2939,9 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) m_selection == ssLower ? correct_lower_value() : correct_higher_value(); if (!m_selection) m_selection = ssHigher; - m_ticks.clear(); + // #ys_FIXME_COLOR + // m_ticks.clear(); + m_ticks_.clear(); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } else @@ -2960,7 +3008,9 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) if (!m_is_left_down && !m_is_one_layer) { m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); - is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon); + // #ys_FIXME_COLOR + // is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon); + is_revert_icon_focused = !m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon); } else if (m_is_left_down || m_is_right_down) { if (m_selection == ssLower) { @@ -2975,6 +3025,7 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) correct_higher_value(); action = (current_value != m_higher_value); } + if (m_is_right_down) m_is_mouse_move = true; } Refresh(); Update(); @@ -3051,16 +3102,29 @@ void DoubleSlider::action_tick(const TicksAction action) const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + // #ys_FIXME_COLOR + // if (action == taOnIcon) { + // if (!m_ticks.insert(tick).second) + // m_ticks.erase(tick); + // } + // else { + // const auto it = m_ticks.find(tick); + // if (it == m_ticks.end() && action == taAdd) + // m_ticks.insert(tick); + // else if (it != m_ticks.end() && action == taDel) + // m_ticks.erase(tick); + // } + if (action == taOnIcon) { - if (!m_ticks.insert(tick).second) - m_ticks.erase(tick); + if (!m_ticks_.insert(TICK_CODE(tick)).second) + m_ticks_.erase(TICK_CODE(tick)); } else { - const auto it = m_ticks.find(tick); - if (it == m_ticks.end() && action == taAdd) - m_ticks.insert(tick); - else if (it != m_ticks.end() && action == taDel) - m_ticks.erase(tick); + const auto it = m_ticks_.find(tick); + if (it == m_ticks_.end() && action == taAdd) + m_ticks_.insert(tick); + else if (it != m_ticks_.end() && action == taDel) + m_ticks_.erase(tick); } wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); @@ -3140,6 +3204,22 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) this->CaptureMouse(); const wxClientDC dc(this); + + wxPoint pos = event.GetLogicalPosition(dc); + if (is_point_in_rect(pos, m_rect_tick_action) && m_is_enabled_tick_manipulation) + { + const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + // if on this Y doesn't exist tick + // #ys_FIXME_COLOR + // if (m_ticks.find(tick) == m_ticks.end()) + if (m_ticks_.find(tick) == m_ticks_.end()) + { + // show context menu on OnRightUp() + m_show_context_menu = true; + return; + } + } + detect_selected_slider(event.GetLogicalPosition(dc)); if (!m_selection) return; @@ -3149,6 +3229,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) else m_lower_value = m_higher_value; + // set slider to "one layer" mode m_is_right_down = m_is_one_layer = true; Refresh(); @@ -3163,11 +3244,55 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) this->ReleaseMouse(); m_is_right_down = m_is_one_layer = false; + if (m_show_context_menu) { + wxMenu menu; + + append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", + [this](wxCommandEvent&) { add_code("M600"); }, "colorchange_add_off.png", &menu); + + append_menu_item(&menu, wxID_ANY, _(L("Add pause SD print")) + " (M25)", "", + [this](wxCommandEvent&) { add_code("M25"); }, "pause_add.png", &menu); + + append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "", + [this](wxCommandEvent&) { add_code(""); }, "add_gcode", &menu); + + Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); + + m_show_context_menu = false; + } + Refresh(); Update(); event.Skip(); } +void DoubleSlider::add_code(std::string code) +{ + const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + // if on this Y doesn't exist tick + if (m_ticks_.find(tick) == m_ticks_.end()) + { + if (code.empty()) + { + wxString msg_text = from_u8(_utf8(L("Enter custom G-code used on current layer"))) + " :"; + wxString msg_header = from_u8((boost::format(_utf8(L("Custom Gcode on current layer (%1% mm)."))) % m_values[tick]).str()); + + // get custom gcode + wxString custom_code = wxGetTextFromUser(msg_text, msg_header); + + if (custom_code.IsEmpty()) + return; + code = custom_code.c_str(); + } + + m_ticks_.insert(TICK_CODE(tick, code)); + + wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + Refresh(); + Update(); + } +} + // ---------------------------------------------------------------------------- // LockButton diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index d4d5e7998..123dc3afa 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -821,6 +821,7 @@ public: void OnChar(wxKeyEvent &event); void OnRightDown(wxMouseEvent& event); void OnRightUp(wxMouseEvent& event); + void add_code(std::string code); protected: @@ -884,6 +885,7 @@ private: bool m_is_action_icon_focesed = false; bool m_is_one_layer_icon_focesed = false; bool m_is_enabled_tick_manipulation = true; + bool m_show_context_menu = false; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; @@ -912,6 +914,25 @@ private: std::vector m_segm_pens; std::set m_ticks; std::vector m_values; + + struct TICK_CODE + { + TICK_CODE(int tick):tick(tick), gcode("M600"), extruder(0) {} + TICK_CODE(int tick, const std::string& code) : + tick(tick), gcode(code), extruder(0) {} + TICK_CODE(int tick, int extruder) : + tick(tick), gcode("M600"), extruder(extruder) {} + TICK_CODE(int tick, const std::string& code, int extruder) : + tick(tick), gcode(code), extruder(extruder) {} + + bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } + + int tick; + std::string gcode; + int extruder; + }; + + std::set m_ticks_; }; From 6ac53aa4f376cdd0464e5a53079eb9ba45115a72 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 9 Oct 2019 15:06:52 +0200 Subject: [PATCH 02/45] Improved Tooltips for selected action icon --- src/slic3r/GUI/wxExtensions.cpp | 23 +++++++++++++++++------ src/slic3r/GUI/wxExtensions.hpp | 8 ++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 1cf425334..9536e3560 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2577,12 +2577,19 @@ void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoin if (tick == 0) return; - wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); // #ys_FIXME_COLOR + // wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); // if (m_ticks.find(tick) != m_ticks.end()) // icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); - if (m_ticks_.find(tick) != m_ticks_.end()) - icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); + wxBitmap* icon = m_action_icon_focesed > 0 ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); + auto tick_code_it = m_ticks_.find(tick); + if (tick_code_it != m_ticks_.end()) { + icon = m_action_icon_focesed > 0 ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); + + if (m_action_icon_focesed > 0) + m_action_icon_focesed = tick_code_it->gcode == "M600" ? fiDelColorChange : + tick_code_it->gcode == "M25" ? fiDelPause : fiDelCustomCode; + } wxCoord x_draw, y_draw; is_horizontal() ? x_draw = pt_beg.x - 0.5*m_tick_icon_dim : y_draw = pt_beg.y - 0.5*m_tick_icon_dim; @@ -3010,9 +3017,10 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) bool is_revert_icon_focused = false; if (!m_is_left_down && !m_is_one_layer) { - m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); // #ys_FIXME_COLOR + // m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); // is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon); + m_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action) ? fiAdd : fiNone; is_revert_icon_focused = !m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon); } else if (m_is_left_down || m_is_right_down) { @@ -3028,7 +3036,6 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) correct_higher_value(); action = (current_value != m_higher_value); } - if (m_is_right_down) m_is_mouse_move = true; } Refresh(); Update(); @@ -3036,7 +3043,11 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) // Set tooltips with information for each icon const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) : - m_is_action_icon_focesed ? _(L("Add/Del color change")) : + // m_is_action_icon_focesed ? _(L("Add/Del color change")) : + m_action_icon_focesed == fiAdd ? _(L("Add color change")) : + m_action_icon_focesed == fiDelColorChange ? _(L("Delete color change")) : + m_action_icon_focesed == fiDelPause ? _(L("Delete pause")) : + m_action_icon_focesed == fiDelCustomCode ? _(L("Delete custom code")) : is_revert_icon_focused ? _(L("Discard all color changes")) : ""; this->SetToolTip(tooltip); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 123dc3afa..a41fe1379 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -883,6 +883,14 @@ private: bool m_is_one_layer = false; bool m_is_focused = false; bool m_is_action_icon_focesed = false; + enum FocusedIcon + { + fiNone = 0, + fiAdd, + fiDelColorChange, + fiDelPause, + fiDelCustomCode + } m_action_icon_focesed { fiNone }; bool m_is_one_layer_icon_focesed = false; bool m_is_enabled_tick_manipulation = true; bool m_show_context_menu = false; From 70ef0f25ef7dc0de6bfbfbd458b3ec1cf2bbd12f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 10 Oct 2019 16:03:58 +0200 Subject: [PATCH 03/45] Information from DoubleSlider is saved to Model GCode creating can work with that values. --- src/libslic3r/GCode.cpp | 20 +++++++-- src/libslic3r/GCode.hpp | 2 + src/libslic3r/Model.hpp | 26 +++++++++++ src/libslic3r/Print.cpp | 5 +++ src/slic3r/GUI/GLCanvas3D.cpp | 23 ++++++++++ src/slic3r/GUI/GUI_Preview.cpp | 58 ++++++++++++++++++++---- src/slic3r/GUI/GUI_Preview.hpp | 5 ++- src/slic3r/GUI/Plater.cpp | 6 ++- src/slic3r/GUI/wxExtensions.cpp | 80 +++++++++++++++++++++++++-------- src/slic3r/GUI/wxExtensions.hpp | 11 ++--- 10 files changed, 193 insertions(+), 43 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 65264c9cd..b5ef3da5b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -870,8 +870,11 @@ void GCode::_do_export(Print &print, FILE *file) this->apply_print_config(print.config()); this->set_extruders(print.extruders()); - // Initialize colorprint. + // #ys_FIXME_COLOR // Initialize colorprint. m_colorprint_heights = cast(print.config().colorprint_heights.values); + // Initialize custom gcode + Model* model = print.get_object(0)->model_object()->get_model(); + m_custom_g_code_heights = model->custom_gcode_per_height; // Initialize autospeed. { @@ -1676,8 +1679,15 @@ void GCode::process_layer( // In case there are more toolchange requests that weren't done yet and should happen simultaneously, erase them all. // (Layers can be close to each other, model could have been resliced with bigger layer height, ...). bool colorprint_change = false; - while (!m_colorprint_heights.empty() && m_colorprint_heights.front()-EPSILON < layer.print_z) { - m_colorprint_heights.erase(m_colorprint_heights.begin()); + // #ys_FIXME_COLOR + // while (!m_colorprint_heights.empty() && m_colorprint_heights.front()-EPSILON < layer.print_z) { + // m_colorprint_heights.erase(m_colorprint_heights.begin()); + // colorprint_change = true; + // } + std::string custom_code = ""; + while (!m_custom_g_code_heights.empty() && m_custom_g_code_heights.front().height-EPSILON < layer.print_z) { + custom_code = m_custom_g_code_heights.front().gcode; + m_custom_g_code_heights.erase(m_custom_g_code_heights.begin()); colorprint_change = true; } @@ -1688,7 +1698,9 @@ void GCode::process_layer( gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n"; // add tag for time estimator gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; - gcode += "M600\n"; + // #ys_FIXME_COLOR + // gcode += "M600\n"; + gcode += custom_code + "\n"; } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 45ff7eda6..a1a83983e 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -353,6 +353,8 @@ protected: // Layer heights for colorprint - updated before the export and erased during the process // so no toolchange occurs twice. std::vector m_colorprint_heights; + // extensions for colorprint - now it's not a just color_print, there can be some custom gcode + std::vector m_custom_g_code_heights; // Time estimators GCodeTimeEstimator m_normal_time_estimator; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 410c2d3ef..2a1edd0ca 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -745,6 +745,32 @@ public: ModelObjectPtrs objects; // Wipe tower object. ModelWipeTower wipe_tower; + + // Extensions for + struct CustomGCode + { + CustomGCode(double height, const std::string& code, int extruder) : + height(height), gcode(code), extruder(extruder) {} + + bool operator<(const CustomGCode& other) const { return other.height > this->height; } + bool operator==(const CustomGCode& other) const + { + return (other.height == this->height) && + (other.gcode == this->gcode) && + (other.extruder == this->extruder ); + } + bool operator!=(const CustomGCode& other) const + { + return (other.height != this->height) || + (other.gcode != this->gcode) || + (other.extruder != this->extruder ); + } + + double height; + std::string gcode; + int extruder; + }; + std::vector custom_gcode_per_height; // Default constructor assigns a new ID to the model. Model() { assert(this->id().valid()); } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 88645df15..3212082a3 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -749,6 +749,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ delete model_object; } } + if (model.custom_gcode_per_height != m_model.custom_gcode_per_height) + { + update_apply_status(this->invalidate_step(psGCodeExport)); + m_model.custom_gcode_per_height = model.custom_gcode_per_height; + } } // 2) Map print objects including their transformation matrices. diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c55d64b47..2aa10a9bb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -839,6 +839,8 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePrevie if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint && wxGetApp().extruders_edited_cnt() == 1) // show color change legend only for single-material presets { + /* + // #ys_FIXME_COLOR auto& config = wxGetApp().preset_bundle->project_config; const std::vector& color_print_values = config.option("colorprint_heights")->values; @@ -854,6 +856,27 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePrevie double current_z = *lower_b; double previous_z = lower_b == print_zs.begin() ? 0.0 : *(--lower_b); + // to avoid duplicate values, check adding values + if (cp_legend_values.empty() || + !(cp_legend_values.back().first == previous_z && cp_legend_values.back().second == current_z) ) + cp_legend_values.push_back(std::pair(previous_z, current_z)); + } + } + */ + std::vector custom_gcode_per_height = wxGetApp().plater()->model().custom_gcode_per_height; + + if (!custom_gcode_per_height.empty()) { + std::vector print_zs = canvas.get_current_print_zs(true); + for (auto custom_code : custom_gcode_per_height) + { + auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.height - DoubleSlider::epsilon()); + + if (lower_b == print_zs.end()) + continue; + + double current_z = *lower_b; + double previous_z = lower_b == print_zs.begin() ? 0.0 : *(--lower_b); + // to avoid duplicate values, check adding values if (cp_legend_values.empty() || !(cp_legend_values.back().first == previous_z && cp_legend_values.back().second == current_z) ) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 98f6a8ee6..df7b5cf54 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -562,12 +562,22 @@ void Preview::update_view_type() { const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; + /* + // #ys_FIXME_COLOR const wxString& choice = !config.option("colorprint_heights")->values.empty() && wxGetApp().extruders_edited_cnt()==1 ? _(L("Color Print")) : config.option("wiping_volumes_matrix")->values.size() > 1 ? _(L("Tool")) : _(L("Feature type")); + */ + + const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() && + wxGetApp().extruders_edited_cnt()==1 ? + _(L("Color Print")) : + config.option("wiping_volumes_matrix")->values.size() > 1 ? + _(L("Tool")) : + _(L("Feature type")); int type = m_choice_view_type->FindString(choice); if (m_choice_view_type->GetSelection() != type) { @@ -609,7 +619,11 @@ void Preview::create_double_slider() Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { - wxGetApp().preset_bundle->project_config.option("colorprint_heights")->values = m_slider->GetTicksValues(); + // #ys_FIXME_COLOR + // wxGetApp().preset_bundle->project_config.option("colorprint_heights")->values = m_slider->GetTicksValues(); + + Model& model = wxGetApp().plater()->model(); + model.custom_gcode_per_height = m_slider->GetTicksValues_(); m_schedule_background_process(); update_view_type(); @@ -645,6 +659,24 @@ static int find_close_layer_idx(const std::vector& zs, double &z, double return -1; } +void Preview::check_slider_values(std::vector& ticks_from_model, + const std::vector& layers_z) +{ + // All ticks that would end up outside the slider range should be erased. + // TODO: this should be placed into more appropriate part of code, + // this function is e.g. not called when the last object is deleted + unsigned int old_size = ticks_from_model.size(); + ticks_from_model.erase(std::remove_if(ticks_from_model.begin(), ticks_from_model.end(), + [layers_z](Model::CustomGCode val) + { + auto it = std::lower_bound(layers_z.begin(), layers_z.end(), val.height - DoubleSlider::epsilon()); + return it == layers_z.end(); + }), + ticks_from_model.end()); + if (ticks_from_model.size() != old_size) + m_schedule_background_process(); +} + void Preview::update_double_slider(const std::vector& layers_z, bool keep_z_range) { // Save the initial slider span. @@ -660,8 +692,11 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max(); - std::vector &ticks_from_config = (wxGetApp().preset_bundle->project_config.option("colorprint_heights"))->values; - check_slider_values(ticks_from_config, layers_z); + // #ys_FIXME_COLOR + // std::vector &ticks_from_config = (wxGetApp().preset_bundle->project_config.option("colorprint_heights"))->values; + // check_slider_values(ticks_from_config, layers_z); + std::vector &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height; + check_slider_values(ticks_from_model, layers_z); m_slider->SetSliderValues(layers_z); assert(m_slider->GetMinValue() == 0); @@ -683,7 +718,9 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee } m_slider->SetSelectionSpan(idx_low, idx_high); - m_slider->SetTicksValues(ticks_from_config); + // #ys_FIXME_COLOR + // m_slider->SetTicksValues(ticks_from_config); + m_slider->SetTicksValues_(ticks_from_model); bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF); if (color_print_enable) { @@ -693,7 +730,7 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee } m_slider->EnableTickManipulation(color_print_enable); } - +// #ys_FIXME_COLOR void Preview::check_slider_values(std::vector& ticks_from_config, const std::vector &layers_z) { @@ -799,10 +836,13 @@ void Preview::load_print_as_fff(bool keep_z_range) { colors = GCodePreviewData::ColorPrintColors(); if (! gcode_preview_data_valid) { - //FIXME accessing full_config() is pretty expensive. - // Only initialize color_print_values for the initial preview, not for the full preview where the color_print_values is extracted from the G-code. - const auto& config = wxGetApp().preset_bundle->project_config; - color_print_values = config.option("colorprint_heights")->values; + // #ys_FIXME_COLOR + // const auto& config = wxGetApp().preset_bundle->project_config; + // color_print_values = config.option("colorprint_heights")->values; + const std::vector& custom_codes = wxGetApp().plater()->model().custom_gcode_per_height; + color_print_values.reserve(custom_codes.size()); + for (const Model::CustomGCode& code : custom_codes) + color_print_values.push_back(code.height); } } else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 08d5991b4..551900277 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -5,6 +5,7 @@ #include "libslic3r/Point.hpp" #include +#include "libslic3r/Model.hpp" class wxNotebook; class wxGLCanvas; @@ -154,9 +155,11 @@ private: // Create/Update/Reset double slider on 3dPreview void create_double_slider(); + void check_slider_values(std::vector &ticks_from_model, + const std::vector &layers_z); void update_double_slider(const std::vector& layers_z, bool keep_z_range = false); void check_slider_values(std::vector &ticks_from_config, - const std::vector &layers_z); + const std::vector &layers_z); // #ys_FIXME_COLOR void reset_double_slider(); // update DoubleSlider after keyDown in canvas void update_double_slider_from_canvas(wxKeyEvent& event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 50621caa8..6812c2b81 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2688,8 +2688,10 @@ void Plater::priv::reset() // The hiding of the slicing results, if shown, is not taken care by the background process, so we do it here this->sidebar->show_sliced_info_sizer(false); - auto& config = wxGetApp().preset_bundle->project_config; - config.option("colorprint_heights")->values.clear(); + // #ys_FIXME_COLOR + // auto& config = wxGetApp().preset_bundle->project_config; + // config.option("colorprint_heights")->values.clear(); + model.custom_gcode_per_height.clear(); } void Plater::priv::mirror(Axis axis) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 9536e3560..aaa8c86fd 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2469,6 +2469,44 @@ std::vector DoubleSlider::GetTicksValues() const return values; } +using t_custom_code = Slic3r::Model::CustomGCode; +std::vector DoubleSlider::GetTicksValues_() const +{ + std::vector values; + + const int val_size = m_values.size(); + if (!m_values.empty()) + for (const TICK_CODE& tick : m_ticks_) { + if (tick.tick > val_size) + break; + values.push_back(t_custom_code(m_values[tick.tick], tick.gcode, tick.extruder)); + } + + return values; +} + +void DoubleSlider::SetTicksValues_(const std::vector& heights) +{ + if (m_values.empty()) + return; + + const bool was_empty = m_ticks_.empty(); + + m_ticks_.clear(); + for (auto h : heights) { + auto it = std::lower_bound(m_values.begin(), m_values.end(), h.height - epsilon()); + + if (it == m_values.end()) + continue; + + m_ticks_.insert(TICK_CODE(it-m_values.begin(), h.gcode, h.extruder)); + } + + if (!was_empty && m_ticks_.empty()) + // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one + wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); +} + void DoubleSlider::SetTicksValues(const std::vector& heights) { if (m_values.empty()) @@ -2577,19 +2615,12 @@ void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoin if (tick == 0) return; + wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); // #ys_FIXME_COLOR - // wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); // if (m_ticks.find(tick) != m_ticks.end()) // icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); - wxBitmap* icon = m_action_icon_focesed > 0 ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); - auto tick_code_it = m_ticks_.find(tick); - if (tick_code_it != m_ticks_.end()) { - icon = m_action_icon_focesed > 0 ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); - - if (m_action_icon_focesed > 0) - m_action_icon_focesed = tick_code_it->gcode == "M600" ? fiDelColorChange : - tick_code_it->gcode == "M25" ? fiDelPause : fiDelCustomCode; - } + if (m_ticks_.find(tick) != m_ticks_.end()) + icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); wxCoord x_draw, y_draw; is_horizontal() ? x_draw = pt_beg.x - 0.5*m_tick_icon_dim : y_draw = pt_beg.y - 0.5*m_tick_icon_dim; @@ -3017,10 +3048,9 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) bool is_revert_icon_focused = false; if (!m_is_left_down && !m_is_one_layer) { + m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); // #ys_FIXME_COLOR - // m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); // is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon); - m_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action) ? fiAdd : fiNone; is_revert_icon_focused = !m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon); } else if (m_is_left_down || m_is_right_down) { @@ -3042,13 +3072,25 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) event.Skip(); // Set tooltips with information for each icon - const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) : - // m_is_action_icon_focesed ? _(L("Add/Del color change")) : - m_action_icon_focesed == fiAdd ? _(L("Add color change")) : - m_action_icon_focesed == fiDelColorChange ? _(L("Delete color change")) : - m_action_icon_focesed == fiDelPause ? _(L("Delete pause")) : - m_action_icon_focesed == fiDelCustomCode ? _(L("Delete custom code")) : - is_revert_icon_focused ? _(L("Discard all color changes")) : ""; + // #ys_FIXME_COLOR + // const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) : + // m_is_action_icon_focesed ? _(L("Add/Del color change")) : + // is_revert_icon_focused ? _(L("Discard all color changes")) : ""; + wxString tooltip(wxEmptyString); + if (m_is_one_layer_icon_focesed) + tooltip = _(L("One layer mode")); + if (is_revert_icon_focused) + tooltip = _(L("Discard all custom changes")); + else if (m_is_action_icon_focesed) + { + const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + const auto tick_code_it = m_ticks_.find(tick); + tooltip = tick_code_it == m_ticks_.end() ? _(L("Add color change")) : + tick_code_it->gcode == "M600" ? _(L("Delete color change")) : + tick_code_it->gcode == "M25" ? _(L("Delete pause")) : + from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); + } + this->SetToolTip(tooltip); if (action) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index a41fe1379..0ee451f44 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -16,6 +16,7 @@ #include #include #include +#include "libslic3r/Model.hpp" namespace Slic3r { enum class ModelVolumeType : int; @@ -795,6 +796,8 @@ public: } void ChangeOneLayerLock(); std::vector GetTicksValues() const; + std::vector GetTicksValues_() const; + void SetTicksValues_(const std::vector &heights); void SetTicksValues(const std::vector& heights); void EnableTickManipulation(bool enable = true) { m_is_enabled_tick_manipulation = enable; @@ -883,14 +886,6 @@ private: bool m_is_one_layer = false; bool m_is_focused = false; bool m_is_action_icon_focesed = false; - enum FocusedIcon - { - fiNone = 0, - fiAdd, - fiDelColorChange, - fiDelPause, - fiDelCustomCode - } m_action_icon_focesed { fiNone }; bool m_is_one_layer_icon_focesed = false; bool m_is_enabled_tick_manipulation = true; bool m_show_context_menu = false; From db6c501b4d4cc88b931a7763c057ff7fe26d9a1f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 10 Oct 2019 16:08:52 +0200 Subject: [PATCH 04/45] Added code to colorized of axes names in manipulation panel (temporarily commented) Related to (#3053) --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 0b3f2b098..d1cb1348c 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -243,11 +243,13 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // Add Axes labels with icons static const char axes[] = { 'X', 'Y', 'Z' }; +// std::vector axes_color = {"#990000", "#009900","#000099"}; for (size_t axis_idx = 0; axis_idx < sizeof(axes); axis_idx++) { const char label = axes[axis_idx]; wxStaticText* axis_name = new wxStaticText(m_parent, wxID_ANY, wxString(label)); set_font_and_background_style(axis_name, wxGetApp().bold_font()); +// axis_name->SetForegroundColour(wxColour(axes_color[axis_idx])); sizer = new wxBoxSizer(wxHORIZONTAL); // Under OSX we use font, smaller than default font, so From 8e6bb7c20dd91f22d8e6f6643edc911352bc9e29 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 11 Oct 2019 10:39:54 +0200 Subject: [PATCH 05/45] Add missed icons --- resources/icons/add_gcode.svg | 12 ++++++++++++ resources/icons/pause_add.png | Bin 0 -> 5883 bytes src/libslic3r/Model.hpp | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 resources/icons/add_gcode.svg create mode 100644 resources/icons/pause_add.png diff --git a/resources/icons/add_gcode.svg b/resources/icons/add_gcode.svg new file mode 100644 index 000000000..e2aa21adf --- /dev/null +++ b/resources/icons/add_gcode.svg @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/resources/icons/pause_add.png b/resources/icons/pause_add.png new file mode 100644 index 0000000000000000000000000000000000000000..afe881de8bbea4b942cc0e9ae35bfba53c9dc057 GIT binary patch literal 5883 zcmcIo)msz})1{GaDUt4yl5%Sjesp(t>@F#du)u!4f5bP> zoH@^&iclG8;55P0w0h>X< zUD4u)KRf=tP+w3PtvTD3q*TxQkG4H4<$of#38Z)^yuZ$5KXg5PVfzbh3q%N?zkErQ z)`Y$wG(x1c4jy4Ez1H*;oF3h~2|HnHSK_BUVMGycJ3v<(QRAx5kl-$5fO`n&*JBV| z{ZeY@g;;!J=U~r?Eq>|`)?+$F_lVh(*O_ZXkInhWuihYV$HYA}M0(_+DqtFDw_?qr zyVjNRlrbJW5*r~91#h0z-a`z+JwvFZQ`xonTSg(fU#V7dSQ|zZTLHc!=Wwwto0vH_ zbH6*_lY8RQr=Xh~7Uq)?8grEyew)E))n%0E7pT!@w_E2!c8w?WNMu2r2l98=O&X$& ziQtvaBNtPi{WiTkW5mb9t091EtJN#|BcknQSa9p_Hth|G>zQ^ep3R4?51(09&;5A# zlHp<1?lIyS4$}pq zHzUBR_)C4=k6IoNfV^if3P*Y(_QOvqc<2fZRvNoygV<34*z8$9b+wq67IkOnM{+!; znST@oU@@oZd$O0L83y19E$e%6H!m9o-f+uUmLC~vR8}`{w>v=Rf4TWi!-D@3DZO(z z)KQ{wxy1^y%W;4h+x>F6Kl*I+6ER+yVer{BxD)TE&!z*^%xBBx0d-kRlQ$C{xV)JyWXrXEGoD!G(e^V@U1UyGcX~7<5fo2uizE|xG-*g)^cnI~ zU_(MNNy6Amb<9|clJUETcpeBoxs^EiBIL$06vFBD+Br#Cav_~0TC~`m372#W8C^eV zEsDsdGbpff{4Z=(t6^*9VkF1%94aaJdxdhky#B#>nuq(U0Yv*XdeQKV^P)w`G@hP- z#P?Tc*#cl);Lo8hxAM}KZn!q9dDTH{LcI%DCDoMHb3)96-_~Cyno;)o^_hC-o zK-W=)Q$lX<-eiBIb?XVFL1%cM1@^7yTi3~cHAxFw)6}&#nG0-`i@Nl3atJF5r3fQE zh`QFs$`1ENnp{aeJ#%Qwl7(T!jV*PnV?0dTlF?`8T1O5IqV@xvIscb0W*Af;!oR3T;} zFl>%B=UKNfG=6_Kv+99V_gDX;3wzSqyC83+@yG=$*Lp#8l+B01sy7&6qk+dC{G_Rz zjiDd(fdY#`Ak-H3bgYZT(nlRnWQ$x1!#qNjGC=0#vD0(kEB?f*$80eoo8a|6U?0Z% ziSY&%`ZWXRHXAj+M_-Bb?EI`#j$yA@$A>qe@Yg%)p@lQXjM_=L$FXm>sig(e*pJzR z6MC|u{UP4M?ymhB0i{PFJ@+O4Ib zZ!wBkl{JfIW?&;U!TQTD;C0|?A7}zYTPVwxWbqEe$*>gc~>Y zwgTJg?$IW8QJ!q>`j%2(s-rxMp{$zTk)^oMVcUFvbu68GTs0D`=MibxqPBO_#I@y^ zIK;-j?T|kYnYr|$(QUHAmRfFknT!@Tf;AJ$$C;92@Fy^c{g|E?9|*MT4WOW$v!k2M z(epc&c+J1ryDm%>XS2|#!_I2|P>-eclaLvqTn3+%Cw5SV3roD>lheNzLm}QLsj$`< zdJONz%=Gbe?0hE1#qShXNv4nbmZPfaKH_u`Ujls#ANgt|J?x(VoW|r$4{O62$33IS zdXh?c$3hS}aG@bMkH%bmgqjiTjFs~p6#K&)4*c3-1}1(Kc+OlXeqvwGqk9UQal3?H zUAbaPXbh{+ViinVXDrI#4Yod>wLTtF|3=x$=^*C*0Ju)v(uHSs6;|Xk)J0#)Igu0z z7*6A0Ssu_ONP^OIb^*50Sq}5)!j+w!8GmaxliU9sJIz!cz&E(+)T9YkC2Y3tCG(JN zW^@-a?16OaZYm@5gLE)|f+rE6T1H+d&kB0uaY~06U3#L>e=XW^RhD18x1x0=mggZ8VMeA5rB$m(Hv;{6 z)L?aIs@vCN_g~*1g_C-tYF@Sx4b@t!He{B4CJw@`Ws?klo_BfD@cVG2MQ8f?%XzGo z+)}7SHfKFOgW}@sB%O+d7qKBTZTCm}>P?P81A9j>nwZ@}gC`3(lrVv6lxe@9HQ@&! zza8C6-=nAYjs=srZLI!&j9N&x<*^u7$g!|akKxwnZ&ckx;EbO8>o9bykUCra@5f1= zs{3EzZ|sMQ=;!@8dmyQ5nZ&V00X&*E4T6ko2)2&0L(;~wL+~)Z<}phgzMKlF0PnXT5)VefTJ3xhPgRO5UyLG0f7nH^_-cT^}Otjf72}~W~%8s!MF)oVqo;W zQ4FwTKJ(2XYnelW>n>XdS}U-@>?W~EGRoq>hL+N# zO=2oK%|M(vIK@~Pa~|Dobpp#FEt4w}dLFlBIKk19SyHeG=?e8iE@xsIc^OmL2M3laz&M10Cxv&}lO*Eff zi*{azdD^M5arbmVUK6R`k!%9@R&B10=n!`xS7g4<>pMXBH$ng8X!F$Y!Rx45%I zx?$Z)#=gPv7Xzh_fwt9Vx8`To+IGpNZf&dGM+LSrGO!_!Wr`fADI;T}J;69EI_%%g(U6U!^*Nl98s+$WkVIF~+U!Y}PQ2x%lu9jG zFZI2_qBj$Ik;j#}JZm9)0f20eMNva1fn_t|4>BAc>hG}Q!B_C6h+4=y8Vm}-bspollRIqEnYG%smb4Z+?P<+gUDvc|LbB-LHlPBD2w$bRH zd1*Ww7Ci`9-B&Vi$7U3XOy4FDcT=nzxGta4JtoZmt6xjTe%4RGF|5<~>;8neg7^|b z&1|_^%wlQSO|>-S&Pah5!DA$*D~>UU>97m=|R zL8ts}pu7Z)>5WP3XgI9z)~WAh)kam#uql-9*9;w9Lud$pSVe_?U!d5*sCK+kno-BVvb`RcaG@4JUWGUa z*s1HFNWT|`%yHOvFSAiWgWkL?##+W*y&kYgWKz}rs|qrsWmnSO?5&QCH6qtM39=wO z$YLCL+1;RZhP$6nG#OMDG?|POs!XX53(IquCe_nD1PhB?R-Df>* zT#;*j=Sa1V&dqS|vNgd-IVEMQrhMowa6ZEq6O~W-&&Jyd2A+^?Pxpi)xYbP^(KQMN zk*F)Y7+-nDul8VRylVZ=Tx6c_XBfhRc{<5jc^*I*C%@(B^y$Z9JiMty@3o9OPn8LZ zs=x|gW|#?DBI78PH&v9&x~)aq+|Ep$W&mm}ZaZR)d-Xt!fhy84mr2Rkgkml68%@pQ zk=mup+nTJ2P={F;{Ye@RAgN=DD}NVPanV~)ZE>o2kmC9IE2Grb4&$w8YsWY2HDo{0 z$t$cWYcY^>oaFaT7idFSn?Q6KV&S6qJ_N1*E25TCGLtILqoA0mDImMuhR87%6o&57 z&ZZsD*5i_6iU|WW-Ef_~(0w^*syaKT)P8D>;0@@kHgTGq1o}Q*;!%gM?SKe^azP;m z7j9O!JHam;U#7@U?-XZW)q75_--mhH;cljzdHHd70ASc{j6pXgx71@&5{|h`u~+>W zOf0QmRU?VS6l44#kMBrQZ)0ornetp|XKXCnj3>kIS2~qsJ)Vt9R3@YNosj&P{dqry zT9(Pa4F1-s&ujQpx+4he_+5VAj=iuB9oJKMbX?Vv39UOs&DzgtkPMN+892wefekkI|rBW?$`Se!l|BgLN(s&rJA2Drbjm5YuzINVl3U zXyPUfK0+!Mi}-5S9J04Qf}DWsFTUt|X3~V}uY+63`H2RX?#l#agaFS@GF)1%JR+gQ z9K3C>UfVn&DZuQ#&k!!jut>$S;McYvJz_;Y(p9-|rBqoMsknuxX>Py!p0znej@hJ~XfHL9_*;=fxU$hH!73(ad$pJ4y># zh5EPnvb1vzI~wr$yzc3vVxyg8u3JhgPAp^qrG|K2GB~(C<|?k*H7n(tJ@{#2Gkf~Z zpj3Q$Y1tkjY{T8XkXk<43m?}ElmwFfT&p)xQ_XhH&$XlHr{1lyw?EWkmSNq-84}`K z8pYrBX=;+0p<9T_|E_5okS06hANq!rWSWSJ?3vx!R!KGe#}$sQiiwTFOkf)}hB5{E z6VY3JBhUVMc&S>hjY#dCqvWNB@tDYyz0AL_42>uzy_F%ye{@Fjk28$j&1k1nC3Sfi zeFiutb8bTCrW$}O$NgZlOQLSpbF<2j{P|A=CVenNoKLuNi`533b;%+RYg^YKEYCTq zONRcr1K(4j&1B}&)uaj<<~A@rirRUWdUKI0+uVqq|E`~J5*x-+oPQj;Rd-vGpZ)qs zwu@6)wZr50oKLiSqdJU!aYLr8rLl+2Cb7sT{h4o*6e^ExAS{77S2dIj@Kqgizg3eovGvG`tCX(LRT#a|Qv8^oFT z>fjq1R;1MOwm6qq)QdtAP1;e`=m#icCY``M??j zL6H8kaB5DgcnpyUT&H^W$Eek$zzI?b9FEg^M6mX%WSP=!sLTf( z6~Cwbn|GtLMRek)VH60zv57v&_wc)jIr)Knjq)6I-z<}j!33w^K&SL9Lfq5Ybj}^+ zvMe7giqb~{i6D3LsdUT;Hn->5P64s)Uvp&oduyuwH`4i8vQw6he>Ntb`06Z>a{Q7w z%pQKM8p=fHB(k3ja#D1WbJ<#Zs02Pq033rD14MgaviJWE%7d8U5X5D6l zb!2^E>$^LDOe)wN=i&j0{togV?NNi8N|bvsu9i|PFPn0418F&~4}yQkxStjjzDixp z{RcgAv$;T3pHVv>xohr^rkcG;l18JT_$BPq1Xu-IGVHedJQ%pVl ze#2_HQO?ZlshQVZd9aP46`6XSTN|V z)$4`N_nr-LSmo>eYA1`#hC+jd5AGQ?;QLbKvJ3+?GHrFba`0jqbW4aTzc#w?gmL#z z(YN3&<r2>CbPL*uYZp1w@(`SivJj4@&A^U35Xy$#J`9!LNwm46MEyNdC@6L}c_2V}nzX`g>0rnjo5 zBIW`18w@sl7kk{Tf0Dkcf~-EpLIPL^yN?c6K0D?2mJfmx-+GY0go}3On(a3qwQORf z#Zi7Kn($b`BGx!?5rRS!#fie)A}Q*YPWTI_9quu59PIsYAomO~k(=LXg_1WCWATJC S?=bzFkEE)orBEYh5&nO)^r2<| literal 0 HcmV?d00001 diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 2a1edd0ca..05147f9dd 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -746,7 +746,7 @@ public: // Wipe tower object. ModelWipeTower wipe_tower; - // Extensions for + // Extensions for color print struct CustomGCode { CustomGCode(double height, const std::string& code, int extruder) : From 5c2b5a167b1ea93c4073420cc05f7ccd18403d35 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 14 Oct 2019 10:05:27 +0200 Subject: [PATCH 06/45] Context menu is extended for multiple material printing --- src/slic3r/GUI/GLCanvas3D.cpp | 4 +- src/slic3r/GUI/GUI_Preview.cpp | 34 +++++++--- src/slic3r/GUI/wxExtensions.cpp | 106 +++++++++++++++++++++++++------- src/slic3r/GUI/wxExtensions.hpp | 15 +++++ 4 files changed, 125 insertions(+), 34 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2aa10a9bb..2dee58136 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -836,8 +836,8 @@ GLCanvas3D::LegendTexture::LegendTexture() void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, std::vector>& cp_legend_values) { - if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint && - wxGetApp().extruders_edited_cnt() == 1) // show color change legend only for single-material presets + if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint /*&& + wxGetApp().extruders_edited_cnt() == 1*/) // show color change legend only for single-material presets { /* // #ys_FIXME_COLOR diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index df7b5cf54..5d0deaaad 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -502,6 +502,8 @@ void Preview::update_sliders(const std::vector& layers_z, bool keep_z_ra m_enabled = true; update_double_slider(layers_z, keep_z_range); m_double_slider_sizer->Show((size_t)0); + if (m_slider->GetManipulationState() != DoubleSlider::msMultiExtruder) + m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide((size_t)0); Layout(); } @@ -572,8 +574,8 @@ void Preview::update_view_type() _(L("Feature type")); */ - const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() && - wxGetApp().extruders_edited_cnt()==1 ? + const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty()// && + /*wxGetApp().extruders_edited_cnt()==1*/ ? _(L("Color Print")) : config.option("wiping_volumes_matrix")->values.size() > 1 ? _(L("Tool")) : @@ -591,9 +593,9 @@ void Preview::update_view_type() void Preview::create_double_slider() { m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100); - m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); + // #ys_FIXME_COLOR + // m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); - /* auto extruder_selector = new wxComboBox(this, wxID_ANY); extruder_selector->Append("Whole print"); int extruder_cnt = wxGetApp().extruders_edited_cnt(); @@ -610,7 +612,6 @@ void Preview::create_double_slider() sizer->Add(m_slider, 1, wxEXPAND, 0); m_double_slider_sizer->Add(sizer, 0, wxEXPAND, 0); - */ // sizer, m_canvas_widget m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this); @@ -723,12 +724,25 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee m_slider->SetTicksValues_(ticks_from_model); bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF); + // #ys_FIXME_COLOR + // if (color_print_enable) { + // const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; + // if (cfg.opt("nozzle_diameter")->values.size() > 1) + // color_print_enable = false; + // } + // m_slider->EnableTickManipulation(color_print_enable); + + m_slider->EnableTickManipulation(color_print_enable); + m_slider->SetManipulationState(DoubleSlider::msSingleExtruder); if (color_print_enable) { const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; - if (cfg.opt("nozzle_diameter")->values.size() > 1) - color_print_enable = false; + if (cfg.opt("nozzle_diameter")->values.size() > 1) { + // ys_TODO : fill is_detected_one_extruder_print value + bool is_detected_one_extruder_print = wxGetApp().plater()->fff_print().extruders().size() == 1; + m_slider->SetManipulationState(is_detected_one_extruder_print ? + DoubleSlider::msMultiExtruderSimple : DoubleSlider::msMultiExtruder); + } } - m_slider->EnableTickManipulation(color_print_enable); } // #ys_FIXME_COLOR void Preview::check_slider_values(std::vector& ticks_from_config, @@ -875,8 +889,8 @@ void Preview::load_print_as_fff(bool keep_z_range) m_loaded = true; } else { // disable color change information for multi-material presets - if (wxGetApp().extruders_edited_cnt() > 1) - color_print_values.clear(); + // if (wxGetApp().extruders_edited_cnt() > 1) // #ys_FIXME_COLOR + // color_print_values.clear(); // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index cc6375af8..e6e569939 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3042,6 +3042,28 @@ void DoubleSlider::correct_higher_value() m_lower_value = m_higher_value; } +wxString DoubleSlider::get_tooltip(bool is_revert_icon_focused) +{ + wxString tooltip(wxEmptyString); + if (m_is_one_layer_icon_focesed) + tooltip = _(L("One layer mode")); + if (is_revert_icon_focused) + tooltip = _(L("Discard all custom changes")); + else if (m_is_action_icon_focesed) + { + const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + const auto tick_code_it = m_ticks_.find(tick); + tooltip = tick_code_it == m_ticks_.end() ? _(L("Add color change")) : + tick_code_it->gcode == "M600" ? _(L("Delete color change")) : + tick_code_it->gcode == "M25" ? _(L("Delete pause")) : + tick_code_it->gcode == "tool_change" ? + from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) : + from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); + } + + return tooltip; +} + void DoubleSlider::OnMotion(wxMouseEvent& event) { bool action = false; @@ -3081,22 +3103,7 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) // const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) : // m_is_action_icon_focesed ? _(L("Add/Del color change")) : // is_revert_icon_focused ? _(L("Discard all color changes")) : ""; - wxString tooltip(wxEmptyString); - if (m_is_one_layer_icon_focesed) - tooltip = _(L("One layer mode")); - if (is_revert_icon_focused) - tooltip = _(L("Discard all custom changes")); - else if (m_is_action_icon_focesed) - { - const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - const auto tick_code_it = m_ticks_.find(tick); - tooltip = tick_code_it == m_ticks_.end() ? _(L("Add color change")) : - tick_code_it->gcode == "M600" ? _(L("Delete color change")) : - tick_code_it->gcode == "M25" ? _(L("Delete pause")) : - from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); - } - - this->SetToolTip(tooltip); + this->SetToolTip(get_tooltip(is_revert_icon_focused)); if (action) { @@ -3298,6 +3305,20 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) event.Skip(); } +int DoubleSlider::get_extruder_for_tick(int tick) +{ + int extruder = 0; + if (!m_ticks_.empty()) { + auto tick_code_it = m_ticks_.lower_bound(tick); + if (tick_code_it != m_ticks_.begin()) { + --tick_code_it; + extruder = tick_code_it->extruder; + } + } + + return extruder; +} + void DoubleSlider::OnRightUp(wxMouseEvent& event) { if (!HasCapture()) @@ -3307,7 +3328,29 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) if (m_show_context_menu) { wxMenu menu; - + + if (m_state == msMultiExtruderSimple) + { + const wxString name = _(L("Change extruder")); + + const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); + if (extruders_cnt > 1) + { + const int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); + + wxMenu* change_extruder_menu = new wxMenu(); + for (int i = 0; i <= extruders_cnt; i++) { + const wxString& item_name = i == 0 ? _(L("Default")) : wxString::Format("%d", i); + + append_menu_radio_item(change_extruder_menu, wxID_ANY, item_name, "", + [this, i](wxCommandEvent&) { change_extruder(i); }, &menu)->Check(i == initial_extruder); + } + + menu.AppendSubMenu(change_extruder_menu, name, _(L("Use another extruder"))); + } + } + + if (m_state != msMultiExtruderSimple) append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", [this](wxCommandEvent&) { add_code("M600"); }, "colorchange_add_off.png", &menu); @@ -3339,14 +3382,33 @@ void DoubleSlider::add_code(std::string code) wxString msg_header = from_u8((boost::format(_utf8(L("Custom Gcode on current layer (%1% mm)."))) % m_values[tick]).str()); // get custom gcode - wxString custom_code = wxGetTextFromUser(msg_text, msg_header); - - if (custom_code.IsEmpty()) + wxTextEntryDialog dlg(nullptr, msg_text, msg_header, wxEmptyString, + wxTextEntryDialogStyle | wxTE_MULTILINE); + if (dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty()) return; - code = custom_code.c_str(); + + code = dlg.GetValue().c_str(); } - m_ticks_.insert(TICK_CODE(tick, code)); + int extruder = 0; + if (m_state == msMultiExtruderSimple) + extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); + + m_ticks_.insert(TICK_CODE(tick, code, extruder)); + + wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + Refresh(); + Update(); + } +} + +void DoubleSlider::change_extruder(int extruder) +{ + const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + // if on this Y doesn't exist tick + if (m_ticks_.find(tick) == m_ticks_.end()) + { + m_ticks_.insert(TICK_CODE(tick, "tool_change", extruder)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 0ee451f44..e874dbf38 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -806,6 +806,16 @@ public: EnableTickManipulation(false); } + static enum ManipulationState { + msSingleExtruder, // single extruder printer preset is selected + msMultiExtruder, // multiple extruder printer preset is selected + msMultiExtruderSimple // multiple extruder printer preset is selected, but one-extruder print is detected + }; + void SetManipulationState(ManipulationState state) { + m_state = state; + } + ManipulationState GetManipulationState() const { return m_state; } + bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } bool is_one_layer() const { return m_is_one_layer; } bool is_lower_at_min() const { return m_lower_value == m_min_value; } @@ -823,8 +833,10 @@ public: void OnKeyUp(wxKeyEvent &event); void OnChar(wxKeyEvent &event); void OnRightDown(wxMouseEvent& event); + int get_extruder_for_tick(int tick); void OnRightUp(wxMouseEvent& event); void add_code(std::string code); + void change_extruder(int extruder); protected: @@ -846,6 +858,7 @@ protected: void detect_selected_slider(const wxPoint& pt); void correct_lower_value(); void correct_higher_value(); + wxString get_tooltip(bool is_revert_icon_focused); void move_current_thumb(const bool condition); void action_tick(const TicksAction action); void enter_window(wxMouseEvent& event, const bool enter); @@ -889,6 +902,7 @@ private: bool m_is_one_layer_icon_focesed = false; bool m_is_enabled_tick_manipulation = true; bool m_show_context_menu = false; + ManipulationState m_state = msSingleExtruder; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; @@ -929,6 +943,7 @@ private: tick(tick), gcode(code), extruder(extruder) {} bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } + bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } int tick; std::string gcode; From 4b0fe7cba4140444d45ba5a5256f9dca36fecc7b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 15 Oct 2019 15:42:30 +0200 Subject: [PATCH 07/45] Implemented custom extruder(tool) change from DoubleSlider --- src/libslic3r/Model.cpp | 15 +++++ src/libslic3r/Model.hpp | 3 + src/libslic3r/Print.cpp | 74 ++++++++++++++++++--- src/libslic3r/Print.hpp | 6 ++ src/slic3r/GUI/BackgroundSlicingProcess.hpp | 5 ++ src/slic3r/GUI/Plater.cpp | 1 + 6 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 061c5bd50..6123be037 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -586,6 +586,21 @@ std::string Model::propose_export_file_name_and_path(const std::string &new_exte return boost::filesystem::path(this->propose_export_file_name_and_path()).replace_extension(new_extension).string(); } +std::vector> Model:: get_custom_tool_changes(double default_layer_height) const +{ + std::vector> custom_tool_changes; + if (!custom_gcode_per_height.empty()) { + for (const CustomGCode& custom_gcode : custom_gcode_per_height) + if (custom_gcode.gcode == "tool_change") { + DynamicPrintConfig config; + config.set_key_value("extruder", new ConfigOptionInt(custom_gcode.extruder)); + // For correct extruders(tools) changing, we should decrease custom_gcode.height value by one default layer height + custom_tool_changes.push_back({ custom_gcode.height - default_layer_height, config }); + } + } + return custom_tool_changes; +} + ModelObject::~ModelObject() { this->clear_volumes(); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 05147f9dd..d78dbdfa6 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -836,6 +836,9 @@ public: // Propose an output path, replace extension. The new_extension shall contain the initial dot. std::string propose_export_file_name_and_path(const std::string &new_extension) const; + // from custom_gcode_per_height get just tool_change codes + std::vector> get_custom_tool_changes(double default_layer_height) const; + private: explicit Model(int) : ObjectBase(-1) { assert(this->id().invalid()); }; void assign_new_unique_ids_recursive(); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 3212082a3..d3451265e 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -636,11 +636,59 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ else m_ranges.emplace_back(t_layer_height_range(m_ranges.back().first.second, DBL_MAX), nullptr); } + + // Convert input config ranges into continuous non-overlapping sorted vector of intervals and their configs, + // considering custom_tool_change values + void assign(const t_layer_config_ranges &in, const std::vector> &custom_tool_changes) { + m_ranges.clear(); + m_ranges.reserve(in.size()); + // Input ranges are sorted lexicographically. First range trims the other ranges. + coordf_t last_z = 0; + for (const std::pair &range : in) + if (range.first.second > last_z) { + coordf_t min_z = std::max(range.first.first, 0.); + if (min_z > last_z + EPSILON) { + m_ranges.emplace_back(t_layer_height_range(last_z, min_z), nullptr); + last_z = min_z; + } + if (range.first.second > last_z + EPSILON) { + const DynamicPrintConfig* cfg = &range.second; + m_ranges.emplace_back(t_layer_height_range(last_z, range.first.second), cfg); + last_z = range.first.second; + } + } + + // add ranges for extruder changes from custom_tool_changes + for (size_t i = 0; i < custom_tool_changes.size(); i++) { + const DynamicPrintConfig* cfg = &custom_tool_changes[i].second; + coordf_t cur_Z = custom_tool_changes[i].first; + coordf_t next_Z = i == custom_tool_changes.size()-1 ? DBL_MAX : custom_tool_changes[i+1].first; + if (cur_Z > last_z + EPSILON) { + if (i==0) + m_ranges.emplace_back(t_layer_height_range(last_z, cur_Z), nullptr); + m_ranges.emplace_back(t_layer_height_range(cur_Z, next_Z), cfg); + } + else if (next_Z > last_z + EPSILON) + m_ranges.emplace_back(t_layer_height_range(last_z, next_Z), cfg); + } + + if (m_ranges.empty()) + m_ranges.emplace_back(t_layer_height_range(0, DBL_MAX), nullptr); + else if (m_ranges.back().second == nullptr) + m_ranges.back().first.second = DBL_MAX; + else if (m_ranges.back().first.second != DBL_MAX) + m_ranges.emplace_back(t_layer_height_range(m_ranges.back().first.second, DBL_MAX), nullptr); + } const DynamicPrintConfig* config(const t_layer_height_range &range) const { auto it = std::lower_bound(m_ranges.begin(), m_ranges.end(), std::make_pair< t_layer_height_range, const DynamicPrintConfig*>(t_layer_height_range(range.first - EPSILON, range.second - EPSILON), nullptr)); - assert(it != m_ranges.end()); - assert(it == m_ranges.end() || std::abs(it->first.first - range.first ) < EPSILON); - assert(it == m_ranges.end() || std::abs(it->first.second - range.second) < EPSILON); + // #ys_FIXME_COLOR + // assert(it != m_ranges.end()); + // assert(it == m_ranges.end() || std::abs(it->first.first - range.first ) < EPSILON); + // assert(it == m_ranges.end() || std::abs(it->first.second - range.second) < EPSILON); + if (it == m_ranges.end() || + std::abs(it->first.first - range.first) > EPSILON || + std::abs(it->first.second - range.second) > EPSILON ) + return nullptr; // desired range doesn't found return (it == m_ranges.end()) ? nullptr : it->second; } std::vector>::const_iterator begin() const { return m_ranges.cbegin(); } @@ -688,6 +736,13 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // The object list did not change. for (const ModelObject *model_object : m_model.objects) model_object_status.emplace(model_object->id(), ModelObjectStatus::Old); + + // But if custom gcode per layer height was changed + if (m_model.custom_gcode_per_height != model.custom_gcode_per_height) { + // we should stop background processing + update_apply_status(this->invalidate_step(psGCodeExport)); + m_model.custom_gcode_per_height = model.custom_gcode_per_height; + } } else if (model_object_list_extended(m_model, model)) { // Add new objects. Their volumes and configs will be synchronized later. update_apply_status(this->invalidate_step(psGCodeExport)); @@ -749,11 +804,6 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ delete model_object; } } - if (model.custom_gcode_per_height != m_model.custom_gcode_per_height) - { - update_apply_status(this->invalidate_step(psGCodeExport)); - m_model.custom_gcode_per_height = model.custom_gcode_per_height; - } } // 2) Map print objects including their transformation matrices. @@ -784,6 +834,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ for (PrintObject *print_object : m_objects) print_object_status.emplace(PrintObjectStatus(print_object)); + std::vector> custom_tool_changes = m_model.get_custom_tool_changes(m_default_object_config.layer_height); + // 3) Synchronize ModelObjects & PrintObjects. for (size_t idx_model_object = 0; idx_model_object < model.objects.size(); ++ idx_model_object) { ModelObject &model_object = *m_model.objects[idx_model_object]; @@ -791,7 +843,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ assert(it_status != model_object_status.end()); assert(it_status->status != ModelObjectStatus::Deleted); const ModelObject& model_object_new = *model.objects[idx_model_object]; - const_cast(*it_status).layer_ranges.assign(model_object_new.layer_config_ranges); + // ys_FIXME_COLOR + // const_cast(*it_status).layer_ranges.assign(model_object_new.layer_config_ranges); + const_cast(*it_status).layer_ranges.assign(model_object_new.layer_config_ranges, custom_tool_changes); if (it_status->status == ModelObjectStatus::New) // PrintObject instances will be added in the next loop. continue; @@ -959,6 +1013,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ PrintRegionConfig this_region_config; bool this_region_config_set = false; for (PrintObject *print_object : m_objects) { + if(m_force_update_print_regions && !custom_tool_changes.empty()) + goto print_object_end; const LayerRanges *layer_ranges; { auto it_status = model_object_status.find(ModelObjectStatus(print_object->model_object()->id())); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 6d94a515f..d5810f057 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -361,6 +361,9 @@ public: // Accessed by SupportMaterial const PrintRegion* get_region(size_t idx) const { return m_regions[idx]; } + // force update of PrintRegions, when custom_tool_change is not empty and (Re)Slicing is started + void set_force_update_print_regions(bool force_update_print_regions) { m_force_update_print_regions = force_update_print_regions; } + protected: // methods for handling regions PrintRegion* get_region(size_t idx) { return m_regions[idx]; } @@ -403,6 +406,9 @@ private: // Estimated print time, filament consumed. PrintStatistics m_print_statistics; + // flag used + bool m_force_update_print_regions = false; + // To allow GCode to set the Print's GCodeExport step status. friend class GCode; // Allow PrintObject to access m_mutex and m_cancel_callback. diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index cf5edd55f..e389c1e86 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -128,6 +128,11 @@ public: // This "finished" flag does not account for the final export of the output file (.gcode or zipped PNGs), // and it does not account for the OctoPrint scheduling. bool finished() const { return m_print->finished(); } + + void set_force_update_print_regions(bool force_update_print_regions) { + if (m_fff_print) + m_fff_print->set_force_update_print_regions(force_update_print_regions); + } private: void thread_proc(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index fc80cb306..96af17999 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2922,6 +2922,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool this->update_print_volume_state(); // Apply new config to the possibly running background task. bool was_running = this->background_process.running(); + this->background_process.set_force_update_print_regions(force_validation); Print::ApplyStatus invalidated = this->background_process.apply(this->q->model(), wxGetApp().preset_bundle->full_config()); // Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile. From 76ec1bc7e3dffad1f0705934965776fead3fedc0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 16 Oct 2019 09:45:11 +0200 Subject: [PATCH 08/45] Improved extruder_selector for DoubleSlider --- src/libslic3r/GCode.cpp | 30 +++++++++----- src/libslic3r/Model.cpp | 5 ++- src/libslic3r/Model.hpp | 2 +- src/libslic3r/Print.cpp | 3 +- src/slic3r/GUI/GUI_Preview.cpp | 70 ++++++++++++++++++++++----------- src/slic3r/GUI/GUI_Preview.hpp | 4 +- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/GUI/wxExtensions.cpp | 18 ++++----- src/slic3r/GUI/wxExtensions.hpp | 3 +- 9 files changed, 88 insertions(+), 49 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 955c76e9f..c3e780041 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1692,15 +1692,27 @@ void GCode::process_layer( } // we should add or not colorprint_change in respect to nozzle_diameter count instead of really used extruders count - if (colorprint_change && print./*extruders()*/config().nozzle_diameter.size()==1) - { - // add tag for analyzer - gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n"; - // add tag for time estimator - gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; - // #ys_FIXME_COLOR - // gcode += "M600\n"; - gcode += custom_code + "\n"; + // #ys_FIXME_COLOR + // if (colorprint_change && print./*extruders()*/config().nozzle_diameter.size()==1) + // { + // // add tag for analyzer + // gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n"; + // // add tag for time estimator + // gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; + // + // gcode += "M600\n"; + // } + if (colorprint_change) { + if (print.config().nozzle_diameter.size() == 1) + { + // add tag for analyzer + gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n"; + // add tag for time estimator + gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; + if (custom_code == "tool_change") + custom_code = "M600"; + gcode += custom_code + "\n"; + } } diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 6123be037..0bb2edfc4 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -586,14 +586,15 @@ std::string Model::propose_export_file_name_and_path(const std::string &new_exte return boost::filesystem::path(this->propose_export_file_name_and_path()).replace_extension(new_extension).string(); } -std::vector> Model:: get_custom_tool_changes(double default_layer_height) const +std::vector> Model::get_custom_tool_changes(double default_layer_height, size_t num_extruders) const { std::vector> custom_tool_changes; if (!custom_gcode_per_height.empty()) { for (const CustomGCode& custom_gcode : custom_gcode_per_height) if (custom_gcode.gcode == "tool_change") { DynamicPrintConfig config; - config.set_key_value("extruder", new ConfigOptionInt(custom_gcode.extruder)); + // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders + config.set_key_value("extruder", new ConfigOptionInt(custom_gcode.extruder > num_extruders ? 0 : custom_gcode.extruder)); // For correct extruders(tools) changing, we should decrease custom_gcode.height value by one default layer height custom_tool_changes.push_back({ custom_gcode.height - default_layer_height, config }); } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index d78dbdfa6..aac6cde06 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -837,7 +837,7 @@ public: std::string propose_export_file_name_and_path(const std::string &new_extension) const; // from custom_gcode_per_height get just tool_change codes - std::vector> get_custom_tool_changes(double default_layer_height) const; + std::vector> get_custom_tool_changes(double default_layer_height, size_t num_extruders) const; private: explicit Model(int) : ObjectBase(-1) { assert(this->id().invalid()); }; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index d3451265e..a8d905efe 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -834,7 +834,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ for (PrintObject *print_object : m_objects) print_object_status.emplace(PrintObjectStatus(print_object)); - std::vector> custom_tool_changes = m_model.get_custom_tool_changes(m_default_object_config.layer_height); + std::vector> custom_tool_changes = + m_model.get_custom_tool_changes(m_default_object_config.layer_height, num_extruders); // 3) Synchronize ModelObjects & PrintObjects. for (size_t idx_model_object = 0; idx_model_object < model.objects.size(); ++ idx_model_object) { diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 5d0deaaad..91ffa4a5a 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -500,9 +500,19 @@ void Preview::reset_sliders() void Preview::update_sliders(const std::vector& layers_z, bool keep_z_range) { m_enabled = true; + // update extruder selector + if (wxGetApp().extruders_edited_cnt() != m_extruder_selector->GetCount()-1) + { + int selection = m_extruder_selector->GetSelection(); + update_extruder_selector(); + if (selection >= m_extruder_selector->GetCount()) + selection = 0; + m_extruder_selector->SetSelection(selection); + } + update_double_slider(layers_z, keep_z_range); m_double_slider_sizer->Show((size_t)0); - if (m_slider->GetManipulationState() != DoubleSlider::msMultiExtruder) + if (m_slider->GetManipulationState() == DoubleSlider::msSingleExtruder) m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide((size_t)0); Layout(); } @@ -560,7 +570,7 @@ void Preview::on_checkbox_legend(wxCommandEvent& evt) m_canvas_widget->Refresh(); } -void Preview::update_view_type() +void Preview::update_view_type(bool slice_completed) { const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; @@ -574,8 +584,8 @@ void Preview::update_view_type() _(L("Feature type")); */ - const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty()// && - /*wxGetApp().extruders_edited_cnt()==1*/ ? + const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() && + (wxGetApp().extruders_edited_cnt()==1 || !slice_completed) ? _(L("Color Print")) : config.option("wiping_volumes_matrix")->values.size() > 1 ? _(L("Tool")) : @@ -590,25 +600,39 @@ void Preview::update_view_type() } } +void Preview::update_extruder_selector() +{ + m_extruder_selector->Clear(); + + m_extruder_selector->Append("Whole print"); + const int extruder_cnt = wxGetApp().extruders_edited_cnt(); + int i = 0; + while (i < extruder_cnt) + { + i++; + m_extruder_selector->Append(wxString::Format("Extruder %d", i)); + } +} + void Preview::create_double_slider() { m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100); // #ys_FIXME_COLOR // m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); - auto extruder_selector = new wxComboBox(this, wxID_ANY); - extruder_selector->Append("Whole print"); - int extruder_cnt = wxGetApp().extruders_edited_cnt(); - int i = 0; - while (i < extruder_cnt) + m_extruder_selector = new wxComboBox(this, wxID_ANY); + update_extruder_selector(); + m_extruder_selector->SetSelection(0); + m_extruder_selector->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) { - i++; - extruder_selector->Append(wxString::Format("Extruder %d", i)); - } - extruder_selector->SetSelection(0); + m_slider->SetManipulationState(m_extruder_selector->GetSelection() == 0 ? + DoubleSlider::msMultiExtruderWholePrint : + DoubleSlider::msMultiExtruder); + }); + m_extruder_selector->Disable(); // temporary disabled to suppress extruder selection auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(extruder_selector, 0, wxEXPAND, 0); + sizer->Add(m_extruder_selector, 0, wxEXPAND, 0); sizer->Add(m_slider, 1, wxEXPAND, 0); m_double_slider_sizer->Add(sizer, 0, wxEXPAND, 0); @@ -627,7 +651,7 @@ void Preview::create_double_slider() model.custom_gcode_per_height = m_slider->GetTicksValues_(); m_schedule_background_process(); - update_view_type(); + update_view_type(false); reload_print(); }); @@ -733,16 +757,14 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee // m_slider->EnableTickManipulation(color_print_enable); m_slider->EnableTickManipulation(color_print_enable); - m_slider->SetManipulationState(DoubleSlider::msSingleExtruder); - if (color_print_enable) { - const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; - if (cfg.opt("nozzle_diameter")->values.size() > 1) { - // ys_TODO : fill is_detected_one_extruder_print value - bool is_detected_one_extruder_print = wxGetApp().plater()->fff_print().extruders().size() == 1; - m_slider->SetManipulationState(is_detected_one_extruder_print ? - DoubleSlider::msMultiExtruderSimple : DoubleSlider::msMultiExtruder); - } + if (color_print_enable && wxGetApp().extruders_edited_cnt() > 1) { + //bool is_detected_full_print = //wxGetApp().plater()->fff_print().extruders().size() == 1; + m_slider->SetManipulationState(m_extruder_selector->GetSelection()==0 ? + DoubleSlider::msMultiExtruderWholePrint : DoubleSlider::msMultiExtruder); } + else + m_slider->SetManipulationState(DoubleSlider::msSingleExtruder); + } // #ys_FIXME_COLOR void Preview::check_slider_values(std::vector& ticks_from_config, diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 551900277..574f827e2 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -103,6 +103,7 @@ class Preview : public wxPanel bool m_enabled; DoubleSlider* m_slider {nullptr}; + wxComboBox* m_extruder_selector {nullptr}; public: Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, @@ -129,7 +130,8 @@ public: void move_double_slider(wxKeyEvent& evt); void edit_double_slider(wxKeyEvent& evt); - void update_view_type(); + void update_view_type(bool slice_completed); + void update_extruder_selector(); bool is_loaded() const { return m_loaded; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 96af17999..477a0b242 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4702,7 +4702,7 @@ void Plater::reslice() p->show_action_buttons(true); // update type of preview - p->preview->update_view_type(); + p->preview->update_view_type(true); } void Plater::reslice_SLA_supports(const ModelObject &object, bool postpone_error_messages) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index e6e569939..e9f5ac329 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3056,8 +3056,8 @@ wxString DoubleSlider::get_tooltip(bool is_revert_icon_focused) tooltip = tick_code_it == m_ticks_.end() ? _(L("Add color change")) : tick_code_it->gcode == "M600" ? _(L("Delete color change")) : tick_code_it->gcode == "M25" ? _(L("Delete pause")) : - tick_code_it->gcode == "tool_change" ? - from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) : + tick_code_it->gcode == "tool_change" ? ( m_state == msSingleExtruder ? _(L("Delete color change")) : + from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) ) : from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); } @@ -3329,7 +3329,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) if (m_show_context_menu) { wxMenu menu; - if (m_state == msMultiExtruderSimple) + if (m_state == msMultiExtruderWholePrint) { const wxString name = _(L("Change extruder")); @@ -3349,9 +3349,8 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) menu.AppendSubMenu(change_extruder_menu, name, _(L("Use another extruder"))); } } - - if (m_state != msMultiExtruderSimple) - append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", + else + append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", [this](wxCommandEvent&) { add_code("M600"); }, "colorchange_add_off.png", &menu); append_menu_item(&menu, wxID_ANY, _(L("Add pause SD print")) + " (M25)", "", @@ -3382,16 +3381,17 @@ void DoubleSlider::add_code(std::string code) wxString msg_header = from_u8((boost::format(_utf8(L("Custom Gcode on current layer (%1% mm)."))) % m_values[tick]).str()); // get custom gcode - wxTextEntryDialog dlg(nullptr, msg_text, msg_header, wxEmptyString, + wxTextEntryDialog dlg(nullptr, msg_text, msg_header, m_custom_gcode, wxTextEntryDialogStyle | wxTE_MULTILINE); if (dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty()) return; - code = dlg.GetValue().c_str(); + m_custom_gcode = dlg.GetValue(); + code = m_custom_gcode.c_str(); } int extruder = 0; - if (m_state == msMultiExtruderSimple) + if (m_state == msMultiExtruderWholePrint) extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); m_ticks_.insert(TICK_CODE(tick, code, extruder)); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index e874dbf38..b7fd81db3 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -809,7 +809,7 @@ public: static enum ManipulationState { msSingleExtruder, // single extruder printer preset is selected msMultiExtruder, // multiple extruder printer preset is selected - msMultiExtruderSimple // multiple extruder printer preset is selected, but one-extruder print is detected + msMultiExtruderWholePrint // multiple extruder printer preset is selected, and "Whole print" is selected }; void SetManipulationState(ManipulationState state) { m_state = state; @@ -903,6 +903,7 @@ private: bool m_is_enabled_tick_manipulation = true; bool m_show_context_menu = false; ManipulationState m_state = msSingleExtruder; + wxString m_custom_gcode = wxEmptyString; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; From ea8695c06cb251250f542c7237b1dbbe92401632 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 16 Oct 2019 12:03:51 +0200 Subject: [PATCH 09/45] Fixed GCode export for color_print extensions. M25 is changed to M601 --- src/libslic3r/GCode.cpp | 5 +++-- src/slic3r/GUI/wxExtensions.cpp | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c3e780041..1a4d58edc 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1703,13 +1703,14 @@ void GCode::process_layer( // gcode += "M600\n"; // } if (colorprint_change) { - if (print.config().nozzle_diameter.size() == 1) + const bool single_material_print = print.config().nozzle_diameter.size() == 1; + if (single_material_print || custom_code != "tool_change") { // add tag for analyzer gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n"; // add tag for time estimator gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; - if (custom_code == "tool_change") + if (single_material_print && custom_code == "tool_change") custom_code = "M600"; gcode += custom_code + "\n"; } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index e9f5ac329..a103e6e0d 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3055,7 +3055,7 @@ wxString DoubleSlider::get_tooltip(bool is_revert_icon_focused) const auto tick_code_it = m_ticks_.find(tick); tooltip = tick_code_it == m_ticks_.end() ? _(L("Add color change")) : tick_code_it->gcode == "M600" ? _(L("Delete color change")) : - tick_code_it->gcode == "M25" ? _(L("Delete pause")) : + tick_code_it->gcode == "M601" ? _(L("Delete pause")) : tick_code_it->gcode == "tool_change" ? ( m_state == msSingleExtruder ? _(L("Delete color change")) : from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) ) : from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); @@ -3353,8 +3353,8 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", [this](wxCommandEvent&) { add_code("M600"); }, "colorchange_add_off.png", &menu); - append_menu_item(&menu, wxID_ANY, _(L("Add pause SD print")) + " (M25)", "", - [this](wxCommandEvent&) { add_code("M25"); }, "pause_add.png", &menu); + append_menu_item(&menu, wxID_ANY, _(L("Add pause SD print")) + " (M601)", "", + [this](wxCommandEvent&) { add_code("M601"); }, "pause_add.png", &menu); append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "", [this](wxCommandEvent&) { add_code(""); }, "add_gcode", &menu); From 33ba6fe4c68fdcac277f1aeb712e3548a68e3901 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 18 Oct 2019 12:35:35 +0200 Subject: [PATCH 10/45] Implemented possibility to set extruder sequence for whole print --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/ExtruderSequenceDialog.cpp | 197 ++++++++++++++++++++++ src/slic3r/GUI/ExtruderSequenceDialog.hpp | 45 +++++ src/slic3r/GUI/GUI_ObjectList.cpp | 16 +- src/slic3r/GUI/GUI_Preview.cpp | 13 +- src/slic3r/GUI/GUI_Preview.hpp | 5 +- src/slic3r/GUI/Plater.cpp | 3 + src/slic3r/GUI/wxExtensions.cpp | 120 ++++++++++++- src/slic3r/GUI/wxExtensions.hpp | 73 +++++++- 9 files changed, 445 insertions(+), 29 deletions(-) create mode 100644 src/slic3r/GUI/ExtruderSequenceDialog.cpp create mode 100644 src/slic3r/GUI/ExtruderSequenceDialog.hpp diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 17b76e629..253488cd4 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -105,6 +105,8 @@ set(SLIC3R_GUI_SOURCES GUI/Camera.hpp GUI/wxExtensions.cpp GUI/wxExtensions.hpp + GUI/ExtruderSequenceDialog.cpp + GUI/ExtruderSequenceDialog.hpp GUI/WipeTowerDialog.cpp GUI/WipeTowerDialog.hpp GUI/RammingChart.cpp diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.cpp b/src/slic3r/GUI/ExtruderSequenceDialog.cpp new file mode 100644 index 000000000..408826957 --- /dev/null +++ b/src/slic3r/GUI/ExtruderSequenceDialog.cpp @@ -0,0 +1,197 @@ +#include "ExtruderSequenceDialog.hpp" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "GUI.hpp" +#include "GUI_App.hpp" +#include "I18N.hpp" +#include "OptionsGroup.hpp" + + +namespace Slic3r { +namespace GUI { + +ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequence& sequence) + : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Set extruder sequence")), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), + m_sequence(sequence) +{ + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + SetDoubleBuffered(true); + SetFont(wxGetApp().normal_font()); + + auto main_sizer = new wxBoxSizer(wxVERTICAL); + const int em = wxGetApp().em_unit(); + + m_bmp_del = ScalableBitmap(this, "remove_copies"); + m_bmp_add = ScalableBitmap(this, "add_copies"); + + auto option_sizer = new wxBoxSizer(wxVERTICAL); + + auto intervals_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder change for every"))+ " : "); + auto intervals_box_sizer = new wxStaticBoxSizer(intervals_box, wxVERTICAL); + + m_intervals_grid_sizer = new wxFlexGridSizer(3, 5, em); + + auto editor_sz = wxSize(4*em, wxDefaultCoord); + + wxRadioButton* rb_by_layers = new wxRadioButton(this, wxID_ANY, ""); + rb_by_layers->Bind(wxEVT_RADIOBUTTON, [this](wxEvent&) { m_sequence.is_mm_intervals = false; }); + + wxStaticText* st_by_layers = new wxStaticText(this, wxID_ANY, _(L("layers"))); + m_interval_by_layers = new wxTextCtrl(this, wxID_ANY, + wxString::Format("%d", m_sequence.interval_by_layers), + wxDefaultPosition, editor_sz); + m_interval_by_layers->Bind(wxEVT_TEXT, [this, rb_by_layers](wxEvent&) + { + wxString str = m_interval_by_layers->GetValue(); + if (str.IsEmpty()) { + m_interval_by_layers->SetValue(wxString::Format("%d", m_sequence.interval_by_layers)); + return; + } + + m_sequence.interval_by_layers = wxAtoi(str); + + m_sequence.is_mm_intervals = false; + rb_by_layers->SetValue(true); + }); + + m_intervals_grid_sizer->Add(rb_by_layers, 0, wxALIGN_CENTER_VERTICAL); + m_intervals_grid_sizer->Add(m_interval_by_layers,0, wxALIGN_CENTER_VERTICAL); + m_intervals_grid_sizer->Add(st_by_layers,0, wxALIGN_CENTER_VERTICAL); + + wxRadioButton* rb_by_mm = new wxRadioButton(this, wxID_ANY, ""); + rb_by_mm->Bind(wxEVT_RADIOBUTTON, [this](wxEvent&) { m_sequence.is_mm_intervals = true; }); + rb_by_mm->SetValue(m_sequence.is_mm_intervals); + + wxStaticText* st_by_mm = new wxStaticText(this, wxID_ANY, _(L("mm"))); + m_interval_by_mm = new wxTextCtrl(this, wxID_ANY, + double_to_string(sequence.interval_by_mm), + wxDefaultPosition, editor_sz); + m_interval_by_mm->Bind(wxEVT_TEXT, [this, rb_by_mm](wxEvent&) + { + wxString str = m_interval_by_mm->GetValue(); + if (str.IsEmpty()) { + m_interval_by_mm->SetValue(wxString::Format("%d", m_sequence.interval_by_mm)); + return; + } + + str.Replace(",", ".", false); + double val; + if (str == "." || !str.ToCDouble(&val)) + val = 0.0; + + m_sequence.interval_by_mm = val; + + m_sequence.is_mm_intervals = true; + rb_by_mm->SetValue(true); + }); + + m_intervals_grid_sizer->Add(rb_by_mm, 0, wxALIGN_CENTER_VERTICAL); + m_intervals_grid_sizer->Add(m_interval_by_mm,0, wxALIGN_CENTER_VERTICAL); + m_intervals_grid_sizer->Add(st_by_mm,0, wxALIGN_CENTER_VERTICAL); + + intervals_box_sizer->Add(m_intervals_grid_sizer, 0, wxLEFT, em); + option_sizer->Add(intervals_box_sizer, 0, wxEXPAND); + + + auto extruders_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder(tool) sequence"))+ " : "); + auto extruders_box_sizer = new wxStaticBoxSizer(extruders_box, wxVERTICAL); + + m_extruders_grid_sizer = new wxFlexGridSizer(3, 5, em); + + apply_extruder_sequence(); + + extruders_box_sizer->Add(m_extruders_grid_sizer, 0, wxALL, em); + option_sizer->Add(extruders_box_sizer, 0, wxEXPAND | wxTOP, em); + + main_sizer->Add(option_sizer, 0, wxEXPAND | wxALL, em); + + wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL); + main_sizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, em); + + SetSizer(main_sizer); + main_sizer->SetSizeHints(this); +} + +void ExtruderSequenceDialog::apply_extruder_sequence() +{ + Freeze(); + m_extruders_grid_sizer->Clear(true); + + for (size_t extruder=0; extruder < m_sequence.extruders.size(); ++extruder) + { + wxBitmapComboBox* extruder_selector = nullptr; + apply_extruder_selector(&extruder_selector, this); + extruder_selector->SetSelection(m_sequence.extruders[extruder]); + + extruder_selector->Bind(wxEVT_COMBOBOX, [this, extruder_selector, extruder](wxCommandEvent& evt) + { + m_sequence.extruders[extruder] = extruder_selector->GetSelection(); + evt.StopPropagation(); + }); + + auto del_btn = new ScalableButton(this, wxID_ANY, m_bmp_del); + del_btn->SetToolTip(_(L("Remove extruder from sequence"))); + if (m_sequence.extruders.size()==1) + del_btn->Disable(); + + del_btn->Bind(wxEVT_BUTTON, [this, extruder](wxEvent&) { + m_sequence.delete_extruder(extruder); + apply_extruder_sequence(); + }); + + auto add_btn = new ScalableButton(this, wxID_ANY, m_bmp_add); + add_btn->SetToolTip(_(L("Add extruder to sequence"))); + + add_btn->Bind(wxEVT_BUTTON, [this, extruder](wxEvent&) { + m_sequence.add_extruder(extruder); + apply_extruder_sequence(); + }); + + m_extruders_grid_sizer->Add(extruder_selector); + m_extruders_grid_sizer->Add(del_btn); + m_extruders_grid_sizer->Add(add_btn); + } + + Fit(); + Refresh(); + + Thaw(); +} + +void ExtruderSequenceDialog::on_dpi_changed(const wxRect& suggested_rect) +{ + SetFont(wxGetApp().normal_font()); + + m_bmp_add.msw_rescale(); + m_bmp_del.msw_rescale(); + + const int em = em_unit(); + + m_intervals_grid_sizer->SetHGap(em); + m_intervals_grid_sizer->SetVGap(em); + m_extruders_grid_sizer->SetHGap(em); + m_extruders_grid_sizer->SetVGap(em); + + msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL }); + + // wxSize size = get_size(); + // SetMinSize(size); + + Fit(); + Refresh(); +} + +} +} + + diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.hpp b/src/slic3r/GUI/ExtruderSequenceDialog.hpp new file mode 100644 index 000000000..3efd9e3a2 --- /dev/null +++ b/src/slic3r/GUI/ExtruderSequenceDialog.hpp @@ -0,0 +1,45 @@ +#ifndef slic3r_GUI_ExtruderSequenceDialog_hpp_ +#define slic3r_GUI_ExtruderSequenceDialog_hpp_ + +#include "GUI_Utils.hpp" +#include "wxExtensions.hpp" + +class wxTextCtrl; +class wxFlexGridSizer; + +namespace Slic3r { +namespace GUI { + +// ---------------------------------------------------------------------------- +// ExtruderSequenceDialog: a node inside ObjectDataViewModel +// ---------------------------------------------------------------------------- + +class ExtruderSequenceDialog: public DPIDialog +{ + ScalableBitmap m_bmp_del; + ScalableBitmap m_bmp_add; + DoubleSlider::ExtrudersSequence m_sequence; + + wxTextCtrl* m_interval_by_layers {nullptr}; + wxTextCtrl* m_interval_by_mm {nullptr}; + + wxFlexGridSizer* m_intervals_grid_sizer {nullptr}; + wxFlexGridSizer* m_extruders_grid_sizer {nullptr}; +public: + ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequence& sequence); + + ~ExtruderSequenceDialog() {} + + DoubleSlider::ExtrudersSequence GetValue() { return m_sequence; } + +protected: + void apply_extruder_sequence(); + void on_dpi_changed(const wxRect& suggested_rect) override; + +}; + +} +} + + +#endif // slic3r_GUI_ExtruderSequenceDialog_hpp_ diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index dc48a218c..377c26e79 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -895,10 +895,12 @@ void ObjectList::extruder_editing() if (!item || !(m_objects_model->GetItemType(item) & (itVolume | itObject))) return; + // ! #ys Use ApplyExtruderSelector instead this code + /* std::vector icons = get_extruder_color_icons(); if (icons.empty()) return; - + */ const int column_width = GetColumn(colExtruder)->GetWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X) + 5; wxPoint pos = get_mouse_position_in_control(); @@ -906,6 +908,10 @@ void ObjectList::extruder_editing() pos.x = GetColumn(colName)->GetWidth() + GetColumn(colPrint)->GetWidth() + 5; pos.y -= GetTextExtent("m").y; + apply_extruder_selector(&m_extruder_editor, this, L("default"), pos, size); + + // ! #ys Use ApplyExtruderSelector instead this code + /* if (!m_extruder_editor) m_extruder_editor = new wxBitmapComboBox(this, wxID_ANY, wxEmptyString, pos, size, 0, nullptr, wxCB_READONLY); @@ -928,6 +934,7 @@ void ObjectList::extruder_editing() m_extruder_editor->Append(wxString::Format("%d", i), *bmp); ++i; } + */ m_extruder_editor->SetSelection(m_objects_model->GetExtruderNumber(item)); auto set_extruder = [this]() @@ -948,13 +955,6 @@ void ObjectList::extruder_editing() set_extruder(); evt.StopPropagation(); }); - /* - m_extruder_editor->Bind(wxEVT_KILL_FOCUS, [set_extruder](wxFocusEvent& evt) - { - set_extruder(); - evt.Skip(); - });*/ - } void ObjectList::copy() diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 91ffa4a5a..e462e7c1d 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -602,16 +602,7 @@ void Preview::update_view_type(bool slice_completed) void Preview::update_extruder_selector() { - m_extruder_selector->Clear(); - - m_extruder_selector->Append("Whole print"); - const int extruder_cnt = wxGetApp().extruders_edited_cnt(); - int i = 0; - while (i < extruder_cnt) - { - i++; - m_extruder_selector->Append(wxString::Format("Extruder %d", i)); - } + apply_extruder_selector(&m_extruder_selector, this, L("Whole print")); } void Preview::create_double_slider() @@ -620,7 +611,6 @@ void Preview::create_double_slider() // #ys_FIXME_COLOR // m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); - m_extruder_selector = new wxComboBox(this, wxID_ANY); update_extruder_selector(); m_extruder_selector->SetSelection(0); m_extruder_selector->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) @@ -628,6 +618,7 @@ void Preview::create_double_slider() m_slider->SetManipulationState(m_extruder_selector->GetSelection() == 0 ? DoubleSlider::msMultiExtruderWholePrint : DoubleSlider::msMultiExtruder); + evt.StopPropagation(); }); m_extruder_selector->Disable(); // temporary disabled to suppress extruder selection diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 574f827e2..64b8baa7f 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -13,6 +13,7 @@ class wxBoxSizer; class wxStaticText; class wxChoice; class wxComboCtrl; +class wxBitmapComboBox; class wxCheckBox; class DoubleSlider; @@ -102,8 +103,8 @@ class Preview : public wxPanel bool m_loaded; bool m_enabled; - DoubleSlider* m_slider {nullptr}; - wxComboBox* m_extruder_selector {nullptr}; + DoubleSlider* m_slider {nullptr}; + wxBitmapComboBox* m_extruder_selector {nullptr}; public: Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 477a0b242..1cbbfda5a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4981,6 +4981,9 @@ std::vector Plater::get_extruder_colors_from_plater_config() const return extruder_colors; extruder_colors = (config->option("extruder_colour"))->values; + if (!wxGetApp().plater()) + return extruder_colors; + const std::vector& filament_colours = (p->config->option("filament_colour"))->values; for (size_t i = 0; i < extruder_colors.size(); ++i) if (extruder_colors[i] == "" && i < filament_colours.size()) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index a103e6e0d..4528a14cc 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -22,6 +22,7 @@ #include "I18N.hpp" #include "GUI_Utils.hpp" #include "PresetBundle.hpp" +#include "ExtruderSequenceDialog.hpp" #include "../Utils/MacDarkMode.hpp" using Slic3r::GUI::from_u8; @@ -449,7 +450,7 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, Slic3r::GUI::BitmapCache* m_bitmap_cache = nullptr; -/*static*/ std::vector get_extruder_color_icons() +std::vector get_extruder_color_icons() { // Create the bitmap with color bars. std::vector bmps; @@ -493,6 +494,42 @@ static wxBitmap get_extruder_color_icon(size_t extruder_idx) return *bmps[extruder_idx >= bmps.size() ? 0 : extruder_idx]; } +void apply_extruder_selector(wxBitmapComboBox** ctrl, + wxWindow* parent, + const std::string& first_item/* = ""*/, + wxPoint pos/* = wxDefaultPosition*/, + wxSize size/* = wxDefaultSize*/) +{ + std::vector icons = get_extruder_color_icons(); + if (icons.empty()) + return; + + if (!*ctrl) + *ctrl = new wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, pos, size, + 0, nullptr, wxCB_READONLY); + else + { + (*ctrl)->SetPosition(pos); + (*ctrl)->SetMinSize(size); + (*ctrl)->SetSize(size); + (*ctrl)->Clear(); + } + + int i = 0; + for (wxBitmap* bmp : icons) { + if (i == 0) { + if (!first_item.empty()) + (*ctrl)->Append(_(first_item), *bmp); + ++i; + } + + (*ctrl)->Append(wxString::Format("%d", i), *bmp); + ++i; + } + (*ctrl)->SetSelection(0); +} + + // ***************************************************************************** // ---------------------------------------------------------------------------- // ObjectDataViewModelNode @@ -2248,6 +2285,8 @@ DoubleSlider::DoubleSlider( wxWindow *parent, m_bmp_revert = ScalableBitmap(this, "undo"); m_revert_icon_dim = m_bmp_revert.bmp().GetSize().x; + m_bmp_cog = ScalableBitmap(this, "cog"); + m_cog_icon_dim = m_bmp_cog.bmp().GetSize().x; m_selection = ssUndef; @@ -2306,6 +2345,8 @@ void DoubleSlider::msw_rescale() m_bmp_revert.msw_rescale(); m_revert_icon_dim = m_bmp_revert.bmp().GetSize().x; + m_bmp_cog.msw_rescale(); + m_cog_icon_dim = m_bmp_cog.bmp().GetSize().x; SLIDER_MARGIN = 4 + Slic3r::GUI::wxGetApp().em_unit(); @@ -2610,6 +2651,9 @@ void DoubleSlider::render() //draw revert bitmap (if it's shown) draw_revert_icon(dc); + + //draw cog bitmap (if it's shown) + draw_cog_icon(dc); } void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end) @@ -2880,6 +2924,24 @@ void DoubleSlider::draw_revert_icon(wxDC& dc) m_rect_revert_icon = wxRect(x_draw, y_draw, m_revert_icon_dim, m_revert_icon_dim); } +void DoubleSlider::draw_cog_icon(wxDC& dc) +{ + if (m_state != msMultiExtruderWholePrint) + return; + + int width, height; + get_size(&width, &height); + + wxCoord x_draw, y_draw; + is_horizontal() ? x_draw = width-2 : x_draw = width - m_cog_icon_dim - 2; + is_horizontal() ? y_draw = height - m_cog_icon_dim - 2 : y_draw = height-2; + + dc.DrawBitmap(m_bmp_cog.bmp(), x_draw, y_draw); + + //update rect of the lock/unlock icon + m_rect_cog_icon = wxRect(x_draw, y_draw, m_cog_icon_dim, m_cog_icon_dim); +} + void DoubleSlider::update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection) { const wxRect& rect = wxRect(begin_x, begin_y, m_thumb_size.x, m_thumb_size.y); @@ -2990,6 +3052,46 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) m_ticks_.clear(); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } + else if (is_point_in_rect(pos, m_rect_cog_icon) && m_state == msMultiExtruderWholePrint) { + // show dialog for set extruder sequence + Slic3r::GUI::ExtruderSequenceDialog dlg(m_extruders_sequence); + if (dlg.ShowModal() != wxID_OK) + return; + + m_extruders_sequence = dlg.GetValue(); + + m_ticks_.erase(std::remove_if(m_ticks_.begin(), m_ticks_.end(), + [](TICK_CODE tick) { return tick.gcode == "tool_change"; }), m_ticks_.end()); + + int tick = 0; + double value = 0.0; + int extruder = 0; + const int extr_cnt = m_extruders_sequence.extruders.size(); + + while (tick <= m_max_value) + { + m_ticks_.insert(TICK_CODE(tick, "tool_change", m_extruders_sequence.extruders[extruder]+1)); + + extruder++; + if (extruder == extr_cnt) + extruder = 0; + if (m_extruders_sequence.is_mm_intervals) + { + value += m_extruders_sequence.interval_by_mm; + auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); + + if (it == m_values.end()) + break; + + tick = it - m_values.begin(); + } + else + tick += m_extruders_sequence.interval_by_layers; + } + + // m_ticks_.clear(); + wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + } else detect_selected_slider(pos); @@ -3042,13 +3144,16 @@ void DoubleSlider::correct_higher_value() m_lower_value = m_higher_value; } -wxString DoubleSlider::get_tooltip(bool is_revert_icon_focused) +wxString DoubleSlider::get_tooltip(IconFocus icon_focus) { wxString tooltip(wxEmptyString); if (m_is_one_layer_icon_focesed) tooltip = _(L("One layer mode")); - if (is_revert_icon_focused) + + if (icon_focus == ifRevert) tooltip = _(L("Discard all custom changes")); + if (icon_focus == ifCog) + tooltip = _(L("Set extruder sequence for whole print")); else if (m_is_action_icon_focesed) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; @@ -3072,13 +3177,16 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) const wxPoint pos = event.GetLogicalPosition(dc); m_is_one_layer_icon_focesed = is_point_in_rect(pos, m_rect_one_layer_icon); - bool is_revert_icon_focused = false; + IconFocus icon_focus = ifNone; if (!m_is_left_down && !m_is_one_layer) { m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); // #ys_FIXME_COLOR // is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon); - is_revert_icon_focused = !m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon); + if (!m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon)) + icon_focus = ifRevert; + else if (is_point_in_rect(pos, m_rect_cog_icon)) + icon_focus = ifCog; } else if (m_is_left_down || m_is_right_down) { if (m_selection == ssLower) { @@ -3103,7 +3211,7 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) // const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) : // m_is_action_icon_focesed ? _(L("Add/Del color change")) : // is_revert_icon_focused ? _(L("Discard all color changes")) : ""; - this->SetToolTip(get_tooltip(is_revert_icon_focused)); + this->SetToolTip(get_tooltip(icon_focus)); if (action) { diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index b7fd81db3..ce5e58a6a 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -49,6 +49,8 @@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, std::function cb, wxEvtHandler* event_handler); class wxDialog; +class wxBitmapComboBox; + void edit_tooltip(wxString& tooltip); void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector& btn_ids); int em_unit(wxWindow* win); @@ -57,6 +59,11 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt = 16, const bool is_horizontal = false, const bool grayscale = false); std::vector get_extruder_color_icons(); +void apply_extruder_selector(wxBitmapComboBox** ctrl, + wxWindow* parent, + const std::string& first_item = "", + wxPoint pos = wxDefaultPosition, + wxSize size = wxDefaultSize); class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup { @@ -750,6 +757,11 @@ enum TicksAction{ class DoubleSlider : public wxControl { + enum IconFocus { + ifNone, + ifRevert, + ifCog + }; public: DoubleSlider( wxWindow *parent, @@ -806,7 +818,7 @@ public: EnableTickManipulation(false); } - static enum ManipulationState { + enum ManipulationState { msSingleExtruder, // single extruder printer preset is selected msMultiExtruder, // multiple extruder printer preset is selected msMultiExtruderWholePrint // multiple extruder printer preset is selected, and "Whole print" is selected @@ -850,6 +862,7 @@ protected: void draw_colored_band(wxDC& dc); void draw_one_layer_icon(wxDC& dc); void draw_revert_icon(wxDC& dc); + void draw_cog_icon(wxDC &dc); void draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection); void draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, SelectedSlider selection); void draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const; @@ -858,7 +871,7 @@ protected: void detect_selected_slider(const wxPoint& pt); void correct_lower_value(); void correct_higher_value(); - wxString get_tooltip(bool is_revert_icon_focused); + wxString get_tooltip(IconFocus icon_focus); void move_current_thumb(const bool condition); void action_tick(const TicksAction action); void enter_window(wxMouseEvent& event, const bool enter); @@ -893,6 +906,7 @@ private: ScalableBitmap m_bmp_one_layer_unlock_on; ScalableBitmap m_bmp_one_layer_unlock_off; ScalableBitmap m_bmp_revert; + ScalableBitmap m_bmp_cog; SelectedSlider m_selection; bool m_is_left_down = false; bool m_is_right_down = false; @@ -910,10 +924,12 @@ private: wxRect m_rect_tick_action; wxRect m_rect_one_layer_icon; wxRect m_rect_revert_icon; + wxRect m_rect_cog_icon; wxSize m_thumb_size; int m_tick_icon_dim; int m_lock_icon_dim; int m_revert_icon_dim; + int m_cog_icon_dim; long m_style; float m_label_koef = 1.0; @@ -945,6 +961,16 @@ private: bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } + TICK_CODE operator=(const TICK_CODE& other) const { + TICK_CODE ret_val(other.tick, other.gcode, other.extruder); + return ret_val; + } + TICK_CODE& operator=(const TICK_CODE& other) { + this->tick = other.tick; + this->gcode = other.gcode; + this->extruder = other.extruder; + return *this; + } int tick; std::string gcode; @@ -952,6 +978,49 @@ private: }; std::set m_ticks_; + +public: + struct ExtrudersSequence + { + bool is_mm_intervals; + double interval_by_mm; + int interval_by_layers; + std::vector extruders; + + ExtrudersSequence() : + is_mm_intervals(true), + interval_by_mm(3.0), + interval_by_layers(10), + extruders({ 0 }) {} + + ExtrudersSequence(const ExtrudersSequence& other) : + is_mm_intervals(other.is_mm_intervals), + interval_by_mm(other.interval_by_mm), + interval_by_layers(other.interval_by_layers), + extruders(other.extruders) {} + + ExtrudersSequence& operator=(const ExtrudersSequence& other) { + this->is_mm_intervals = other.is_mm_intervals; + this->interval_by_mm = other.interval_by_mm; + this->interval_by_layers= other.interval_by_layers; + this->extruders = other.extruders; + + return *this; + } + + void add_extruder(size_t pos) + { + extruders.insert(extruders.begin() + pos+1, size_t(0)); + } + + void delete_extruder(size_t pos) + { + if (extruders.size() == 1) + return;// last item can't be deleted + extruders.erase(extruders.begin() + pos); + } + } + m_extruders_sequence; }; From 2a5cf689a44b4758ab7f64d233d75c9f32c08101 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 24 Oct 2019 08:43:27 +0200 Subject: [PATCH 11/45] Preview mode: Implemented a show of the part printed by selected extruder --- src/slic3r/GUI/GLCanvas3D.cpp | 49 +++++++++++++++++++++++----------- src/slic3r/GUI/GLCanvas3D.hpp | 2 ++ src/slic3r/GUI/GUI_Preview.cpp | 37 +++++++++++++++++-------- src/slic3r/GUI/GUI_Preview.hpp | 3 ++- 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2dee58136..146cdd75f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2094,20 +2094,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, contained_min_one && !m_model->objects.empty() && state != ModelInstance::PVS_Partly_Outside)); - -// #ys_FIXME_delete_after_testing -// bool contained = m_volumes.check_outside_state(m_config, &state); -// if (!contained) -// { -// _set_warning_texture(WarningTexture::ObjectOutside, true); -// post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, state == ModelInstance::PVS_Fully_Outside)); -// } -// else -// { -// m_volumes.reset_outside_state(); -// _set_warning_texture(WarningTexture::ObjectOutside, false); -// post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, !m_model->objects.empty())); -// } } else { @@ -4748,6 +4734,8 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c // Maximum size of an allocation block: 32MB / sizeof(float) BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start" << m_volumes.log_memory_info() << log_memory_info(); + const bool is_selected_separate_extruder = m_selected_extruder > 0 && ctxt.color_by_color_print(); + //FIXME Improve the heuristics for a grain size. size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1)); tbb::spin_mutex new_volume_mutex; @@ -4765,7 +4753,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c const size_t volumes_cnt_initial = m_volumes.volumes.size(); tbb::parallel_for( tbb::blocked_range(0, ctxt.layers.size(), grain_size), - [&ctxt, &new_volume](const tbb::blocked_range& range) { + [&ctxt, &new_volume, is_selected_separate_extruder, this](const tbb::blocked_range& range) { GLVolumePtrs vols; std::vector color_print_layer_to_glvolume; auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { @@ -4801,6 +4789,26 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c vol->indexed_vertex_array.reserve(VERTEX_BUFFER_RESERVE_SIZE / 6); for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { const Layer *layer = ctxt.layers[idx_layer]; + + if (is_selected_separate_extruder) + { + bool at_least_one_has_correct_extruder = false; + for (const LayerRegion* layerm : layer->regions()) + { + if (layerm->slices.surfaces.empty()) + continue; + const PrintRegionConfig& cfg = layerm->region()->config(); + if (cfg.perimeter_extruder.value == m_selected_extruder || + cfg.infill_extruder.value == m_selected_extruder || + cfg.solid_infill_extruder.value == m_selected_extruder ) { + at_least_one_has_correct_extruder = true; + break; + } + } + if (!at_least_one_has_correct_extruder) + continue; + } + for (GLVolume *vol : vols) if (vol->print_zs.empty() || vol->print_zs.back() != layer->print_z) { vol->print_zs.push_back(layer->print_z); @@ -4809,6 +4817,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c } for (const Point © : *ctxt.shifted_copies) { for (const LayerRegion *layerm : layer->regions()) { + if (is_selected_separate_extruder) + { + const PrintRegionConfig& cfg = layerm->region()->config(); + if (cfg.perimeter_extruder.value != m_selected_extruder || + cfg.infill_extruder.value != m_selected_extruder || + cfg.solid_infill_extruder.value != m_selected_extruder) + continue; + } if (ctxt.has_perimeters) _3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy, volume(idx_layer, layerm->region()->config().perimeter_extruder.value, 0)); @@ -5157,10 +5173,13 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - populate volumes" << m_volumes.log_memory_info() << log_memory_info(); // populates volumes + const bool is_selected_separate_extruder = m_selected_extruder > 0 && preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint; for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers) { for (const GCodePreviewData::Extrusion::Path& path : layer.paths) { + if (is_selected_separate_extruder && path.extruder_id != m_selected_extruder - 1) + continue; std::vector> &filters = roles_filters[size_t(path.extrusion_role)]; auto key = std::make_pair(Helper::path_filter(preview_data.extrusion.view_type, path), nullptr); auto it_filter = std::lower_bound(filters.begin(), filters.end(), key); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2c2676ae7..e5e845304 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -436,6 +436,7 @@ private: #endif // ENABLE_RENDER_STATISTICS int m_imgui_undo_redo_hovered_pos{ -1 }; + int m_selected_extruder; public: GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar); @@ -578,6 +579,7 @@ public: int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; } int get_first_hover_volume_idx() const { return m_hover_volume_idxs.empty() ? -1 : m_hover_volume_idxs.front(); } + void set_selected_extruder(int extruder) { m_selected_extruder = extruder;} class WipeTowerInfo { protected: diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index e462e7c1d..18ddb65ba 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -490,11 +490,14 @@ void Preview::show_hide_ui_elements(const std::string& what) m_choice_view_type->Show(visible); } -void Preview::reset_sliders() +void Preview::reset_sliders(bool reset_all) { m_enabled = false; // reset_double_slider(); - m_double_slider_sizer->Hide((size_t)0); + if (reset_all) + m_double_slider_sizer->Hide((size_t)0); + else + m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide(1); } void Preview::update_sliders(const std::vector& layers_z, bool keep_z_range) @@ -503,11 +506,11 @@ void Preview::update_sliders(const std::vector& layers_z, bool keep_z_ra // update extruder selector if (wxGetApp().extruders_edited_cnt() != m_extruder_selector->GetCount()-1) { - int selection = m_extruder_selector->GetSelection(); + m_selected_extruder = m_extruder_selector->GetSelection(); update_extruder_selector(); - if (selection >= m_extruder_selector->GetCount()) - selection = 0; - m_extruder_selector->SetSelection(selection); + if (m_selected_extruder >= m_extruder_selector->GetCount()) + m_selected_extruder = 0; + m_extruder_selector->SetSelection(m_selected_extruder); } update_double_slider(layers_z, keep_z_range); @@ -615,12 +618,23 @@ void Preview::create_double_slider() m_extruder_selector->SetSelection(0); m_extruder_selector->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) { - m_slider->SetManipulationState(m_extruder_selector->GetSelection() == 0 ? + m_selected_extruder = m_extruder_selector->GetSelection(); + m_slider->SetManipulationState(m_selected_extruder == 0 ? DoubleSlider::msMultiExtruderWholePrint : DoubleSlider::msMultiExtruder); + + int type = m_choice_view_type->FindString(_(L("Color Print"))); + + if (m_choice_view_type->GetSelection() != type) { + m_choice_view_type->SetSelection(type); + if (0 <= type && type < (int)GCodePreviewData::Extrusion::Num_View_Types) + m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; + m_preferred_color_mode = "feature"; + } + reload_print(); + evt.StopPropagation(); }); - m_extruder_selector->Disable(); // temporary disabled to suppress extruder selection auto sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(m_extruder_selector, 0, wxEXPAND, 0); @@ -834,7 +848,7 @@ void Preview::load_print_as_fff(bool keep_z_range) if (! has_layers) { - reset_sliders(); + reset_sliders(true); m_canvas->reset_legend_texture(); m_canvas_widget->Refresh(); return; @@ -896,6 +910,7 @@ void Preview::load_print_as_fff(bool keep_z_range) if (IsShown()) { + m_canvas->set_selected_extruder(m_selected_extruder); if (gcode_preview_data_valid) { // Load the real G-code preview. m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); @@ -913,7 +928,7 @@ void Preview::load_print_as_fff(bool keep_z_range) std::vector zs = m_canvas->get_current_print_zs(true); if (zs.empty()) { // all layers filtered out - reset_sliders(); + reset_sliders(m_selected_extruder==0); m_canvas_widget->Refresh(); } else update_sliders(zs, keep_z_range); @@ -944,7 +959,7 @@ void Preview::load_print_as_sla() n_layers = (unsigned int)zs.size(); if (n_layers == 0) { - reset_sliders(); + reset_sliders(true); m_canvas_widget->Refresh(); } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 64b8baa7f..7a11e334c 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -105,6 +105,7 @@ class Preview : public wxPanel DoubleSlider* m_slider {nullptr}; wxBitmapComboBox* m_extruder_selector {nullptr}; + int m_selected_extruder {0}; // 0 means "Whole print" public: Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, @@ -144,7 +145,7 @@ private: void show_hide_ui_elements(const std::string& what); - void reset_sliders(); + void reset_sliders(bool reset_all); void update_sliders(const std::vector& layers_z, bool keep_z_range = false); void on_size(wxSizeEvent& evt); From 398d20c79be368eba12b44d196e5a6b0f001a45d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 24 Oct 2019 10:38:36 +0200 Subject: [PATCH 12/45] Improvements for extruder selector (added possibility to create combobox with thin icons) Call of an update extruder selector after a change of extruder or filament color --- src/slic3r/GUI/ExtruderSequenceDialog.cpp | 2 +- src/slic3r/GUI/GUI_Preview.cpp | 5 ++++- src/slic3r/GUI/Plater.cpp | 3 +++ src/slic3r/GUI/wxExtensions.cpp | 22 +++++++++++++--------- src/slic3r/GUI/wxExtensions.hpp | 9 +++++---- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.cpp b/src/slic3r/GUI/ExtruderSequenceDialog.cpp index 408826957..ef60a041b 100644 --- a/src/slic3r/GUI/ExtruderSequenceDialog.cpp +++ b/src/slic3r/GUI/ExtruderSequenceDialog.cpp @@ -130,7 +130,7 @@ void ExtruderSequenceDialog::apply_extruder_sequence() for (size_t extruder=0; extruder < m_sequence.extruders.size(); ++extruder) { wxBitmapComboBox* extruder_selector = nullptr; - apply_extruder_selector(&extruder_selector, this); + apply_extruder_selector(&extruder_selector, this, "", wxDefaultPosition, wxSize(12*wxGetApp().em_unit(), -1)); extruder_selector->SetSelection(m_sequence.extruders[extruder]); extruder_selector->Bind(wxEVT_COMBOBOX, [this, extruder_selector, extruder](wxCommandEvent& evt) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 18ddb65ba..d4397c449 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -533,6 +533,9 @@ void Preview::on_choice_view_type(wxCommandEvent& evt) if ((0 <= selection) && (selection < (int)GCodePreviewData::Extrusion::Num_View_Types)) m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)selection; + if (m_gcode_preview_data->extrusion.view_type != GCodePreviewData::Extrusion::ColorPrint) + m_extruder_selector->SetSelection(0); + reload_print(); } @@ -605,7 +608,7 @@ void Preview::update_view_type(bool slice_completed) void Preview::update_extruder_selector() { - apply_extruder_selector(&m_extruder_selector, this, L("Whole print")); + apply_extruder_selector(&m_extruder_selector, this, L("Whole print"), wxDefaultPosition, wxDefaultSize, true); } void Preview::create_double_slider() diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 1cbbfda5a..5b1fdc91c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4868,6 +4868,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) filament_colors.push_back(filaments.find_preset(filament_preset, true)->config.opt_string("filament_colour", (unsigned)0)); p->config->option(opt_key)->values = filament_colors; + p->preview->update_extruder_selector(); p->sidebar->obj_list()->update_extruder_colors(); continue; } @@ -4894,6 +4895,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) else if(opt_key == "extruder_colour") { update_scheduled = true; p->preview->set_number_extruders(p->config->option(opt_key)->values.size()); + p->preview->update_extruder_selector(); p->sidebar->obj_list()->update_extruder_colors(); } else if(opt_key == "max_print_height") { update_scheduled = true; @@ -4945,6 +4947,7 @@ void Plater::force_filament_colors_update() if (update_scheduled) { update(); + p->preview->update_extruder_selector(); p->sidebar->obj_list()->update_extruder_colors(); } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 4528a14cc..10aecb5c5 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -450,7 +450,7 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, Slic3r::GUI::BitmapCache* m_bitmap_cache = nullptr; -std::vector get_extruder_color_icons() +std::vector get_extruder_color_icons(bool thin_icon/* = false*/) { // Create the bitmap with color bars. std::vector bmps; @@ -466,16 +466,18 @@ std::vector get_extruder_color_icons() * and scale them in respect to em_unit value */ const double em = Slic3r::GUI::wxGetApp().em_unit(); - const int icon_width = lround(3.2 * em); + const int icon_width = lround((thin_icon ? 1 : 3.2) * em); const int icon_height = lround(1.6 * em); for (const std::string& color : colors) { - wxBitmap* bitmap = m_bitmap_cache->find(color); + std::string bitmap_key = color + "-h" + std::to_string(icon_height) + "-w" + std::to_string(icon_width); + + wxBitmap* bitmap = m_bitmap_cache->find(bitmap_key); if (bitmap == nullptr) { // Paint the color icon. Slic3r::PresetBundle::parse_color(color, rgb); - bitmap = m_bitmap_cache->insert(color, m_bitmap_cache->mksolid(icon_width, icon_height, rgb)); + bitmap = m_bitmap_cache->insert(bitmap_key, m_bitmap_cache->mksolid(icon_width, icon_height, rgb)); } bmps.emplace_back(bitmap); } @@ -484,10 +486,10 @@ std::vector get_extruder_color_icons() } -static wxBitmap get_extruder_color_icon(size_t extruder_idx) +static wxBitmap get_extruder_color_icon(size_t extruder_idx, bool thin_icon = false) { // Create the bitmap with color bars. - std::vector bmps = get_extruder_color_icons(); + std::vector bmps = get_extruder_color_icons(thin_icon); if (bmps.empty()) return wxNullBitmap; @@ -498,9 +500,10 @@ void apply_extruder_selector(wxBitmapComboBox** ctrl, wxWindow* parent, const std::string& first_item/* = ""*/, wxPoint pos/* = wxDefaultPosition*/, - wxSize size/* = wxDefaultSize*/) + wxSize size/* = wxDefaultSize*/, + bool use_thin_icon/* = false*/) { - std::vector icons = get_extruder_color_icons(); + std::vector icons = get_extruder_color_icons(use_thin_icon); if (icons.empty()) return; @@ -516,6 +519,7 @@ void apply_extruder_selector(wxBitmapComboBox** ctrl, } int i = 0; + wxString str = _(L("Extruder")); for (wxBitmap* bmp : icons) { if (i == 0) { if (!first_item.empty()) @@ -523,7 +527,7 @@ void apply_extruder_selector(wxBitmapComboBox** ctrl, ++i; } - (*ctrl)->Append(wxString::Format("%d", i), *bmp); + (*ctrl)->Append(wxString::Format("%s %d", str, i), *bmp); ++i; } (*ctrl)->SetSelection(0); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index ce5e58a6a..0fedaee09 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -58,12 +58,13 @@ int em_unit(wxWindow* win); wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt = 16, const bool is_horizontal = false, const bool grayscale = false); -std::vector get_extruder_color_icons(); +std::vector get_extruder_color_icons(bool thin_icon = false); void apply_extruder_selector(wxBitmapComboBox** ctrl, wxWindow* parent, const std::string& first_item = "", wxPoint pos = wxDefaultPosition, - wxSize size = wxDefaultSize); + wxSize size = wxDefaultSize, + bool use_thin_icon = false); class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup { @@ -964,13 +965,13 @@ private: TICK_CODE operator=(const TICK_CODE& other) const { TICK_CODE ret_val(other.tick, other.gcode, other.extruder); return ret_val; - } + }/* TICK_CODE& operator=(const TICK_CODE& other) { this->tick = other.tick; this->gcode = other.gcode; this->extruder = other.extruder; return *this; - } + }*/ int tick; std::string gcode; From 8ebd9ce7c4c786e7d6b12c8f86e45a9099e1b54b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 29 Oct 2019 15:34:35 +0100 Subject: [PATCH 13/45] Save "color_change" for a selected extruder to G_code --- src/libslic3r/GCode.cpp | 16 ++++++++++++++-- src/libslic3r/Model.hpp | 3 ++- src/slic3r/GUI/GUI_Preview.cpp | 9 +++------ src/slic3r/GUI/wxExtensions.cpp | 13 ++++++++----- src/slic3r/GUI/wxExtensions.hpp | 6 ++++++ 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 1a4d58edc..f3fe802cc 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1685,8 +1685,11 @@ void GCode::process_layer( // colorprint_change = true; // } std::string custom_code = ""; + int m600_before_extruder = -1; while (!m_custom_g_code_heights.empty() && m_custom_g_code_heights.front().height-EPSILON < layer.print_z) { custom_code = m_custom_g_code_heights.front().gcode; + if (custom_code == "M600" && m_custom_g_code_heights.front().extruder > 0) + m600_before_extruder = m_custom_g_code_heights.front().extruder - 1; m_custom_g_code_heights.erase(m_custom_g_code_heights.begin()); colorprint_change = true; } @@ -1711,8 +1714,17 @@ void GCode::process_layer( // add tag for time estimator gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; if (single_material_print && custom_code == "tool_change") - custom_code = "M600"; - gcode += custom_code + "\n"; + custom_code = "M600"; + + if (!single_material_print && custom_code == "M600" && + m600_before_extruder >= 0 && first_extruder_id != m600_before_extruder + // && !MMU1 + ) { + gcode += "M601\n"; // pause print + gcode += "M117 Change filament for Extruder " + std::to_string(m600_before_extruder) + "\n"; + } + else + gcode += custom_code + "\n"; } } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index aac6cde06..47f735508 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -768,7 +768,8 @@ public: double height; std::string gcode; - int extruder; + int extruder; // 0 - "gcode" will be applied for whole print + // else - "gcode" will be applied only for "extruder" print }; std::vector custom_gcode_per_height; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index d4397c449..e50a4099b 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -622,9 +622,7 @@ void Preview::create_double_slider() m_extruder_selector->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) { m_selected_extruder = m_extruder_selector->GetSelection(); - m_slider->SetManipulationState(m_selected_extruder == 0 ? - DoubleSlider::msMultiExtruderWholePrint : - DoubleSlider::msMultiExtruder); + m_slider->SetExtruderID(m_selected_extruder); int type = m_choice_view_type->FindString(_(L("Color Print"))); @@ -767,11 +765,10 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee m_slider->EnableTickManipulation(color_print_enable); if (color_print_enable && wxGetApp().extruders_edited_cnt() > 1) { //bool is_detected_full_print = //wxGetApp().plater()->fff_print().extruders().size() == 1; - m_slider->SetManipulationState(m_extruder_selector->GetSelection()==0 ? - DoubleSlider::msMultiExtruderWholePrint : DoubleSlider::msMultiExtruder); + m_slider->SetExtruderID(m_extruder_selector->GetSelection()); } else - m_slider->SetManipulationState(DoubleSlider::msSingleExtruder); + m_slider->SetExtruderID(-1); } // #ys_FIXME_COLOR diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 10aecb5c5..217c4b672 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3461,11 +3461,12 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) menu.AppendSubMenu(change_extruder_menu, name, _(L("Use another extruder"))); } } - else - append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", + + append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", [this](wxCommandEvent&) { add_code("M600"); }, "colorchange_add_off.png", &menu); - - append_menu_item(&menu, wxID_ANY, _(L("Add pause SD print")) + " (M601)", "", + + if (m_state != msMultiExtruder) + append_menu_item(&menu, wxID_ANY, _(L("Add pause print")) + " (M601)", "", [this](wxCommandEvent&) { add_code("M601"); }, "pause_add.png", &menu); append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "", @@ -3503,8 +3504,10 @@ void DoubleSlider::add_code(std::string code) } int extruder = 0; - if (m_state == msMultiExtruderWholePrint) + if (m_state == msMultiExtruderWholePrint && m_custom_gcode != "M600" ) extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); + else if (m_state == msMultiExtruder && m_current_extruder > 0) + extruder = m_current_extruder; m_ticks_.insert(TICK_CODE(tick, code, extruder)); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 0fedaee09..a4ac16d4d 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -828,6 +828,11 @@ public: m_state = state; } ManipulationState GetManipulationState() const { return m_state; } + void SetExtruderID(int extruder) { + m_current_extruder = extruder; + m_state = extruder < 0 ? msSingleExtruder : + extruder > 0 ? msMultiExtruder : msMultiExtruderWholePrint; + } bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } bool is_one_layer() const { return m_is_one_layer; } @@ -919,6 +924,7 @@ private: bool m_show_context_menu = false; ManipulationState m_state = msSingleExtruder; wxString m_custom_gcode = wxEmptyString; + int m_current_extruder = -1; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; From 8d27cfd4a6fb987f83d76789e1118ebe35d60bc5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 31 Oct 2019 15:24:20 +0100 Subject: [PATCH 14/45] Changed context menu for DoubleSlider --- src/slic3r/GUI/GUI_Preview.cpp | 9 +++- src/slic3r/GUI/wxExtensions.cpp | 85 ++++++++++++++++++++++++++------- src/slic3r/GUI/wxExtensions.hpp | 4 +- 3 files changed, 77 insertions(+), 21 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index e50a4099b..c83d82284 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -604,6 +604,9 @@ void Preview::update_view_type(bool slice_completed) m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; m_preferred_color_mode = "feature"; } + + if (type != GCodePreviewData::Extrusion::EViewType::ColorPrint) + m_extruder_selector->SetSelection(0); } void Preview::update_extruder_selector() @@ -726,7 +729,11 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee // #ys_FIXME_COLOR // std::vector &ticks_from_config = (wxGetApp().preset_bundle->project_config.option("colorprint_heights"))->values; // check_slider_values(ticks_from_config, layers_z); - std::vector &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height; + std::vector tmp_ticks_from_model; + if (m_selected_extruder != 0) + tmp_ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height; + std::vector &ticks_from_model = m_selected_extruder != 0 ? tmp_ticks_from_model : + wxGetApp().plater()->model().custom_gcode_per_height; check_slider_values(ticks_from_model, layers_z); m_slider->SetSliderValues(layers_z); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 217c4b672..8ddbdb193 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2552,7 +2552,7 @@ void DoubleSlider::SetTicksValues_(const std::vector& heights) m_ticks_.insert(TICK_CODE(it-m_values.begin(), h.gcode, h.extruder)); } - if (!was_empty && m_ticks_.empty()) + if (!was_empty && m_ticks_.empty() && m_state != msMultiExtruder) // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } @@ -3232,6 +3232,33 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) return; this->ReleaseMouse(); m_is_left_down = false; + + if (m_show_context_menu) + { + if (m_state == msMultiExtruderWholePrint) + { + wxMenu menu; + const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); + if (extruders_cnt > 1) + { + const int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); + + wxMenu* add_color_change_menu = new wxMenu(); + + for (int i = 1; i <= extruders_cnt; i++) + append_menu_radio_item(add_color_change_menu, wxID_ANY, wxString::Format(_(L("Extruder %d")), i), "", + [this, i](wxCommandEvent&) { add_code("M600", i); }, &menu)->Check(i == initial_extruder); + + const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % "M600").str()); + wxMenuItem* add_color_change_menu_item = menu.AppendSubMenu(add_color_change_menu, menu_name, ""); + add_color_change_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "colorchange_add_off.png")); + } + + Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); + m_show_context_menu = false; + } + } + Refresh(); Update(); event.Skip(); @@ -3295,17 +3322,25 @@ void DoubleSlider::action_tick(const TicksAction action) // m_ticks.erase(tick); // } - if (action == taOnIcon) { - if (!m_ticks_.insert(TICK_CODE(tick)).second) - m_ticks_.erase(TICK_CODE(tick)); + const auto it = m_ticks_.find(tick); + + if (it != m_ticks_.end()) + { + if (action == taAdd) + return; + m_ticks_.erase(TICK_CODE(tick)); } - else { - const auto it = m_ticks_.find(tick); - if (it == m_ticks_.end() && action == taAdd) - m_ticks_.insert(tick); - else if (it != m_ticks_.end() && action == taDel) - m_ticks_.erase(tick); + else if (action == taDel) + return; + else if (m_state == msMultiExtruderWholePrint) + { + if (action == taAdd) + return; + m_show_context_menu = true; + return; } + else + m_ticks_.insert(TICK_CODE(tick, "M600", m_state == msSingleExtruder ? 0 : m_current_extruder)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); @@ -3443,25 +3478,35 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) if (m_state == msMultiExtruderWholePrint) { - const wxString name = _(L("Change extruder")); - const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); if (extruders_cnt > 1) { const int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); wxMenu* change_extruder_menu = new wxMenu(); + wxMenu* add_color_change_menu = new wxMenu(); + for (int i = 0; i <= extruders_cnt; i++) { - const wxString& item_name = i == 0 ? _(L("Default")) : wxString::Format("%d", i); + const wxString item_name = i == 0 ? _(L("Default")) : wxString::Format(_(L("Extruder %d")), i); append_menu_radio_item(change_extruder_menu, wxID_ANY, item_name, "", [this, i](wxCommandEvent&) { change_extruder(i); }, &menu)->Check(i == initial_extruder); + + if (i==0) // don't use M600 for default extruder, if multimaterial print is selected + continue; + append_menu_radio_item(add_color_change_menu, wxID_ANY, /*i == 0 ? _(L("current extruder")) : */item_name, "", + [this, i](wxCommandEvent&) { add_code("M600", i); }, &menu)->Check(i == initial_extruder); } - menu.AppendSubMenu(change_extruder_menu, name, _(L("Use another extruder"))); + wxMenuItem* change_extruder_menu_item = menu.AppendSubMenu(change_extruder_menu, _(L("Change extruder")), _(L("Use another extruder"))); + change_extruder_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "change_extruder")); + + const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % "M600").str()); + wxMenuItem* add_color_change_menu_item = menu.AppendSubMenu(add_color_change_menu, menu_name, ""); + add_color_change_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "colorchange_add_off.png")); } } - + else append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", [this](wxCommandEvent&) { add_code("M600"); }, "colorchange_add_off.png", &menu); @@ -3482,7 +3527,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) event.Skip(); } -void DoubleSlider::add_code(std::string code) +void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; // if on this Y doesn't exist tick @@ -3504,8 +3549,12 @@ void DoubleSlider::add_code(std::string code) } int extruder = 0; - if (m_state == msMultiExtruderWholePrint && m_custom_gcode != "M600" ) - extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); + if (m_state == msMultiExtruderWholePrint) { + if (code == "M600" && selected_extruder >= 0) + extruder = selected_extruder; + else + extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); + } else if (m_state == msMultiExtruder && m_current_extruder > 0) extruder = m_current_extruder; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index a4ac16d4d..1b8dc2fa5 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -851,9 +851,9 @@ public: void OnKeyUp(wxKeyEvent &event); void OnChar(wxKeyEvent &event); void OnRightDown(wxMouseEvent& event); - int get_extruder_for_tick(int tick); + int get_extruder_for_tick(int tick); void OnRightUp(wxMouseEvent& event); - void add_code(std::string code); + void add_code(std::string code, int selected_extruder = -1); void change_extruder(int extruder); protected: From 674c6ce1c53f4b0cf9b3340de5f5e75087a8f5a1 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sun, 3 Nov 2019 19:33:02 +0100 Subject: [PATCH 15/45] Implemented coloration of multi-extruder print with color changes for separated extruder. --- src/slic3r/GUI/GLCanvas3D.cpp | 108 ++++++++++++++++++++++++++++++-- src/slic3r/GUI/GLCanvas3D.hpp | 9 ++- src/slic3r/GUI/GUI_Preview.cpp | 31 ++++++++- src/slic3r/GUI/wxExtensions.cpp | 10 ++- 4 files changed, 142 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 146cdd75f..6b9232e1d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2247,7 +2247,9 @@ void GLCanvas3D::load_sla_preview() } } -void GLCanvas3D::load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values) +// #ys_FIXME_COLOR +// void GLCanvas3D::load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values) +void GLCanvas3D::load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values) { const Print *print = this->fff_print(); if (print == nullptr) @@ -4675,7 +4677,9 @@ void GLCanvas3D::_load_print_toolpaths() volume->indexed_vertex_array.finalize_geometry(m_initialized); } -void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) +// #ys_FIXME_COLOR +// void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) +void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) { std::vector tool_colors = _parse_colors(str_tool_colors); @@ -4687,11 +4691,15 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c bool has_infill; bool has_support; const std::vector* tool_colors; - const std::vector* color_print_values; + // #ys_FIXME_COLOR + // const std::vector* color_print_values; + bool is_single_material_print; + const std::vector* color_print_values; static const float* color_perimeters() { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow static const float* color_infill() { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish + static const float* color_pause_or_custom_code() { static float color[4] = { 0.5f, 0.5f, 0.5f, 1.f }; return color; } // gray // For cloring by a tool, return a parsed color. bool color_by_tool() const { return tool_colors != nullptr; } @@ -4701,9 +4709,26 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c // For coloring by a color_print(M600), return a parsed color. bool color_by_color_print() const { return color_print_values!=nullptr; } const size_t color_print_color_idx_by_layer_idx(const size_t layer_idx) const { - auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON); + // #ys_FIXME_COLOR + // auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON); + const Model::CustomGCode value(layers[layer_idx]->print_z + EPSILON, "", 0); + auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); return (it - color_print_values->begin()) % number_tools(); } + + const bool pause_or_custom_code_layer(const size_t layer_idx) const + { + const coordf_t print_z = layers[layer_idx]->print_z; + auto it = std::find_if(color_print_values->begin(), color_print_values->end(), + [print_z](const Model::CustomGCode& code) + { return fabs(code.height - print_z) < EPSILON; }); + if (it == color_print_values->end()) + return false; + + const std::string& code = (*it).gcode; + return code == "M601" || (code != "M600" && code != "tool_change"); + } + } ctxt; ctxt.has_perimeters = print_object.is_step_done(posPerimeters); @@ -4711,6 +4736,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c ctxt.has_support = print_object.is_step_done(posSupportMaterial); ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors; ctxt.color_print_values = color_print_values.empty() ? nullptr : &color_print_values; + ctxt.is_single_material_print = this->fff_print()->extruders().size()==1; ctxt.shifted_copies = &print_object.copies(); @@ -4757,14 +4783,65 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c GLVolumePtrs vols; std::vector color_print_layer_to_glvolume; auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { - return *vols[ctxt.color_by_color_print() ? + if (ctxt.color_by_color_print() && !ctxt.is_single_material_print) + { + const coordf_t print_z = ctxt.layers[layer_idx]->print_z; + const std::vector* cp_values = ctxt.color_print_values; + + // pause print or custom Gcode + auto it = std::find_if(cp_values->begin(), cp_values->end(), + [print_z](const Model::CustomGCode& code) + { return fabs(code.height - print_z) < EPSILON; }); + if (it != cp_values->end()) + { + const std::string& code = (*it).gcode; + if (code == "M601" || (code != "M600" && code != "tool_change")) + return *vols[ctxt.number_tools()];//*vols.back(); + // change tool (extruder) + if (code == "tool_change") + return *vols[std::min(ctxt.number_tools() - 1, std::max(it->extruder - 1, 0))]; + if (code == "M600" && it->extruder == extruder) { + int shift = 1; + while (it != cp_values->begin()) { + --it; + if (it->gcode == "M600") + shift++; + } + return *vols[ctxt.number_tools()+shift]; + } + } + + const Model::CustomGCode value(print_z + EPSILON, "", 0); + it = std::lower_bound(cp_values->begin(), cp_values->end(), value); + while (it != cp_values->begin()) + { + --it; + const std::string& code = (*it).gcode; + if (code == "M600" && it->extruder == extruder) { + auto it_n = it; + int shift = 1; + while (it_n != cp_values->begin()) { + --it_n; + if (it_n->gcode == "M600") + shift++; + } + return *vols[ctxt.number_tools() + shift]; + } + if (code == "tool_change") + return *vols[std::min(ctxt.number_tools() - 1, std::max((*it).extruder - 1, 0))]; + } + + return *vols[std::min(ctxt.number_tools() - 1, std::max(extruder - 1, 0))]; + } + + return *vols[ctxt.color_by_color_print() && ctxt.is_single_material_print ? color_print_layer_to_glvolume[layer_idx - range.begin()] : ctxt.color_by_tool() ? std::min(ctxt.number_tools() - 1, std::max(extruder - 1, 0)) : feature ]; }; - if (ctxt.color_by_color_print()) { + if (ctxt.color_by_color_print() && ctxt.is_single_material_print) { // Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color. std::vector color_print_tool_to_glvolume(ctxt.number_tools(), -1); color_print_layer_to_glvolume.reserve(range.end() - range.begin()); @@ -4778,6 +4855,25 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c color_print_layer_to_glvolume.emplace_back(color_print_tool_to_glvolume[idx_tool]); } } + else if (ctxt.color_by_color_print() && !ctxt.is_single_material_print) { + for (size_t i = 0; i < ctxt.number_tools(); ++i) + vols.emplace_back(new_volume(ctxt.color_tool(i))); + vols.emplace_back(new_volume(ctxt.color_pause_or_custom_code())); + + for ( auto it = ctxt.color_print_values->begin(); it < ctxt.color_print_values->end(); it++) { + if (it->gcode == "M600" && it->extruder != 0) + { + int cp_id = it - ctxt.color_print_values->begin() + 1; + float koef = fabs(1- cp_id * 0.1); + float color_f[4]; + memcpy(color_f, ctxt.color_tool(it->extruder - 1), sizeof(float) * 4); + for (int i=0; i<3; i++) + color_f[i] = clamp(0.0f, 1.0f, koef * color_f[i]); + + vols.emplace_back(new_volume(color_f)); + } + } + } else if (ctxt.color_by_tool()) { for (size_t i = 0; i < ctxt.number_tools(); ++i) vols.emplace_back(new_volume(ctxt.color_tool(i))); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e5e845304..9a0582fee 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -538,7 +538,9 @@ public: void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); void load_sla_preview(); - void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); + // #ys_FIXME_COLOR + // void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); + void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); void bind_event_handlers(); void unbind_event_handlers(); @@ -690,7 +692,10 @@ private: // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes, // one for perimeters, one for infill and one for supports. void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, - const std::vector& color_print_values); + const std::vector& color_print_values); + // #ys_FIXME_COLOR + // void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, + // const std::vector& color_print_values); // Create 3D thick extrusion lines for wipe tower extrusions void _load_wipe_tower_toolpaths(const std::vector& str_tool_colors); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index c83d82284..064fcb5c5 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -878,19 +878,46 @@ void Preview::load_print_as_fff(bool keep_z_range) bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); // Collect colors per extruder. std::vector colors; - std::vector color_print_values = {}; + // #ys_FIXME_COLOR + // std::vector color_print_values = {}; + std::vector color_print_values = {}; // set color print values, if it si selected "ColorPrint" view type if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) { - colors = GCodePreviewData::ColorPrintColors(); + unsigned int number_extruders = (unsigned int)print->extruders().size(); + if (number_extruders == 1) // use GCodePreviewData::ColorPrintColors() just for Single-extruder printing + colors = GCodePreviewData::ColorPrintColors(); + else + { + const ConfigOptionStrings* extruders_opt = dynamic_cast(m_config->option("extruder_colour")); + const ConfigOptionStrings* filamemts_opt = dynamic_cast(m_config->option("filament_colour")); + unsigned int colors_count = std::max((unsigned int)extruders_opt->values.size(), (unsigned int)filamemts_opt->values.size()); + + unsigned char rgb[3]; + for (unsigned int i = 0; i < colors_count; ++i) + { + std::string color = m_config->opt_string("extruder_colour", i); + if (!PresetBundle::parse_color(color, rgb)) + { + color = m_config->opt_string("filament_colour", i); + if (!PresetBundle::parse_color(color, rgb)) + color = "#FFFFFF"; + } + + colors.emplace_back(color); + } + } if (! gcode_preview_data_valid) { // #ys_FIXME_COLOR // const auto& config = wxGetApp().preset_bundle->project_config; // color_print_values = config.option("colorprint_heights")->values; + /* const std::vector& custom_codes = wxGetApp().plater()->model().custom_gcode_per_height; color_print_values.reserve(custom_codes.size()); for (const Model::CustomGCode& code : custom_codes) color_print_values.push_back(code.height); + */ + color_print_values = wxGetApp().plater()->model().custom_gcode_per_height; } } else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 8ddbdb193..238860ce7 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3241,13 +3241,11 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); if (extruders_cnt > 1) { - const int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); - wxMenu* add_color_change_menu = new wxMenu(); for (int i = 1; i <= extruders_cnt; i++) - append_menu_radio_item(add_color_change_menu, wxID_ANY, wxString::Format(_(L("Extruder %d")), i), "", - [this, i](wxCommandEvent&) { add_code("M600", i); }, &menu)->Check(i == initial_extruder); + append_menu_item(add_color_change_menu, wxID_ANY, wxString::Format(_(L("Extruder %d")), i), "", + [this, i](wxCommandEvent&) { add_code("M600", i); }, "", &menu); const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % "M600").str()); wxMenuItem* add_color_change_menu_item = menu.AppendSubMenu(add_color_change_menu, menu_name, ""); @@ -3494,8 +3492,8 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) if (i==0) // don't use M600 for default extruder, if multimaterial print is selected continue; - append_menu_radio_item(add_color_change_menu, wxID_ANY, /*i == 0 ? _(L("current extruder")) : */item_name, "", - [this, i](wxCommandEvent&) { add_code("M600", i); }, &menu)->Check(i == initial_extruder); + append_menu_item(add_color_change_menu, wxID_ANY, item_name, "", + [this, i](wxCommandEvent&) { add_code("M600", i); }, "", &menu); } wxMenuItem* change_extruder_menu_item = menu.AppendSubMenu(change_extruder_menu, _(L("Change extruder")), _(L("Use another extruder"))); From d5f7956a55f8625fb4b8ddfd5203ddfbe8ff8f3c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 4 Nov 2019 13:42:47 +0100 Subject: [PATCH 16/45] Set custom color for color change --- src/libslic3r/Model.hpp | 11 ++- src/slic3r/GUI/GLCanvas3D.cpp | 142 ++++++++++++++------------------ src/slic3r/GUI/GUI_Preview.cpp | 36 ++------ src/slic3r/GUI/wxExtensions.cpp | 93 +++++++++++++++------ src/slic3r/GUI/wxExtensions.hpp | 10 ++- 5 files changed, 150 insertions(+), 142 deletions(-) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 47f735508..21b5896e0 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -749,27 +749,30 @@ public: // Extensions for color print struct CustomGCode { - CustomGCode(double height, const std::string& code, int extruder) : - height(height), gcode(code), extruder(extruder) {} + CustomGCode(double height, const std::string& code, int extruder, const std::string& color) : + height(height), gcode(code), extruder(extruder), color(color) {} bool operator<(const CustomGCode& other) const { return other.height > this->height; } bool operator==(const CustomGCode& other) const { return (other.height == this->height) && (other.gcode == this->gcode) && - (other.extruder == this->extruder ); + (other.extruder == this->extruder )&& + (other.color == this->color ); } bool operator!=(const CustomGCode& other) const { return (other.height != this->height) || (other.gcode != this->gcode) || - (other.extruder != this->extruder ); + (other.extruder != this->extruder )|| + (other.color != this->color ); } double height; std::string gcode; int extruder; // 0 - "gcode" will be applied for whole print // else - "gcode" will be applied only for "extruder" print + std::string color; }; std::vector custom_gcode_per_height; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7e782dee3..b9b4c93a4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4694,6 +4694,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c // #ys_FIXME_COLOR // const std::vector* color_print_values; bool is_single_material_print; + int extruders_cnt; const std::vector* color_print_values; static const float* color_perimeters() { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow @@ -4711,24 +4712,64 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c const size_t color_print_color_idx_by_layer_idx(const size_t layer_idx) const { // #ys_FIXME_COLOR // auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON); - const Model::CustomGCode value(layers[layer_idx]->print_z + EPSILON, "", 0); + const Model::CustomGCode value(layers[layer_idx]->print_z + EPSILON, "", 0, ""); auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); return (it - color_print_values->begin()) % number_tools(); } - const bool pause_or_custom_code_layer(const size_t layer_idx) const + const size_t color_print_color_idx_by_layer_idx_and_extruder(const size_t layer_idx, const int extruder) const { const coordf_t print_z = layers[layer_idx]->print_z; - auto it = std::find_if(color_print_values->begin(), color_print_values->end(), - [print_z](const Model::CustomGCode& code) - { return fabs(code.height - print_z) < EPSILON; }); - if (it == color_print_values->end()) - return false; - const std::string& code = (*it).gcode; - return code == "M601" || (code != "M600" && code != "tool_change"); + auto it = std::find_if(color_print_values->begin(), color_print_values->end(), + [print_z](const Model::CustomGCode& code) + { return fabs(code.height - print_z) < EPSILON; }); + if (it != color_print_values->end()) + { + const std::string& code = it->gcode; + // pause print or custom Gcode + if (code == "M601" || (code != "M600" && code != "tool_change")) + return number_tools(); + + // change tool (extruder) + if (code == "tool_change") + return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); + // change color for current extruder + if (code == "M600" && it->extruder == extruder) { + int shift = 0; + while (it != color_print_values->begin()) { + --it; + if (it->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } + } + + const Model::CustomGCode value(print_z + EPSILON, "", 0, ""); + it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); + while (it != color_print_values->begin()) + { + --it; + const std::string& code = it->gcode; + // change color for current extruder + if (code == "M600" && it->extruder == extruder) { + auto it_n = it; + int shift = 0; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } + // change tool (extruder) + if (code == "tool_change") + return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); + } + + return std::min(extruders_cnt - 1, std::max(extruder - 1, 0));; } - } ctxt; ctxt.has_perimeters = print_object.is_step_done(posPerimeters); @@ -4737,6 +4778,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors; ctxt.color_print_values = color_print_values.empty() ? nullptr : &color_print_values; ctxt.is_single_material_print = this->fff_print()->extruders().size()==1; + ctxt.extruders_cnt = wxGetApp().extruders_edited_cnt(); ctxt.shifted_copies = &print_object.copies(); @@ -4782,67 +4824,17 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c [&ctxt, &new_volume, is_selected_separate_extruder, this](const tbb::blocked_range& range) { GLVolumePtrs vols; std::vector color_print_layer_to_glvolume; - auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { - if (ctxt.color_by_color_print() && !ctxt.is_single_material_print) - { - const coordf_t print_z = ctxt.layers[layer_idx]->print_z; - const std::vector* cp_values = ctxt.color_print_values; - - // pause print or custom Gcode - auto it = std::find_if(cp_values->begin(), cp_values->end(), - [print_z](const Model::CustomGCode& code) - { return fabs(code.height - print_z) < EPSILON; }); - if (it != cp_values->end()) - { - const std::string& code = (*it).gcode; - if (code == "M601" || (code != "M600" && code != "tool_change")) - return *vols[ctxt.number_tools()];//*vols.back(); - // change tool (extruder) - if (code == "tool_change") - return *vols[std::min(ctxt.number_tools() - 1, std::max(it->extruder - 1, 0))]; - if (code == "M600" && it->extruder == extruder) { - int shift = 1; - while (it != cp_values->begin()) { - --it; - if (it->gcode == "M600") - shift++; - } - return *vols[ctxt.number_tools()+shift]; - } - } - - const Model::CustomGCode value(print_z + EPSILON, "", 0); - it = std::lower_bound(cp_values->begin(), cp_values->end(), value); - while (it != cp_values->begin()) - { - --it; - const std::string& code = (*it).gcode; - if (code == "M600" && it->extruder == extruder) { - auto it_n = it; - int shift = 1; - while (it_n != cp_values->begin()) { - --it_n; - if (it_n->gcode == "M600") - shift++; - } - return *vols[ctxt.number_tools() + shift]; - } - if (code == "tool_change") - return *vols[std::min(ctxt.number_tools() - 1, std::max((*it).extruder - 1, 0))]; - } - - return *vols[std::min(ctxt.number_tools() - 1, std::max(extruder - 1, 0))]; - } - - return *vols[ctxt.color_by_color_print() && ctxt.is_single_material_print ? - color_print_layer_to_glvolume[layer_idx - range.begin()] : + auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { + return *vols[ctxt.color_by_color_print()? + //color_print_layer_to_glvolume[layer_idx - range.begin()] : + ctxt.color_print_color_idx_by_layer_idx_and_extruder(layer_idx/* - range.begin()*/, extruder) : ctxt.color_by_tool() ? std::min(ctxt.number_tools() - 1, std::max(extruder - 1, 0)) : feature ]; }; - if (ctxt.color_by_color_print() && ctxt.is_single_material_print) { - // Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color. + if (ctxt.color_by_color_print()) { + /* // Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color. std::vector color_print_tool_to_glvolume(ctxt.number_tools(), -1); color_print_layer_to_glvolume.reserve(range.end() - range.begin()); vols.reserve(ctxt.number_tools()); @@ -4854,25 +4846,11 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c } color_print_layer_to_glvolume.emplace_back(color_print_tool_to_glvolume[idx_tool]); } - } - else if (ctxt.color_by_color_print() && !ctxt.is_single_material_print) { + vols.emplace_back(new_volume(ctxt.color_pause_or_custom_code())); + }*/ for (size_t i = 0; i < ctxt.number_tools(); ++i) vols.emplace_back(new_volume(ctxt.color_tool(i))); vols.emplace_back(new_volume(ctxt.color_pause_or_custom_code())); - - for ( auto it = ctxt.color_print_values->begin(); it < ctxt.color_print_values->end(); it++) { - if (it->gcode == "M600" && it->extruder != 0) - { - int cp_id = it - ctxt.color_print_values->begin() + 1; - float koef = fabs(1- cp_id * 0.1); - float color_f[4]; - memcpy(color_f, ctxt.color_tool(it->extruder - 1), sizeof(float) * 4); - for (int i=0; i<3; i++) - color_f[i] = clamp(0.0f, 1.0f, koef * color_f[i]); - - vols.emplace_back(new_volume(color_f)); - } - } } else if (ctxt.color_by_tool()) { for (size_t i = 0; i < ctxt.number_tools(); ++i) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 81367081f..dcb11cf0b 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -886,41 +886,23 @@ void Preview::load_print_as_fff(bool keep_z_range) // set color print values, if it si selected "ColorPrint" view type if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) { - unsigned int number_extruders = (unsigned int)print->extruders().size(); - if (number_extruders == 1) // use GCodePreviewData::ColorPrintColors() just for Single-extruder printing - colors = GCodePreviewData::ColorPrintColors(); - else - { - const ConfigOptionStrings* extruders_opt = dynamic_cast(m_config->option("extruder_colour")); - const ConfigOptionStrings* filamemts_opt = dynamic_cast(m_config->option("filament_colour")); - unsigned int colors_count = std::max((unsigned int)extruders_opt->values.size(), (unsigned int)filamemts_opt->values.size()); + colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); + color_print_values = wxGetApp().plater()->model().custom_gcode_per_height; - unsigned char rgb[3]; - for (unsigned int i = 0; i < colors_count; ++i) - { - std::string color = m_config->opt_string("extruder_colour", i); - if (!PresetBundle::parse_color(color, rgb)) - { - color = m_config->opt_string("filament_colour", i); - if (!PresetBundle::parse_color(color, rgb)) - color = "#FFFFFF"; - } + for (const Model::CustomGCode& code : color_print_values) + if (code.gcode == "M600") + colors.push_back(code.color); - colors.emplace_back(color); - } - } + if (gcode_preview_data_valid) + color_print_values.clear(); + /* if (! gcode_preview_data_valid) { // #ys_FIXME_COLOR // const auto& config = wxGetApp().preset_bundle->project_config; // color_print_values = config.option("colorprint_heights")->values; - /* - const std::vector& custom_codes = wxGetApp().plater()->model().custom_gcode_per_height; - color_print_values.reserve(custom_codes.size()); - for (const Model::CustomGCode& code : custom_codes) - color_print_values.push_back(code.height); - */ color_print_values = wxGetApp().plater()->model().custom_gcode_per_height; } + */ } else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) { diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 40f509ad7..835737198 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2529,7 +2529,7 @@ std::vector DoubleSlider::GetTicksValues_() const for (const TICK_CODE& tick : m_ticks_) { if (tick.tick > val_size) break; - values.push_back(t_custom_code(m_values[tick.tick], tick.gcode, tick.extruder)); + values.push_back(t_custom_code(m_values[tick.tick], tick.gcode, tick.extruder, tick.color)); } return values; @@ -2549,7 +2549,7 @@ void DoubleSlider::SetTicksValues_(const std::vector& heights) if (it == m_values.end()) continue; - m_ticks_.insert(TICK_CODE(it-m_values.begin(), h.gcode, h.extruder)); + m_ticks_.insert(TICK_CODE(it-m_values.begin(), h.gcode, h.extruder, h.color)); } if (!was_empty && m_ticks_.empty() && m_state != msMultiExtruder) @@ -3071,10 +3071,13 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) double value = 0.0; int extruder = 0; const int extr_cnt = m_extruders_sequence.extruders.size(); + + std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); while (tick <= m_max_value) { - m_ticks_.insert(TICK_CODE(tick, "tool_change", m_extruders_sequence.extruders[extruder]+1)); + int cur_extruder = m_extruders_sequence.extruders[extruder]; + m_ticks_.insert(TICK_CODE(tick, "tool_change", cur_extruder+1, colors[cur_extruder])); extruder++; if (extruder == extr_cnt) @@ -3253,8 +3256,11 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) } Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); - m_show_context_menu = false; } + else + add_code("M600"); + + m_show_context_menu = false; } Refresh(); @@ -3300,6 +3306,23 @@ void DoubleSlider::move_current_thumb(const bool condition) ProcessWindowEvent(e); } +static std::string get_new_color(const std::string& color) +{ + wxColour clr(color); + if (!clr.IsOk()) + clr = wxColour(0, 0, 0); // Don't set alfa to transparence + + auto data = new wxColourData(); + data->SetChooseFull(1); + data->SetColour(clr); + + wxColourDialog dialog(nullptr, data); + dialog.CenterOnParent(); + if (dialog.ShowModal() == wxID_OK) + return dialog.GetColourData().GetColour().GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); + return color; +} + void DoubleSlider::action_tick(const TicksAction action) { if (m_selection == ssUndef) @@ -3319,30 +3342,40 @@ void DoubleSlider::action_tick(const TicksAction action) // else if (it != m_ticks.end() && action == taDel) // m_ticks.erase(tick); // } + // wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + // Refresh(); + // Update(); const auto it = m_ticks_.find(tick); - if (it != m_ticks_.end()) + if (it != m_ticks_.end()) // erase this tick { if (action == taAdd) return; m_ticks_.erase(TICK_CODE(tick)); - } - else if (action == taDel) - return; - else if (m_state == msMultiExtruderWholePrint) - { - if (action == taAdd) - return; - m_show_context_menu = true; - return; - } - else - m_ticks_.insert(TICK_CODE(tick, "M600", m_state == msSingleExtruder ? 0 : m_current_extruder)); - wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); - Refresh(); - Update(); + wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + Refresh(); + Update(); + return; + } + + if (action == taDel) + return; + if (action == taAdd) + { + // OnChar() is called immediately after OnKeyDown(), which can cause call of add_code() twice. + // To avoid this case we should suppress second add_code() call. + if (m_suppress_add_code) + return; + m_suppress_add_code = true; + if (m_state != msMultiExtruderWholePrint) + add_code("M600"); + m_suppress_add_code = false; + return; + } + + m_show_context_menu = true; } void DoubleSlider::OnWheel(wxMouseEvent& event) @@ -3529,9 +3562,16 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; // if on this Y doesn't exist tick - if (m_ticks_.find(tick) == m_ticks_.end()) + auto it = m_ticks_.find(tick); + if (it == m_ticks_.end()) { - if (code.empty()) + std::string color = ""; + if (code == "M600") + { + std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); + color = get_new_color(colors[selected_extruder > 0 ? selected_extruder-1 : 0]); + } + else if (code.empty()) { wxString msg_text = from_u8(_utf8(L("Enter custom G-code used on current layer"))) + " :"; wxString msg_header = from_u8((boost::format(_utf8(L("Custom Gcode on current layer (%1% mm)."))) % m_values[tick]).str()); @@ -3546,7 +3586,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) code = m_custom_gcode.c_str(); } - int extruder = 0; + int extruder = 1; if (m_state == msMultiExtruderWholePrint) { if (code == "M600" && selected_extruder >= 0) extruder = selected_extruder; @@ -3556,7 +3596,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) else if (m_state == msMultiExtruder && m_current_extruder > 0) extruder = m_current_extruder; - m_ticks_.insert(TICK_CODE(tick, code, extruder)); + m_ticks_.insert(TICK_CODE(tick, code, extruder, color)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); @@ -3567,10 +3607,13 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) void DoubleSlider::change_extruder(int extruder) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + + std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); + // if on this Y doesn't exist tick if (m_ticks_.find(tick) == m_ticks_.end()) { - m_ticks_.insert(TICK_CODE(tick, "tool_change", extruder)); + m_ticks_.insert(TICK_CODE(tick, "tool_change", extruder, colors[extruder-1])); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 1b8dc2fa5..5cdf99c60 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -922,6 +922,7 @@ private: bool m_is_one_layer_icon_focesed = false; bool m_is_enabled_tick_manipulation = true; bool m_show_context_menu = false; + bool m_suppress_add_code = false; ManipulationState m_state = msSingleExtruder; wxString m_custom_gcode = wxEmptyString; int m_current_extruder = -1; @@ -958,18 +959,18 @@ private: struct TICK_CODE { - TICK_CODE(int tick):tick(tick), gcode("M600"), extruder(0) {} + TICK_CODE(int tick):tick(tick), gcode("M600"), extruder(0), color("") {} TICK_CODE(int tick, const std::string& code) : tick(tick), gcode(code), extruder(0) {} TICK_CODE(int tick, int extruder) : tick(tick), gcode("M600"), extruder(extruder) {} - TICK_CODE(int tick, const std::string& code, int extruder) : - tick(tick), gcode(code), extruder(extruder) {} + TICK_CODE(int tick, const std::string& code, int extruder, const std::string& color) : + tick(tick), gcode(code), extruder(extruder), color(color) {} bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } TICK_CODE operator=(const TICK_CODE& other) const { - TICK_CODE ret_val(other.tick, other.gcode, other.extruder); + TICK_CODE ret_val(other.tick, other.gcode, other.extruder, other.color); return ret_val; }/* TICK_CODE& operator=(const TICK_CODE& other) { @@ -982,6 +983,7 @@ private: int tick; std::string gcode; int extruder; + std::string color; }; std::set m_ticks_; From 6ed9adaefffa675c9df02ddc7428f89158ad2e29 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 4 Nov 2019 16:28:57 +0100 Subject: [PATCH 17/45] New legend for color print. Some improvements for coloration multimaterial print indicator --- src/libslic3r/GCode/PreviewData.cpp | 42 ++++- src/libslic3r/GCode/PreviewData.hpp | 4 +- src/slic3r/GUI/GLCanvas3D.cpp | 232 ++++++++++++++++++++++++---- src/slic3r/GUI/GLCanvas3D.hpp | 3 + src/slic3r/GUI/GUI_Preview.cpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 36 +++-- 6 files changed, 270 insertions(+), 48 deletions(-) diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index 53c13a2f2..dc4e8cf48 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -379,7 +379,10 @@ std::string GCodePreviewData::get_legend_title() const return ""; } -GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector& tool_colors, const std::vector>& cp_values) const +// #ys_FIXME_COLOR +// GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector& tool_colors, const std::vector>& cp_values) const +GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector& tool_colors, + const std::vector& cp_items, bool is_single_material_print) const { struct Helper { @@ -452,11 +455,17 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: break; } - case Extrusion::ColorPrint: + // #ys_FIXME_COLOR + /*case Extrusion::ColorPrint: { const int color_cnt = (int)tool_colors.size()/4; - const auto color_print_cnt = (int)cp_values.size(); + if (color_print_cnt > 0) { + GCodePreviewData::Color color; + ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (color_cnt-1) * 4), 4 * sizeof(float)); + items.emplace_back(Slic3r::I18N::translate(L("Pause print or custom G-code")), color); + } + for (int i = color_print_cnt; i >= 0 ; --i) { GCodePreviewData::Color color; @@ -482,6 +491,33 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: items.emplace_back(id_str + (boost::format(Slic3r::I18N::translate(L("%.2f - %.2f mm"))) % cp_values[i - 1].second% cp_values[i].first).str(), color); } break; + }*/ + case Extrusion::ColorPrint: + { + const int color_cnt = (int)tool_colors.size()/4; + const auto color_print_cnt = (int)cp_items.size(); + if (color_print_cnt == 1) // means "Default print color" + { + Color color; + ::memcpy((void*)color.rgba, (const void*)(tool_colors.data()), 4 * sizeof(float)); + + items.emplace_back(cp_items[0], color); + break; + } + + if (color_cnt != color_print_cnt) + break; + + for (int i = is_single_material_print ? color_print_cnt-1 : 0 ; + is_single_material_print ? i >= 0 : i < color_print_cnt; + is_single_material_print ? --i : ++i) + { + Color color; + ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (i % color_cnt) * 4), 4 * sizeof(float)); + + items.emplace_back(cp_items[i], color); + } + break; } case Extrusion::Num_View_Types: break; // just to supress warning about non-handled value diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 70b6edffd..149627a32 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -237,7 +237,9 @@ public: void set_extrusion_paths_colors(const std::vector& colors); std::string get_legend_title() const; - LegendItemsList get_legend_items(const std::vector& tool_colors, const std::vector>& cp_values) const; + // #ys_FIXME_COLOR + // LegendItemsList get_legend_items(const std::vector& tool_colors, const std::vector>& cp_values) const; + LegendItemsList get_legend_items(const std::vector& tool_colors, const std::vector& cp_items, bool is_single_material_print) const; // Return an estimate of the memory consumed by the time estimator. size_t memory_used() const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b9b4c93a4..d2980fd35 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -886,6 +886,74 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePrevie } } +void GLCanvas3D::LegendTexture::fill_color_print_legend_items(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, + std::vector& cp_legend_items) +{ + if (preview_data.extrusion.view_type != GCodePreviewData::Extrusion::ColorPrint ) + return; + + std::vector custom_gcode_per_height = wxGetApp().plater()->model().custom_gcode_per_height; + if (custom_gcode_per_height.empty()) { + cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); + return; + } + + const int extruders_cnt = wxGetApp().extruders_edited_cnt(); + + if (extruders_cnt == 1) + { + std::vector> cp_values; + + std::vector print_zs = canvas.get_current_print_zs(true); + for (auto custom_code : custom_gcode_per_height) + { + if (custom_code.gcode != "M600") + continue; + auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.height - DoubleSlider::epsilon()); + + if (lower_b == print_zs.end()) + continue; + + double current_z = *lower_b; + double previous_z = lower_b == print_zs.begin() ? 0.0 : *(--lower_b); + + // to avoid duplicate values, check adding values + if (cp_values.empty() || + !(cp_values.back().first == previous_z && cp_values.back().second == current_z)) + cp_values.push_back(std::pair(previous_z, current_z)); + } + + const auto items_cnt = (int)cp_values.size(); + + for (int i = 0; items_cnt > 0 && i <= items_cnt; ++i) + { + std::string id_str = std::to_string(i + 1) + ": "; + + if (i == 0) { + cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values[0].first).str()); + continue; + } + if (i == items_cnt) { + cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str()); + break; + } + + cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str()); + } + } + else + { + for (unsigned int i = 0; i < extruders_cnt; ++i) + cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); + + for (auto custom_code : custom_gcode_per_height) + if (custom_code.gcode == "M600") + cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_code.extruder % custom_code.height).str()); + } + + cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); +} + bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector& tool_colors, const GLCanvas3D& canvas, bool compress) { reset(); @@ -893,10 +961,17 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c // collects items to render auto title = _(preview_data.get_legend_title()); - std::vector> cp_legend_values; - fill_color_print_legend_values(preview_data, canvas, cp_legend_values); + // #ys_FIXME_COLOR + // std::vector> cp_legend_values; + // fill_color_print_legend_values(preview_data, canvas, cp_legend_values); - const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_values); + // const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_values); + + std::vector cp_legend_items; + cp_legend_items.reserve(tool_colors.size()); + fill_color_print_legend_items(preview_data, canvas, cp_legend_items); + + const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_items, wxGetApp().extruders_edited_cnt() == 1); unsigned int items_count = (unsigned int)items.size(); if (items_count == 0) @@ -4729,20 +4804,71 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c const std::string& code = it->gcode; // pause print or custom Gcode if (code == "M601" || (code != "M600" && code != "tool_change")) - return number_tools(); + return number_tools()-1; // last color item is a gray color for pause print or custom G-code // change tool (extruder) - if (code == "tool_change") - return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); - // change color for current extruder - if (code == "M600" && it->extruder == extruder) { - int shift = 0; - while (it != color_print_values->begin()) { - --it; - if (it->gcode == "M600") - shift++; + if (code == "tool_change") { + if (number_tools() == extruders_cnt+1) + return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); + + auto it_n = it; + bool apply_color_change = false; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "M600" && it_n->extruder == it->extruder) { + apply_color_change = true; + break; + } + } + if (apply_color_change) + { + int shift = 0; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } + + return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); + } + // change color for current extruder + if (code == "M600") { + if (it->extruder == extruder) { + int shift = 0; + while (it != color_print_values->begin()) { + --it; + if (it->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } + + if (is_single_material_print) + { + auto it_n = it; + bool apply_color_change = false; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "tool_change") { + if (it_n->extruder == it->extruder) + apply_color_change = true; + break; + } + } + + if (apply_color_change) + { + int shift = 0; + while (it != color_print_values->begin()) { + --it; + if (it->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } } - return extruders_cnt + shift; } } @@ -4753,19 +4879,71 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c --it; const std::string& code = it->gcode; // change color for current extruder - if (code == "M600" && it->extruder == extruder) { - auto it_n = it; - int shift = 0; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->gcode == "M600") - shift++; + if (code == "M600") + { + if (it->extruder == extruder) { + int shift = 0; + while (it != color_print_values->begin()) { + --it; + if (it->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } + + if (is_single_material_print) + { + auto it_n = it; + bool apply_color_change = false; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "tool_change") { + if (it_n->extruder == it->extruder) + apply_color_change = true; + break; + } + } + + if (apply_color_change) + { + int shift = 0; + while (it != color_print_values->begin()) { + --it; + if (it->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } } - return extruders_cnt + shift; } // change tool (extruder) if (code == "tool_change") + { + if (number_tools() == extruders_cnt + 1) + return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); + + auto it_n = it; + bool apply_color_change = false; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "M600" && it_n->extruder == it->extruder) { + apply_color_change = true; + break; + } + } + if (apply_color_change) + { + int shift = 0; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } + return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); + } } return std::min(extruders_cnt - 1, std::max(extruder - 1, 0));; @@ -4827,14 +5005,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { return *vols[ctxt.color_by_color_print()? //color_print_layer_to_glvolume[layer_idx - range.begin()] : - ctxt.color_print_color_idx_by_layer_idx_and_extruder(layer_idx/* - range.begin()*/, extruder) : + ctxt.color_print_color_idx_by_layer_idx_and_extruder(layer_idx, extruder) : ctxt.color_by_tool() ? std::min(ctxt.number_tools() - 1, std::max(extruder - 1, 0)) : feature ]; }; - if (ctxt.color_by_color_print()) { - /* // Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color. + /*if (ctxt.color_by_color_print()) { + // Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color. std::vector color_print_tool_to_glvolume(ctxt.number_tools(), -1); color_print_layer_to_glvolume.reserve(range.end() - range.begin()); vols.reserve(ctxt.number_tools()); @@ -4847,12 +5025,12 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c color_print_layer_to_glvolume.emplace_back(color_print_tool_to_glvolume[idx_tool]); } vols.emplace_back(new_volume(ctxt.color_pause_or_custom_code())); - }*/ + } for (size_t i = 0; i < ctxt.number_tools(); ++i) vols.emplace_back(new_volume(ctxt.color_tool(i))); vols.emplace_back(new_volume(ctxt.color_pause_or_custom_code())); } - else if (ctxt.color_by_tool()) { + else */if (ctxt.color_by_color_print() || ctxt.color_by_tool()) { for (size_t i = 0; i < ctxt.number_tools(); ++i) vols.emplace_back(new_volume(ctxt.color_tool(i))); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9a0582fee..01d109fd6 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -348,6 +348,9 @@ private: void fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, std::vector>& cp_legend_values); + void fill_color_print_legend_items(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, + std::vector& cp_legend_items); + bool generate(const GCodePreviewData& preview_data, const std::vector& tool_colors, const GLCanvas3D& canvas, bool compress); void render(const GLCanvas3D& canvas) const; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index dcb11cf0b..7aa613883 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -892,6 +892,7 @@ void Preview::load_print_as_fff(bool keep_z_range) for (const Model::CustomGCode& code : color_print_values) if (code.gcode == "M600") colors.push_back(code.color); + colors.push_back("#808080"); // gray color for pause print or custom G-code if (gcode_preview_data_valid) color_print_values.clear(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 835737198..d2a61f10f 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3306,23 +3306,6 @@ void DoubleSlider::move_current_thumb(const bool condition) ProcessWindowEvent(e); } -static std::string get_new_color(const std::string& color) -{ - wxColour clr(color); - if (!clr.IsOk()) - clr = wxColour(0, 0, 0); // Don't set alfa to transparence - - auto data = new wxColourData(); - data->SetChooseFull(1); - data->SetColour(clr); - - wxColourDialog dialog(nullptr, data); - dialog.CenterOnParent(); - if (dialog.ShowModal() == wxID_OK) - return dialog.GetColourData().GetColour().GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); - return color; -} - void DoubleSlider::action_tick(const TicksAction action) { if (m_selection == ssUndef) @@ -3558,6 +3541,23 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) event.Skip(); } +static std::string get_new_color(const std::string& color) +{ + wxColour clr(color); + if (!clr.IsOk()) + clr = wxColour(0, 0, 0); // Don't set alfa to transparence + + auto data = new wxColourData(); + data->SetChooseFull(1); + data->SetColour(clr); + + wxColourDialog dialog(nullptr, data); + dialog.CenterOnParent(); + if (dialog.ShowModal() == wxID_OK) + return dialog.GetColourData().GetColour().GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); + return ""; +} + void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; @@ -3570,6 +3570,8 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) { std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); color = get_new_color(colors[selected_extruder > 0 ? selected_extruder-1 : 0]); + if (color.empty()) + return; } else if (code.empty()) { From ba0ad954e8d7075f1fae6c819a57077919a8dccd Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 5 Nov 2019 12:55:16 +0100 Subject: [PATCH 18/45] Code cleaning for the 6ed9adaefffa675c9df02ddc7428f89158ad2e29 commit --- src/slic3r/GUI/GLCanvas3D.cpp | 195 +++++++++++--------------------- src/slic3r/GUI/GUI_Preview.cpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 2 +- 3 files changed, 68 insertions(+), 130 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d2980fd35..f6fe759d9 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -893,15 +893,14 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(const GCodePreview return; std::vector custom_gcode_per_height = wxGetApp().plater()->model().custom_gcode_per_height; - if (custom_gcode_per_height.empty()) { - cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); - return; - } const int extruders_cnt = wxGetApp().extruders_edited_cnt(); - if (extruders_cnt == 1) { + if (custom_gcode_per_height.empty()) { + cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); + return; + } std::vector> cp_values; std::vector print_zs = canvas.get_current_print_zs(true); @@ -4807,68 +4806,13 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c return number_tools()-1; // last color item is a gray color for pause print or custom G-code // change tool (extruder) - if (code == "tool_change") { - if (number_tools() == extruders_cnt+1) - return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); - - auto it_n = it; - bool apply_color_change = false; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->gcode == "M600" && it_n->extruder == it->extruder) { - apply_color_change = true; - break; - } - } - if (apply_color_change) - { - int shift = 0; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->gcode == "M600") - shift++; - } - return extruders_cnt + shift; - } - - return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); - } + if (code == "tool_change") + return get_color_idx_for_tool_change(it, extruder); // change color for current extruder if (code == "M600") { - if (it->extruder == extruder) { - int shift = 0; - while (it != color_print_values->begin()) { - --it; - if (it->gcode == "M600") - shift++; - } - return extruders_cnt + shift; - } - - if (is_single_material_print) - { - auto it_n = it; - bool apply_color_change = false; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->gcode == "tool_change") { - if (it_n->extruder == it->extruder) - apply_color_change = true; - break; - } - } - - if (apply_color_change) - { - int shift = 0; - while (it != color_print_values->begin()) { - --it; - if (it->gcode == "M600") - shift++; - } - return extruders_cnt + shift; - } - } + int color_idx = get_color_idx_for_color_change(it, extruder); + if (color_idx >= 0) + return color_idx; } } @@ -4877,77 +4821,70 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c while (it != color_print_values->begin()) { --it; - const std::string& code = it->gcode; // change color for current extruder - if (code == "M600") - { - if (it->extruder == extruder) { - int shift = 0; - while (it != color_print_values->begin()) { - --it; - if (it->gcode == "M600") - shift++; - } - return extruders_cnt + shift; - } - - if (is_single_material_print) - { - auto it_n = it; - bool apply_color_change = false; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->gcode == "tool_change") { - if (it_n->extruder == it->extruder) - apply_color_change = true; - break; - } - } - - if (apply_color_change) - { - int shift = 0; - while (it != color_print_values->begin()) { - --it; - if (it->gcode == "M600") - shift++; - } - return extruders_cnt + shift; - } - } + if (it->gcode == "M600") { + int color_idx = get_color_idx_for_color_change(it, extruder); + if (color_idx >= 0) + return color_idx; } // change tool (extruder) - if (code == "tool_change") - { - if (number_tools() == extruders_cnt + 1) - return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); - - auto it_n = it; - bool apply_color_change = false; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->gcode == "M600" && it_n->extruder == it->extruder) { - apply_color_change = true; - break; - } - } - if (apply_color_change) - { - int shift = 0; - while (it_n != color_print_values->begin()) { - --it_n; - if (it_n->gcode == "M600") - shift++; - } - return extruders_cnt + shift; - } - - return std::min(extruders_cnt - 1, std::max(it->extruder - 1, 0)); - } + if (it->gcode == "tool_change") + return get_color_idx_for_tool_change(it, extruder); } return std::min(extruders_cnt - 1, std::max(extruder - 1, 0));; } + + private: + int get_m600_color_idx(std::vector::const_iterator it) const + { + int shift = 0; + while (it != color_print_values->begin()) { + --it; + if (it->gcode == "M600") + shift++; + } + return extruders_cnt + shift; + } + + int get_color_idx_for_tool_change(std::vector::const_iterator it, const int extruder) const + { + const int current_extruder = it->extruder == 0 ? extruder : it->extruder; + if (number_tools() == extruders_cnt + 1) // there is no one "M600" + return std::min(extruders_cnt - 1, std::max(current_extruder - 1, 0)); + + auto it_n = it; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "M600" && it_n->extruder == current_extruder) + return get_m600_color_idx(it_n); + } + + return std::min(extruders_cnt - 1, std::max(current_extruder - 1, 0)); + } + + int get_color_idx_for_color_change(std::vector::const_iterator it, const int extruder) const + { + if (extruders_cnt == 1) + return get_m600_color_idx(it); + + auto it_n = it; + bool is_tool_change = false; + while (it_n != color_print_values->begin()) { + --it_n; + if (it_n->gcode == "tool_change") { + is_tool_change = true; + if (it_n->extruder == it->extruder) + return get_m600_color_idx(it); + break; + } + } + if (!is_tool_change && it->extruder == extruder) + return get_m600_color_idx(it); + + return -1; + } + } ctxt; ctxt.has_perimeters = print_object.is_step_done(posPerimeters); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 7aa613883..cfcf5a67c 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -641,6 +641,7 @@ void Preview::create_double_slider() evt.StopPropagation(); }); + m_extruder_selector->Disable(); auto sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(m_extruder_selector, 0, wxEXPAND, 0); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index d2a61f10f..0234b864e 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3615,7 +3615,7 @@ void DoubleSlider::change_extruder(int extruder) // if on this Y doesn't exist tick if (m_ticks_.find(tick) == m_ticks_.end()) { - m_ticks_.insert(TICK_CODE(tick, "tool_change", extruder, colors[extruder-1])); + m_ticks_.insert(TICK_CODE(tick, "tool_change", extruder, extruder == 0 ? "" : colors[extruder-1])); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); From c4a62819f4de328a90ec508b3cebf3eae372f48e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 6 Nov 2019 16:06:21 +0100 Subject: [PATCH 19/45] Implemented new color change preview from Gcode + Added missed "change_extruder.svg" --- resources/icons/change_extruder.svg | 9 +++++ src/libslic3r/GCode.cpp | 48 +++++++++++++++++++++++- src/libslic3r/GCode/Analyzer.cpp | 58 +++++++++++++++++++++++++++-- src/libslic3r/GCode/Analyzer.hpp | 16 +++++++- src/libslic3r/GCode/PreviewData.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 14 ++++--- 6 files changed, 133 insertions(+), 14 deletions(-) create mode 100644 resources/icons/change_extruder.svg diff --git a/resources/icons/change_extruder.svg b/resources/icons/change_extruder.svg new file mode 100644 index 000000000..fe8de635d --- /dev/null +++ b/resources/icons/change_extruder.svg @@ -0,0 +1,9 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + + + \ No newline at end of file diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2a74de41d..9d196cbd2 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1709,8 +1709,47 @@ void GCode::process_layer( // // gcode += "M600\n"; // } - if (colorprint_change) { + + // don't save "tool_change" code to GCode + if (colorprint_change && custom_code != "tool_change") { const bool single_material_print = print.config().nozzle_diameter.size() == 1; + + if (custom_code == "M600") // color change + { + // add tag for analyzer + gcode += "; " + GCodeAnalyzer::Color_Change_Tag + ",T" + std::to_string(m600_before_extruder) + "\n"; + // add tag for time estimator + gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; + + if (!single_material_print && m600_before_extruder >= 0 && first_extruder_id != m600_before_extruder + // && !MMU1 + ) { + gcode += "M601\n"; // pause print + gcode += "M117 Change filament for Extruder " + std::to_string(m600_before_extruder) + "\n"; + } + else + gcode += custom_code + "\n"; + } + else + { + if (custom_code == "M601") // Pause print + { + // add tag for analyzer + gcode += "; " + GCodeAnalyzer::Pause_Print_Tag + "\n"; + // add tag for time estimator + //gcode += "; " + GCodeTimeEstimator::Pause_Print_Tag + "\n"; + } + else // custom Gcode + { + // add tag for analyzer + gcode += "; " + GCodeAnalyzer::Custom_Code_Tag + "\n"; + // add tag for time estimator + //gcode += "; " + GCodeTimeEstimator::Custom_Code_Tag + "\n"; + } + gcode += custom_code + "\n"; + } + + /* if (single_material_print || custom_code != "tool_change") { // add tag for analyzer @@ -1730,6 +1769,7 @@ void GCode::process_layer( else gcode += custom_code + "\n"; } + */ } @@ -2039,6 +2079,12 @@ void GCode::process_layer( if (m_cooling_buffer) gcode = m_cooling_buffer->process_layer(gcode, layer.id()); + // add tag for analyzer + if (gcode.find(GCodeAnalyzer::Pause_Print_Tag) != gcode.npos) + gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; + else if (gcode.find(GCodeAnalyzer::Custom_Code_Tag) != gcode.npos) + gcode += "\n; " + GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag + "\n"; + #ifdef HAS_PRESSURE_EQUALIZER // Apply pressure equalization if enabled; // printf("G-code before filter:\n%s\n", gcode.c_str()); diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index 3f0b8735f..f73f4b4ba 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -29,6 +29,9 @@ const std::string GCodeAnalyzer::Mm3_Per_Mm_Tag = "_ANALYZER_MM3_PER_MM:"; const std::string GCodeAnalyzer::Width_Tag = "_ANALYZER_WIDTH:"; const std::string GCodeAnalyzer::Height_Tag = "_ANALYZER_HEIGHT:"; const std::string GCodeAnalyzer::Color_Change_Tag = "_ANALYZER_COLOR_CHANGE"; +const std::string GCodeAnalyzer::Pause_Print_Tag = "_ANALYZER_PAUSE_PRINT"; +const std::string GCodeAnalyzer::Custom_Code_Tag = "_ANALYZER_CUSTOM_CODE"; +const std::string GCodeAnalyzer::End_Pause_Print_Or_Custom_Code_Tag = "_ANALYZER_END_PAUSE_PRINT_OR_CUSTOM_CODE"; const double GCodeAnalyzer::Default_mm3_per_mm = 0.0; const float GCodeAnalyzer::Default_Width = 0.0f; @@ -118,6 +121,8 @@ void GCodeAnalyzer::set_extruder_offsets(const GCodeAnalyzer::ExtruderOffsetsMap void GCodeAnalyzer::set_extruders_count(unsigned int count) { m_extruders_count = count; + for (unsigned int i=0; i GCodeMovesList; typedef std::map TypeToMovesMap; typedef std::map ExtruderOffsetsMap; + typedef std::map ExtruderToColorMap; private: struct State @@ -102,7 +106,7 @@ private: float start_extrusion; float position[Num_Axis]; float origin[Num_Axis]; - unsigned int cur_cp_color_id = 0; + unsigned int cp_color_counter = 0; }; private: @@ -113,6 +117,8 @@ private: unsigned int m_extruders_count; GCodeFlavor m_gcode_flavor; + ExtruderToColorMap m_extruder_color; + // The output of process_layer() std::string m_process_output; @@ -212,7 +218,13 @@ private: void _process_height_tag(const std::string& comment, size_t pos); // Processes color change tag - void _process_color_change_tag(); + void _process_color_change_tag(int extruder); + + // Processes pause print and custom gcode tag + void _process_pause_print_or_custom_code_tag(); + + // Processes new layer tag + void _process_end_pause_print_or_custom_code_tag(); void _set_units(EUnits units); EUnits _get_units() const; diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index dc4e8cf48..69f685fd4 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -513,7 +513,7 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: is_single_material_print ? --i : ++i) { Color color; - ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (i % color_cnt) * 4), 4 * sizeof(float)); + ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + i * 4), 4 * sizeof(float)); items.emplace_back(cp_items[i], color); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f6fe759d9..6943aa248 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4874,7 +4874,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c --it_n; if (it_n->gcode == "tool_change") { is_tool_change = true; - if (it_n->extruder == it->extruder) + if (it_n->extruder == it->extruder || (it_n->extruder == 0 && it->extruder == extruder)) return get_m600_color_idx(it); break; } @@ -5296,12 +5296,14 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat } case GCodePreviewData::Extrusion::ColorPrint: { - int color_cnt = (int)tool_colors.size() / 4; + // int color_cnt = (int)tool_colors.size() / 4; + + // int val = int(value); + // while (val >= color_cnt) + // val -= color_cnt; + + unsigned int val = unsigned int(value) >= INT_MAX ? tool_colors.size()*4 - 1 : value; - int val = int(value); - while (val >= color_cnt) - val -= color_cnt; - GCodePreviewData::Color color; ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + val * 4), 4 * sizeof(float)); From 72852ffab59574049afe144a8388f9c31d55942a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Nov 2019 13:51:54 +0100 Subject: [PATCH 20/45] Updated DoubleSlider band. Added smart color selection for M600 --- src/slic3r/GUI/GLCanvas3D.cpp | 4 +- src/slic3r/GUI/GUI_Preview.cpp | 5 +- src/slic3r/GUI/Plater.cpp | 11 +++ src/slic3r/GUI/Plater.hpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 135 +++++++++++++++++++++++++++----- src/slic3r/GUI/wxExtensions.hpp | 2 + 6 files changed, 136 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6943aa248..3fde9a084 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5296,13 +5296,13 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat } case GCodePreviewData::Extrusion::ColorPrint: { - // int color_cnt = (int)tool_colors.size() / 4; + int color_cnt = (int)tool_colors.size() / 4; // int val = int(value); // while (val >= color_cnt) // val -= color_cnt; - unsigned int val = unsigned int(value) >= INT_MAX ? tool_colors.size()*4 - 1 : value; + int val = value > color_cnt ? color_cnt - 1 : value; GCodePreviewData::Color color; ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + val * 4), 4 * sizeof(float)); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index cfcf5a67c..a52322e04 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -887,12 +887,13 @@ void Preview::load_print_as_fff(bool keep_z_range) // set color print values, if it si selected "ColorPrint" view type if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) { - colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); color_print_values = wxGetApp().plater()->model().custom_gcode_per_height; + /* colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); for (const Model::CustomGCode& code : color_print_values) if (code.gcode == "M600") - colors.push_back(code.color); + colors.push_back(code.color);*/ + colors = wxGetApp().plater()->get_colors_for_color_print(); colors.push_back("#808080"); // gray color for pause print or custom G-code if (gcode_preview_data_valid) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 14fbdf72c..0089910a0 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4995,6 +4995,17 @@ std::vector Plater::get_extruder_colors_from_plater_config() const return extruder_colors; } +std::vector Plater::get_colors_for_color_print() const +{ + std::vector colors = get_extruder_colors_from_plater_config(); + + for (const Model::CustomGCode& code : p->model.custom_gcode_per_height) + if (code.gcode == "M600") + colors.push_back(code.color); + + return colors; +} + wxString Plater::get_project_filename(const wxString& extension) const { return p->get_project_filename(extension); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 00ceb89bc..623886780 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -221,6 +221,7 @@ public: void on_activate(); const DynamicPrintConfig* get_plater_config() const; std::vector get_extruder_colors_from_plater_config() const; + std::vector get_colors_for_color_print() const; void update_object_menu(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 0234b864e..bbba3a2fd 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2644,12 +2644,12 @@ void DoubleSlider::render() // //higher slider: // draw_thumb(dc, higher_pos, ssHigher); - // draw both sliders - draw_thumbs(dc, lower_pos, higher_pos); - //draw color print ticks draw_ticks(dc); + // draw both sliders + draw_thumbs(dc, lower_pos, higher_pos); + //draw lock/unlock draw_one_layer_icon(dc); @@ -2827,6 +2827,18 @@ void DoubleSlider::draw_ticks(wxDC& dc) dc.DrawLine(mid - 14, pos/* - 1*/, mid - 9, pos/* - 1*/); is_horizontal() ? dc.DrawLine(pos, mid+14, pos, mid+9) : dc.DrawLine(mid + 14, pos/* - 1*/, mid + 9, pos/* - 1*/); + + // Draw icon for "Pause print" or "Extruder change" + if (tick.gcode != "M600" && tick.gcode != "tool_change") + { + wxBitmap icon = create_scaled_bitmap(nullptr, tick.gcode == "M601" ? "pause_add.png" : "add_gcode"); + + wxCoord x_draw, y_draw; + is_horizontal() ? x_draw = pos - 0.5 * m_tick_icon_dim : y_draw = pos - 0.5 * m_tick_icon_dim; + is_horizontal() ? y_draw = mid + 22 : x_draw = mid + 22 ; + + dc.DrawBitmap(icon, x_draw, y_draw); + } } } @@ -2853,7 +2865,7 @@ void DoubleSlider::draw_colored_band(wxDC& dc) // #ys_FIXME_COLOR // if (m_ticks.empty()) { - if (m_ticks_.empty()) { + /*if (m_ticks_.empty()) { dc.SetPen(GetParent()->GetBackgroundColour()); dc.SetBrush(GetParent()->GetBackgroundColour()); dc.DrawRectangle(main_band); @@ -2886,6 +2898,37 @@ void DoubleSlider::draw_colored_band(wxDC& dc) dc.SetBrush(clr); dc.DrawRectangle(main_band); i++; + }*/ + + auto draw_band = [](wxDC& dc, const wxColour& clr, const wxRect& band_rc) { + dc.SetPen(clr); + dc.SetBrush(clr); + dc.DrawRectangle(band_rc); + }; + + const std::vector& colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); + int colors_cnt = colors.size(); + + const wxColour bg_clr = GetParent()->GetBackgroundColour(); + + wxColour clr = m_state == msSingleExtruder ? wxColour(colors[0]) : bg_clr; + draw_band(dc, clr, main_band); + + size_t i = 1; + for (auto tick : m_ticks_) + { + if ( (m_state == msSingleExtruder && tick.gcode != "M600") || + (m_state == msMultiExtruderWholePrint && tick.gcode != "tool_change") ) + continue; + + const wxCoord pos = get_position_from_value(tick.tick); + is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) : + main_band.SetBottom(pos - 1); + + clr = (m_state == msMultiExtruderWholePrint && tick.color.empty()) ? bg_clr : + m_state == msMultiExtruderWholePrint ? wxColour(colors[std::min(colors_cnt - 1, tick.extruder-1)]) : wxColour(tick.color); + draw_band(dc, clr, main_band); + i++; } } @@ -3166,11 +3209,13 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus) const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; const auto tick_code_it = m_ticks_.find(tick); tooltip = tick_code_it == m_ticks_.end() ? _(L("Add color change")) : - tick_code_it->gcode == "M600" ? _(L("Delete color change")) : + // tick_code_it->gcode == "M600" ? _(L("Delete color change")) : + tick_code_it->gcode == "M600" ? ( m_state == msSingleExtruder ? _(L("Delete color change")) : + from_u8((boost::format(_utf8(L("Delete color change for Extruder %1%"))) % tick_code_it->extruder).str()) ): tick_code_it->gcode == "M601" ? _(L("Delete pause")) : - tick_code_it->gcode == "tool_change" ? ( m_state == msSingleExtruder ? _(L("Delete color change")) : - from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) ) : - from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); + tick_code_it->gcode == "tool_change" ? //( m_state == msSingleExtruder ? _(L("Delete color change")) : + from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) /*) */: + from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); } return tooltip; @@ -3441,12 +3486,19 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) // if on this Y doesn't exist tick // #ys_FIXME_COLOR // if (m_ticks.find(tick) == m_ticks.end()) - if (m_ticks_.find(tick) == m_ticks_.end()) + auto it = m_ticks_.find(tick); + if (it == m_ticks_.end()) { // show context menu on OnRightUp() m_show_context_menu = true; return; } + if (it->gcode == "M600") + { + // show "Edit color" or "Delete color change" menu on OnRightUp() + m_show_edit_color_menu = true; + return; + } } detect_selected_slider(event.GetLogicalPosition(dc)); @@ -3469,15 +3521,17 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) int DoubleSlider::get_extruder_for_tick(int tick) { int extruder = 0; - if (!m_ticks_.empty()) { - auto tick_code_it = m_ticks_.lower_bound(tick); - if (tick_code_it != m_ticks_.begin()) { - --tick_code_it; - extruder = tick_code_it->extruder; - } + if (m_ticks_.empty()) + return 0; + + auto it = m_ticks_.lower_bound(tick); + while (it != m_ticks_.begin()) { + --it; + if(it->gcode == "tool_change") + return it->extruder; } - return extruder; + return 0; } void DoubleSlider::OnRightUp(wxMouseEvent& event) @@ -3535,6 +3589,19 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) m_show_context_menu = false; } + else if (m_show_edit_color_menu) { + wxMenu menu; + + append_menu_item(&menu, wxID_ANY, _(L("Edit color")), "", + [this](wxCommandEvent&) { edit_color(); }, "change_extruder", &menu); + + append_menu_item(&menu, wxID_ANY, _(L("Delete color change")), "", + [this](wxCommandEvent&) { action_tick(taDel); }, "colorchange_delete_off.png", &menu); + + Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); + + m_show_edit_color_menu = false; + } Refresh(); Update(); @@ -3561,7 +3628,7 @@ static std::string get_new_color(const std::string& color) void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - // if on this Y doesn't exist tick + // if on this Z doesn't exist tick auto it = m_ticks_.find(tick); if (it == m_ticks_.end()) { @@ -3569,7 +3636,20 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) if (code == "M600") { std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); - color = get_new_color(colors[selected_extruder > 0 ? selected_extruder-1 : 0]); + + if (m_state == msSingleExtruder && !m_ticks_.empty()) { + auto before_tick_it = std::lower_bound(m_ticks_.begin(), m_ticks_.end(), tick); + if (before_tick_it == m_ticks_.begin()) + color = colors[0]; + else { + --before_tick_it; + color = before_tick_it->color; + } + } + else + color = colors[selected_extruder > 0 ? selected_extruder-1 : 0]; + + color = get_new_color(color); if (color.empty()) return; } @@ -3606,6 +3686,25 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) } } +void DoubleSlider::edit_color() +{ + const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + // if on this Z exists tick + std::set::iterator it = m_ticks_.find(tick); + if (it != m_ticks_.end()) + { + std::string color = get_new_color(it->color); + if (color.empty()) + return; + TICK_CODE changed_tick = *it; + changed_tick.color = color; + m_ticks_.erase(it); + m_ticks_.insert(changed_tick); + + wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + } +} + void DoubleSlider::change_extruder(int extruder) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 5cdf99c60..48c3ac08d 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -854,6 +854,7 @@ public: int get_extruder_for_tick(int tick); void OnRightUp(wxMouseEvent& event); void add_code(std::string code, int selected_extruder = -1); + void edit_color(); void change_extruder(int extruder); protected: @@ -922,6 +923,7 @@ private: bool m_is_one_layer_icon_focesed = false; bool m_is_enabled_tick_manipulation = true; bool m_show_context_menu = false; + bool m_show_edit_color_menu = false; bool m_suppress_add_code = false; ManipulationState m_state = msSingleExtruder; wxString m_custom_gcode = wxEmptyString; From f2120c11227bafa5fa8d3f32e865eebe5c95d92d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Nov 2019 16:36:24 +0100 Subject: [PATCH 21/45] Fixed a sequence of the legend items --- src/libslic3r/GCode/PreviewData.cpp | 6 +-- src/libslic3r/GCode/PreviewData.hpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 78 ++++++++++++++++++++++------- src/slic3r/GUI/GLCanvas3D.hpp | 6 ++- src/slic3r/GUI/wxExtensions.cpp | 14 ++++-- 5 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index 69f685fd4..ba0584e57 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -382,7 +382,7 @@ std::string GCodePreviewData::get_legend_title() const // #ys_FIXME_COLOR // GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector& tool_colors, const std::vector>& cp_values) const GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector& tool_colors, - const std::vector& cp_items, bool is_single_material_print) const + const std::vector& cp_items) const { struct Helper { @@ -508,9 +508,7 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: if (color_cnt != color_print_cnt) break; - for (int i = is_single_material_print ? color_print_cnt-1 : 0 ; - is_single_material_print ? i >= 0 : i < color_print_cnt; - is_single_material_print ? --i : ++i) + for (int i = 0 ; i < color_print_cnt; ++i) { Color color; ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + i * 4), 4 * sizeof(float)); diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 149627a32..78de04d0a 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -239,7 +239,7 @@ public: std::string get_legend_title() const; // #ys_FIXME_COLOR // LegendItemsList get_legend_items(const std::vector& tool_colors, const std::vector>& cp_values) const; - LegendItemsList get_legend_items(const std::vector& tool_colors, const std::vector& cp_items, bool is_single_material_print) const; + LegendItemsList get_legend_items(const std::vector& tool_colors, const std::vector& cp_items) const; // Return an estimate of the memory consumed by the time estimator. size_t memory_used() const; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3fde9a084..074713f82 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -886,12 +886,11 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePrevie } } -void GLCanvas3D::LegendTexture::fill_color_print_legend_items(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, - std::vector& cp_legend_items) +void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D& canvas, + const std::vector& colors_in, + std::vector& colors, + std::vector& cp_legend_items) { - if (preview_data.extrusion.view_type != GCodePreviewData::Extrusion::ColorPrint ) - return; - std::vector custom_gcode_per_height = wxGetApp().plater()->model().custom_gcode_per_height; const int extruders_cnt = wxGetApp().extruders_edited_cnt(); @@ -899,6 +898,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(const GCodePreview { if (custom_gcode_per_height.empty()) { cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); + colors = colors_in; return; } std::vector> cp_values; @@ -923,18 +923,36 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(const GCodePreview } const auto items_cnt = (int)cp_values.size(); - - for (int i = 0; items_cnt > 0 && i <= items_cnt; ++i) + if (items_cnt == 0) // There is no one color change, but there is/are some pause print or custom Gcode { + cp_legend_items.push_back(I18N::translate_utf8(L("Default print color"))); + cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); + colors = colors_in; + return; + } + + const int color_cnt = (int)colors_in.size() / 4; + colors.resize(colors_in.size(), 0.0); + + ::memcpy((void*)(colors.data()), (const void*)(colors_in.data() + (color_cnt - 1) * 4), 4 * sizeof(float)); + cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); + size_t color_pos = 4; + + for (int i = items_cnt; i >= 0; --i, color_pos+=4) + { + // update colors for color print item + ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + i * 4), 4 * sizeof(float)); + + // create label for color print item std::string id_str = std::to_string(i + 1) + ": "; if (i == 0) { cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("up to %.2f mm"))) % cp_values[0].first).str()); - continue; + break; } if (i == items_cnt) { cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("above %.2f mm"))) % cp_values[i - 1].second).str()); - break; + continue; } cp_legend_items.push_back(id_str + (boost::format(I18N::translate_utf8(L("%.2f - %.2f mm"))) % cp_values[i - 1].second % cp_values[i].first).str()); @@ -942,18 +960,34 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items(const GCodePreview } else { + // colors = colors_in; + const int color_cnt = (int)colors_in.size() / 4; + colors.resize(colors_in.size(), 0.0); + + ::memcpy((void*)(colors.data()), (const void*)(colors_in.data()), 4 * extruders_cnt * sizeof(float)); + size_t color_pos = 4 * extruders_cnt; + size_t color_in_pos = 4 * (color_cnt - 1); + for (unsigned int i = 0; i < extruders_cnt; ++i) cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Extruder %d"))) % (i + 1)).str()); - - for (auto custom_code : custom_gcode_per_height) - if (custom_code.gcode == "M600") - cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_code.extruder % custom_code.height).str()); - } - cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); + ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); + color_pos += 4; + color_in_pos -= 4; + cp_legend_items.push_back(I18N::translate_utf8(L("Pause print or custom G-code"))); + + int cnt = custom_gcode_per_height.size(); + for (int i = cnt-1; i >= 0; --i) + if (custom_gcode_per_height[i].gcode == "M600") { + ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); + color_pos += 4; + color_in_pos -= 4; + cp_legend_items.push_back((boost::format(I18N::translate_utf8(L("Color change for Extruder %d at %.2f mm"))) % custom_gcode_per_height[i].extruder % custom_gcode_per_height[i].height).str()); + } + } } -bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector& tool_colors, const GLCanvas3D& canvas, bool compress) +bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector& tool_colors_in, const GLCanvas3D& canvas, bool compress) { reset(); @@ -967,10 +1001,16 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c // const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_values); std::vector cp_legend_items; - cp_legend_items.reserve(tool_colors.size()); - fill_color_print_legend_items(preview_data, canvas, cp_legend_items); + std::vector cp_colors; - const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_items, wxGetApp().extruders_edited_cnt() == 1); + if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) + { + cp_legend_items.reserve(cp_colors.size()); + fill_color_print_legend_items(canvas, tool_colors_in, cp_colors, cp_legend_items); + } + + const std::vector& tool_colors = preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint ? cp_colors : tool_colors_in; + const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_items); unsigned int items_count = (unsigned int)items.size(); if (items_count == 0) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 01d109fd6..43de4b35b 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -348,8 +348,10 @@ private: void fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, std::vector>& cp_legend_values); - void fill_color_print_legend_items(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, - std::vector& cp_legend_items); + void fill_color_print_legend_items(const GLCanvas3D& canvas, + const std::vector& colors_in, + std::vector& colors, + std::vector& cp_legend_items); bool generate(const GCodePreviewData& preview_data, const std::vector& tool_colors, const GLCanvas3D& canvas, bool compress); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index bbba3a2fd..f4c46c0f9 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -3520,7 +3521,6 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) int DoubleSlider::get_extruder_for_tick(int tick) { - int extruder = 0; if (m_ticks_.empty()) return 0; @@ -3639,12 +3639,16 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) if (m_state == msSingleExtruder && !m_ticks_.empty()) { auto before_tick_it = std::lower_bound(m_ticks_.begin(), m_ticks_.end(), tick); - if (before_tick_it == m_ticks_.begin()) - color = colors[0]; - else { + while (before_tick_it != m_ticks_.begin()) { --before_tick_it; - color = before_tick_it->color; + if (before_tick_it->gcode == "M600") { + color = before_tick_it->color; + break; + } } + + if (color.empty()) + color = colors[0]; } else color = colors[selected_extruder > 0 ? selected_extruder-1 : 0]; From ae4948bd946af8d3f4c2e184a686aa1d66468e55 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 8 Nov 2019 11:24:57 +0100 Subject: [PATCH 22/45] Fixed crash from start if SLA preset is selected. Fixed extruder selection from ObjectList under OSX --- src/slic3r/GUI/GUI_ObjectList.cpp | 32 +------------------------------ src/slic3r/GUI/GUI_Preview.cpp | 2 ++ src/slic3r/GUI/wxExtensions.cpp | 12 +++++++++--- 3 files changed, 12 insertions(+), 34 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 1cbfc2bdf..0fef8988e 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -895,12 +895,6 @@ void ObjectList::extruder_editing() if (!item || !(m_objects_model->GetItemType(item) & (itVolume | itObject))) return; - // ! #ys Use ApplyExtruderSelector instead this code - /* - std::vector icons = get_extruder_color_icons(); - if (icons.empty()) - return; - */ const int column_width = GetColumn(colExtruder)->GetWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X) + 5; wxPoint pos = get_mouse_position_in_control(); @@ -910,32 +904,8 @@ void ObjectList::extruder_editing() apply_extruder_selector(&m_extruder_editor, this, L("default"), pos, size); - // ! #ys Use ApplyExtruderSelector instead this code - /* - if (!m_extruder_editor) - m_extruder_editor = new wxBitmapComboBox(this, wxID_ANY, wxEmptyString, pos, size, - 0, nullptr, wxCB_READONLY); - else - { - m_extruder_editor->SetPosition(pos); - m_extruder_editor->SetMinSize(size); - m_extruder_editor->SetSize(size); - m_extruder_editor->Clear(); - m_extruder_editor->Show(); - } - - int i = 0; - for (wxBitmap* bmp : icons) { - if (i == 0) { - m_extruder_editor->Append(_(L("default")), *bmp); - ++i; - } - - m_extruder_editor->Append(wxString::Format("%d", i), *bmp); - ++i; - } - */ m_extruder_editor->SetSelection(m_objects_model->GetExtruderNumber(item)); + m_extruder_editor->Show(); auto set_extruder = [this]() { diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index a52322e04..847b87fd5 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -619,6 +619,8 @@ void Preview::update_extruder_selector() void Preview::create_double_slider() { m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100); + m_slider->EnableTickManipulation(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF); + // #ys_FIXME_COLOR // m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index f4c46c0f9..39fc799d7 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -505,8 +505,6 @@ void apply_extruder_selector(wxBitmapComboBox** ctrl, bool use_thin_icon/* = false*/) { std::vector icons = get_extruder_color_icons(use_thin_icon); - if (icons.empty()) - return; if (!*ctrl) *ctrl = new wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, pos, size, @@ -519,6 +517,14 @@ void apply_extruder_selector(wxBitmapComboBox** ctrl, (*ctrl)->Clear(); } + if (icons.empty() && !first_item.empty()) { + (*ctrl)->Append(_(first_item), wxNullBitmap); + return; + } + + // For ObjectList we use short extruder name (just a number) + const bool use_full_item_name = dynamic_cast(parent) == nullptr; + int i = 0; wxString str = _(L("Extruder")); for (wxBitmap* bmp : icons) { @@ -528,7 +534,7 @@ void apply_extruder_selector(wxBitmapComboBox** ctrl, ++i; } - (*ctrl)->Append(wxString::Format("%s %d", str, i), *bmp); + (*ctrl)->Append(use_full_item_name ? wxString::Format("%s %d", str, i) : std::to_string(i), *bmp); ++i; } (*ctrl)->SetSelection(0); From db458df3b50bd34dbab55fe58f7b1feb9a5481c1 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 8 Nov 2019 14:52:11 +0100 Subject: [PATCH 23/45] Fixed controls layout in ExtruderSequenceDialog Dimension of SVG-icons is calculated now according to the scale factor (on Retina displays) --- src/slic3r/GUI/ExtruderSequenceDialog.cpp | 6 ++--- src/slic3r/GUI/wxExtensions.cpp | 33 ++++++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.cpp b/src/slic3r/GUI/ExtruderSequenceDialog.cpp index ef60a041b..9f873d4c5 100644 --- a/src/slic3r/GUI/ExtruderSequenceDialog.cpp +++ b/src/slic3r/GUI/ExtruderSequenceDialog.cpp @@ -157,9 +157,9 @@ void ExtruderSequenceDialog::apply_extruder_sequence() apply_extruder_sequence(); }); - m_extruders_grid_sizer->Add(extruder_selector); - m_extruders_grid_sizer->Add(del_btn); - m_extruders_grid_sizer->Add(add_btn); + m_extruders_grid_sizer->Add(extruder_selector, 0, wxALIGN_CENTER_VERTICAL); + m_extruders_grid_sizer->Add(del_btn, 0, wxALIGN_CENTER_VERTICAL); + m_extruders_grid_sizer->Add(add_btn, 0, wxALIGN_CENTER_VERTICAL); } Fit(); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 39fc799d7..1929a3c60 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -406,6 +406,23 @@ int em_unit(wxWindow* win) return Slic3r::GUI::wxGetApp().em_unit(); } +static float get_svg_scale_factor(wxWindow *win) +{ +#ifdef __APPLE__ + // Note: win->GetContentScaleFactor() is not used anymore here because it tends to + // return bogus results quite often (such as 1.0 on Retina or even 0.0). + // We're using the max scaling factor across all screens because it's very likely to be good enough. + + static float max_scaling_factor = NAN; + if (std::isnan(max_scaling_factor)) { + max_scaling_factor = Slic3r::GUI::mac_max_scaling_factor(); + } + return win != nullptr ? max_scaling_factor : 1.0f; +#else + return 1.0f; +#endif +} + // If an icon has horizontal orientation (width > height) call this function with is_horizontal = true wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, const int px_cnt/* = 16*/, const bool is_horizontal /* = false*/, const bool grayscale/* = false*/) @@ -2278,6 +2295,8 @@ DoubleSlider::DoubleSlider( wxWindow *parent, if (!is_osx) SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX + const float scale_factor = get_svg_scale_factor(this); + m_bmp_thumb_higher = (style == wxSL_HORIZONTAL ? ScalableBitmap(this, "right_half_circle.png") : ScalableBitmap(this, "up_half_circle.png", 16, true)); m_bmp_thumb_lower = (style == wxSL_HORIZONTAL ? ScalableBitmap(this, "left_half_circle.png" ) : ScalableBitmap(this, "down_half_circle.png", 16, true)); m_thumb_size = m_bmp_thumb_lower.bmp().GetSize(); @@ -2288,16 +2307,16 @@ DoubleSlider::DoubleSlider( wxWindow *parent, m_bmp_del_tick_off = ScalableBitmap(this, "colorchange_delete_off.png"); m_tick_icon_dim = m_bmp_add_tick_on.bmp().GetSize().x; - m_bmp_one_layer_lock_on = ScalableBitmap(this, "one_layer_lock_on.png"); - m_bmp_one_layer_lock_off = ScalableBitmap(this, "one_layer_lock_off.png"); - m_bmp_one_layer_unlock_on = ScalableBitmap(this, "one_layer_unlock_on.png"); - m_bmp_one_layer_unlock_off = ScalableBitmap(this, "one_layer_unlock_off.png"); - m_lock_icon_dim = m_bmp_one_layer_lock_on.bmp().GetSize().x; + m_bmp_one_layer_lock_on = ScalableBitmap(this, "lock_closed"); + m_bmp_one_layer_lock_off = ScalableBitmap(this, "lock_closed_f"); + m_bmp_one_layer_unlock_on = ScalableBitmap(this, "lock_open"); + m_bmp_one_layer_unlock_off = ScalableBitmap(this, "lock_open_f"); + m_lock_icon_dim = int((float)m_bmp_one_layer_lock_on.bmp().GetSize().x / scale_factor); m_bmp_revert = ScalableBitmap(this, "undo"); - m_revert_icon_dim = m_bmp_revert.bmp().GetSize().x; + m_revert_icon_dim = int((float)m_bmp_revert.bmp().GetSize().x / scale_factor); m_bmp_cog = ScalableBitmap(this, "cog"); - m_cog_icon_dim = m_bmp_cog.bmp().GetSize().x; + m_cog_icon_dim = int((float)m_bmp_cog.bmp().GetSize().x / scale_factor); m_selection = ssUndef; From 7a22e438258ddac329b3565f07a413194cca2694 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 8 Nov 2019 16:38:04 +0100 Subject: [PATCH 24/45] Hided extruder selector in preview mode. Fixed tooltips for double slider. Changed left button menu for multi-material print --- src/slic3r/GUI/ExtruderSequenceDialog.cpp | 2 +- src/slic3r/GUI/GUI_Preview.cpp | 2 +- src/slic3r/GUI/wxExtensions.cpp | 114 ++++++++++++++-------- src/slic3r/GUI/wxExtensions.hpp | 2 + 4 files changed, 76 insertions(+), 44 deletions(-) diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.cpp b/src/slic3r/GUI/ExtruderSequenceDialog.cpp index 9f873d4c5..be412ee30 100644 --- a/src/slic3r/GUI/ExtruderSequenceDialog.cpp +++ b/src/slic3r/GUI/ExtruderSequenceDialog.cpp @@ -130,7 +130,7 @@ void ExtruderSequenceDialog::apply_extruder_sequence() for (size_t extruder=0; extruder < m_sequence.extruders.size(); ++extruder) { wxBitmapComboBox* extruder_selector = nullptr; - apply_extruder_selector(&extruder_selector, this, "", wxDefaultPosition, wxSize(12*wxGetApp().em_unit(), -1)); + apply_extruder_selector(&extruder_selector, this, "", wxDefaultPosition, wxSize(15*wxGetApp().em_unit(), -1)); extruder_selector->SetSelection(m_sequence.extruders[extruder]); extruder_selector->Bind(wxEVT_COMBOBOX, [this, extruder_selector, extruder](wxCommandEvent& evt) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 847b87fd5..897dfd9fc 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -517,7 +517,7 @@ void Preview::update_sliders(const std::vector& layers_z, bool keep_z_ra update_double_slider(layers_z, keep_z_range); m_double_slider_sizer->Show((size_t)0); - if (m_slider->GetManipulationState() == DoubleSlider::msSingleExtruder) +// if (m_slider->GetManipulationState() == DoubleSlider::msSingleExtruder) m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide((size_t)0); Layout(); } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 1929a3c60..57fd9907a 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3127,46 +3127,7 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) } else if (is_point_in_rect(pos, m_rect_cog_icon) && m_state == msMultiExtruderWholePrint) { // show dialog for set extruder sequence - Slic3r::GUI::ExtruderSequenceDialog dlg(m_extruders_sequence); - if (dlg.ShowModal() != wxID_OK) - return; - - m_extruders_sequence = dlg.GetValue(); - - m_ticks_.erase(std::remove_if(m_ticks_.begin(), m_ticks_.end(), - [](TICK_CODE tick) { return tick.gcode == "tool_change"; }), m_ticks_.end()); - - int tick = 0; - double value = 0.0; - int extruder = 0; - const int extr_cnt = m_extruders_sequence.extruders.size(); - - std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); - - while (tick <= m_max_value) - { - int cur_extruder = m_extruders_sequence.extruders[extruder]; - m_ticks_.insert(TICK_CODE(tick, "tool_change", cur_extruder+1, colors[cur_extruder])); - - extruder++; - if (extruder == extr_cnt) - extruder = 0; - if (m_extruders_sequence.is_mm_intervals) - { - value += m_extruders_sequence.interval_by_mm; - auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); - - if (it == m_values.end()) - break; - - tick = it - m_values.begin(); - } - else - tick += m_extruders_sequence.interval_by_layers; - } - - // m_ticks_.clear(); - wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + m_edit_extruder_sequence = true; } else detect_selected_slider(pos); @@ -3234,9 +3195,14 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; const auto tick_code_it = m_ticks_.find(tick); - tooltip = tick_code_it == m_ticks_.end() ? _(L("Add color change")) : + tooltip = tick_code_it == m_ticks_.end() ? (m_state == msSingleExtruder ? //_(L("Add color change")) : + _(L("For add color change use left mouse button click")) : + _(L("For add change extruder use left mouse button click"))) + "\n" + + _(L("For add another code use right mouse button click")) : // tick_code_it->gcode == "M600" ? _(L("Delete color change")) : - tick_code_it->gcode == "M600" ? ( m_state == msSingleExtruder ? _(L("Delete color change")) : + tick_code_it->gcode == "M600" ? ( m_state == msSingleExtruder ? //_(L("Delete color change")) : + _(L("For Delete color change use left mouse button click\n" + "For Delete color change or Edit color use right mouse button click")) : from_u8((boost::format(_utf8(L("Delete color change for Extruder %1%"))) % tick_code_it->extruder).str()) ): tick_code_it->gcode == "M601" ? _(L("Delete pause")) : tick_code_it->gcode == "tool_change" ? //( m_state == msSingleExtruder ? _(L("Delete color change")) : @@ -3315,6 +3281,7 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); if (extruders_cnt > 1) { + /* wxMenu* add_color_change_menu = new wxMenu(); for (int i = 1; i <= extruders_cnt; i++) @@ -3324,6 +3291,21 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % "M600").str()); wxMenuItem* add_color_change_menu_item = menu.AppendSubMenu(add_color_change_menu, menu_name, ""); add_color_change_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "colorchange_add_off.png")); + */ + + const int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); + + wxMenu* change_extruder_menu = new wxMenu(); + + for (int i = 0; i <= extruders_cnt; i++) { + const wxString item_name = i == 0 ? _(L("Default")) : wxString::Format(_(L("Extruder %d")), i); + + append_menu_radio_item(change_extruder_menu, wxID_ANY, item_name, "", + [this, i](wxCommandEvent&) { change_extruder(i); }, &menu)->Check(i == initial_extruder); + } + + wxMenuItem* change_extruder_menu_item = menu.AppendSubMenu(change_extruder_menu, _(L("Change extruder")), _(L("Use another extruder"))); + change_extruder_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "change_extruder")); } Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); @@ -3334,6 +3316,11 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) m_show_context_menu = false; } + if (m_edit_extruder_sequence) { + edit_extruder_sequence(); + m_edit_extruder_sequence = false; + } + Refresh(); Update(); event.Skip(); @@ -3751,6 +3738,49 @@ void DoubleSlider::change_extruder(int extruder) } } +void DoubleSlider::edit_extruder_sequence() +{ + Slic3r::GUI::ExtruderSequenceDialog dlg(m_extruders_sequence); + if (dlg.ShowModal() != wxID_OK) + return; + + m_extruders_sequence = dlg.GetValue(); + + m_ticks_.erase(std::remove_if(m_ticks_.begin(), m_ticks_.end(), + [](TICK_CODE tick) { return tick.gcode == "tool_change"; }), m_ticks_.end()); + + int tick = 0; + double value = 0.0; + int extruder = 0; + const int extr_cnt = m_extruders_sequence.extruders.size(); + + std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); + + while (tick <= m_max_value) + { + int cur_extruder = m_extruders_sequence.extruders[extruder]; + m_ticks_.insert(TICK_CODE(tick, "tool_change", cur_extruder + 1, colors[cur_extruder])); + + extruder++; + if (extruder == extr_cnt) + extruder = 0; + if (m_extruders_sequence.is_mm_intervals) + { + value += m_extruders_sequence.interval_by_mm; + auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); + + if (it == m_values.end()) + break; + + tick = it - m_values.begin(); + } + else + tick += m_extruders_sequence.interval_by_layers; + } + + wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); +} + // ---------------------------------------------------------------------------- // LockButton diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 48c3ac08d..89dc6d9fa 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -856,6 +856,7 @@ public: void add_code(std::string code, int selected_extruder = -1); void edit_color(); void change_extruder(int extruder); + void edit_extruder_sequence(); protected: @@ -924,6 +925,7 @@ private: bool m_is_enabled_tick_manipulation = true; bool m_show_context_menu = false; bool m_show_edit_color_menu = false; + bool m_edit_extruder_sequence = false; bool m_suppress_add_code = false; ManipulationState m_state = msSingleExtruder; wxString m_custom_gcode = wxEmptyString; From 6c8bb51f4af894333ec56ed2133f0772d14b5044 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 11 Nov 2019 09:38:45 +0100 Subject: [PATCH 25/45] Use constant names for G-codes like M600, M601 and "tool_change"(Change extruder) --- src/libslic3r/GCode.cpp | 18 ++++++------ src/libslic3r/Model.cpp | 2 +- src/libslic3r/PrintConfig.hpp | 6 ++++ src/slic3r/GUI/GLCanvas3D.cpp | 21 ++++++------- src/slic3r/GUI/GUI_Preview.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/GUI/wxExtensions.cpp | 52 ++++++++++++++++----------------- src/slic3r/GUI/wxExtensions.hpp | 12 ++------ 8 files changed, 58 insertions(+), 57 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 9d196cbd2..311575bce 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1692,7 +1692,7 @@ void GCode::process_layer( int m600_before_extruder = -1; while (!m_custom_g_code_heights.empty() && m_custom_g_code_heights.front().height-EPSILON < layer.print_z) { custom_code = m_custom_g_code_heights.front().gcode; - if (custom_code == "M600" && m_custom_g_code_heights.front().extruder > 0) + if (custom_code == ColorChangeCode && m_custom_g_code_heights.front().extruder > 0) m600_before_extruder = m_custom_g_code_heights.front().extruder - 1; m_custom_g_code_heights.erase(m_custom_g_code_heights.begin()); colorprint_change = true; @@ -1710,11 +1710,11 @@ void GCode::process_layer( // gcode += "M600\n"; // } - // don't save "tool_change" code to GCode - if (colorprint_change && custom_code != "tool_change") { + // don't save "tool_change"(ExtruderChangeCode) code to GCode + if (colorprint_change && custom_code != ExtruderChangeCode) { const bool single_material_print = print.config().nozzle_diameter.size() == 1; - if (custom_code == "M600") // color change + if (custom_code == ColorChangeCode) // color change { // add tag for analyzer gcode += "; " + GCodeAnalyzer::Color_Change_Tag + ",T" + std::to_string(m600_before_extruder) + "\n"; @@ -1732,7 +1732,7 @@ void GCode::process_layer( } else { - if (custom_code == "M601") // Pause print + if (custom_code == PausePrintCode) // Pause print { // add tag for analyzer gcode += "; " + GCodeAnalyzer::Pause_Print_Tag + "\n"; @@ -1750,16 +1750,16 @@ void GCode::process_layer( } /* - if (single_material_print || custom_code != "tool_change") + if (single_material_print || custom_code != ExtruderChangeCode) { // add tag for analyzer gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n"; // add tag for time estimator gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; - if (single_material_print && custom_code == "tool_change") - custom_code = "M600"; + if (single_material_print && custom_code == ExtruderChangeCode) + custom_code = ColorChangeCode; - if (!single_material_print && custom_code == "M600" && + if (!single_material_print && custom_code == ColorChangeCode && m600_before_extruder >= 0 && first_extruder_id != m600_before_extruder // && !MMU1 ) { diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 0bb2edfc4..861ad9dc1 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -591,7 +591,7 @@ std::vector> Model::get_custom_tool_change std::vector> custom_tool_changes; if (!custom_gcode_per_height.empty()) { for (const CustomGCode& custom_gcode : custom_gcode_per_height) - if (custom_gcode.gcode == "tool_change") { + if (custom_gcode.gcode == ExtruderChangeCode) { DynamicPrintConfig config; // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders config.set_key_value("extruder", new ConfigOptionInt(custom_gcode.extruder > num_extruders ? 0 : custom_gcode.extruder)); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 5c287ba93..2d4d43ddf 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -71,6 +71,12 @@ enum SLAPillarConnectionMode { slapcmDynamic }; +// ys_FIXME ! may be, it's not a best place +// Additional Codes which can be set by user using DoubleSlider +static const std::string ColorChangeCode = "M600"; +static const std::string PausePrintCode = "M601"; +static const std::string ExtruderChangeCode = "tool_change"; + template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 074713f82..97e15bb0a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -906,7 +906,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D std::vector print_zs = canvas.get_current_print_zs(true); for (auto custom_code : custom_gcode_per_height) { - if (custom_code.gcode != "M600") + if (custom_code.gcode != ColorChangeCode) continue; auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.height - DoubleSlider::epsilon()); @@ -978,7 +978,7 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D int cnt = custom_gcode_per_height.size(); for (int i = cnt-1; i >= 0; --i) - if (custom_gcode_per_height[i].gcode == "M600") { + if (custom_gcode_per_height[i].gcode == ColorChangeCode) { ::memcpy((void*)(colors.data() + color_pos), (const void*)(colors_in.data() + color_in_pos), 4 * sizeof(float)); color_pos += 4; color_in_pos -= 4; @@ -4842,14 +4842,15 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c { const std::string& code = it->gcode; // pause print or custom Gcode - if (code == "M601" || (code != "M600" && code != "tool_change")) + if (code == PausePrintCode || + (code != ColorChangeCode && code != ExtruderChangeCode)) return number_tools()-1; // last color item is a gray color for pause print or custom G-code // change tool (extruder) - if (code == "tool_change") + if (code == ExtruderChangeCode) return get_color_idx_for_tool_change(it, extruder); // change color for current extruder - if (code == "M600") { + if (code == ColorChangeCode) { int color_idx = get_color_idx_for_color_change(it, extruder); if (color_idx >= 0) return color_idx; @@ -4862,13 +4863,13 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c { --it; // change color for current extruder - if (it->gcode == "M600") { + if (it->gcode == ColorChangeCode) { int color_idx = get_color_idx_for_color_change(it, extruder); if (color_idx >= 0) return color_idx; } // change tool (extruder) - if (it->gcode == "tool_change") + if (it->gcode == ExtruderChangeCode) return get_color_idx_for_tool_change(it, extruder); } @@ -4881,7 +4882,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c int shift = 0; while (it != color_print_values->begin()) { --it; - if (it->gcode == "M600") + if (it->gcode == ColorChangeCode) shift++; } return extruders_cnt + shift; @@ -4896,7 +4897,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c auto it_n = it; while (it_n != color_print_values->begin()) { --it_n; - if (it_n->gcode == "M600" && it_n->extruder == current_extruder) + if (it_n->gcode == ColorChangeCode && it_n->extruder == current_extruder) return get_m600_color_idx(it_n); } @@ -4912,7 +4913,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c bool is_tool_change = false; while (it_n != color_print_values->begin()) { --it_n; - if (it_n->gcode == "tool_change") { + if (it_n->gcode == ExtruderChangeCode) { is_tool_change = true; if (it_n->extruder == it->extruder || (it_n->extruder == 0 && it->extruder == extruder)) return get_m600_color_idx(it); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 897dfd9fc..dc6ac0431 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -893,7 +893,7 @@ void Preview::load_print_as_fff(bool keep_z_range) /* colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); for (const Model::CustomGCode& code : color_print_values) - if (code.gcode == "M600") + if (code.gcode == ColorChangeCode) colors.push_back(code.color);*/ colors = wxGetApp().plater()->get_colors_for_color_print(); colors.push_back("#808080"); // gray color for pause print or custom G-code diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0089910a0..f64fd8b43 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5000,7 +5000,7 @@ std::vector Plater::get_colors_for_color_print() const std::vector colors = get_extruder_colors_from_plater_config(); for (const Model::CustomGCode& code : p->model.custom_gcode_per_height) - if (code.gcode == "M600") + if (code.gcode == ColorChangeCode) colors.push_back(code.color); return colors; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 57fd9907a..8cfbf2206 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2854,10 +2854,10 @@ void DoubleSlider::draw_ticks(wxDC& dc) is_horizontal() ? dc.DrawLine(pos, mid+14, pos, mid+9) : dc.DrawLine(mid + 14, pos/* - 1*/, mid + 9, pos/* - 1*/); - // Draw icon for "Pause print" or "Extruder change" - if (tick.gcode != "M600" && tick.gcode != "tool_change") + // Draw icon for "Pause print" or "Custom Gcode" + if (tick.gcode != Slic3r::ColorChangeCode && tick.gcode != Slic3r::ExtruderChangeCode) { - wxBitmap icon = create_scaled_bitmap(nullptr, tick.gcode == "M601" ? "pause_add.png" : "add_gcode"); + wxBitmap icon = create_scaled_bitmap(nullptr, tick.gcode == Slic3r::PausePrintCode ? "pause_add.png" : "add_gcode"); wxCoord x_draw, y_draw; is_horizontal() ? x_draw = pos - 0.5 * m_tick_icon_dim : y_draw = pos - 0.5 * m_tick_icon_dim; @@ -2943,8 +2943,8 @@ void DoubleSlider::draw_colored_band(wxDC& dc) size_t i = 1; for (auto tick : m_ticks_) { - if ( (m_state == msSingleExtruder && tick.gcode != "M600") || - (m_state == msMultiExtruderWholePrint && tick.gcode != "tool_change") ) + if ( (m_state == msSingleExtruder && tick.gcode != Slic3r::ColorChangeCode) || + (m_state == msMultiExtruderWholePrint && tick.gcode != Slic3r::ExtruderChangeCode) ) continue; const wxCoord pos = get_position_from_value(tick.tick); @@ -3199,13 +3199,13 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus) _(L("For add color change use left mouse button click")) : _(L("For add change extruder use left mouse button click"))) + "\n" + _(L("For add another code use right mouse button click")) : - // tick_code_it->gcode == "M600" ? _(L("Delete color change")) : - tick_code_it->gcode == "M600" ? ( m_state == msSingleExtruder ? //_(L("Delete color change")) : + // tick_code_it->gcode == Slic3r::ColorChangeCode ? _(L("Delete color change")) : + tick_code_it->gcode == Slic3r::ColorChangeCode ? ( m_state == msSingleExtruder ? //_(L("Delete color change")) : _(L("For Delete color change use left mouse button click\n" "For Delete color change or Edit color use right mouse button click")) : from_u8((boost::format(_utf8(L("Delete color change for Extruder %1%"))) % tick_code_it->extruder).str()) ): - tick_code_it->gcode == "M601" ? _(L("Delete pause")) : - tick_code_it->gcode == "tool_change" ? //( m_state == msSingleExtruder ? _(L("Delete color change")) : + tick_code_it->gcode == Slic3r::PausePrintCode ? _(L("Delete pause")) : + tick_code_it->gcode == Slic3r::ExtruderChangeCode ? //( m_state == msSingleExtruder ? _(L("Delete color change")) : from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) /*) */: from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); } @@ -3286,9 +3286,9 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) for (int i = 1; i <= extruders_cnt; i++) append_menu_item(add_color_change_menu, wxID_ANY, wxString::Format(_(L("Extruder %d")), i), "", - [this, i](wxCommandEvent&) { add_code("M600", i); }, "", &menu); + [this, i](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode, i); }, "", &menu); - const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % "M600").str()); + const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % Slic3r::ColorChangeCode).str()); wxMenuItem* add_color_change_menu_item = menu.AppendSubMenu(add_color_change_menu, menu_name, ""); add_color_change_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "colorchange_add_off.png")); */ @@ -3311,7 +3311,7 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); } else - add_code("M600"); + add_code(Slic3r::ColorChangeCode); m_show_context_menu = false; } @@ -3411,7 +3411,7 @@ void DoubleSlider::action_tick(const TicksAction action) return; m_suppress_add_code = true; if (m_state != msMultiExtruderWholePrint) - add_code("M600"); + add_code(Slic3r::ColorChangeCode); m_suppress_add_code = false; return; } @@ -3506,7 +3506,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) m_show_context_menu = true; return; } - if (it->gcode == "M600") + if (it->gcode == Slic3r::ColorChangeCode) { // show "Edit color" or "Delete color change" menu on OnRightUp() m_show_edit_color_menu = true; @@ -3524,7 +3524,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) m_lower_value = m_higher_value; // set slider to "one layer" mode - m_is_right_down = m_is_one_layer = true; + m_is_right_down = m_is_one_layer = true; Refresh(); Update(); @@ -3539,7 +3539,7 @@ int DoubleSlider::get_extruder_for_tick(int tick) auto it = m_ticks_.lower_bound(tick); while (it != m_ticks_.begin()) { --it; - if(it->gcode == "tool_change") + if(it->gcode == Slic3r::ExtruderChangeCode) return it->extruder; } @@ -3575,24 +3575,24 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) if (i==0) // don't use M600 for default extruder, if multimaterial print is selected continue; append_menu_item(add_color_change_menu, wxID_ANY, item_name, "", - [this, i](wxCommandEvent&) { add_code("M600", i); }, "", &menu); + [this, i](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode, i); }, "", &menu); } wxMenuItem* change_extruder_menu_item = menu.AppendSubMenu(change_extruder_menu, _(L("Change extruder")), _(L("Use another extruder"))); change_extruder_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "change_extruder")); - const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % "M600").str()); + const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % Slic3r::ColorChangeCode).str()); wxMenuItem* add_color_change_menu_item = menu.AppendSubMenu(add_color_change_menu, menu_name, ""); add_color_change_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "colorchange_add_off.png")); } } else append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", - [this](wxCommandEvent&) { add_code("M600"); }, "colorchange_add_off.png", &menu); + [this](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode); }, "colorchange_add_off.png", &menu); if (m_state != msMultiExtruder) append_menu_item(&menu, wxID_ANY, _(L("Add pause print")) + " (M601)", "", - [this](wxCommandEvent&) { add_code("M601"); }, "pause_add.png", &menu); + [this](wxCommandEvent&) { add_code(Slic3r::PausePrintCode); }, "pause_add.png", &menu); append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "", [this](wxCommandEvent&) { add_code(""); }, "add_gcode", &menu); @@ -3645,7 +3645,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) if (it == m_ticks_.end()) { std::string color = ""; - if (code == "M600") + if (code == Slic3r::ColorChangeCode) { std::vector colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); @@ -3653,7 +3653,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) auto before_tick_it = std::lower_bound(m_ticks_.begin(), m_ticks_.end(), tick); while (before_tick_it != m_ticks_.begin()) { --before_tick_it; - if (before_tick_it->gcode == "M600") { + if (before_tick_it->gcode == Slic3r::ColorChangeCode) { color = before_tick_it->color; break; } @@ -3686,7 +3686,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) int extruder = 1; if (m_state == msMultiExtruderWholePrint) { - if (code == "M600" && selected_extruder >= 0) + if (code == Slic3r::ColorChangeCode && selected_extruder >= 0) extruder = selected_extruder; else extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); @@ -3730,7 +3730,7 @@ void DoubleSlider::change_extruder(int extruder) // if on this Y doesn't exist tick if (m_ticks_.find(tick) == m_ticks_.end()) { - m_ticks_.insert(TICK_CODE(tick, "tool_change", extruder, extruder == 0 ? "" : colors[extruder-1])); + m_ticks_.insert(TICK_CODE(tick, Slic3r::ExtruderChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1])); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); Refresh(); @@ -3747,7 +3747,7 @@ void DoubleSlider::edit_extruder_sequence() m_extruders_sequence = dlg.GetValue(); m_ticks_.erase(std::remove_if(m_ticks_.begin(), m_ticks_.end(), - [](TICK_CODE tick) { return tick.gcode == "tool_change"; }), m_ticks_.end()); + [](TICK_CODE tick) { return tick.gcode == Slic3r::ExtruderChangeCode; }), m_ticks_.end()); int tick = 0; double value = 0.0; @@ -3759,7 +3759,7 @@ void DoubleSlider::edit_extruder_sequence() while (tick <= m_max_value) { int cur_extruder = m_extruders_sequence.extruders[extruder]; - m_ticks_.insert(TICK_CODE(tick, "tool_change", cur_extruder + 1, colors[cur_extruder])); + m_ticks_.insert(TICK_CODE(tick, Slic3r::ExtruderChangeCode, cur_extruder + 1, colors[cur_extruder])); extruder++; if (extruder == extr_cnt) diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 89dc6d9fa..32e96f326 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -963,11 +963,11 @@ private: struct TICK_CODE { - TICK_CODE(int tick):tick(tick), gcode("M600"), extruder(0), color("") {} + TICK_CODE(int tick):tick(tick), gcode(Slic3r::ColorChangeCode), extruder(0), color("") {} TICK_CODE(int tick, const std::string& code) : tick(tick), gcode(code), extruder(0) {} TICK_CODE(int tick, int extruder) : - tick(tick), gcode("M600"), extruder(extruder) {} + tick(tick), gcode(Slic3r::ColorChangeCode), extruder(extruder) {} TICK_CODE(int tick, const std::string& code, int extruder, const std::string& color) : tick(tick), gcode(code), extruder(extruder), color(color) {} @@ -976,13 +976,7 @@ private: TICK_CODE operator=(const TICK_CODE& other) const { TICK_CODE ret_val(other.tick, other.gcode, other.extruder, other.color); return ret_val; - }/* - TICK_CODE& operator=(const TICK_CODE& other) { - this->tick = other.tick; - this->gcode = other.gcode; - this->extruder = other.extruder; - return *this; - }*/ + } int tick; std::string gcode; From 519291394abcec3641865f0509cb0155c24e3d39 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 11 Nov 2019 16:01:34 +0100 Subject: [PATCH 26/45] Save/Load new color print data to/from amf and 3mf files. --- src/libslic3r/Format/3mf.cpp | 101 ++++++++++++++++++++++++++++++++++- src/libslic3r/Format/AMF.cpp | 66 ++++++++++++++++++++++- src/libslic3r/Model.cpp | 6 +++ src/slic3r/GUI/Plater.cpp | 2 + 4 files changed, 172 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 47a8e5280..acc94af76 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -45,6 +45,7 @@ const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config"; const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; const std::string LAYER_CONFIG_RANGES_FILE = "Metadata/Prusa_Slicer_layer_config_ranges.xml"; const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt"; +const std::string CUSTOM_GCODE_PER_HEIGHT_FILE = "Metadata/Prusa_Slicer_custom_gcode_per_height.xml"; const char* MODEL_TAG = "model"; const char* RESOURCES_TAG = "resources"; @@ -411,6 +412,8 @@ namespace Slic3r { void _extract_layer_config_ranges_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); void _extract_sla_support_points_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); + void _extract_custom_gcode_per_height_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); + void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig& config, const std::string& archive_filename); bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model); @@ -620,6 +623,11 @@ namespace Slic3r { // extract slic3r print config file _extract_print_config_from_archive(archive, stat, config, filename); } + if (boost::algorithm::iequals(name, CUSTOM_GCODE_PER_HEIGHT_FILE)) + { + // extract slic3r layer config ranges file + _extract_custom_gcode_per_height_from_archive(archive, stat); + } else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) { // extract slic3r model config file @@ -1050,6 +1058,43 @@ namespace Slic3r { return true; } + void _3MF_Importer::_extract_custom_gcode_per_height_from_archive(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat) + { + if (stat.m_uncomp_size > 0) + { + std::string buffer((size_t)stat.m_uncomp_size, 0); + mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0); + if (res == 0) { + add_error("Error while reading custom Gcodes per height data to buffer"); + return; + } + + std::istringstream iss(buffer); // wrap returned xml to istringstream + pt::ptree main_tree; + pt::read_xml(iss, main_tree); + + if (main_tree.front().first != "custom_gcodes_per_height") + return; + pt::ptree code_tree = main_tree.front().second; + + if (!m_model->custom_gcode_per_height.empty()) + m_model->custom_gcode_per_height.clear(); + + for (const auto& code : code_tree) + { + if (code.first != "code") + continue; + pt::ptree tree = code.second; + double height = tree.get(".height"); + std::string gcode = tree.get(".gcode"); + int extruder = tree.get(".extruder"); + std::string color = tree.get(".color"); + + m_model->custom_gcode_per_height.push_back(Model::CustomGCode(height, gcode, extruder, color)) ; + } + } + } + void _3MF_Importer::_handle_start_model_xml_element(const char* name, const char** attributes) { if (m_xml_parser == nullptr) @@ -1821,6 +1866,7 @@ namespace Slic3r { bool _add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model); bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config); bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); + bool _add_custom_gcode_per_height_file_to_archive(mz_zip_archive& archive, Model& model); }; bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) @@ -1898,6 +1944,15 @@ namespace Slic3r { return false; } + // Adds custom gcode per height file ("Metadata/Prusa_Slicer_custom_gcode_per_height.xml"). + // All custom gcode per height of whole Model are stored here + if (!_add_custom_gcode_per_height_file_to_archive(archive, model)) + { + close_zip_writer(&archive); + boost::filesystem::remove(filename); + return false; + } + // Adds slic3r print config file ("Metadata/Slic3r_PE.config"). // This file contains the content of FullPrintConfing / SLAFullPrintConfig. if (config != nullptr) @@ -2256,7 +2311,7 @@ namespace Slic3r { if (!tree.empty()) { std::ostringstream oss; - boost::property_tree::write_xml(oss, tree); + pt::write_xml(oss, tree); out = oss.str(); // Post processing("beautification") of the output string for a better preview @@ -2442,7 +2497,49 @@ namespace Slic3r { return true; } - bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version) +bool _3MF_Exporter::_add_custom_gcode_per_height_file_to_archive( mz_zip_archive& archive, Model& model) +{ + std::string out = ""; + + if (!model.custom_gcode_per_height.empty()) + { + pt::ptree tree; + pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); + + for (const Model::CustomGCode& code : model.custom_gcode_per_height) + { + pt::ptree& code_tree = main_tree.add("code", ""); + // store minX and maxZ + code_tree.put(".height" , code.height ); + code_tree.put(".gcode" , code.gcode ); + code_tree.put(".extruder" , code.extruder ); + code_tree.put(".color" , code.color ); + } + + if (!tree.empty()) + { + std::ostringstream oss; + boost::property_tree::write_xml(oss, tree); + out = oss.str(); + + // Post processing("beautification") of the output string + boost::replace_all(out, "><", ">\n<"); + } + } + + if (!out.empty()) + { + if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_HEIGHT_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) + { + add_error("Unable to add custom Gcodes per height file to archive"); + return false; + } + } + + return true; +} + +bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version) { if ((path == nullptr) || (config == nullptr) || (model == nullptr)) return false; diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index 181d6cb99..213952df3 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -16,6 +16,10 @@ #include "AMF.hpp" +#include +#include +namespace pt = boost::property_tree; + #include #include #include @@ -147,6 +151,8 @@ struct AMFParserContext NODE_TYPE_MIRRORY, // amf/constellation/instance/mirrory NODE_TYPE_MIRRORZ, // amf/constellation/instance/mirrorz NODE_TYPE_PRINTABLE, // amf/constellation/instance/mirrorz + NODE_TYPE_CUSTOM_GCODE, // amf/custom_code_per_height + NODE_TYPE_GCODE_PER_HEIGHT, // amf/custom_code_per_height/code NODE_TYPE_METADATA, // anywhere under amf/*/metadata }; @@ -227,7 +233,7 @@ struct AMFParserContext // Current instance allocated for an amf/constellation/instance subtree. Instance *m_instance; // Generic string buffer for vertices, face indices, metadata etc. - std::string m_value[3]; + std::string m_value[4]; // Pointer to config to update if config data are stored inside the amf file DynamicPrintConfig *m_config; @@ -268,6 +274,8 @@ void AMFParserContext::startElement(const char *name, const char **atts) } } else if (strcmp(name, "constellation") == 0) { node_type_new = NODE_TYPE_CONSTELLATION; + } else if (strcmp(name, "custom_gcodes_per_height") == 0) { + node_type_new = NODE_TYPE_CUSTOM_GCODE; } break; case 2: @@ -294,6 +302,13 @@ void AMFParserContext::startElement(const char *name, const char **atts) } else this->stop(); + } + else if (strcmp(name, "code") == 0 && m_path[1] == NODE_TYPE_CUSTOM_GCODE) { + node_type_new = NODE_TYPE_GCODE_PER_HEIGHT; + m_value[0] = get_attribute(atts, "height"); + m_value[1] = get_attribute(atts, "gcode"); + m_value[2] = get_attribute(atts, "extruder"); + m_value[3] = get_attribute(atts, "color"); } break; case 3: @@ -616,6 +631,19 @@ void AMFParserContext::endElement(const char * /* name */) m_instance = nullptr; break; + case NODE_TYPE_GCODE_PER_HEIGHT: { + double height = double(atof(m_value[0].c_str())); + const std::string& gcode = m_value[1]; + int extruder = atoi(m_value[2].c_str()); + const std::string& color = m_value[3]; + + m_model.custom_gcode_per_height.push_back(Model::CustomGCode(height, gcode, extruder, color)); + + for (std::string& val: m_value) + val.clear(); + break; + } + case NODE_TYPE_METADATA: if ((m_config != nullptr) && strncmp(m_value[0].c_str(), SLIC3R_CONFIG_TYPE, strlen(SLIC3R_CONFIG_TYPE)) == 0) m_config->load_from_gcode_string(m_value[1].c_str()); @@ -1190,6 +1218,42 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) stream << instances; stream << " \n"; } + + if (!model->custom_gcode_per_height.empty()) + { + std::string out = ""; + pt::ptree tree; + + pt::ptree& main_tree = tree.add("custom_gcodes_per_height", ""); + + for (const Model::CustomGCode& code : model->custom_gcode_per_height) + { + pt::ptree& code_tree = main_tree.add("code", ""); + // store minX and maxZ + code_tree.put(".height", code.height); + code_tree.put(".gcode", code.gcode); + code_tree.put(".extruder", code.extruder); + code_tree.put(".color", code.color); + } + + if (!tree.empty()) + { + std::ostringstream oss; + pt::write_xml(oss, tree); + out = oss.str(); + + int del_header_pos = out.find("\n <", ">\n<"); + + stream << out << "\n"; + } + } + stream << "\n"; std::string internal_amf_filename = boost::ireplace_last_copy(boost::filesystem::path(export_path).filename().string(), ".zip.amf", ".amf"); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 861ad9dc1..ce3debfb5 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -41,6 +41,9 @@ Model& Model::assign_copy(const Model &rhs) mo->set_model(this); this->objects.emplace_back(mo); } + + // copy custom code per height + this->custom_gcode_per_height = rhs.custom_gcode_per_height; return *this; } @@ -59,6 +62,9 @@ Model& Model::assign_copy(Model &&rhs) for (ModelObject *model_object : this->objects) model_object->set_model(this); rhs.objects.clear(); + + // copy custom code per height + this->custom_gcode_per_height = rhs.custom_gcode_per_height; return *this; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f64fd8b43..6f1610d72 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2270,6 +2270,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ // and place the loaded config over the base. config += std::move(config_loaded); } + + this->model.custom_gcode_per_height = model.custom_gcode_per_height; } if (load_config) From 74e4a743af3eb939307baff8df1d84f2ef5dd176 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 Nov 2019 10:28:01 +0100 Subject: [PATCH 27/45] Added missed update for a config after extruder change from the ObjectList. Fixed erase "tool_change" ticks from ticks set. --- src/slic3r/GUI/GUI_ObjectList.cpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 15 ++++++++++++--- src/slic3r/GUI/wxExtensions.hpp | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 0fef8988e..aa10aca52 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -917,6 +917,7 @@ void ObjectList::extruder_editing() m_objects_model->SetExtruder(m_extruder_editor->GetString(selection), item); m_extruder_editor->Hide(); + update_extruder_in_config(item); }; // to avoid event propagation to other sidebar items diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 8cfbf2206..e27323886 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -3744,10 +3744,19 @@ void DoubleSlider::edit_extruder_sequence() if (dlg.ShowModal() != wxID_OK) return; - m_extruders_sequence = dlg.GetValue(); + const ExtrudersSequence& from_dlg_val = dlg.GetValue(); + if (m_extruders_sequence == from_dlg_val) + return; - m_ticks_.erase(std::remove_if(m_ticks_.begin(), m_ticks_.end(), - [](TICK_CODE tick) { return tick.gcode == Slic3r::ExtruderChangeCode; }), m_ticks_.end()); + m_extruders_sequence = from_dlg_val; + + auto it = m_ticks_.begin(); + while (it != m_ticks_.end()) { + if (it->gcode == Slic3r::ExtruderChangeCode) + it = m_ticks_.erase(it); + else + ++it; + } int tick = 0; double value = 0.0; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 32e96f326..cedff40c5 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -1014,6 +1014,20 @@ public: return *this; } + bool operator==(const ExtrudersSequence& other) const + { + return (other.is_mm_intervals == this->is_mm_intervals ) && + (other.interval_by_mm == this->interval_by_mm ) && + (other.interval_by_layers == this->interval_by_layers ) && + (other.extruders == this->extruders ) ; + } + bool operator!=(const ExtrudersSequence& other) const + { + return (other.is_mm_intervals != this->is_mm_intervals ) && + (other.interval_by_mm != this->interval_by_mm ) && + (other.interval_by_layers != this->interval_by_layers ) && + (other.extruders != this->extruders ) ; + } void add_extruder(size_t pos) { From 8ec1465ea5ac26b010ac7721910f138991cd566e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 Nov 2019 16:59:27 +0100 Subject: [PATCH 28/45] Added editing of custom G-code + Code cleaning --- src/slic3r/GUI/GUI_Preview.cpp | 9 +- src/slic3r/GUI/wxExtensions.cpp | 221 ++++++++------------------------ src/slic3r/GUI/wxExtensions.hpp | 12 +- 3 files changed, 60 insertions(+), 182 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index dc6ac0431..0ca283d2f 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -658,11 +658,8 @@ void Preview::create_double_slider() Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { - // #ys_FIXME_COLOR - // wxGetApp().preset_bundle->project_config.option("colorprint_heights")->values = m_slider->GetTicksValues(); - Model& model = wxGetApp().plater()->model(); - model.custom_gcode_per_height = m_slider->GetTicksValues_(); + model.custom_gcode_per_height = m_slider->GetTicksValues(); m_schedule_background_process(); update_view_type(false); @@ -761,9 +758,7 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee } m_slider->SetSelectionSpan(idx_low, idx_high); - // #ys_FIXME_COLOR - // m_slider->SetTicksValues(ticks_from_config); - m_slider->SetTicksValues_(ticks_from_model); + m_slider->SetTicksValues(ticks_from_model); bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF); // #ys_FIXME_COLOR diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index e27323886..c2262d949 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2524,29 +2524,8 @@ double DoubleSlider::get_double_value(const SelectedSlider& selection) return m_values[selection == ssLower ? m_lower_value : m_higher_value]; } -std::vector DoubleSlider::GetTicksValues() const -{ - std::vector values; - - const int val_size = m_values.size(); - if (!m_values.empty()) - // #ys_FIXME_COLOR - // for (int tick : m_ticks) { - // if (tick > val_size) - // break; - // values.push_back(m_values[tick]); - // } - for (const TICK_CODE& tick : m_ticks_) { - if (tick.tick > val_size) - break; - values.push_back(m_values[tick.tick]); - } - - return values; -} - using t_custom_code = Slic3r::Model::CustomGCode; -std::vector DoubleSlider::GetTicksValues_() const +std::vector DoubleSlider::GetTicksValues() const { std::vector values; @@ -2561,7 +2540,7 @@ std::vector DoubleSlider::GetTicksValues_() const return values; } -void DoubleSlider::SetTicksValues_(const std::vector& heights) +void DoubleSlider::SetTicksValues(const std::vector& heights) { if (m_values.empty()) return; @@ -2583,45 +2562,6 @@ void DoubleSlider::SetTicksValues_(const std::vector& heights) wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } -void DoubleSlider::SetTicksValues(const std::vector& heights) -{ - if (m_values.empty()) - return; - - // #ys_FIXME_COLOR - // const bool was_empty = m_ticks.empty(); - // - // m_ticks.clear(); - // for (auto h : heights) { - // auto it = std::lower_bound(m_values.begin(), m_values.end(), h - epsilon()); - // - // if (it == m_values.end()) - // continue; - // - // m_ticks.insert(it-m_values.begin()); - // } - // - // if (!was_empty && m_ticks.empty()) - // // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one - // wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); - - const bool was_empty = m_ticks_.empty(); - - m_ticks_.clear(); - for (auto h : heights) { - auto it = std::lower_bound(m_values.begin(), m_values.end(), h - epsilon()); - - if (it == m_values.end()) - continue; - - m_ticks_.insert(it-m_values.begin()); - } - - if (!was_empty && m_ticks_.empty()) - // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one - wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); -} - void DoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos) { const double step = get_scroll_step(); @@ -2695,9 +2635,6 @@ void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoin return; wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); - // #ys_FIXME_COLOR - // if (m_ticks.find(tick) != m_ticks.end()) - // icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); if (m_ticks_.find(tick) != m_ticks_.end()) icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); @@ -2841,12 +2778,8 @@ void DoubleSlider::draw_ticks(wxDC& dc) int height, width; get_size(&width, &height); const wxCoord mid = is_horizontal() ? 0.5*height : 0.5*width; - // #ys_FIXME_COLOR - // for (auto tick : m_ticks) for (auto tick : m_ticks_) { - // #ys_FIXME_COLOR - // const wxCoord pos = get_position_from_value(tick); const wxCoord pos = get_position_from_value(tick.tick); is_horizontal() ? dc.DrawLine(pos, mid-14, pos, mid-9) : @@ -2889,43 +2822,6 @@ void DoubleSlider::draw_colored_band(wxDC& dc) main_band.SetBottom(height - SLIDER_MARGIN + 1); } - // #ys_FIXME_COLOR - // if (m_ticks.empty()) { - /*if (m_ticks_.empty()) { - dc.SetPen(GetParent()->GetBackgroundColour()); - dc.SetBrush(GetParent()->GetBackgroundColour()); - dc.DrawRectangle(main_band); - return; - } - - const std::vector& colors = Slic3r::GCodePreviewData::ColorPrintColors(); - const size_t colors_cnt = colors.size(); - - wxColour clr(colors[0]); - dc.SetPen(clr); - dc.SetBrush(clr); - dc.DrawRectangle(main_band); - - size_t i = 1; - // #ys_FIXME_COLOR - // for (auto tick : m_ticks) - for (auto tick : m_ticks_) - { - if (i == colors_cnt) - i = 0; - // #ys_FIXME_COLOR - //const wxCoord pos = get_position_from_value(tick); - const wxCoord pos = get_position_from_value(tick.tick); - is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) : - main_band.SetBottom(pos-1); - - clr = wxColour(colors[i]); - dc.SetPen(clr); - dc.SetBrush(clr); - dc.DrawRectangle(main_band); - i++; - }*/ - auto draw_band = [](wxDC& dc, const wxColour& clr, const wxRect& band_rc) { dc.SetPen(clr); dc.SetBrush(clr); @@ -2979,8 +2875,6 @@ void DoubleSlider::draw_one_layer_icon(wxDC& dc) void DoubleSlider::draw_revert_icon(wxDC& dc) { - // #ys_FIXME_COLOR - // if (m_ticks.empty() || !m_is_enabled_tick_manipulation) if (m_ticks_.empty() || !m_is_enabled_tick_manipulation) return; @@ -3051,23 +2945,15 @@ bool DoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) int DoubleSlider::is_point_near_tick(const wxPoint& pt) { - // #ys_FIXME_COLOR - // for (auto tick : m_ticks) { for (auto tick : m_ticks_) { - // #ys_FIXME_COLOR - // const wxCoord pos = get_position_from_value(tick); const wxCoord pos = get_position_from_value(tick.tick); if (is_horizontal()) { if (pos - 4 <= pt.x && pt.x <= pos + 4) - // #ys_FIXME_COLOR - // return tick; return tick.tick; } else { if (pos - 4 <= pt.y && pt.y <= pos + 4) - // #ys_FIXME_COLOR - // return tick; return tick.tick; } } @@ -3120,8 +3006,6 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) m_selection == ssLower ? correct_lower_value() : correct_higher_value(); if (!m_selection) m_selection = ssHigher; - // #ys_FIXME_COLOR - // m_ticks.clear(); m_ticks_.clear(); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } @@ -3202,12 +3086,14 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus) // tick_code_it->gcode == Slic3r::ColorChangeCode ? _(L("Delete color change")) : tick_code_it->gcode == Slic3r::ColorChangeCode ? ( m_state == msSingleExtruder ? //_(L("Delete color change")) : _(L("For Delete color change use left mouse button click\n" - "For Delete color change or Edit color use right mouse button click")) : + "For Edit color use right mouse button click")) : from_u8((boost::format(_utf8(L("Delete color change for Extruder %1%"))) % tick_code_it->extruder).str()) ): tick_code_it->gcode == Slic3r::PausePrintCode ? _(L("Delete pause")) : tick_code_it->gcode == Slic3r::ExtruderChangeCode ? //( m_state == msSingleExtruder ? _(L("Delete color change")) : from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) /*) */: - from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); + // from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); + from_u8((boost::format(_utf8(L("For Delete \"%1%\" code use left mouse button click\n" + "For Edit \"%1%\" code use right mouse button click"))) % tick_code_it->gcode ).str()); } return tooltip; @@ -3225,8 +3111,6 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) if (!m_is_left_down && !m_is_one_layer) { m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); - // #ys_FIXME_COLOR - // is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon); if (!m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon)) icon_focus = ifRevert; else if (is_point_in_rect(pos, m_rect_cog_icon)) @@ -3251,10 +3135,6 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) event.Skip(); // Set tooltips with information for each icon - // #ys_FIXME_COLOR - // const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) : - // m_is_action_icon_focesed ? _(L("Add/Del color change")) : - // is_revert_icon_focused ? _(L("Discard all color changes")) : ""; this->SetToolTip(get_tooltip(icon_focus)); if (action) @@ -3371,22 +3251,6 @@ void DoubleSlider::action_tick(const TicksAction action) const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - // #ys_FIXME_COLOR - // if (action == taOnIcon) { - // if (!m_ticks.insert(tick).second) - // m_ticks.erase(tick); - // } - // else { - // const auto it = m_ticks.find(tick); - // if (it == m_ticks.end() && action == taAdd) - // m_ticks.insert(tick); - // else if (it != m_ticks.end() && action == taDel) - // m_ticks.erase(tick); - // } - // wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); - // Refresh(); - // Update(); - const auto it = m_ticks_.find(tick); if (it != m_ticks_.end()) // erase this tick @@ -3496,9 +3360,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) if (is_point_in_rect(pos, m_rect_tick_action) && m_is_enabled_tick_manipulation) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - // if on this Y doesn't exist tick - // #ys_FIXME_COLOR - // if (m_ticks.find(tick) == m_ticks.end()) + // if on this Z doesn't exist tick auto it = m_ticks_.find(tick); if (it == m_ticks_.end()) { @@ -3506,10 +3368,10 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) m_show_context_menu = true; return; } - if (it->gcode == Slic3r::ColorChangeCode) + if (it->gcode != Slic3r::ExtruderChangeCode && it->gcode != Slic3r::PausePrintCode) { - // show "Edit color" or "Delete color change" menu on OnRightUp() - m_show_edit_color_menu = true; + // show "Edit" and "Delete" menu on OnRightUp() + m_show_edit_menu = true; return; } } @@ -3601,18 +3463,21 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) m_show_context_menu = false; } - else if (m_show_edit_color_menu) { + else if (m_show_edit_menu) { wxMenu menu; - append_menu_item(&menu, wxID_ANY, _(L("Edit color")), "", - [this](wxCommandEvent&) { edit_color(); }, "change_extruder", &menu); + std::set::iterator it = m_ticks_.find(m_selection == ssLower ? m_lower_value : m_higher_value); + const bool is_color_change = it->gcode == Slic3r::ColorChangeCode; - append_menu_item(&menu, wxID_ANY, _(L("Delete color change")), "", + append_menu_item(&menu, wxID_ANY, is_color_change ? _(L("Edit color")) : _(L("Edit custom G-code")), "", + [this](wxCommandEvent&) { edit_tick(); }, "change_extruder", &menu); + + append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Delete color change")) : _(L("Delete custom G-code")), "", [this](wxCommandEvent&) { action_tick(taDel); }, "colorchange_delete_off.png", &menu); Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); - m_show_edit_color_menu = false; + m_show_edit_menu = false; } Refresh(); @@ -3637,6 +3502,20 @@ static std::string get_new_color(const std::string& color) return ""; } +static std::string get_custom_code(const std::string& code_in, double height) +{ + wxString msg_text = from_u8(_utf8(L("Enter custom G-code used on current layer"))) + " :"; + wxString msg_header = from_u8((boost::format(_utf8(L("Custom Gcode on current layer (%1% mm)."))) % height).str()); + + // get custom gcode + wxTextEntryDialog dlg(nullptr, msg_text, msg_header, code_in, + wxTextEntryDialogStyle | wxTE_MULTILINE); + if (dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty()) + return ""; + + return dlg.GetValue().ToStdString(); +} + void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; @@ -3671,17 +3550,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) } else if (code.empty()) { - wxString msg_text = from_u8(_utf8(L("Enter custom G-code used on current layer"))) + " :"; - wxString msg_header = from_u8((boost::format(_utf8(L("Custom Gcode on current layer (%1% mm)."))) % m_values[tick]).str()); - - // get custom gcode - wxTextEntryDialog dlg(nullptr, msg_text, msg_header, m_custom_gcode, - wxTextEntryDialogStyle | wxTE_MULTILINE); - if (dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty()) - return; - - m_custom_gcode = dlg.GetValue(); - code = m_custom_gcode.c_str(); + m_custom_gcode = code = get_custom_code(m_custom_gcode, m_values[tick]); } int extruder = 1; @@ -3702,18 +3571,34 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) } } -void DoubleSlider::edit_color() +void DoubleSlider::edit_tick() { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; // if on this Z exists tick std::set::iterator it = m_ticks_.find(tick); if (it != m_ticks_.end()) { - std::string color = get_new_color(it->color); - if (color.empty()) + std::string edited_value; + if (it->gcode == Slic3r::ColorChangeCode) + edited_value = get_new_color(it->color); + else + edited_value = get_custom_code(it->gcode, m_values[it->tick]); + + if (edited_value.empty()) return; + TICK_CODE changed_tick = *it; - changed_tick.color = color; + if (it->gcode == Slic3r::ColorChangeCode) { + if (it->color == edited_value) + return; + changed_tick.color = edited_value; + } + else { + if (it->gcode == edited_value) + return; + changed_tick.gcode = edited_value; + } + m_ticks_.erase(it); m_ticks_.insert(changed_tick); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index cedff40c5..612cd6236 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -808,10 +808,8 @@ public: m_values = values; } void ChangeOneLayerLock(); - std::vector GetTicksValues() const; - std::vector GetTicksValues_() const; - void SetTicksValues_(const std::vector &heights); - void SetTicksValues(const std::vector& heights); + std::vector GetTicksValues() const; + void SetTicksValues(const std::vector &heights); void EnableTickManipulation(bool enable = true) { m_is_enabled_tick_manipulation = enable; } @@ -854,7 +852,7 @@ public: int get_extruder_for_tick(int tick); void OnRightUp(wxMouseEvent& event); void add_code(std::string code, int selected_extruder = -1); - void edit_color(); + void edit_tick(); void change_extruder(int extruder); void edit_extruder_sequence(); @@ -924,11 +922,11 @@ private: bool m_is_one_layer_icon_focesed = false; bool m_is_enabled_tick_manipulation = true; bool m_show_context_menu = false; - bool m_show_edit_color_menu = false; + bool m_show_edit_menu = false; bool m_edit_extruder_sequence = false; bool m_suppress_add_code = false; ManipulationState m_state = msSingleExtruder; - wxString m_custom_gcode = wxEmptyString; + std::string m_custom_gcode = ""; int m_current_extruder = -1; wxRect m_rect_lower_thumb; From 0fb8b2ce09458719fd8af7f3b1c2e7dd8e8f468e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 15 Nov 2019 16:36:29 +0100 Subject: [PATCH 29/45] Delete color changes for unused extruders --- src/libslic3r/GCode.cpp | 45 ++++++++++++++++++++- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 9 +++++ src/slic3r/GUI/GLCanvas3D.cpp | 5 --- src/slic3r/GUI/GUI_Preview.cpp | 4 +- src/slic3r/GUI/wxExtensions.cpp | 3 ++ 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 311575bce..1e17e3ad9 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -875,7 +875,7 @@ void GCode::_do_export(Print &print, FILE *file) this->set_extruders(print.extruders()); // #ys_FIXME_COLOR // Initialize colorprint. - m_colorprint_heights = cast(print.config().colorprint_heights.values); + // m_colorprint_heights = cast(print.config().colorprint_heights.values); // Initialize custom gcode Model* model = print.get_object(0)->model_object()->get_model(); m_custom_g_code_heights = model->custom_gcode_per_height; @@ -1020,6 +1020,49 @@ void GCode::_do_export(Print &print, FILE *file) } print.throw_if_canceled(); + + // #ys_FIXME_COLOR + /* To avoid change filament for non-used extruder for Multi-material, + * check model->custom_gcode_per_height using tool_ordering values + * */ + if (!m_custom_g_code_heights. empty()) + { + bool delete_executed = false; + auto it = m_custom_g_code_heights.end(); + while (it != m_custom_g_code_heights.begin()) + { + --it; + if (it->gcode != ColorChangeCode) + continue; + + auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(it->height)); + + bool used_extruder = false; + for (; it_layer_tools != tool_ordering.end(); it_layer_tools++) + { + const std::vector& extruders = it_layer_tools->extruders; + if (std::find(extruders.begin(), extruders.end(), (unsigned)(it->extruder-1)) != extruders.end()) + { + used_extruder = true; + break; + } + } + if (used_extruder) + continue; + + /* If we are there, current extruder wouldn't be used, + * so this color change is a redundant move. + * Delete this item from m_custom_g_code_heights + * */ + it = m_custom_g_code_heights.erase(it); + delete_executed = true; + } + + if (delete_executed) + model->custom_gcode_per_height = m_custom_g_code_heights; + } + + m_cooling_buffer->set_current_extruder(initial_extruder_id); // Emit machine envelope limits for the Marlin firmware. diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 6c138d4d0..991bc94a6 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -29,6 +29,7 @@ #include #include #include "I18N.hpp" +#include "GUI.hpp" namespace Slic3r { @@ -84,6 +85,14 @@ void BackgroundSlicingProcess::process_fff() m_print->process(); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); + + if (m_fff_print->model().custom_gcode_per_height != GUI::wxGetApp().model().custom_gcode_per_height) { + GUI::wxGetApp().model().custom_gcode_per_height = m_fff_print->model().custom_gcode_per_height; + // #ys_FIXME : controll text + GUI::show_info(nullptr, _(L("To except of redundant tool manipulation, \n" + "Color change(s) for unused extruder(s) was(were) deleted")), _(L("Info"))); + } + if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { //FIXME localize the messages diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 97e15bb0a..f5005b798 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5338,11 +5338,6 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat case GCodePreviewData::Extrusion::ColorPrint: { int color_cnt = (int)tool_colors.size() / 4; - - // int val = int(value); - // while (val >= color_cnt) - // val -= color_cnt; - int val = value > color_cnt ? color_cnt - 1 : value; GCodePreviewData::Color color; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 0ca283d2f..8f4b8a19b 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -592,8 +592,8 @@ void Preview::update_view_type(bool slice_completed) _(L("Feature type")); */ - const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() && - (wxGetApp().extruders_edited_cnt()==1 || !slice_completed) ? + const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() /*&& + (wxGetApp().extruders_edited_cnt()==1 || !slice_completed) */? _(L("Color Print")) : config.option("wiping_volumes_matrix")->values.size() > 1 ? _(L("Tool")) : diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index c2262d949..d62408acc 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2560,6 +2560,9 @@ void DoubleSlider::SetTicksValues(const std::vector& heights) if (!was_empty && m_ticks_.empty() && m_state != msMultiExtruder) // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + + Refresh(); + Update(); } void DoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos) From 5e4c4a689ce28898f02ee25e9891087b2623ddfa Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 25 Nov 2019 10:56:50 +0100 Subject: [PATCH 30/45] According to cmake, minimum required call shall go before project(). BTW This will make boost config detect the right toolset on every platform. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 633ab3f19..a41229987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -project(PrusaSlicer) cmake_minimum_required(VERSION 3.2) +project(PrusaSlicer) include("version.inc") include(GNUInstallDirs) From 2bbd916cccccaa28a46351f16af568f8624f2e8e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 25 Nov 2019 11:13:50 +0100 Subject: [PATCH 31/45] Fixed build on Linux --- src/slic3r/GUI/Mouse3DController.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Mouse3DController.cpp b/src/slic3r/GUI/Mouse3DController.cpp index 39542e652..38840fbdf 100644 --- a/src/slic3r/GUI/Mouse3DController.cpp +++ b/src/slic3r/GUI/Mouse3DController.cpp @@ -339,11 +339,10 @@ bool Mouse3DController::connect_device() return false; // check time since last detection took place - auto now = std::chrono::high_resolution_clock::now(); - if (std::chrono::duration_cast(now - m_last_time).count() < DETECTION_TIME) + if (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - m_last_time).count() < DETECTION_TIME) return false; - m_last_time = now; + m_last_time = std::chrono::high_resolution_clock::now(); // Enumerates devices hid_device_info* devices = hid_enumerate(0, 0); From df3e47e093deab88fe6365039ae82d43264c6cb9 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 25 Nov 2019 12:45:49 +0100 Subject: [PATCH 32/45] Another attempt to fix build on Linux (due to ab00f501f1363802282986ea9ab86d2e305bc24d) --- src/slic3r/GUI/Mouse3DController.cpp | 4 ++-- src/slic3r/GUI/Mouse3DController.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Mouse3DController.cpp b/src/slic3r/GUI/Mouse3DController.cpp index 38840fbdf..e69ef4857 100644 --- a/src/slic3r/GUI/Mouse3DController.cpp +++ b/src/slic3r/GUI/Mouse3DController.cpp @@ -333,13 +333,13 @@ void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsign bool Mouse3DController::connect_device() { - static const long long DETECTION_TIME = 2; // seconds + static const long long DETECTION_TIME_MS = 2000; // seconds if (is_device_connected()) return false; // check time since last detection took place - if (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - m_last_time).count() < DETECTION_TIME) + if (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - m_last_time).count() < DETECTION_TIME_MS) return false; m_last_time = std::chrono::high_resolution_clock::now(); diff --git a/src/slic3r/GUI/Mouse3DController.hpp b/src/slic3r/GUI/Mouse3DController.hpp index 40c489853..cc03d4a24 100644 --- a/src/slic3r/GUI/Mouse3DController.hpp +++ b/src/slic3r/GUI/Mouse3DController.hpp @@ -131,7 +131,7 @@ class Mouse3DController std::string m_device_str; bool m_running; bool m_settings_dialog; - std::chrono::time_point m_last_time; + std::chrono::time_point m_last_time; public: Mouse3DController(); From 44d7ac44742905f79f328180b2b6c824b259decf Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 25 Nov 2019 14:42:36 +0100 Subject: [PATCH 33/45] Fixed crash when calling Reload from disk command after slicing on SLA printer --- src/slic3r/GUI/Plater.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 61a42d06a..789271581 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3177,9 +3177,13 @@ void Plater::priv::reload_from_disk() for (unsigned int idx : selected_volumes_idxs) { const GLVolume* v = selection.get_volume(idx); - int o_idx = v->object_idx(); int v_idx = v->volume_idx(); - selected_volumes.push_back({ o_idx, v_idx }); + if (v_idx >= 0) + { + int o_idx = v->object_idx(); + if ((0 <= o_idx) && (o_idx < (int)model.objects.size())) + selected_volumes.push_back({ o_idx, v_idx }); + } } std::sort(selected_volumes.begin(), selected_volumes.end()); selected_volumes.erase(std::unique(selected_volumes.begin(), selected_volumes.end()), selected_volumes.end()); From d3ec53d9a606500f445ad55aac3ab0484c2b0085 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 25 Nov 2019 15:55:59 +0100 Subject: [PATCH 34/45] WIP: Improvement in path planning reorder_by_three_exchanges_with_segment_flipping() works, but it is excessively slow, with close to O(n^3) time complexity. Commited, but not used in production until sped up. --- src/libslic3r/ShortestPath.cpp | 237 +++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index ae6023e7a..9362e6043 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -1333,6 +1333,82 @@ static inline std::pair minimum_crossover_cost( return std::make_pair(cost_min, flip_min); } +static inline std::pair minimum_crossover_cost( + const std::vector &edges, + const std::pair &span1, const ConnectionCost &cost1, + const std::pair &span2, const ConnectionCost &cost2, + const std::pair &span3, const ConnectionCost &cost3, + const std::pair &span4, const ConnectionCost &cost4, + const double cost_current) +{ + auto connection_cost = [&edges]( + const std::pair &span1, const ConnectionCost &cost1, bool reversed1, bool flipped1, + const std::pair &span2, const ConnectionCost &cost2, bool reversed2, bool flipped2, + const std::pair &span3, const ConnectionCost &cost3, bool reversed3, bool flipped3, + const std::pair &span4, const ConnectionCost &cost4, bool reversed4, bool flipped4) { + auto first_point = [&edges](const std::pair &span, bool flipped) { return flipped ? edges[span.first].p2 : edges[span.first].p1; }; + auto last_point = [&edges](const std::pair &span, bool flipped) { return flipped ? edges[span.second - 1].p1 : edges[span.second - 1].p2; }; + auto point = [first_point, last_point](const std::pair &span, bool start, bool flipped) { return start ? first_point(span, flipped) : last_point(span, flipped); }; + auto cost = [](const ConnectionCost &acost, bool flipped) { + assert(acost.cost >= 0. && acost.cost_flipped >= 0.); + return flipped ? acost.cost_flipped : acost.cost; + }; + // Ignore reversed single segment spans. + auto simple_span_ignore = [](const std::pair& span, bool reversed) { + return span.first + 1 == span.second && reversed; + }; + assert(span1.first < span1.second); + assert(span2.first < span2.second); + assert(span3.first < span3.second); + assert(span4.first < span4.second); + return + simple_span_ignore(span1, reversed1) || simple_span_ignore(span2, reversed2) || simple_span_ignore(span3, reversed3) || simple_span_ignore(span4, reversed4) ? + // Don't perform unnecessary calculations simulating reversion of single segment spans. + std::numeric_limits::max() : + // Calculate the cost of reverting chains and / or flipping segment orientations. + cost(cost1, flipped1) + cost(cost2, flipped2) + cost(cost3, flipped3) + cost(cost4, flipped4) + + (point(span2, ! reversed2, flipped2) - point(span1, reversed1, flipped1)).norm() + + (point(span3, ! reversed3, flipped3) - point(span2, reversed2, flipped2)).norm() + + (point(span4, ! reversed4, flipped4) - point(span3, reversed3, flipped3)).norm(); + }; + +#ifndef NDEBUG + { + double c = connection_cost(span1, cost1, false, false, span2, cost2, false, false, span3, cost3, false, false, span4, cost4, false, false); + assert(std::abs(c - cost_current) < SCALED_EPSILON); + } +#endif /* NDEBUG */ + + double cost_min = cost_current; + size_t flip_min = 0; // no flip, no improvement + for (size_t i = 0; i < (1 << 8); ++ i) { + // From the three combinations of 1,2,3 ordering, the other three are reversals of the first three. + size_t permutation = 0; + for (double c : { + (i == 0) ? cost_current : + connection_cost(span1, cost1, (i & 1) != 0, (i & (1 << 1)) != 0, span2, cost2, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span3, cost3, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, cost4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span1, cost1, (i & 1) != 0, (i & (1 << 1)) != 0, span2, cost2, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span4, cost4, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span3, cost3, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span1, cost1, (i & 1) != 0, (i & (1 << 1)) != 0, span3, cost3, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span2, cost2, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, cost4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span1, cost1, (i & 1) != 0, (i & (1 << 1)) != 0, span3, cost3, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span4, cost4, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span2, cost2, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span1, cost1, (i & 1) != 0, (i & (1 << 1)) != 0, span4, cost4, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span2, cost2, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span3, cost3, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span1, cost1, (i & 1) != 0, (i & (1 << 1)) != 0, span4, cost4, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span3, cost3, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span2, cost2, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span2, cost2, (i & 1) != 0, (i & (1 << 1)) != 0, span1, cost1, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span3, cost3, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, cost4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span2, cost2, (i & 1) != 0, (i & (1 << 1)) != 0, span1, cost1, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span4, cost4, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span3, cost3, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span2, cost2, (i & 1) != 0, (i & (1 << 1)) != 0, span3, cost3, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span1, cost1, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, cost4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span2, cost2, (i & 1) != 0, (i & (1 << 1)) != 0, span4, cost4, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span1, cost1, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span3, cost3, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span3, cost3, (i & 1) != 0, (i & (1 << 1)) != 0, span1, cost1, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span2, cost2, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, cost4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0), + connection_cost(span3, cost3, (i & 1) != 0, (i & (1 << 1)) != 0, span2, cost2, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span1, cost1, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, cost4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0) + }) { + if (c < cost_min) { + cost_min = c; + flip_min = i + (permutation << 8); + } + ++ permutation; + } + } + return std::make_pair(cost_min, flip_min); +} + static inline void do_crossover(const std::vector &edges_in, std::vector &edges_out, const std::pair &span1, const std::pair &span2, const std::pair &span3, size_t i) @@ -1374,6 +1450,79 @@ static inline void do_crossover(const std::vector &edges_in, std::vect assert(edges_in.size() == edges_out.size()); } + +static inline void do_crossover(const std::vector &edges_in, std::vector &edges_out, + const std::pair &span1, const std::pair &span2, const std::pair &span3, const std::pair &span4, + size_t i) +{ + assert(edges_in.size() == edges_out.size()); + auto do_it = [&edges_in, &edges_out]( + const std::pair &span1, bool reversed1, bool flipped1, + const std::pair &span2, bool reversed2, bool flipped2, + const std::pair &span3, bool reversed3, bool flipped3, + const std::pair &span4, bool reversed4, bool flipped4) { + auto it_edges_out = edges_out.begin(); + auto copy_span = [&edges_in, &edges_out, &it_edges_out](std::pair span, bool reversed, bool flipped) { + assert(span.first < span.second); + auto it = it_edges_out; + if (reversed) + std::reverse_copy(edges_in.begin() + span.first, edges_in.begin() + span.second, it_edges_out); + else + std::copy (edges_in.begin() + span.first, edges_in.begin() + span.second, it_edges_out); + it_edges_out += span.second - span.first; + if (reversed != flipped) { + for (; it != it_edges_out; ++ it) + it->flip(); + } + }; + copy_span(span1, reversed1, flipped1); + copy_span(span2, reversed2, flipped2); + copy_span(span3, reversed3, flipped3); + copy_span(span4, reversed4, flipped4); + }; + switch (i >> 8) { + case 0: + assert(i != 0); // otherwise it would be a no-op + do_it(span1, (i & 1) != 0, (i & (1 << 1)) != 0, span2, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span3, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 1: + do_it(span1, (i & 1) != 0, (i & (1 << 1)) != 0, span2, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span4, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span3, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 2: + do_it(span1, (i & 1) != 0, (i & (1 << 1)) != 0, span3, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span2, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 3: + do_it(span1, (i & 1) != 0, (i & (1 << 1)) != 0, span3, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span4, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span2, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 4: + do_it(span1, (i & 1) != 0, (i & (1 << 1)) != 0, span4, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span2, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span3, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 5: + do_it(span1, (i & 1) != 0, (i & (1 << 1)) != 0, span4, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span3, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span2, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 6: + do_it(span2, (i & 1) != 0, (i & (1 << 1)) != 0, span1, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span3, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 7: + do_it(span2, (i & 1) != 0, (i & (1 << 1)) != 0, span1, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span4, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span3, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 8: + do_it(span2, (i & 1) != 0, (i & (1 << 1)) != 0, span3, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span1, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 9: + do_it(span2, (i & 1) != 0, (i & (1 << 1)) != 0, span4, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span1, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span3, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + case 10: + do_it(span3, (i & 1) != 0, (i & (1 << 1)) != 0, span1, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span2, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + default: + assert((i >> 8) == 11); + do_it(span3, (i & 1) != 0, (i & (1 << 1)) != 0, span2, (i & (1 << 2)) != 0, (i & (1 << 3)) != 0, span1, (i & (1 << 4)) != 0, (i & (1 << 5)) != 0, span4, (i & (1 << 6)) != 0, (i & (1 << 7)) != 0); + break; + } + assert(edges_in.size() == edges_out.size()); +} + static inline void reorder_by_two_exchanges_with_segment_flipping(std::vector &edges) { if (edges.size() < 2) @@ -1448,6 +1597,90 @@ static inline void reorder_by_two_exchanges_with_segment_flipping(std::vector &edges) +{ + if (edges.size() < 3) { + reorder_by_two_exchanges_with_segment_flipping(edges); + return; + } + + std::vector connections(edges.size()); + std::vector edges_tmp(edges); + std::vector> connection_lengths(edges.size() - 1, std::pair(0., 0)); + std::vector connection_tried(edges.size(), false); + for (size_t iter = 0; iter < edges.size(); ++ iter) { + // Initialize connection costs and connection lengths. + for (size_t i = 1; i < edges.size(); ++ i) { + const FlipEdge &e1 = edges[i - 1]; + const FlipEdge &e2 = edges[i]; + ConnectionCost &c = connections[i]; + c = connections[i - 1]; + double l = (e2.p1 - e1.p2).norm(); + c.cost += l; + c.cost_flipped += (e2.p2 - e1.p1).norm(); + connection_lengths[i - 1] = std::make_pair(l, i); + } + std::sort(connection_lengths.begin(), connection_lengths.end(), [](const std::pair &l, const std::pair &r) { return l.first > r.first; }); + std::fill(connection_tried.begin(), connection_tried.end(), false); + size_t crossover1_pos_final = std::numeric_limits::max(); + size_t crossover2_pos_final = std::numeric_limits::max(); + size_t crossover3_pos_final = std::numeric_limits::max(); + size_t crossover_flip_final = 0; + for (const std::pair &first_crossover_candidate : connection_lengths) { + double longest_connection_length = first_crossover_candidate.first; + size_t longest_connection_idx = first_crossover_candidate.second; + connection_tried[longest_connection_idx] = true; + // Find the second crossover connection with the lowest total chain cost. + size_t crossover_pos_min = std::numeric_limits::max(); + double crossover_cost_min = connections.back().cost; + for (size_t j = 1; j < connections.size(); ++ j) + if (! connection_tried[j]) { + for (size_t k = j + 1; k < connections.size(); ++ k) + if (! connection_tried[k]) { + size_t a = longest_connection_idx; + size_t b = j; + size_t c = k; + if (a > c) + std::swap(a, c); + if (a > b) + std::swap(a, b); + if (b > c) + std::swap(b, c); + std::pair cost_and_flip = minimum_crossover_cost(edges, + std::make_pair(size_t(0), a), connections[a - 1], std::make_pair(a, b), connections[b - 1] - connections[a], + std::make_pair(b, c), connections[c - 1] - connections[b], std::make_pair(c, edges.size()), connections.back() - connections[c], + connections.back().cost); + if (cost_and_flip.second > 0 && cost_and_flip.first < crossover_cost_min) { + crossover_cost_min = cost_and_flip.first; + crossover1_pos_final = a; + crossover2_pos_final = b; + crossover3_pos_final = c; + crossover_flip_final = cost_and_flip.second; + assert(crossover_cost_min < connections.back().cost + EPSILON); + } + } + } + if (crossover_flip_final > 0) { + // The cost of the chain with the proposed two crossovers has a lower total cost than the current chain. Apply the crossover. + break; + } else { + // Continue with another long candidate edge. + } + } + if (crossover_flip_final > 0) { + // Pair of cross over positions and flip / reverse constellation has been found, which improves the total cost of the connection. + // Perform a crossover. + do_crossover(edges, edges_tmp, std::make_pair(size_t(0), crossover1_pos_final), std::make_pair(crossover1_pos_final, crossover2_pos_final), + std::make_pair(crossover2_pos_final, crossover3_pos_final), std::make_pair(crossover3_pos_final, edges.size()), crossover_flip_final); + edges.swap(edges_tmp); + } else { + // No valid pair of cross over positions was found improving the total cost. Giving up. + break; + } + } +} + // Flip the sequences of polylines to lower the total length of connecting lines. static inline void improve_ordering_by_two_exchanges_with_segment_flipping(Polylines &polylines, bool fixed_start) { @@ -1471,7 +1704,11 @@ static inline void improve_ordering_by_two_exchanges_with_segment_flipping(Polyl edges.reserve(polylines.size()); std::transform(polylines.begin(), polylines.end(), std::back_inserter(edges), [&polylines](const Polyline &pl){ return FlipEdge(pl.first_point().cast(), pl.last_point().cast(), &pl - polylines.data()); }); +#if 1 reorder_by_two_exchanges_with_segment_flipping(edges); +#else + reorder_by_three_exchanges_with_segment_flipping(edges); +#endif Polylines out; out.reserve(polylines.size()); for (const FlipEdge &edge : edges) { From 643b26a0f340dc2db449362da29debc11626e8a2 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Nov 2019 12:24:07 +0100 Subject: [PATCH 35/45] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Small refactoring --- src/libslic3r/Slicing.cpp | 2 +- src/libslic3r/SlicingAdaptive.cpp | 14 +++++++------- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 81e9bf0c5..9af6048ab 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -267,7 +267,7 @@ std::vector layer_height_profile_adaptive( int current_facet = 0; #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE while (slice_z <= slicing_params.object_print_z_height()) { - double height = 999.0; + double height = slicing_params.max_layer_height; #else double height = slicing_params.first_object_layer_height; while ((slice_z - height) <= slicing_params.object_print_z_height()) { diff --git a/src/libslic3r/SlicingAdaptive.cpp b/src/libslic3r/SlicingAdaptive.cpp index bc02a89c1..6776d8d71 100644 --- a/src/libslic3r/SlicingAdaptive.cpp +++ b/src/libslic3r/SlicingAdaptive.cpp @@ -94,8 +94,8 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet continue; // compute cusp-height for this facet and store minimum of all heights float normal_z = m_face_normal_z[ordered_id]; - height = std::min(height, (normal_z == 0.f) ? 9999.f : std::abs(cusp_value / normal_z)); - } + height = std::min(height, (normal_z == 0.0f) ? (float)m_slicing_params.max_layer_height : std::abs(cusp_value / normal_z)); + } } // lower height limit due to printer capabilities @@ -115,13 +115,13 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet // Compute cusp-height for this facet and check against height. float normal_z = m_face_normal_z[ordered_id]; - float cusp = (normal_z == 0) ? 9999 : abs(cusp_value / normal_z); - + float cusp = (normal_z == 0.0f) ? (float)m_slicing_params.max_layer_height : abs(cusp_value / normal_z); + float z_diff = zspan.first - z; // handle horizontal facets - if (m_face_normal_z[ordered_id] > 0.999) { - // Slic3r::debugf "cusp computation, height is reduced from %f", $height; + if (normal_z > 0.999f) { + // Slic3r::debugf "cusp computation, height is reduced from %f", $height; height = z_diff; // Slic3r::debugf "to %f due to near horizontal facet\n", $height; } else if (cusp > z_diff) { @@ -139,7 +139,7 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet // lower height limit due to printer capabilities again height = std::max(height, float(m_slicing_params.min_layer_height)); } - + // Slic3r::debugf "cusp computation, layer-bottom at z:%f, cusp_value:%f, resulting layer height:%f\n", unscale $z, $cusp_value, $height; return height; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 693204435..c67604603 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -278,8 +278,8 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SameLine(); float widget_align = ImGui::GetCursorPosX(); ImGui::PushItemWidth(120.0f); - m_adaptive_cusp = std::min(m_adaptive_cusp, (float)m_slicing_parameters->max_layer_height); - ImGui::SliderFloat("", &m_adaptive_cusp, 0.0f, (float)m_slicing_parameters->max_layer_height, "%.2f"); + m_adaptive_cusp = clamp((float)m_slicing_parameters->min_layer_height, (float)m_slicing_parameters->max_layer_height, m_adaptive_cusp); + ImGui::SliderFloat("", &m_adaptive_cusp, (float)m_slicing_parameters->min_layer_height, (float)m_slicing_parameters->max_layer_height, "%.2f"); ImGui::Separator(); if (imgui.button(_(L("Smooth")))) From 77d6c97febf21fb37152b024af2ca5526ddce74a Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 26 Nov 2019 12:30:43 +0100 Subject: [PATCH 36/45] deps-linux newer openSSL --- deps/deps-linux.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/deps-linux.cmake b/deps/deps-linux.cmake index f5571d470..209cc3fd4 100644 --- a/deps/deps-linux.cmake +++ b/deps/deps-linux.cmake @@ -26,8 +26,8 @@ ExternalProject_Add(dep_boost ExternalProject_Add(dep_libopenssl EXCLUDE_FROM_ALL 1 - URL "https://github.com/openssl/openssl/archive/OpenSSL_1_1_0g.tar.gz" - URL_HASH SHA256=8e9516b8635bb9113c51a7b5b27f9027692a56b104e75b709e588c3ffd6a0422 + URL "https://github.com/openssl/openssl/archive/OpenSSL_1_1_0l.tar.gz" + URL_HASH SHA256=e2acf0cf58d9bff2b42f2dc0aee79340c8ffe2c5e45d3ca4533dd5d4f5775b1d BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ./config "--prefix=${DESTDIR}/usr/local" From 381d7e6c2ebdaf422e6217f2def0a3092ef588f8 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Nov 2019 12:50:57 +0100 Subject: [PATCH 37/45] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Attempt to fix sliders size, on Mac, into imgui dialog for adaptive layers --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c67604603..ef2d814a1 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -289,7 +289,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SetCursorPosX(text_align); imgui.text(_(L("Radius"))); ImGui::SameLine(); - ImGui::PushItemWidth(120.0f); + ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); ImGui::SetCursorPosX(widget_align); int radius = (int)m_smooth_params.radius; if (ImGui::SliderInt("##1", &radius, 1, 10)) @@ -298,7 +298,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SetCursorPosX(text_align); imgui.text(_(L("Keep min"))); ImGui::SameLine(); - ImGui::PushItemWidth(120.0f); + ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); ImGui::SetCursorPosX(widget_align); imgui.checkbox("##2", m_smooth_params.keep_min); From 55a163e216478fa794f58cbb1ac57838fa99b9cd Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 26 Nov 2019 14:44:14 +0100 Subject: [PATCH 38/45] Added tooltip, showing layer height at mouse cursor, to layer height profile bar --- src/slic3r/GUI/GLCanvas3D.cpp | 39 ++++++++++++++++++++++++++++++++--- src/slic3r/GUI/GLCanvas3D.hpp | 2 ++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ef2d814a1..c716f3140 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -277,7 +277,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const imgui.text(_(L("Cusp (mm)"))); ImGui::SameLine(); float widget_align = ImGui::GetCursorPosX(); - ImGui::PushItemWidth(120.0f); + ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); m_adaptive_cusp = clamp((float)m_slicing_parameters->min_layer_height, (float)m_slicing_parameters->max_layer_height, m_adaptive_cusp); ImGui::SliderFloat("", &m_adaptive_cusp, (float)m_slicing_parameters->min_layer_height, (float)m_slicing_parameters->max_layer_height, "%.2f"); @@ -289,8 +289,8 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SetCursorPosX(text_align); imgui.text(_(L("Radius"))); ImGui::SameLine(); - ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); ImGui::SetCursorPosX(widget_align); + ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); int radius = (int)m_smooth_params.radius; if (ImGui::SliderInt("##1", &radius, 1, 10)) m_smooth_params.radius = (unsigned int)radius; @@ -298,8 +298,8 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::SetCursorPosX(text_align); imgui.text(_(L("Keep min"))); ImGui::SameLine(); - ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); ImGui::SetCursorPosX(widget_align); + ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); imgui.checkbox("##2", m_smooth_params.keep_min); ImGui::Separator(); @@ -411,6 +411,35 @@ bool GLCanvas3D::LayersEditing::is_initialized() const return m_shader.is_initialized(); } +std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const +{ + std::string ret; + if (m_enabled && (m_layer_height_profile.size() >= 4)) + { + float z = get_cursor_z_relative(canvas); + if (z != -1000.0f) + { + z *= m_object_max_z; + + float h = 0.0f; + for (size_t i = m_layer_height_profile.size() - 2; i >= 2; i -= 2) + { + float zi = m_layer_height_profile[i]; + float zi_1 = m_layer_height_profile[i - 2]; + if ((zi_1 <= z) && (z <= zi)) + { + float dz = zi - zi_1; + h = (dz != 0.0f) ? lerp(m_layer_height_profile[i - 1], m_layer_height_profile[i + 1], (z - zi_1) / dz) : m_layer_height_profile[i + 1]; + break; + } + } + if (h > 0.0f) + ret = std::to_string(h); + } + } + return ret; +} + #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const { @@ -3136,6 +3165,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) if ((m_layers_editing.state != LayersEditing::Unknown) && (layer_editing_object_idx != -1)) { + set_tooltip(""); if (m_layers_editing.state == LayersEditing::Editing) _perform_layer_editing_action(&evt); } @@ -3245,6 +3275,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.position = pos.cast(); std::string tooltip = ""; + if (tooltip.empty()) + tooltip = m_layers_editing.get_tooltip(*this); + if (tooltip.empty()) tooltip = m_gizmos.get_tooltip(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index c673bc39b..e69971dfd 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -254,6 +254,8 @@ private: float object_max_z() const { return m_object_max_z; } + std::string get_tooltip(const GLCanvas3D& canvas) const; + private: bool is_initialized() const; void generate_layer_height_texture(); From 963969e210587e0edfc0053778d63f47809017d4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 27 Nov 2019 09:21:28 +0100 Subject: [PATCH 39/45] Fixed RadioButton selection in ExtruderSequenceDialog under OSX --- src/slic3r/GUI/ExtruderSequenceDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.cpp b/src/slic3r/GUI/ExtruderSequenceDialog.cpp index 8025741ff..a850ac192 100644 --- a/src/slic3r/GUI/ExtruderSequenceDialog.cpp +++ b/src/slic3r/GUI/ExtruderSequenceDialog.cpp @@ -47,6 +47,7 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ wxRadioButton* rb_by_layers = new wxRadioButton(this, ID_RADIO_BUTTON, "", wxDefaultPosition, wxDefaultSize, wxRB_GROUP); rb_by_layers->Bind(wxEVT_RADIOBUTTON, [this](wxCommandEvent& event) { m_sequence.is_mm_intervals = false; }); + rb_by_layers->SetValue(!m_sequence.is_mm_intervals); wxStaticText* st_by_layers = new wxStaticText(this, wxID_ANY, _(L("layers"))); m_interval_by_layers = new wxTextCtrl(this, wxID_ANY, From 5fcf41a3aaca3f9444409bfce61aa317250bf5cf Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 27 Nov 2019 11:08:10 +0100 Subject: [PATCH 40/45] ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Added undo/redo --- src/slic3r/GUI/GLCanvas3D.cpp | 6 +++++- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c716f3140..7160b0128 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -22,6 +22,7 @@ #include "slic3r/GUI/PresetBundle.hpp" #include "slic3r/GUI/Tab.hpp" #include "slic3r/GUI/GUI_Preview.hpp" + #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" #include "GUI_ObjectManipulation.hpp" @@ -688,7 +689,7 @@ void GLCanvas3D::LayersEditing::accept_changes(GLCanvas3D& canvas) { if (last_object_id >= 0) { if (m_layer_height_profile_modified) { - wxGetApp().plater()->take_snapshot(_(L("Layers heights"))); + wxGetApp().plater()->take_snapshot(_(L("Layer height profile-Manual edit"))); const_cast(m_model_object)->layer_height_profile = m_layer_height_profile; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } @@ -1588,6 +1589,7 @@ bool GLCanvas3D::is_layers_editing_allowed() const #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void GLCanvas3D::reset_layer_height_profile() { + wxGetApp().plater()->take_snapshot(_(L("Layer height profile-Reset"))); m_layers_editing.reset_layer_height_profile(*this); m_layers_editing.state = LayersEditing::Completed; m_dirty = true; @@ -1595,6 +1597,7 @@ void GLCanvas3D::reset_layer_height_profile() void GLCanvas3D::adaptive_layer_height_profile(float cusp) { + wxGetApp().plater()->take_snapshot(_(L("Layer height profile-Adaptive"))); m_layers_editing.adaptive_layer_height_profile(*this, cusp); m_layers_editing.state = LayersEditing::Completed; m_dirty = true; @@ -1602,6 +1605,7 @@ void GLCanvas3D::adaptive_layer_height_profile(float cusp) void GLCanvas3D::smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params) { + wxGetApp().plater()->take_snapshot(_(L("Layer height profile-Smooth all"))); m_layers_editing.smooth_layer_height_profile(*this, smoothing_params); m_layers_editing.state = LayersEditing::Completed; m_dirty = true; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e69971dfd..3b2772d08 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -179,7 +179,7 @@ private: float m_object_max_z; // Owned by LayersEditing. SlicingParameters *m_slicing_parameters; - std::vector m_layer_height_profile; + std::vector m_layer_height_profile; bool m_layer_height_profile_modified; #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 789271581..139b673bc 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4177,6 +4177,7 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator // Disable layer editing before the Undo / Redo jump. if (!new_variable_layer_editing_active && view3D->is_layers_editing_enabled()) view3D->get_canvas3d()->force_main_toolbar_left_action(view3D->get_canvas3d()->get_main_toolbar_item_id("layersediting")); + // Make a copy of the snapshot, undo/redo could invalidate the iterator const UndoRedo::Snapshot snapshot_copy = *it_snapshot; // Do the jump in time. From 1ba3f0a4f6d9c7a9abb13f30116130eb2efeab04 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 27 Nov 2019 13:37:37 +0100 Subject: [PATCH 41/45] Transparent background for thumbnails saved into gcode and sl1 files --- src/libslic3r/GCode.cpp | 2 +- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 8 ++++---- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 014deb79c..f9a16e1ad 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -991,7 +991,7 @@ void GCode::_do_export(Print& print, FILE* file) { const size_t max_row_length = 78; ThumbnailsList thumbnails; - thumbnail_cb(thumbnails, print.full_print_config().option("thumbnails")->values, true, true, false); + thumbnail_cb(thumbnails, print.full_print_config().option("thumbnails")->values, true, true, true); for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 570841a45..8d64ecf43 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -139,8 +139,8 @@ void BackgroundSlicingProcess::process_sla() if (m_thumbnail_cb != nullptr) { ThumbnailsList thumbnails; - m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, true, false); -// m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, false, false); // renders also supports and pad + m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, true, true); +// m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, false, true); // renders also supports and pad for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) @@ -464,8 +464,8 @@ void BackgroundSlicingProcess::prepare_upload() if (m_thumbnail_cb != nullptr) { ThumbnailsList thumbnails; - m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, true, false); -// m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, false, false); // renders also supports and pad + m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, true, true); +// m_thumbnail_cb(thumbnails, current_print()->full_print_config().option("thumbnails")->values, true, false, true); // renders also supports and pad for (const ThumbnailData& data : thumbnails) { if (data.is_valid()) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7160b0128..1af1f8e40 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3847,7 +3847,7 @@ static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volu camera.apply_projection(box); if (transparent_background) - glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 0.0f)); + glsafe(::glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); From 496e09302f4afe52c2cef1e4853cc1c243420379 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 27 Nov 2019 14:44:33 +0100 Subject: [PATCH 42/45] Implemented a message on Printer display for pause print + Added new icons --- resources/icons/edit_gcode.svg | 15 +++++++++ resources/icons/edit_uni.svg | 20 ++++++++++++ resources/icons/pause_print.svg | 18 +++++++++++ src/libslic3r/GCode.cpp | 9 ++++++ src/libslic3r/Model.hpp | 3 +- src/slic3r/GUI/wxExtensions.cpp | 57 ++++++++++++++++++++++++--------- src/slic3r/GUI/wxExtensions.hpp | 1 + 7 files changed, 107 insertions(+), 16 deletions(-) create mode 100644 resources/icons/edit_gcode.svg create mode 100644 resources/icons/edit_uni.svg create mode 100644 resources/icons/pause_print.svg diff --git a/resources/icons/edit_gcode.svg b/resources/icons/edit_gcode.svg new file mode 100644 index 000000000..694e106cc --- /dev/null +++ b/resources/icons/edit_gcode.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/resources/icons/edit_uni.svg b/resources/icons/edit_uni.svg new file mode 100644 index 000000000..f7b1673a6 --- /dev/null +++ b/resources/icons/edit_uni.svg @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/resources/icons/pause_print.svg b/resources/icons/pause_print.svg new file mode 100644 index 000000000..a905b1ea1 --- /dev/null +++ b/resources/icons/pause_print.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 381bd3e66..8afeecb1e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1868,11 +1868,16 @@ void GCode::process_layer( // colorprint_change = true; // } std::string custom_code = ""; + std::string pause_print_msg = ""; int m600_before_extruder = -1; while (!m_custom_g_code_heights.empty() && m_custom_g_code_heights.front().height-EPSILON < layer.print_z) { custom_code = m_custom_g_code_heights.front().gcode; if (custom_code == ColorChangeCode && m_custom_g_code_heights.front().extruder > 0) m600_before_extruder = m_custom_g_code_heights.front().extruder - 1; + + if (custom_code == PausePrintCode) + pause_print_msg = m_custom_g_code_heights.front().color; + m_custom_g_code_heights.erase(m_custom_g_code_heights.begin()); colorprint_change = true; } @@ -1903,6 +1908,7 @@ void GCode::process_layer( if (!single_material_print && m600_before_extruder >= 0 && first_extruder_id != m600_before_extruder // && !MMU1 ) { + //! FIXME_in_fw show message during print pause gcode += "M601\n"; // pause print gcode += "M117 Change filament for Extruder " + std::to_string(m600_before_extruder) + "\n"; } @@ -1915,6 +1921,9 @@ void GCode::process_layer( { // add tag for analyzer gcode += "; " + GCodeAnalyzer::Pause_Print_Tag + "\n"; + //! FIXME_in_fw show message during print pause + if (!pause_print_msg.empty()) + gcode += "M117 " + pause_print_msg + "\n"; // add tag for time estimator //gcode += "; " + GCodeTimeEstimator::Pause_Print_Tag + "\n"; } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 21b5896e0..c2942a4ea 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -772,7 +772,8 @@ public: std::string gcode; int extruder; // 0 - "gcode" will be applied for whole print // else - "gcode" will be applied only for "extruder" print - std::string color; + std::string color; // if gcode is equal to PausePrintCode, + // this field is used for save a short message shown on Printer display }; std::vector custom_gcode_per_height; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 532eaa551..720f2a8d7 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -27,6 +27,7 @@ #include "../Utils/MacDarkMode.hpp" using Slic3r::GUI::from_u8; +using Slic3r::GUI::into_u8; wxDEFINE_EVENT(wxCUSTOMEVT_TICKSCHANGED, wxEvent); wxDEFINE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent); @@ -2321,6 +2322,7 @@ DoubleSlider::DoubleSlider( wxWindow *parent, m_cog_icon_dim = int((float)m_bmp_cog.bmp().GetSize().x / scale_factor); m_selection = ssUndef; + m_pause_print_msg = _utf8(L("Place bearings in slots and resume")); // slider events Bind(wxEVT_PAINT, &DoubleSlider::OnPaint, this); @@ -2795,7 +2797,7 @@ void DoubleSlider::draw_ticks(wxDC& dc) // Draw icon for "Pause print" or "Custom Gcode" if (tick.gcode != Slic3r::ColorChangeCode && tick.gcode != Slic3r::ExtruderChangeCode) { - wxBitmap icon = create_scaled_bitmap(nullptr, tick.gcode == Slic3r::PausePrintCode ? "pause_add.png" : "add_gcode"); + wxBitmap icon = create_scaled_bitmap(nullptr, tick.gcode == Slic3r::PausePrintCode ? "pause_print" : "edit_gcode"); wxCoord x_draw, y_draw; is_horizontal() ? x_draw = pos - 0.5 * m_tick_icon_dim : y_draw = pos - 0.5 * m_tick_icon_dim; @@ -3084,19 +3086,17 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; const auto tick_code_it = m_ticks_.find(tick); - tooltip = tick_code_it == m_ticks_.end() ? (m_state == msSingleExtruder ? //_(L("Add color change")) : + tooltip = tick_code_it == m_ticks_.end() ? (m_state == msSingleExtruder ? _(L("For add color change use left mouse button click")) : _(L("For add change extruder use left mouse button click"))) + "\n" + _(L("For add another code use right mouse button click")) : - // tick_code_it->gcode == Slic3r::ColorChangeCode ? _(L("Delete color change")) : - tick_code_it->gcode == Slic3r::ColorChangeCode ? ( m_state == msSingleExtruder ? //_(L("Delete color change")) : + tick_code_it->gcode == Slic3r::ColorChangeCode ? ( m_state == msSingleExtruder ? _(L("For Delete color change use left mouse button click\n" "For Edit color use right mouse button click")) : from_u8((boost::format(_utf8(L("Delete color change for Extruder %1%"))) % tick_code_it->extruder).str()) ): - tick_code_it->gcode == Slic3r::PausePrintCode ? _(L("Delete pause")) : - tick_code_it->gcode == Slic3r::ExtruderChangeCode ? //( m_state == msSingleExtruder ? _(L("Delete color change")) : - from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) /*) */: - // from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str()); +// tick_code_it->gcode == Slic3r::PausePrintCode ? _(L("Delete pause")) : + tick_code_it->gcode == Slic3r::ExtruderChangeCode ? + from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) : from_u8((boost::format(_utf8(L("For Delete \"%1%\" code use left mouse button click\n" "For Edit \"%1%\" code use right mouse button click"))) % tick_code_it->gcode ).str()); } @@ -3373,7 +3373,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) m_show_context_menu = true; return; } - if (it->gcode != Slic3r::ExtruderChangeCode && it->gcode != Slic3r::PausePrintCode) + if (it->gcode != Slic3r::ExtruderChangeCode) { // show "Edit" and "Delete" menu on OnRightUp() m_show_edit_menu = true; @@ -3459,10 +3459,10 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) if (m_state != msMultiExtruder) append_menu_item(&menu, wxID_ANY, _(L("Add pause print")) + " (M601)", "", - [this](wxCommandEvent&) { add_code(Slic3r::PausePrintCode); }, "pause_add.png", &menu); + [this](wxCommandEvent&) { add_code(Slic3r::PausePrintCode); }, "pause_print", &menu); append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "", - [this](wxCommandEvent&) { add_code(""); }, "add_gcode", &menu); + [this](wxCommandEvent&) { add_code(""); }, "edit_gcode", &menu); Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); @@ -3474,10 +3474,14 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) std::set::iterator it = m_ticks_.find(m_selection == ssLower ? m_lower_value : m_higher_value); const bool is_color_change = it->gcode == Slic3r::ColorChangeCode; - append_menu_item(&menu, wxID_ANY, is_color_change ? _(L("Edit color")) : _(L("Edit custom G-code")), "", - [this](wxCommandEvent&) { edit_tick(); }, "change_extruder", &menu); + append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Edit color")) : + it->gcode == Slic3r::PausePrintCode ? _(L("Edit pause print message")) : + _(L("Edit custom G-code")), "", + [this](wxCommandEvent&) { edit_tick(); }, "edit_uni", &menu); - append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Delete color change")) : _(L("Delete custom G-code")), "", + append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Delete color change")) : + it->gcode == Slic3r::PausePrintCode ? _(L("Delete pause print")) : + _(L("Delete custom G-code")), "", [this](wxCommandEvent&) { action_tick(taDel); }, "colorchange_delete_off.png", &menu); Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); @@ -3521,6 +3525,20 @@ static std::string get_custom_code(const std::string& code_in, double height) return dlg.GetValue().ToStdString(); } +static std::string get_pause_print_msg(const std::string& msg_in, double height) +{ + wxString msg_text = from_u8(_utf8(L("Enter short message shown on Printer display during pause print"))) + " :"; + wxString msg_header = from_u8((boost::format(_utf8(L("Message for pause print on current layer (%1% mm)."))) % height).str()); + + // get custom gcode + wxTextEntryDialog dlg(nullptr, msg_text, msg_header, from_u8(msg_in), + wxTextEntryDialogStyle); + if (dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty()) + return ""; + + return into_u8(dlg.GetValue()); +} + void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; @@ -3553,6 +3571,13 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) if (color.empty()) return; } + else if (code == Slic3r::PausePrintCode) + { + /* PausePrintCode doesn't need a color, so + * this field is used for save a short message shown on Printer display + * */ + m_pause_print_msg = color = get_pause_print_msg(m_pause_print_msg, m_values[tick]); + } else if (code.empty()) { m_custom_gcode = code = get_custom_code(m_custom_gcode, m_values[tick]); @@ -3586,6 +3611,8 @@ void DoubleSlider::edit_tick() std::string edited_value; if (it->gcode == Slic3r::ColorChangeCode) edited_value = get_new_color(it->color); + else if (it->gcode == Slic3r::PausePrintCode) + edited_value = get_pause_print_msg(it->color, m_values[it->tick]); else edited_value = get_custom_code(it->gcode, m_values[it->tick]); @@ -3593,7 +3620,7 @@ void DoubleSlider::edit_tick() return; TICK_CODE changed_tick = *it; - if (it->gcode == Slic3r::ColorChangeCode) { + if (it->gcode == Slic3r::ColorChangeCode || it->gcode == Slic3r::PausePrintCode) { if (it->color == edited_value) return; changed_tick.color = edited_value; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 612cd6236..c1bf82821 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -927,6 +927,7 @@ private: bool m_suppress_add_code = false; ManipulationState m_state = msSingleExtruder; std::string m_custom_gcode = ""; + std::string m_pause_print_msg; int m_current_extruder = -1; wxRect m_rect_lower_thumb; From 901a20b3b1bb44166c9d909af172f8c5d76822f0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 27 Nov 2019 15:27:44 +0100 Subject: [PATCH 43/45] Code cleaning --- src/libslic3r/GCode.cpp | 44 +------------- src/libslic3r/GCode.hpp | 9 +-- src/libslic3r/GCode/PreviewData.cpp | 39 ------------- src/libslic3r/GCode/PreviewData.hpp | 2 - src/slic3r/GUI/GLCanvas3D.cpp | 89 +---------------------------- src/slic3r/GUI/GLCanvas3D.hpp | 8 --- src/slic3r/GUI/GUI_Preview.cpp | 81 +------------------------- src/slic3r/GUI/GUI_Preview.hpp | 2 - src/slic3r/GUI/Plater.cpp | 3 - 9 files changed, 11 insertions(+), 266 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8afeecb1e..869449a97 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -928,8 +928,6 @@ void GCode::_do_export(Print &print, FILE *file) this->apply_print_config(print.config()); this->set_extruders(print.extruders()); - // #ys_FIXME_COLOR // Initialize colorprint. - // m_colorprint_heights = cast(print.config().colorprint_heights.values); // Initialize custom gcode Model* model = print.get_object(0)->model_object()->get_model(); m_custom_g_code_heights = model->custom_gcode_per_height; @@ -1153,8 +1151,6 @@ void GCode::_do_export(Print &print, FILE *file) } print.throw_if_canceled(); - - // #ys_FIXME_COLOR /* To avoid change filament for non-used extruder for Multi-material, * check model->custom_gcode_per_height using tool_ordering values * */ @@ -1862,19 +1858,15 @@ void GCode::process_layer( // In case there are more toolchange requests that weren't done yet and should happen simultaneously, erase them all. // (Layers can be close to each other, model could have been resliced with bigger layer height, ...). bool colorprint_change = false; - // #ys_FIXME_COLOR - // while (!m_colorprint_heights.empty() && m_colorprint_heights.front()-EPSILON < layer.print_z) { - // m_colorprint_heights.erase(m_colorprint_heights.begin()); - // colorprint_change = true; - // } + std::string custom_code = ""; std::string pause_print_msg = ""; int m600_before_extruder = -1; while (!m_custom_g_code_heights.empty() && m_custom_g_code_heights.front().height-EPSILON < layer.print_z) { custom_code = m_custom_g_code_heights.front().gcode; + if (custom_code == ColorChangeCode && m_custom_g_code_heights.front().extruder > 0) m600_before_extruder = m_custom_g_code_heights.front().extruder - 1; - if (custom_code == PausePrintCode) pause_print_msg = m_custom_g_code_heights.front().color; @@ -1883,16 +1875,6 @@ void GCode::process_layer( } // we should add or not colorprint_change in respect to nozzle_diameter count instead of really used extruders count - // #ys_FIXME_COLOR - // if (colorprint_change && print./*extruders()*/config().nozzle_diameter.size()==1) - // { - // // add tag for analyzer - // gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n"; - // // add tag for time estimator - // gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; - // - // gcode += "M600\n"; - // } // don't save "tool_change"(ExtruderChangeCode) code to GCode if (colorprint_change && custom_code != ExtruderChangeCode) { @@ -1936,28 +1918,6 @@ void GCode::process_layer( } gcode += custom_code + "\n"; } - - /* - if (single_material_print || custom_code != ExtruderChangeCode) - { - // add tag for analyzer - gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n"; - // add tag for time estimator - gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n"; - if (single_material_print && custom_code == ExtruderChangeCode) - custom_code = ColorChangeCode; - - if (!single_material_print && custom_code == ColorChangeCode && - m600_before_extruder >= 0 && first_extruder_id != m600_before_extruder - // && !MMU1 - ) { - gcode += "M601\n"; // pause print - gcode += "M117 Change filament for Extruder " + std::to_string(m600_before_extruder) + "\n"; - } - else - gcode += custom_code + "\n"; - } - */ } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 97f31dc6a..261a24d01 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -362,10 +362,11 @@ protected: bool m_second_layer_things_done; // Index of a last object copy extruded. std::pair m_last_obj_copy; - // Layer heights for colorprint - updated before the export and erased during the process - // so no toolchange occurs twice. - std::vector m_colorprint_heights; - // extensions for colorprint - now it's not a just color_print, there can be some custom gcode + /* Extensions for colorprint - now it's not a just color_print_heights, + * there can be some custom gcode. + * Updated before the export and erased during the process, + * so no toolchange occurs twice. + * */ std::vector m_custom_g_code_heights; // Time estimators diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index ba0584e57..e7475089a 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -379,8 +379,6 @@ std::string GCodePreviewData::get_legend_title() const return ""; } -// #ys_FIXME_COLOR -// GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector& tool_colors, const std::vector>& cp_values) const GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::vector& tool_colors, const std::vector& cp_items) const { @@ -455,43 +453,6 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: break; } - // #ys_FIXME_COLOR - /*case Extrusion::ColorPrint: - { - const int color_cnt = (int)tool_colors.size()/4; - const auto color_print_cnt = (int)cp_values.size(); - if (color_print_cnt > 0) { - GCodePreviewData::Color color; - ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (color_cnt-1) * 4), 4 * sizeof(float)); - items.emplace_back(Slic3r::I18N::translate(L("Pause print or custom G-code")), color); - } - - for (int i = color_print_cnt; i >= 0 ; --i) - { - GCodePreviewData::Color color; - ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (i % color_cnt) * 4), 4 * sizeof(float)); - - if (color_print_cnt == 0) { - items.emplace_back(Slic3r::I18N::translate(L("Default print color")), color); - break; - } - - std::string id_str = std::to_string(i + 1) + ": "; - - if (i == 0) { - items.emplace_back(id_str + (boost::format(Slic3r::I18N::translate(L("up to %.2f mm"))) % cp_values[0].first).str(), color); - break; - } - if (i == color_print_cnt) { - items.emplace_back(id_str + (boost::format(Slic3r::I18N::translate(L("above %.2f mm"))) % cp_values[i - 1].second).str(), color); - continue; - } - -// items.emplace_back((boost::format(Slic3r::I18N::translate(L("%.2f - %.2f mm"))) % cp_values[i-1] % cp_values[i]).str(), color); - items.emplace_back(id_str + (boost::format(Slic3r::I18N::translate(L("%.2f - %.2f mm"))) % cp_values[i - 1].second% cp_values[i].first).str(), color); - } - break; - }*/ case Extrusion::ColorPrint: { const int color_cnt = (int)tool_colors.size()/4; diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 78de04d0a..725c0258d 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -237,8 +237,6 @@ public: void set_extrusion_paths_colors(const std::vector& colors); std::string get_legend_title() const; - // #ys_FIXME_COLOR - // LegendItemsList get_legend_items(const std::vector& tool_colors, const std::vector>& cp_values) const; LegendItemsList get_legend_items(const std::vector& tool_colors, const std::vector& cp_items) const; // Return an estimate of the memory consumed by the time estimator. diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ece858c9c..909907e81 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -836,59 +836,6 @@ GLCanvas3D::LegendTexture::LegendTexture() { } -void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, - std::vector>& cp_legend_values) -{ - if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint /*&& - wxGetApp().extruders_edited_cnt() == 1*/) // show color change legend only for single-material presets - { - /* - // #ys_FIXME_COLOR - auto& config = wxGetApp().preset_bundle->project_config; - const std::vector& color_print_values = config.option("colorprint_heights")->values; - - if (!color_print_values.empty()) { - std::vector print_zs = canvas.get_current_print_zs(true); - for (auto cp_value : color_print_values) - { - auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), cp_value - DoubleSlider::epsilon()); - - if (lower_b == print_zs.end()) - continue; - - double current_z = *lower_b; - double previous_z = lower_b == print_zs.begin() ? 0.0 : *(--lower_b); - - // to avoid duplicate values, check adding values - if (cp_legend_values.empty() || - !(cp_legend_values.back().first == previous_z && cp_legend_values.back().second == current_z) ) - cp_legend_values.push_back(std::pair(previous_z, current_z)); - } - } - */ - std::vector custom_gcode_per_height = wxGetApp().plater()->model().custom_gcode_per_height; - - if (!custom_gcode_per_height.empty()) { - std::vector print_zs = canvas.get_current_print_zs(true); - for (auto custom_code : custom_gcode_per_height) - { - auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.height - DoubleSlider::epsilon()); - - if (lower_b == print_zs.end()) - continue; - - double current_z = *lower_b; - double previous_z = lower_b == print_zs.begin() ? 0.0 : *(--lower_b); - - // to avoid duplicate values, check adding values - if (cp_legend_values.empty() || - !(cp_legend_values.back().first == previous_z && cp_legend_values.back().second == current_z) ) - cp_legend_values.push_back(std::pair(previous_z, current_z)); - } - } - } -} - void GLCanvas3D::LegendTexture::fill_color_print_legend_items( const GLCanvas3D& canvas, const std::vector& colors_in, std::vector& colors, @@ -997,12 +944,6 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c // collects items to render auto title = _(preview_data.get_legend_title()); - // #ys_FIXME_COLOR - // std::vector> cp_legend_values; - // fill_color_print_legend_values(preview_data, canvas, cp_legend_values); - - // const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_values); - std::vector cp_legend_items; std::vector cp_colors; @@ -2380,8 +2321,6 @@ void GLCanvas3D::load_sla_preview() } } -// #ys_FIXME_COLOR -// void GLCanvas3D::load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values) void GLCanvas3D::load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values) { const Print *print = this->fff_print(); @@ -5159,8 +5098,6 @@ void GLCanvas3D::_load_print_toolpaths() volume->indexed_vertex_array.finalize_geometry(m_initialized); } -// #ys_FIXME_COLOR -// void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) { std::vector tool_colors = _parse_colors(str_tool_colors); @@ -5173,8 +5110,6 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c bool has_infill; bool has_support; const std::vector* tool_colors; - // #ys_FIXME_COLOR - // const std::vector* color_print_values; bool is_single_material_print; int extruders_cnt; const std::vector* color_print_values; @@ -5192,8 +5127,6 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c // For coloring by a color_print(M600), return a parsed color. bool color_by_color_print() const { return color_print_values!=nullptr; } const size_t color_print_color_idx_by_layer_idx(const size_t layer_idx) const { - // #ys_FIXME_COLOR - // auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON); const Model::CustomGCode value(layers[layer_idx]->print_z + EPSILON, "", 0, ""); auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value); return (it - color_print_values->begin()) % number_tools(); @@ -5350,33 +5283,13 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c std::vector color_print_layer_to_glvolume; auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { return *vols[ctxt.color_by_color_print()? - //color_print_layer_to_glvolume[layer_idx - range.begin()] : ctxt.color_print_color_idx_by_layer_idx_and_extruder(layer_idx, extruder) : ctxt.color_by_tool() ? std::min(ctxt.number_tools() - 1, std::max(extruder - 1, 0)) : feature ]; }; - /*if (ctxt.color_by_color_print()) { - // Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color. - std::vector color_print_tool_to_glvolume(ctxt.number_tools(), -1); - color_print_layer_to_glvolume.reserve(range.end() - range.begin()); - vols.reserve(ctxt.number_tools()); - for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { - int idx_tool = (int)ctxt.color_print_color_idx_by_layer_idx(idx_layer); - if (color_print_tool_to_glvolume[idx_tool] == -1) { - color_print_tool_to_glvolume[idx_tool] = (int)vols.size(); - vols.emplace_back(new_volume(ctxt.color_tool(idx_tool))); - } - color_print_layer_to_glvolume.emplace_back(color_print_tool_to_glvolume[idx_tool]); - } - vols.emplace_back(new_volume(ctxt.color_pause_or_custom_code())); - } - for (size_t i = 0; i < ctxt.number_tools(); ++i) - vols.emplace_back(new_volume(ctxt.color_tool(i))); - vols.emplace_back(new_volume(ctxt.color_pause_or_custom_code())); - } - else */if (ctxt.color_by_color_print() || ctxt.color_by_tool()) { + if (ctxt.color_by_color_print() || ctxt.color_by_tool()) { for (size_t i = 0; i < ctxt.number_tools(); ++i) vols.emplace_back(new_volume(ctxt.color_tool(i))); } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index f89dd006b..729b707d2 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -352,9 +352,6 @@ private: public: LegendTexture(); - void fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, - std::vector>& cp_legend_values); - void fill_color_print_legend_items(const GLCanvas3D& canvas, const std::vector& colors_in, std::vector& colors, @@ -555,8 +552,6 @@ public: void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); void load_sla_preview(); - // #ys_FIXME_COLOR - // void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); void bind_event_handlers(); void unbind_event_handlers(); @@ -722,9 +717,6 @@ private: // one for perimeters, one for infill and one for supports. void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values); - // #ys_FIXME_COLOR - // void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, - // const std::vector& color_print_values); // Create 3D thick extrusion lines for wipe tower extrusions void _load_wipe_tower_toolpaths(const std::vector& str_tool_colors); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 8f4b8a19b..cb926f1f1 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -582,16 +582,6 @@ void Preview::update_view_type(bool slice_completed) { const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config; - /* - // #ys_FIXME_COLOR - const wxString& choice = !config.option("colorprint_heights")->values.empty() && - wxGetApp().extruders_edited_cnt()==1 ? - _(L("Color Print")) : - config.option("wiping_volumes_matrix")->values.size() > 1 ? - _(L("Tool")) : - _(L("Feature type")); - */ - const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() /*&& (wxGetApp().extruders_edited_cnt()==1 || !slice_completed) */? _(L("Color Print")) : @@ -728,9 +718,6 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max(); - // #ys_FIXME_COLOR - // std::vector &ticks_from_config = (wxGetApp().preset_bundle->project_config.option("colorprint_heights"))->values; - // check_slider_values(ticks_from_config, layers_z); std::vector tmp_ticks_from_model; if (m_selected_extruder != 0) tmp_ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height; @@ -761,41 +748,15 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee m_slider->SetTicksValues(ticks_from_model); bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF); - // #ys_FIXME_COLOR - // if (color_print_enable) { - // const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config; - // if (cfg.opt("nozzle_diameter")->values.size() > 1) - // color_print_enable = false; - // } - // m_slider->EnableTickManipulation(color_print_enable); m_slider->EnableTickManipulation(color_print_enable); if (color_print_enable && wxGetApp().extruders_edited_cnt() > 1) { - //bool is_detected_full_print = //wxGetApp().plater()->fff_print().extruders().size() == 1; m_slider->SetExtruderID(m_extruder_selector->GetSelection()); } else m_slider->SetExtruderID(-1); } -// #ys_FIXME_COLOR -void Preview::check_slider_values(std::vector& ticks_from_config, - const std::vector &layers_z) -{ - // All ticks that would end up outside the slider range should be erased. - // TODO: this should be placed into more appropriate part of code, - // this function is e.g. not called when the last object is deleted - unsigned int old_size = ticks_from_config.size(); - ticks_from_config.erase(std::remove_if(ticks_from_config.begin(), ticks_from_config.end(), - [layers_z](double val) - { - auto it = std::lower_bound(layers_z.begin(), layers_z.end(), val - DoubleSlider::epsilon()); - return it == layers_z.end(); - }), - ticks_from_config.end()); - if (ticks_from_config.size() != old_size) - m_schedule_background_process(); -} void Preview::reset_double_slider() { @@ -878,51 +839,19 @@ void Preview::load_print_as_fff(bool keep_z_range) bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); // Collect colors per extruder. std::vector colors; - // #ys_FIXME_COLOR - // std::vector color_print_values = {}; std::vector color_print_values = {}; // set color print values, if it si selected "ColorPrint" view type if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) { - color_print_values = wxGetApp().plater()->model().custom_gcode_per_height; - /* colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); - - for (const Model::CustomGCode& code : color_print_values) - if (code.gcode == ColorChangeCode) - colors.push_back(code.color);*/ - colors = wxGetApp().plater()->get_colors_for_color_print(); + colors = wxGetApp().plater()->get_colors_for_color_print(); colors.push_back("#808080"); // gray color for pause print or custom G-code - if (gcode_preview_data_valid) - color_print_values.clear(); - /* - if (! gcode_preview_data_valid) { - // #ys_FIXME_COLOR - // const auto& config = wxGetApp().preset_bundle->project_config; - // color_print_values = config.option("colorprint_heights")->values; + if (!gcode_preview_data_valid) color_print_values = wxGetApp().plater()->model().custom_gcode_per_height; - } - */ } else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) { - const ConfigOptionStrings* extruders_opt = dynamic_cast(m_config->option("extruder_colour")); - const ConfigOptionStrings* filamemts_opt = dynamic_cast(m_config->option("filament_colour")); - unsigned int colors_count = std::max((unsigned int)extruders_opt->values.size(), (unsigned int)filamemts_opt->values.size()); - - unsigned char rgb[3]; - for (unsigned int i = 0; i < colors_count; ++i) - { - std::string color = m_config->opt_string("extruder_colour", i); - if (!PresetBundle::parse_color(color, rgb)) - { - color = m_config->opt_string("filament_colour", i); - if (!PresetBundle::parse_color(color, rgb)) - color = "#FFFFFF"; - } - - colors.emplace_back(color); - } + colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); color_print_values.clear(); } @@ -934,10 +863,6 @@ void Preview::load_print_as_fff(bool keep_z_range) m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); m_loaded = true; } else { - // disable color change information for multi-material presets - // if (wxGetApp().extruders_edited_cnt() > 1) // #ys_FIXME_COLOR - // color_print_values.clear(); - // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 7a11e334c..900368baa 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -162,8 +162,6 @@ private: void check_slider_values(std::vector &ticks_from_model, const std::vector &layers_z); void update_double_slider(const std::vector& layers_z, bool keep_z_range = false); - void check_slider_values(std::vector &ticks_from_config, - const std::vector &layers_z); // #ys_FIXME_COLOR void reset_double_slider(); // update DoubleSlider after keyDown in canvas void update_double_slider_from_canvas(wxKeyEvent& event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 09a496ca4..bf858215e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2725,9 +2725,6 @@ void Plater::priv::reset() // The hiding of the slicing results, if shown, is not taken care by the background process, so we do it here this->sidebar->show_sliced_info_sizer(false); - // #ys_FIXME_COLOR - // auto& config = wxGetApp().preset_bundle->project_config; - // config.option("colorprint_heights")->values.clear(); model.custom_gcode_per_height.clear(); } From 322c0230c3de9e8c49287fde6fd2f301bb7dc648 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 27 Nov 2019 16:03:16 +0100 Subject: [PATCH 44/45] Code cleaning - deleted extruder selector --- src/slic3r/GUI/GUI_Preview.cpp | 66 ++++------------------------------ src/slic3r/GUI/GUI_Preview.hpp | 3 -- src/slic3r/GUI/Plater.cpp | 3 -- 3 files changed, 6 insertions(+), 66 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index cb926f1f1..c44993048 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -505,20 +505,10 @@ void Preview::reset_sliders(bool reset_all) void Preview::update_sliders(const std::vector& layers_z, bool keep_z_range) { m_enabled = true; - // update extruder selector - if (wxGetApp().extruders_edited_cnt() != m_extruder_selector->GetCount()-1) - { - m_selected_extruder = m_extruder_selector->GetSelection(); - update_extruder_selector(); - if (m_selected_extruder >= m_extruder_selector->GetCount()) - m_selected_extruder = 0; - m_extruder_selector->SetSelection(m_selected_extruder); - } update_double_slider(layers_z, keep_z_range); m_double_slider_sizer->Show((size_t)0); -// if (m_slider->GetManipulationState() == DoubleSlider::msSingleExtruder) - m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide((size_t)0); + Layout(); } @@ -535,9 +525,6 @@ void Preview::on_choice_view_type(wxCommandEvent& evt) if ((0 <= selection) && (selection < (int)GCodePreviewData::Extrusion::Num_View_Types)) m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)selection; - if (m_gcode_preview_data->extrusion.view_type != GCodePreviewData::Extrusion::ColorPrint) - m_extruder_selector->SetSelection(0); - reload_print(); } @@ -596,14 +583,6 @@ void Preview::update_view_type(bool slice_completed) m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; m_preferred_color_mode = "feature"; } - - if (type != GCodePreviewData::Extrusion::EViewType::ColorPrint) - m_extruder_selector->SetSelection(0); -} - -void Preview::update_extruder_selector() -{ - apply_extruder_selector(&m_extruder_selector, this, L("Whole print"), wxDefaultPosition, wxDefaultSize, true); } void Preview::create_double_slider() @@ -611,35 +590,7 @@ void Preview::create_double_slider() m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100); m_slider->EnableTickManipulation(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptFFF); - // #ys_FIXME_COLOR - // m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); - - update_extruder_selector(); - m_extruder_selector->SetSelection(0); - m_extruder_selector->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) - { - m_selected_extruder = m_extruder_selector->GetSelection(); - m_slider->SetExtruderID(m_selected_extruder); - - int type = m_choice_view_type->FindString(_(L("Color Print"))); - - if (m_choice_view_type->GetSelection() != type) { - m_choice_view_type->SetSelection(type); - if (0 <= type && type < (int)GCodePreviewData::Extrusion::Num_View_Types) - m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; - m_preferred_color_mode = "feature"; - } - reload_print(); - - evt.StopPropagation(); - }); - m_extruder_selector->Disable(); - - auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(m_extruder_selector, 0, wxEXPAND, 0); - sizer->Add(m_slider, 1, wxEXPAND, 0); - - m_double_slider_sizer->Add(sizer, 0, wxEXPAND, 0); + m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); // sizer, m_canvas_widget m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this); @@ -718,11 +669,7 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max(); - std::vector tmp_ticks_from_model; - if (m_selected_extruder != 0) - tmp_ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height; - std::vector &ticks_from_model = m_selected_extruder != 0 ? tmp_ticks_from_model : - wxGetApp().plater()->model().custom_gcode_per_height; + std::vector &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height; check_slider_values(ticks_from_model, layers_z); m_slider->SetSliderValues(layers_z); @@ -751,11 +698,10 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee m_slider->EnableTickManipulation(color_print_enable); if (color_print_enable && wxGetApp().extruders_edited_cnt() > 1) { - m_slider->SetExtruderID(m_extruder_selector->GetSelection()); + m_slider->SetExtruderID(0); } else m_slider->SetExtruderID(-1); - } void Preview::reset_double_slider() @@ -857,7 +803,7 @@ void Preview::load_print_as_fff(bool keep_z_range) if (IsShown()) { - m_canvas->set_selected_extruder(m_selected_extruder); + m_canvas->set_selected_extruder(0); if (gcode_preview_data_valid) { // Load the real G-code preview. m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); @@ -871,7 +817,7 @@ void Preview::load_print_as_fff(bool keep_z_range) std::vector zs = m_canvas->get_current_print_zs(true); if (zs.empty()) { // all layers filtered out - reset_sliders(m_selected_extruder==0); + reset_sliders(true); m_canvas_widget->Refresh(); } else update_sliders(zs, keep_z_range); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 900368baa..b0dac4223 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -104,8 +104,6 @@ class Preview : public wxPanel bool m_enabled; DoubleSlider* m_slider {nullptr}; - wxBitmapComboBox* m_extruder_selector {nullptr}; - int m_selected_extruder {0}; // 0 means "Whole print" public: Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, @@ -133,7 +131,6 @@ public: void edit_double_slider(wxKeyEvent& evt); void update_view_type(bool slice_completed); - void update_extruder_selector(); bool is_loaded() const { return m_loaded; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index bf858215e..409e9a11e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4965,7 +4965,6 @@ void Plater::on_config_change(const DynamicPrintConfig &config) filament_colors.push_back(filaments.find_preset(filament_preset, true)->config.opt_string("filament_colour", (unsigned)0)); p->config->option(opt_key)->values = filament_colors; - p->preview->update_extruder_selector(); p->sidebar->obj_list()->update_extruder_colors(); continue; } @@ -4992,7 +4991,6 @@ void Plater::on_config_change(const DynamicPrintConfig &config) else if(opt_key == "extruder_colour") { update_scheduled = true; p->preview->set_number_extruders(p->config->option(opt_key)->values.size()); - p->preview->update_extruder_selector(); p->sidebar->obj_list()->update_extruder_colors(); } else if(opt_key == "max_print_height") { update_scheduled = true; @@ -5044,7 +5042,6 @@ void Plater::force_filament_colors_update() if (update_scheduled) { update(); - p->preview->update_extruder_selector(); p->sidebar->obj_list()->update_extruder_colors(); } From c87feb987030a4081509eb38b8d261594d438cf7 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 28 Nov 2019 08:38:28 +0100 Subject: [PATCH 45/45] Code cleaning - removed unused state from DoubleSlider --- src/slic3r/GUI/GUI_Preview.cpp | 6 +----- src/slic3r/GUI/wxExtensions.cpp | 23 ++++++++++------------- src/slic3r/GUI/wxExtensions.hpp | 14 +++++--------- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index c44993048..edb244b34 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -697,11 +697,7 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF); m_slider->EnableTickManipulation(color_print_enable); - if (color_print_enable && wxGetApp().extruders_edited_cnt() > 1) { - m_slider->SetExtruderID(0); - } - else - m_slider->SetExtruderID(-1); + m_slider->SetManipulationState(wxGetApp().extruders_edited_cnt()); } void Preview::reset_double_slider() diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 720f2a8d7..90cfe6824 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -2561,7 +2561,7 @@ void DoubleSlider::SetTicksValues(const std::vector& heights) m_ticks_.insert(TICK_CODE(it-m_values.begin(), h.gcode, h.extruder, h.color)); } - if (!was_empty && m_ticks_.empty() && m_state != msMultiExtruder) + if (!was_empty && m_ticks_.empty()) // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); @@ -2847,15 +2847,15 @@ void DoubleSlider::draw_colored_band(wxDC& dc) for (auto tick : m_ticks_) { if ( (m_state == msSingleExtruder && tick.gcode != Slic3r::ColorChangeCode) || - (m_state == msMultiExtruderWholePrint && tick.gcode != Slic3r::ExtruderChangeCode) ) + (m_state == msMultiExtruder && tick.gcode != Slic3r::ExtruderChangeCode) ) continue; const wxCoord pos = get_position_from_value(tick.tick); is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) : main_band.SetBottom(pos - 1); - clr = (m_state == msMultiExtruderWholePrint && tick.color.empty()) ? bg_clr : - m_state == msMultiExtruderWholePrint ? wxColour(colors[std::min(colors_cnt - 1, tick.extruder-1)]) : wxColour(tick.color); + clr = (m_state == msMultiExtruder && tick.color.empty()) ? bg_clr : + m_state == msMultiExtruder ? wxColour(colors[std::min(colors_cnt - 1, tick.extruder-1)]) : wxColour(tick.color); draw_band(dc, clr, main_band); i++; } @@ -2900,7 +2900,7 @@ void DoubleSlider::draw_revert_icon(wxDC& dc) void DoubleSlider::draw_cog_icon(wxDC& dc) { - if (m_state != msMultiExtruderWholePrint) + if (m_state != msMultiExtruder) return; int width, height; @@ -3016,7 +3016,7 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) m_ticks_.clear(); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } - else if (is_point_in_rect(pos, m_rect_cog_icon) && m_state == msMultiExtruderWholePrint) { + else if (is_point_in_rect(pos, m_rect_cog_icon) && m_state == msMultiExtruder) { // show dialog for set extruder sequence m_edit_extruder_sequence = true; } @@ -3160,7 +3160,7 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) if (m_show_context_menu) { - if (m_state == msMultiExtruderWholePrint) + if (m_state == msMultiExtruder) { wxMenu menu; const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); @@ -3279,7 +3279,7 @@ void DoubleSlider::action_tick(const TicksAction action) if (m_suppress_add_code) return; m_suppress_add_code = true; - if (m_state != msMultiExtruderWholePrint) + if (m_state != msMultiExtruder) add_code(Slic3r::ColorChangeCode); m_suppress_add_code = false; return; @@ -3423,7 +3423,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) if (m_show_context_menu) { wxMenu menu; - if (m_state == msMultiExtruderWholePrint) + if (m_state == msMultiExtruder) { const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); if (extruders_cnt > 1) @@ -3457,7 +3457,6 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", [this](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode); }, "colorchange_add_off.png", &menu); - if (m_state != msMultiExtruder) append_menu_item(&menu, wxID_ANY, _(L("Add pause print")) + " (M601)", "", [this](wxCommandEvent&) { add_code(Slic3r::PausePrintCode); }, "pause_print", &menu); @@ -3584,14 +3583,12 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) } int extruder = 1; - if (m_state == msMultiExtruderWholePrint) { + if (m_state == msMultiExtruder) { if (code == Slic3r::ColorChangeCode && selected_extruder >= 0) extruder = selected_extruder; else extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); } - else if (m_state == msMultiExtruder && m_current_extruder > 0) - extruder = m_current_extruder; m_ticks_.insert(TICK_CODE(tick, code, extruder, color)); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index c1bf82821..7841b62fe 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -818,19 +818,16 @@ public: } enum ManipulationState { - msSingleExtruder, // single extruder printer preset is selected - msMultiExtruder, // multiple extruder printer preset is selected - msMultiExtruderWholePrint // multiple extruder printer preset is selected, and "Whole print" is selected + msSingleExtruder, // single extruder printer preset is selected + msMultiExtruder // multiple extruder printer preset is selected, and "Whole print" is selected }; void SetManipulationState(ManipulationState state) { m_state = state; } - ManipulationState GetManipulationState() const { return m_state; } - void SetExtruderID(int extruder) { - m_current_extruder = extruder; - m_state = extruder < 0 ? msSingleExtruder : - extruder > 0 ? msMultiExtruder : msMultiExtruderWholePrint; + void SetManipulationState(int extruders_cnt) { + m_state = extruders_cnt ==1 ? msSingleExtruder : msMultiExtruder; } + ManipulationState GetManipulationState() const { return m_state; } bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } bool is_one_layer() const { return m_is_one_layer; } @@ -928,7 +925,6 @@ private: ManipulationState m_state = msSingleExtruder; std::string m_custom_gcode = ""; std::string m_pause_print_msg; - int m_current_extruder = -1; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb;