ENH: support custom the first layer print sequence

Change-Id: I0516948292933fe47d39fb3ae2f7e91473b45b3a
(cherry picked from commit 5bbdb28c86509d5f94b5b9c33a0f2e1b2749e94b)
(cherry picked from commit 22c6e9f1d2c6f1b86c70827c8bec65a857fe2bc5)
This commit is contained in:
zhimin.zeng 2023-08-08 10:54:07 +08:00 committed by lane.wei
parent f926f9e00f
commit f783da81ce
6 changed files with 124 additions and 0 deletions

View file

@ -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<PrintSequence>::from_string(value, print_sequence);
m_curr_plater->config.set_key_value("print_sequence", new ConfigOptionEnum<PrintSequence>(print_sequence));
}
else if (key == FIRST_LAYER_PRINT_SEQUENCE_ATTR) {
auto get_vector_from_string = [](const std::string &str) -> std::vector<int> {
std::stringstream stream(str);
int value;
std::vector<int> 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<ConfigOptionInts>("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<int>& 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()) {

View file

@ -267,6 +267,22 @@ std::vector<unsigned int> 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<ConfigOptionInts>("first_layer_print_sequence");
if (first_layer_print_sequence_op) {
const std::vector<int>& 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<unsigned int> 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<ConfigOptionInts>("first_layer_print_sequence");
if (first_layer_print_sequence_op) {
const std::vector<int>& 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;
}

View file

@ -623,6 +623,13 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.emplace_back(L("Textured PEI Plate"));
def->set_default_value(new ConfigOptionEnum<BedType>(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");

View file

@ -2796,6 +2796,56 @@ int PartPlate::load_pattern_box_data(std::string filename)
}
}
std::vector<int> PartPlate::get_first_layer_print_sequence() const
{
const ConfigOptionInts *op_print_sequence_1st = m_config.option<ConfigOptionInts>("first_layer_print_sequence");
if (op_print_sequence_1st)
return op_print_sequence_1st->values;
else
return std::vector<int>();
}
void PartPlate::set_first_layer_print_sequence(const std::vector<int>& 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<ConfigOptionInts>("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<ConfigOptionInts>("first_layer_print_sequence");
if (!op_print_sequence_1st) {
return;
}
std::vector<int> &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;

View file

@ -445,6 +445,10 @@ public:
//load pattern box data from file
int load_pattern_box_data(std::string filename);
std::vector<int> get_first_layer_print_sequence() const;
void set_first_layer_print_sequence(const std::vector<int> &sorted_filaments);
void update_first_layer_print_sequence(size_t filament_nums);
void print() const;
friend class cereal::access;

View file

@ -11071,6 +11071,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);