From 8a965afb1a16a6593488acb35207b36d8d2382d0 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Tue, 27 Feb 2024 10:55:45 +0800 Subject: [PATCH] ENH: add customize other layers print sequence Jira: 6338 Change-Id: Ic14b2671ade37ab37583b81c5b509447b6c0d8f8 --- src/libslic3r/CMakeLists.txt | 2 ++ src/libslic3r/Format/bbs_3mf.cpp | 33 +++++++++++++++++++++ src/libslic3r/GCode/ToolOrdering.cpp | 38 ++++++++++++++++++++++++ src/libslic3r/ParameterUtils.cpp | 43 ++++++++++++++++++++++++++++ src/libslic3r/ParameterUtils.hpp | 14 +++++++++ src/libslic3r/Print.cpp | 2 ++ src/libslic3r/PrintConfig.cpp | 10 +++++++ src/libslic3r/PrintConfig.hpp | 2 ++ 8 files changed, 144 insertions(+) create mode 100644 src/libslic3r/ParameterUtils.cpp create mode 100644 src/libslic3r/ParameterUtils.hpp diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 04e0b4c82..239c38b59 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -215,6 +215,8 @@ set(lisbslic3r_sources MutablePriorityQueue.hpp ObjectID.cpp ObjectID.hpp + ParameterUtils.cpp + ParameterUtils.hpp PerimeterGenerator.cpp PerimeterGenerator.hpp PlaceholderParser.cpp diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 35c7aa25c..a24a06259 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -277,6 +277,8 @@ 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* OTHER_LAYERS_PRINT_SEQUENCE_ATTR = "other_layers_print_sequence"; +static constexpr const char* OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR = "other_layers_print_sequence_nums"; static constexpr const char* SPIRAL_VASE_MODE = "spiral_mode"; static constexpr const char* GCODE_FILE_ATTR = "gcode_file"; static constexpr const char* THUMBNAIL_FILE_ATTR = "thumbnail_file"; @@ -3897,6 +3899,19 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) }; m_curr_plater->config.set_key_value("first_layer_print_sequence", new ConfigOptionInts(get_vector_from_string(value))); } + else if (key == OTHER_LAYERS_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("other_layers_print_sequence", new ConfigOptionInts(get_vector_from_string(value))); + } + else if (key == OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR) { + m_curr_plater->config.set_key_value("other_layers_print_sequence_nums", new ConfigOptionInt(stoi(value))); + } else if (key == SPIRAL_VASE_MODE) { bool spiral_mode = false; std::istringstream(value) >> std::boolalpha >> spiral_mode; @@ -7176,6 +7191,24 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << "\"/>\n"; } + + ConfigOptionInts *other_layers_print_sequence_opt = plate_data->config.option("other_layers_print_sequence"); + if (other_layers_print_sequence_opt != nullptr) { + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << OTHER_LAYERS_PRINT_SEQUENCE_ATTR << "\" " << VALUE_ATTR << "=\""; + const std::vector &values = other_layers_print_sequence_opt->values; + for (int i = 0; i < values.size(); ++i) { + stream << values[i]; + if (i != (values.size() - 1)) + stream << " "; + } + stream << "\"/>\n"; + } + + const ConfigOptionInt *sequence_nums_opt = dynamic_cast(plate_data->config.option("other_layers_print_sequence_nums")); + if (sequence_nums_opt != nullptr) { + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR << "\" " << VALUE_ATTR << "=\"" << sequence_nums_opt->getInt() << "\"/>\n"; + } + ConfigOption* spiral_mode_opt = plate_data->config.option("spiral_mode"); if (spiral_mode_opt) stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SPIRAL_VASE_MODE << "\" " << VALUE_ATTR << "=\"" << spiral_mode_opt->getBool() << "\"/>\n"; diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 2c1d8f6b6..a5e3cd23f 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -2,6 +2,7 @@ #include "ToolOrdering.hpp" #include "Layer.hpp" #include "ClipperUtils.hpp" +#include "ParameterUtils.hpp" // #define SLIC3R_DEBUG @@ -831,12 +832,49 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume() return hash_key; }; + std::vector other_layers_seqs; + const ConfigOptionInts *other_layers_print_sequence_op = print_config->option("other_layers_print_sequence"); + const ConfigOptionInt *other_layers_print_sequence_nums_op = print_config->option("other_layers_print_sequence_nums"); + if (other_layers_print_sequence_op && other_layers_print_sequence_nums_op) { + const std::vector &print_sequence = other_layers_print_sequence_op->values; + int sequence_nums = other_layers_print_sequence_nums_op->value; + other_layers_seqs = get_other_layers_print_sequence(sequence_nums, print_sequence); + } + + // other_layers_seq: the layer_idx and extruder_idx are base on 1 + auto get_custom_seq = [&other_layers_seqs](int layer_idx, std::vector& out_seq) -> bool { + for (size_t idx = other_layers_seqs.size() - 1; idx != size_t(-1); --idx) { + const auto &other_layers_seq = other_layers_seqs[idx]; + if (layer_idx + 1 >= other_layers_seq.first.first && layer_idx + 1 <= other_layers_seq.first.second) { + out_seq = other_layers_seq.second; + return true; + } + } + return false; + }; unsigned int current_extruder_id = -1; for (int i = 0; i < m_layer_tools.size(); ++i) { LayerTools& lt = m_layer_tools[i]; if (lt.extruders.empty()) continue; + + std::vector custom_extruder_seq; + if (get_custom_seq(i, custom_extruder_seq) && !custom_extruder_seq.empty()) { + std::vector unsign_custom_extruder_seq; + for (int extruder : custom_extruder_seq) { + unsigned int unsign_extruder = static_cast(extruder) - 1; + auto it = std::find(lt.extruders.begin(), lt.extruders.end(), unsign_extruder); + if (it != lt.extruders.end()) { + unsign_custom_extruder_seq.emplace_back(unsign_extruder); + } + } + assert(lt.extruders.size() == unsign_custom_extruder_seq.size()); + lt.extruders = unsign_custom_extruder_seq; + current_extruder_id = lt.extruders.back(); + continue; + } + // The algorithm complexity is O(n2*2^n) if (i != 0) { auto hash_key = extruders_to_hash_key(lt.extruders, current_extruder_id); diff --git a/src/libslic3r/ParameterUtils.cpp b/src/libslic3r/ParameterUtils.cpp new file mode 100644 index 000000000..c72468567 --- /dev/null +++ b/src/libslic3r/ParameterUtils.cpp @@ -0,0 +1,43 @@ +#include "ParameterUtils.hpp" + +namespace Slic3r { + +std::vector get_other_layers_print_sequence(int sequence_nums, const std::vector &sequence) +{ + std::vector res; + if (sequence_nums == 0 || sequence.empty()) + return res; + + assert(sequence.size() % sequence_nums == 0); + + res.reserve(sequence_nums); + size_t item_nums = sequence.size() / sequence_nums; + + for (int i = 0; i < sequence_nums; ++i) { + std::vector item; + item.assign(sequence.begin() + i * item_nums, sequence.begin() + ((i + 1) * item_nums - 1)); + + assert(item.size() > 2); + std::pair, std::vector> res_item; + res_item.first.first = item[0]; + res_item.first.second = item[1]; + res_item.second.assign(item.begin() + 2, item.end()); + res.emplace_back(std::move(res_item)); + } + + return res; +} + +void get_other_layers_print_sequence(const std::vector &customize_sequences, int &sequence_nums, std::vector &sequence) +{ + sequence_nums = 0; + sequence.clear(); + if (customize_sequences.empty()) { return; } + + sequence_nums = (int) customize_sequences.size(); + for (const auto &customize_sequence : customize_sequences) { + sequence.insert(sequence.end(), customize_sequence.second.begin(), customize_sequence.second.end()); + } +} + +}; // namespace Slic3r diff --git a/src/libslic3r/ParameterUtils.hpp b/src/libslic3r/ParameterUtils.hpp new file mode 100644 index 000000000..090fd8d80 --- /dev/null +++ b/src/libslic3r/ParameterUtils.hpp @@ -0,0 +1,14 @@ +#ifndef slic3r_Parameter_Utils_hpp_ +#define slic3r_Parameter_Utils_hpp_ + +#include +#include + +namespace Slic3r { +using LayerPrintSequence = std::pair, std::vector>; +std::vector get_other_layers_print_sequence(int sequence_nums, const std::vector &sequence); +void get_other_layers_print_sequence(const std::vector &customize_sequences, int &sequence_nums, std::vector &sequence); + +} // namespace Slic3r + +#endif // slic3r_Parameter_Utils_hpp_ diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 5c9ee959d..502e7e712 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -232,6 +232,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n || opt_key == "prime_tower_width" || opt_key == "prime_tower_brim_width" || opt_key == "first_layer_print_sequence" + || opt_key == "other_layers_print_sequence" + || opt_key == "other_layers_print_sequence_nums" //|| opt_key == "wipe_tower_bridging" || opt_key == "wipe_tower_no_sparse_layers" || opt_key == "flush_volumes_matrix" diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 216491660..4550293c8 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -660,6 +660,16 @@ void PrintConfigDef::init_fff_params() def->max = 16; def->set_default_value(new ConfigOptionInts{0}); + def = this->add("other_layers_print_sequence", coInts); + def->label = L("Other layers print sequence"); + def->min = 0; + def->max = 16; + def->set_default_value(new ConfigOptionInts{0}); + + def = this->add("other_layers_print_sequence_nums", coInt); + def->label = L("The number of other layers print sequence"); + def->set_default_value(new ConfigOptionInt{0}); + def = this->add("first_layer_sequence_choice", coEnum); def->category = L("Quality"); def->label = L("First layer filament sequence"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 2d84d74fd..5fa8e1964 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -956,6 +956,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionEnumsGeneric, overhang_fan_threshold)) ((ConfigOptionEnum,print_sequence)) ((ConfigOptionInts, first_layer_print_sequence)) + ((ConfigOptionInts, other_layers_print_sequence)) + ((ConfigOptionInt, other_layers_print_sequence_nums)) ((ConfigOptionBools, slow_down_for_layer_cooling)) ((ConfigOptionFloat, default_acceleration)) ((ConfigOptionFloat, inner_wall_acceleration))