From d5f7956a55f8625fb4b8ddfd5203ddfbe8ff8f3c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 4 Nov 2019 13:42:47 +0100 Subject: [PATCH] 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_;