From 476ca1968985150d9ca6e06eb9c9d81cf94401cc Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Tue, 8 Aug 2023 10:54:07 +0800 Subject: [PATCH] ENH: support custom the first layer print sequence Change-Id: I0516948292933fe47d39fb3ae2f7e91473b45b3a (cherry picked from commit 5bbdb28c86509d5f94b5b9c33a0f2e1b2749e94b) --- src/libslic3r/Format/bbs_3mf.cpp | 25 ++++++++++++++ src/libslic3r/GCode/ToolOrdering.cpp | 32 ++++++++++++++++++ src/libslic3r/PrintConfig.cpp | 7 ++++ src/slic3r/GUI/PartPlate.cpp | 50 ++++++++++++++++++++++++++++ src/slic3r/GUI/PartPlate.hpp | 4 +++ src/slic3r/GUI/Plater.cpp | 6 ++++ 6 files changed, 124 insertions(+) diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index a88e7b2d0..d17716725 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -266,6 +266,7 @@ static constexpr const char* SUBTYPE_ATTR = "subtype"; static constexpr const char* LOCK_ATTR = "locked"; static constexpr const char* BED_TYPE_ATTR = "bed_type"; static constexpr const char* PRINT_SEQUENCE_ATTR = "print_sequence"; +static constexpr const char* FIRST_LAYER_PRINT_SEQUENCE_ATTR = "first_layer_print_sequence"; static constexpr const char* GCODE_FILE_ATTR = "gcode_file"; static constexpr const char* THUMBNAIL_FILE_ATTR = "thumbnail_file"; static constexpr const char* TOP_FILE_ATTR = "top_file"; @@ -3852,6 +3853,18 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) ConfigOptionEnum::from_string(value, print_sequence); m_curr_plater->config.set_key_value("print_sequence", new ConfigOptionEnum(print_sequence)); } + else if (key == FIRST_LAYER_PRINT_SEQUENCE_ATTR) { + auto get_vector_from_string = [](const std::string &str) -> std::vector { + std::stringstream stream(str); + int value; + std::vector results; + while (stream >> value) { + results.push_back(value); + } + return results; + }; + m_curr_plater->config.set_key_value("first_layer_print_sequence", new ConfigOptionInts(get_vector_from_string(value))); + } else if (key == GCODE_FILE_ATTR) { m_curr_plater->gcode_file = value; @@ -7022,6 +7035,18 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (print_sequence_opt != nullptr && print_sequence_names.size() > print_sequence_opt->getInt()) stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PRINT_SEQUENCE_ATTR << "\" " << VALUE_ATTR << "=\"" << print_sequence_names[print_sequence_opt->getInt()] << "\"/>\n"; + ConfigOptionInts *first_layer_print_sequence_opt = plate_data->config.option("first_layer_print_sequence"); + if (first_layer_print_sequence_opt != nullptr) { + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << FIRST_LAYER_PRINT_SEQUENCE_ATTR << "\" " << VALUE_ATTR << "=\""; + const std::vector& values = first_layer_print_sequence_opt->values; + for (int i = 0; i < values.size(); ++i) { + stream << values[i]; + if (i != (values.size() - 1)) + stream << " "; + } + stream << "\"/>\n"; + } + if (save_gcode) stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << xml_escape(plate_data->gcode_file) << "\"/>\n"; if (!plate_data->gcode_file.empty()) { diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 042d8d7d2..1897a2da3 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -267,6 +267,22 @@ std::vector ToolOrdering::generate_first_layer_tool_order(const Pr tool_order.insert(iter, ape.first); } + const ConfigOptionInts* first_layer_print_sequence_op = print.full_print_config().option("first_layer_print_sequence"); + if (first_layer_print_sequence_op) { + const std::vector& print_sequence_1st = first_layer_print_sequence_op->values; + if (print_sequence_1st.size() >= tool_order.size()) { + std::sort(tool_order.begin(), tool_order.end(), [&print_sequence_1st](int lh, int rh) { + auto lh_it = std::find(print_sequence_1st.begin(), print_sequence_1st.end(), lh); + auto rh_it = std::find(print_sequence_1st.begin(), print_sequence_1st.end(), rh); + + if (lh_it == print_sequence_1st.end() || rh_it == print_sequence_1st.end()) + return false; + + return lh_it < rh_it; + }); + } + } + return tool_order; } @@ -306,6 +322,22 @@ std::vector ToolOrdering::generate_first_layer_tool_order(const Pr tool_order.insert(iter, ape.first); } + const ConfigOptionInts* first_layer_print_sequence_op = object.print()->full_print_config().option("first_layer_print_sequence"); + if (first_layer_print_sequence_op) { + const std::vector& print_sequence_1st = first_layer_print_sequence_op->values; + if (print_sequence_1st.size() >= tool_order.size()) { + std::sort(tool_order.begin(), tool_order.end(), [&print_sequence_1st](int lh, int rh) { + auto lh_it = std::find(print_sequence_1st.begin(), print_sequence_1st.end(), lh); + auto rh_it = std::find(print_sequence_1st.begin(), print_sequence_1st.end(), rh); + + if (lh_it == print_sequence_1st.end() || rh_it == print_sequence_1st.end()) + return false; + + return lh_it < rh_it; + }); + } + } + return tool_order; } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 59ac00510..22f8624f7 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -623,6 +623,13 @@ void PrintConfigDef::init_fff_params() def->enum_labels.emplace_back(L("Textured PEI Plate")); def->set_default_value(new ConfigOptionEnum(btPC)); + // BBS + def = this->add("first_layer_print_sequence", coInts); + def->label = L("First layer print sequence"); + def->min = 0; + def->max = 16; + def->set_default_value(new ConfigOptionInts{0}); + def = this->add("before_layer_change_gcode", coString); def->label = L("Before layer change G-code"); def->tooltip = L("This G-code is inserted at every layer change before lifting z"); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 156c7a182..dadc9f456 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -2836,6 +2836,56 @@ int PartPlate::load_pattern_box_data(std::string filename) } } +std::vector PartPlate::get_first_layer_print_sequence() const +{ + const ConfigOptionInts *op_print_sequence_1st = m_config.option("first_layer_print_sequence"); + if (op_print_sequence_1st) + return op_print_sequence_1st->values; + else + return std::vector(); +} + +void PartPlate::set_first_layer_print_sequence(const std::vector& sorted_filaments) +{ + if (sorted_filaments.size() > 0) { + if (sorted_filaments.size() == 1 && sorted_filaments[0] == 0) { + m_config.erase("first_layer_print_sequence"); + } + else { + ConfigOptionInts *op_print_sequence_1st = m_config.option("first_layer_print_sequence"); + if (op_print_sequence_1st) + op_print_sequence_1st->values = sorted_filaments; + else + m_config.set_key_value("first_layer_print_sequence", new ConfigOptionInts(sorted_filaments)); + } + } + else { + m_config.erase("first_layer_print_sequence"); + } +} + +void PartPlate::update_first_layer_print_sequence(size_t filament_nums) +{ + ConfigOptionInts * op_print_sequence_1st = m_config.option("first_layer_print_sequence"); + if (!op_print_sequence_1st) { + return; + } + + std::vector &print_sequence_1st = op_print_sequence_1st->values; + if (print_sequence_1st.size() == 0 || print_sequence_1st[0] == 0) + return; + + if (print_sequence_1st.size() > filament_nums) { + print_sequence_1st.erase(std::remove_if(print_sequence_1st.begin(), print_sequence_1st.end(), [filament_nums](int n) { return n > filament_nums; }), + print_sequence_1st.end()); + } + else if (print_sequence_1st.size() < filament_nums) { + for (size_t extruder_id = print_sequence_1st.size(); extruder_id < filament_nums; ++extruder_id) { + print_sequence_1st.push_back(extruder_id + 1); + } + } +} + void PartPlate::print() const { unsigned int count=0; diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 22fd7bf5e..434ea93a4 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -445,6 +445,10 @@ public: //load pattern box data from file int load_pattern_box_data(std::string filename); + std::vector get_first_layer_print_sequence() const; + void set_first_layer_print_sequence(const std::vector &sorted_filaments); + void update_first_layer_print_sequence(size_t filament_nums); + void print() const; friend class cereal::access; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c354ba1c1..3a628d1d4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -11085,6 +11085,12 @@ void Plater::on_filaments_change(size_t num_filaments) sidebar().on_filaments_change(num_filaments); sidebar().obj_list()->update_objects_list_filament_column(num_filaments); + Slic3r::GUI::PartPlateList &plate_list = get_partplate_list(); + for (int i = 0; i < plate_list.get_plate_count(); ++i) { + PartPlate* part_plate = plate_list.get_plate(i); + part_plate->update_first_layer_print_sequence(num_filaments); + } + for (ModelObject* mo : wxGetApp().model().objects) { for (ModelVolume* mv : mo->volumes) { mv->update_extruder_count(num_filaments);