diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index b96988fb9..dc199ec5b 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -1367,61 +1367,61 @@ ModelVolumeType type_from_string(const std::string &s) void _3MF_Importer::_extract_custom_gcode_per_print_z_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; - } + //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); + // 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_print_z") - return; - pt::ptree code_tree = main_tree.front().second; + // if (main_tree.front().first != "custom_gcodes_per_print_z") + // return; + // pt::ptree code_tree = main_tree.front().second; - m_model->custom_gcode_per_print_z.gcodes.clear(); + // m_model->custom_gcode_per_print_z.gcodes.clear(); - for (const auto& code : code_tree) { - if (code.first == "mode") { - pt::ptree tree = code.second; - std::string mode = tree.get(".value"); - m_model->custom_gcode_per_print_z.mode = mode == CustomGCode::SingleExtruderMode ? CustomGCode::Mode::SingleExtruder : - mode == CustomGCode::MultiAsSingleMode ? CustomGCode::Mode::MultiAsSingle : - CustomGCode::Mode::MultiExtruder; - } - if (code.first != "code") - continue; + // for (const auto& code : code_tree) { + // if (code.first == "mode") { + // pt::ptree tree = code.second; + // std::string mode = tree.get(".value"); + // m_model->custom_gcode_per_print_z.mode = mode == CustomGCode::SingleExtruderMode ? CustomGCode::Mode::SingleExtruder : + // mode == CustomGCode::MultiAsSingleMode ? CustomGCode::Mode::MultiAsSingle : + // CustomGCode::Mode::MultiExtruder; + // } + // if (code.first != "code") + // continue; - pt::ptree tree = code.second; - double print_z = tree.get (".print_z" ); - int extruder = tree.get (".extruder"); - std::string color = tree.get (".color" ); + // pt::ptree tree = code.second; + // double print_z = tree.get (".print_z" ); + // int extruder = tree.get (".extruder"); + // std::string color = tree.get (".color" ); - CustomGCode::Type type; - std::string extra; - pt::ptree attr_tree = tree.find("")->second; - if (attr_tree.find("type") == attr_tree.not_found()) { - // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer - // read old data ... - std::string gcode = tree.get (".gcode"); - // ... and interpret them to the new data - type = gcode == "M600" ? CustomGCode::ColorChange : - gcode == "M601" ? CustomGCode::PausePrint : - gcode == "tool_change" ? CustomGCode::ToolChange : CustomGCode::Custom; - extra = type == CustomGCode::PausePrint ? color : - type == CustomGCode::Custom ? gcode : ""; - } - else { - type = static_cast(tree.get(".type")); - extra = tree.get(".extra"); - } - m_model->custom_gcode_per_print_z.gcodes.push_back(CustomGCode::Item{print_z, type, extruder, color, extra}) ; - } - } + // CustomGCode::Type type; + // std::string extra; + // pt::ptree attr_tree = tree.find("")->second; + // if (attr_tree.find("type") == attr_tree.not_found()) { + // // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer + // // read old data ... + // std::string gcode = tree.get (".gcode"); + // // ... and interpret them to the new data + // type = gcode == "M600" ? CustomGCode::ColorChange : + // gcode == "M601" ? CustomGCode::PausePrint : + // gcode == "tool_change" ? CustomGCode::ToolChange : CustomGCode::Custom; + // extra = type == CustomGCode::PausePrint ? color : + // type == CustomGCode::Custom ? gcode : ""; + // } + // else { + // type = static_cast(tree.get(".type")); + // extra = tree.get(".extra"); + // } + // m_model->custom_gcode_per_print_z.gcodes.push_back(CustomGCode::Item{print_z, type, extruder, color, extra}) ; + // } + //} } void _3MF_Importer::_handle_start_model_xml_element(const char* name, const char** attributes) @@ -3182,54 +3182,55 @@ ModelVolumeType type_from_string(const std::string &s) bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archive& archive, Model& model, const DynamicPrintConfig* config) { - std::string out = ""; + return false; + //std::string out = ""; - if (!model.custom_gcode_per_print_z.gcodes.empty()) { - pt::ptree tree; - pt::ptree& main_tree = tree.add("custom_gcodes_per_print_z", ""); + //if (!model.custom_gcode_per_print_z.gcodes.empty()) { + // pt::ptree tree; + // pt::ptree& main_tree = tree.add("custom_gcodes_per_print_z", ""); - for (const CustomGCode::Item& code : model.custom_gcode_per_print_z.gcodes) { - pt::ptree& code_tree = main_tree.add("code", ""); + // for (const CustomGCode::Item& code : model.custom_gcode_per_print_z.gcodes) { + // pt::ptree& code_tree = main_tree.add("code", ""); - // store data of custom_gcode_per_print_z - code_tree.put(".print_z" , code.print_z ); - code_tree.put(".type" , static_cast(code.type)); - code_tree.put(".extruder" , code.extruder ); - code_tree.put(".color" , code.color ); - code_tree.put(".extra" , code.extra ); + // // store data of custom_gcode_per_print_z + // code_tree.put(".print_z" , code.print_z ); + // code_tree.put(".type" , static_cast(code.type)); + // code_tree.put(".extruder" , code.extruder ); + // code_tree.put(".color" , code.color ); + // code_tree.put(".extra" , code.extra ); - //BBS - std::string gcode = //code.type == CustomGCode::ColorChange ? config->opt_string("color_change_gcode") : - code.type == CustomGCode::PausePrint ? config->opt_string("machine_pause_gcode") : - code.type == CustomGCode::Template ? config->opt_string("template_custom_gcode") : - code.type == CustomGCode::ToolChange ? "tool_change" : code.extra; - code_tree.put(".gcode" , gcode ); - } + // //BBS + // std::string gcode = //code.type == CustomGCode::ColorChange ? config->opt_string("color_change_gcode") : + // code.type == CustomGCode::PausePrint ? config->opt_string("machine_pause_gcode") : + // code.type == CustomGCode::Template ? config->opt_string("template_custom_gcode") : + // code.type == CustomGCode::ToolChange ? "tool_change" : code.extra; + // code_tree.put(".gcode" , gcode ); + // } - pt::ptree& mode_tree = main_tree.add("mode", ""); - // store mode of a custom_gcode_per_print_z - mode_tree.put(".value", model.custom_gcode_per_print_z.mode == CustomGCode::Mode::SingleExtruder ? CustomGCode::SingleExtruderMode : - model.custom_gcode_per_print_z.mode == CustomGCode::Mode::MultiAsSingle ? CustomGCode::MultiAsSingleMode : - CustomGCode::MultiExtruderMode); + // pt::ptree& mode_tree = main_tree.add("mode", ""); + // // store mode of a custom_gcode_per_print_z + // mode_tree.put(".value", model.custom_gcode_per_print_z.mode == CustomGCode::Mode::SingleExtruder ? CustomGCode::SingleExtruderMode : + // model.custom_gcode_per_print_z.mode == CustomGCode::Mode::MultiAsSingle ? CustomGCode::MultiAsSingleMode : + // CustomGCode::MultiExtruderMode); - if (!tree.empty()) { - std::ostringstream oss; - boost::property_tree::write_xml(oss, tree); - out = oss.str(); + // 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<"); - } - } + // // 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_PRINT_Z_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) { - add_error("Unable to add custom Gcodes per print_z file to archive"); - return false; - } - } + //if (!out.empty()) { + // if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_PRINT_Z_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) { + // add_error("Unable to add custom Gcodes per print_z file to archive"); + // return false; + // } + //} - return true; + //return true; } // Perform conversions based on the config values available. diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 619947df8..a3b0d1eb5 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -1777,6 +1777,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) plate_data_list[it->first-1]->pattern_file = (m_load_restore || it->second->pattern_file.empty()) ? it->second->pattern_file : m_backup_path + "/" + it->second->pattern_file; plate_data_list[it->first-1]->pattern_bbox_file = (m_load_restore || it->second->pattern_bbox_file.empty()) ? it->second->pattern_bbox_file : m_backup_path + "/" + it->second->pattern_bbox_file; plate_data_list[it->first-1]->config = it->second->config; + current_plate_data = plate_data_list[it->first - 1]; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate %1%, thumbnail_file=%2%")%it->first %plate_data_list[it->first-1]->thumbnail_file; it++; @@ -2500,6 +2501,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) void _BBS_3MF_Importer::_extract_custom_gcode_per_print_z_from_archive(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat) { + //BBS: add plate tree related logic 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); @@ -2514,45 +2516,71 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (main_tree.front().first != "custom_gcodes_per_layer") return; - pt::ptree code_tree = main_tree.front().second; - m_model->custom_gcode_per_print_z.gcodes.clear(); + auto extract_code = [this](int plate_id, pt::ptree code_tree) { + for (const auto& code : code_tree) { + if (code.first == "mode") { + pt::ptree tree = code.second; + std::string mode = tree.get(".value"); + m_model->plates_custom_gcodes[plate_id - 1].mode = mode == CustomGCode::SingleExtruderMode ? CustomGCode::Mode::SingleExtruder : + mode == CustomGCode::MultiAsSingleMode ? CustomGCode::Mode::MultiAsSingle : + CustomGCode::Mode::MultiExtruder; + } + if (code.first == "layer") { + pt::ptree tree = code.second; + double print_z = tree.get(".top_z"); + int extruder = tree.get(".extruder"); + std::string color = tree.get(".color"); - for (const auto& code : code_tree) { - if (code.first == "mode") { - pt::ptree tree = code.second; - std::string mode = tree.get(".value"); - m_model->custom_gcode_per_print_z.mode = mode == CustomGCode::SingleExtruderMode ? CustomGCode::Mode::SingleExtruder : - mode == CustomGCode::MultiAsSingleMode ? CustomGCode::Mode::MultiAsSingle : - CustomGCode::Mode::MultiExtruder; + CustomGCode::Type type; + std::string extra; + pt::ptree attr_tree = tree.find("")->second; + if (attr_tree.find("type") == attr_tree.not_found()) { + // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer + // read old data ... + std::string gcode = tree.get(".gcode"); + // ... and interpret them to the new data + type = gcode == "M600" ? CustomGCode::ColorChange : + gcode == "M601" ? CustomGCode::PausePrint : + gcode == "tool_change" ? CustomGCode::ToolChange : CustomGCode::Custom; + extra = type == CustomGCode::PausePrint ? color : + type == CustomGCode::Custom ? gcode : ""; + } + else { + type = static_cast(tree.get(".type")); + extra = tree.get(".extra"); + } + m_model->plates_custom_gcodes[plate_id - 1].gcodes.push_back(CustomGCode::Item{ print_z, type, extruder, color, extra }); + } } - if (code.first != "layer") - continue; + }; - pt::ptree tree = code.second; - double print_z = tree.get (".top_z" ); - int extruder = tree.get (".extruder"); - std::string color = tree.get (".color" ); + m_model->plates_custom_gcodes.clear(); - CustomGCode::Type type; - std::string extra; - pt::ptree attr_tree = tree.find("")->second; - if (attr_tree.find("type") == attr_tree.not_found()) { - // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer - // read old data ... - std::string gcode = tree.get (".gcode"); - // ... and interpret them to the new data - type = gcode == "M600" ? CustomGCode::ColorChange : - gcode == "M601" ? CustomGCode::PausePrint : - gcode == "tool_change" ? CustomGCode::ToolChange : CustomGCode::Custom; - extra = type == CustomGCode::PausePrint ? color : - type == CustomGCode::Custom ? gcode : ""; + bool has_plate_info = false; + for (const auto& element : main_tree.front().second) { + if (element.first == "plate") { + has_plate_info = true; + + int plate_id = -1; + pt::ptree code_tree = element.second; + for (const auto& code : code_tree) { + if (code.first == "plate_info") { + plate_id = code.second.get(".id"); + } + + } + if (plate_id == -1) + continue; + + extract_code(plate_id, code_tree); } - else { - type = static_cast(tree.get(".type")); - extra = tree.get(".extra"); - } - m_model->custom_gcode_per_print_z.gcodes.push_back(CustomGCode::Item{print_z, type, extruder, color, extra}) ; + } + + if (!has_plate_info) { + int plate_id = 1; + pt::ptree code_tree = main_tree.front().second; + extract_code(plate_id, code_tree); } } } @@ -6635,46 +6663,50 @@ bool _BBS_3MF_Exporter::_add_gcode_file_to_archive(mz_zip_archive& archive, cons return result; } -bool _BBS_3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archive& archive, Model& model, const DynamicPrintConfig* config) +bool _BBS_3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive(mz_zip_archive& archive, Model& model, const DynamicPrintConfig* config) { + //BBS: add plate tree related logic std::string out = ""; - - if (!model.custom_gcode_per_print_z.gcodes.empty()) { - pt::ptree tree; - pt::ptree& main_tree = tree.add("custom_gcodes_per_layer", ""); - - for (const CustomGCode::Item& code : model.custom_gcode_per_print_z.gcodes) { - pt::ptree& code_tree = main_tree.add("layer", ""); + bool has_custom_gcode = false; + pt::ptree tree; + pt::ptree& main_tree = tree.add("custom_gcodes_per_layer", ""); + for (auto custom_gcodes : model.plates_custom_gcodes) { + has_custom_gcode = true; + pt::ptree& plate_tree = main_tree.add("plate", ""); + pt::ptree& plate_idx_tree = plate_tree.add("plate_info", ""); + plate_idx_tree.put(".id", custom_gcodes.first + 1); // store data of custom_gcode_per_print_z - code_tree.put(".top_z" , code.print_z ); - code_tree.put(".type" , static_cast(code.type)); - code_tree.put(".extruder" , code.extruder ); - code_tree.put(".color" , code.color ); - code_tree.put(".extra" , code.extra ); + for (const CustomGCode::Item& code : custom_gcodes.second.gcodes) { + pt::ptree& code_tree = plate_tree.add("layer", ""); + code_tree.put(".top_z", code.print_z); + code_tree.put(".type", static_cast(code.type)); + code_tree.put(".extruder", code.extruder); + code_tree.put(".color", code.color); + code_tree.put(".extra", code.extra); - //BBS - std::string gcode = //code.type == CustomGCode::ColorChange ? config->opt_string("color_change_gcode") : - code.type == CustomGCode::PausePrint ? config->opt_string("machine_pause_gcode") : - code.type == CustomGCode::Template ? config->opt_string("template_custom_gcode") : - code.type == CustomGCode::ToolChange ? "tool_change" : code.extra; - code_tree.put(".gcode" , gcode ); - } + //BBS + std::string gcode = //code.type == CustomGCode::ColorChange ? config->opt_string("color_change_gcode") : + code.type == CustomGCode::PausePrint ? config->opt_string("machine_pause_gcode") : + code.type == CustomGCode::Template ? config->opt_string("template_custom_gcode") : + code.type == CustomGCode::ToolChange ? "tool_change" : code.extra; + code_tree.put(".gcode", gcode); + } - pt::ptree& mode_tree = main_tree.add("mode", ""); - // store mode of a custom_gcode_per_print_z - mode_tree.put(".value", model.custom_gcode_per_print_z.mode == CustomGCode::Mode::SingleExtruder ? CustomGCode::SingleExtruderMode : - model.custom_gcode_per_print_z.mode == CustomGCode::Mode::MultiAsSingle ? CustomGCode::MultiAsSingleMode : - CustomGCode::MultiExtruderMode); + pt::ptree& mode_tree = plate_tree.add("mode", ""); + // store mode of a custom_gcode_per_print_z + mode_tree.put(".value", custom_gcodes.second.mode == CustomGCode::Mode::SingleExtruder ? CustomGCode::SingleExtruderMode : + custom_gcodes.second.mode == CustomGCode::Mode::MultiAsSingle ? CustomGCode::MultiAsSingleMode : + CustomGCode::MultiExtruderMode); + + } + if (has_custom_gcode) { + std::ostringstream oss; + boost::property_tree::write_xml(oss, tree); + out = oss.str(); - 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<"); - } + // Post processing("beautification") of the output string + boost::replace_all(out, "><", ">\n<"); } if (!out.empty()) { diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 96c4a408d..67e7441b2 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -195,10 +195,11 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool // BBS if (auto num_filaments = unsigned(print.config().filament_diameter.size()); num_filaments > 1 && print.object_extruders().size() == 1 && // the current Print's configuration is CustomGCode::MultiAsSingle - print.model().custom_gcode_per_print_z.mode == CustomGCode::MultiAsSingle) { + //BBS: replace model custom gcode with current plate custom gcode + print.model().get_curr_plate_custom_gcodes().mode == CustomGCode::MultiAsSingle) { // Printing a single extruder platter on a printer with more than 1 extruder (or single-extruder multi-material). // There may be custom per-layer tool changes available at the model. - per_layer_extruder_switches = custom_tool_changes(print.model().custom_gcode_per_print_z, num_filaments); + per_layer_extruder_switches = custom_tool_changes(print.model().get_curr_plate_custom_gcodes(), num_filaments); } // Collect extruders reuqired to print the layers. @@ -759,12 +760,15 @@ void ToolOrdering::mark_skirt_layers(const PrintConfig &config, coordf_t max_lay // Assign a pointer to a custom G-code to the respective ToolOrdering::LayerTools. // Ignore color changes, which are performed on a layer and for such an extruder, that the extruder will not be printing above that layer. // If multiple events are planned over a span of a single layer, use the last one. + +// BBS: replace model custom gcode with current plate custom gcode +static CustomGCode::Info custom_gcode_per_print_z; void ToolOrdering::assign_custom_gcodes(const Print &print) { // Only valid for non-sequential print. assert(print.config().print_sequence == PrintSequence::ByLayer); - const CustomGCode::Info &custom_gcode_per_print_z = print.model().custom_gcode_per_print_z; + custom_gcode_per_print_z = print.model().get_curr_plate_custom_gcodes(); if (custom_gcode_per_print_z.gcodes.empty()) return; @@ -773,7 +777,7 @@ void ToolOrdering::assign_custom_gcodes(const Print &print) CustomGCode::Mode mode = (num_filaments == 1) ? CustomGCode::SingleExtruder : print.object_extruders().size() == 1 ? CustomGCode::MultiAsSingle : CustomGCode::MultiExtruder; - CustomGCode::Mode model_mode = print.model().custom_gcode_per_print_z.mode; + CustomGCode::Mode model_mode = print.model().get_curr_plate_custom_gcodes().mode; std::vector extruder_printing_above(num_filaments, false); auto custom_gcode_it = custom_gcode_per_print_z.gcodes.rbegin(); // Tool changes and color changes will be ignored, if the model's tool/color changes were entered in mm mode and the print is in non mm mode diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 831d849ee..b8ed5d10a 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -63,7 +63,9 @@ Model& Model::assign_copy(const Model &rhs) } // copy custom code per height - this->custom_gcode_per_print_z = rhs.custom_gcode_per_print_z; + // BBS + this->plates_custom_gcodes = rhs.plates_custom_gcodes; + this->curr_plate_index = rhs.curr_plate_index; // BBS: for design info this->design_info = rhs.design_info; @@ -89,7 +91,9 @@ Model& Model::assign_copy(Model &&rhs) rhs.objects.clear(); // copy custom code per height - this->custom_gcode_per_print_z = std::move(rhs.custom_gcode_per_print_z); + // BBS + this->plates_custom_gcodes = std::move(rhs.plates_custom_gcodes); + this->curr_plate_index = rhs.curr_plate_index; //BBS: add auxiliary path logic // BBS: backup, all in one temp dir @@ -203,7 +207,9 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c //BBS //CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config); - CustomGCode::check_mode_for_custom_gcode_per_print_z(model.custom_gcode_per_print_z); + //BBS + for (auto& plate_gcodes : model.plates_custom_gcodes) + CustomGCode::check_mode_for_custom_gcode_per_print_z(plate_gcodes.second); sort_remove_duplicates(config_substitutions->substitutions); return model; @@ -277,7 +283,9 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig throw Slic3r::RuntimeError("Canceled"); } - CustomGCode::check_mode_for_custom_gcode_per_print_z(model.custom_gcode_per_print_z); + //BBS + for (auto& plate_gcodes : model.plates_custom_gcodes) + CustomGCode::check_mode_for_custom_gcode_per_print_z(plate_gcodes.second); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_CHECK_MODE_GCODE\n"); if (proFn) { diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 94aea8fa6..a9acd2db5 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1301,7 +1301,17 @@ public: } // Extensions for color print - CustomGCode::Info custom_gcode_per_print_z; + // CustomGCode::Info custom_gcode_per_print_z; + //BBS: replace model custom gcode with current plate custom gcode + int curr_plate_index{ 0 }; + std::map plates_custom_gcodes; //map + + const CustomGCode::Info get_curr_plate_custom_gcodes() const { + if (plates_custom_gcodes.find(curr_plate_index) != plates_custom_gcodes.end()) { + return plates_custom_gcodes.at(curr_plate_index); + } + return CustomGCode::Info(); + } // 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 a09f0a9c5..1ac4a1632 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -336,9 +336,12 @@ std::vector Print::extruders(bool conside_custom_gcode) const append(extruders, this->support_material_extruders()); if (conside_custom_gcode) { - for (auto item : m_model.custom_gcode_per_print_z.gcodes) { - if (item.type == CustomGCode::Type::ToolChange) - extruders.push_back((unsigned int)item.extruder); + //BBS + for (auto plate_data : m_model.plates_custom_gcodes) { + for (auto item : plate_data.second.gcodes) { + if (item.type == CustomGCode::Type::ToolChange) + extruders.push_back((unsigned int)item.extruder); + } } } diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index c1ab2c804..79a9143ea 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1118,17 +1118,19 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ for (const ModelObject *model_object : m_model.objects) model_object_status_db.add(*model_object, ModelObjectStatus::New); } else { - if (m_model.custom_gcode_per_print_z != model.custom_gcode_per_print_z) { - update_apply_status(num_extruders_changed || - // Tool change G-codes are applied as color changes for a single extruder printer, no need to invalidate tool ordering. - //FIXME The tool ordering may be invalidated unnecessarily if the custom_gcode_per_print_z.mode is not applicable - // to the active print / model state, and then it is reset, so it is being applicable, but empty, thus the effect is the same. - (num_extruders > 1 && custom_per_printz_gcodes_tool_changes_differ(m_model.custom_gcode_per_print_z.gcodes, model.custom_gcode_per_print_z.gcodes)) ? - // The Tool Ordering and the Wipe Tower are no more valid. - this->invalidate_steps({ psWipeTower, psGCodeExport }) : - // There is no change in Tool Changes stored in custom_gcode_per_print_z, therefore there is no need to update Tool Ordering. - this->invalidate_step(psGCodeExport)); - m_model.custom_gcode_per_print_z = model.custom_gcode_per_print_z; + //BBS: replace model custom gcode with current plate custom gcode + m_model.curr_plate_index = model.curr_plate_index; + if (m_model.get_curr_plate_custom_gcodes() != model.get_curr_plate_custom_gcodes()) { + update_apply_status(num_extruders_changed || + // Tool change G-codes are applied as color changes for a single extruder printer, no need to invalidate tool ordering. + //FIXME The tool ordering may be invalidated unnecessarily if the custom_gcode_per_print_z.mode is not applicable + // to the active print / model state, and then it is reset, so it is being applicable, but empty, thus the effect is the same. + (num_extruders > 1 && custom_per_printz_gcodes_tool_changes_differ(m_model.get_curr_plate_custom_gcodes().gcodes, model.get_curr_plate_custom_gcodes().gcodes)) ? + // The Tool Ordering and the Wipe Tower are no more valid. + this->invalidate_steps({ psWipeTower, psGCodeExport }) : + // There is no change in Tool Changes stored in custom_gcode_per_print_z, therefore there is no need to update Tool Ordering. + this->invalidate_step(psGCodeExport)); + m_model.plates_custom_gcodes[m_model.curr_plate_index] = model.get_curr_plate_custom_gcodes(); } if (model_object_list_equal(m_model, model)) { // The object list did not change. diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 2c4272756..2b6f05204 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -201,6 +201,8 @@ set(SLIC3R_GUI_SOURCES GUI/GUI_ObjectTableSettings.hpp GUI/MeshUtils.cpp GUI/MeshUtils.hpp + GUI/TickCode.cpp + GUI/TickCode.hpp GUI/Tab.cpp GUI/Tab.hpp GUI/ParamsDialog.cpp diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 2485c3128..db8a1aa9a 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4691,7 +4691,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } case EViewType::ColorPrint: { - const std::vector& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z; + //BBS: replace model custom gcode with current plate custom gcode + const std::vector& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z; size_t total_items = 1; for (size_t extruder_id : m_extruder_ids) { total_items += color_print_ranges(extruder_id, custom_gcode_per_print_z).size(); @@ -4873,7 +4874,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv auto generate_partial_times = [this, get_used_filament_from_volume](const TimesList& times, const std::vector& used_filaments) { PartialTimes items; - std::vector custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z; + //BBS: replace model custom gcode with current plate custom gcode + std::vector custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z; std::vector last_color(m_extruders_count); for (size_t i = 0; i < m_extruders_count; ++i) { last_color[i] = m_tools.m_tool_colors[i]; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 883f96de3..15368534d 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -551,15 +551,16 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee // Detect and set manipulation mode for double slider update_layers_slider_mode(); - Plater * plater = wxGetApp().plater(); - CustomGCode::Info ticks_info_from_model; + Plater* plater = wxGetApp().plater(); + //BBS: replace model custom gcode with current plate custom gcode + CustomGCode::Info ticks_info_from_curr_plate; if (wxGetApp().is_editor()) - ticks_info_from_model = plater->model().custom_gcode_per_print_z; + ticks_info_from_curr_plate = plater->model().get_curr_plate_custom_gcodes(); else { - ticks_info_from_model.mode = CustomGCode::Mode::SingleExtruder; - ticks_info_from_model.gcodes = m_canvas->get_custom_gcode_per_print_z(); + ticks_info_from_curr_plate.mode = CustomGCode::Mode::SingleExtruder; + ticks_info_from_curr_plate.gcodes = m_canvas->get_custom_gcode_per_print_z(); } - check_layers_slider_values(ticks_info_from_model.gcodes, layers_z); + check_layers_slider_values(ticks_info_from_curr_plate.gcodes, layers_z); // first of all update extruder colors to avoid crash, when we are switching printer preset from MM to SM m_layers_slider->SetExtruderColors(plater->get_extruder_colors_from_plater_config(wxGetApp().is_editor() ? nullptr : m_gcode_result)); @@ -580,7 +581,7 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee } } m_layers_slider->SetSelectionSpan(idx_low, idx_high); - m_layers_slider->SetTicksValues(ticks_info_from_model); + m_layers_slider->SetTicksValues(ticks_info_from_curr_plate); auto curr_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); auto curr_print_seq = curr_plate->get_real_print_seq(); @@ -689,7 +690,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode) if (!gcode_preview_data_valid) { if (wxGetApp().is_editor()) - color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; + //BBS + color_print_values = wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes; else color_print_values = m_canvas->get_custom_gcode_per_print_z(); colors.push_back("#808080"); // gray color for pause print or custom G-code @@ -735,7 +737,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode) (unsigned int)print->extruders().size() : m_canvas->get_gcode_extruders_count(); std::vector gcodes = wxGetApp().is_editor() ? - wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : + //BBS + wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_canvas->get_custom_gcode_per_print_z(); const wxString choice = !gcodes.empty() ? _L("Multicolor Print") : diff --git a/src/slic3r/GUI/IMSlider.cpp b/src/slic3r/GUI/IMSlider.cpp index 2a943659b..4512571cb 100644 --- a/src/slic3r/GUI/IMSlider.cpp +++ b/src/slic3r/GUI/IMSlider.cpp @@ -1,22 +1,6 @@ -#include "libslic3r/libslic3r.h" #include "IMSlider.hpp" #include "libslic3r/GCode.hpp" -#include "GUI.hpp" #include "GUI_App.hpp" -#include "Plater.hpp" -#include "I18N.hpp" -#include "libslic3r/Print.hpp" -#include "libslic3r/AppConfig.hpp" -#include "GUI_Utils.hpp" -#include "MsgDialog.hpp" -#include "Tab.hpp" -#include "GUI_ObjectList.hpp" - -#include -#include -#include -#include "Field.hpp" -#include "format.hpp" #include "NotificationManager.hpp" #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS @@ -25,10 +9,6 @@ namespace Slic3r { -using GUI::from_u8; -using GUI::into_u8; -using GUI::format_wxstr; - namespace GUI { constexpr double min_delta_area = scale_(scale_(25)); // equal to 25 mm2 @@ -136,292 +116,6 @@ static std::string short_and_splitted_time(const std::string &time) } -std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int extruder) -{ - if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) { -#if 1 - if (ticks.empty()) return color_generator.get_opposite_color((*m_colors)[0]); - - auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick); - if (before_tick_it == ticks.end()) { - while (before_tick_it != ticks.begin()) - if (--before_tick_it; before_tick_it->type == ColorChange) break; - if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(before_tick_it->color); - return color_generator.get_opposite_color((*m_colors)[0]); - } - - if (before_tick_it == ticks.begin()) { - const std::string &frst_color = (*m_colors)[0]; - if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, before_tick_it->color); - - auto next_tick_it = before_tick_it; - while (next_tick_it != ticks.end()) - if (++next_tick_it; next_tick_it->type == ColorChange) break; - if (next_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, next_tick_it->color); - - return color_generator.get_opposite_color(frst_color); - } - - std::string frst_color = ""; - if (before_tick_it->type == ColorChange) - frst_color = before_tick_it->color; - else { - auto next_tick_it = before_tick_it; - while (next_tick_it != ticks.end()) - if (++next_tick_it; next_tick_it->type == ColorChange) { - frst_color = next_tick_it->color; - break; - } - } - - while (before_tick_it != ticks.begin()) - if (--before_tick_it; before_tick_it->type == ColorChange) break; - - if (before_tick_it->type == ColorChange) { - if (frst_color.empty()) return color_generator.get_opposite_color(before_tick_it->color); - return color_generator.get_opposite_color(before_tick_it->color, frst_color); - } - - if (frst_color.empty()) return color_generator.get_opposite_color((*m_colors)[0]); - return color_generator.get_opposite_color((*m_colors)[0], frst_color); -#else - const std::vector &colors = ColorPrintColors::get(); - if (ticks.empty()) return colors[0]; - m_default_color_idx++; - - return colors[m_default_color_idx % colors.size()]; -#endif - } - - std::string color = (*m_colors)[extruder - 1]; - - if (type == ColorChange) { - if (!ticks.empty()) { - auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick); - while (before_tick_it != ticks.begin()) { - --before_tick_it; - if (before_tick_it->type == ColorChange && before_tick_it->extruder == extruder) { - color = before_tick_it->color; - break; - } - } - } - - //TODO - //color = get_new_color(color); - } - return color; -} - - -bool TickCodeInfo::add_tick(const int tick, Type type, const int extruder, double print_z) -{ - std::string color; - std::string extra; - if (type == Custom) // custom Gcode - { - //extra = get_custom_code(custom_gcode, print_z); - //if (extra.empty()) return false; - //custom_gcode = extra; - } else if (type == PausePrint) { - //BBS do not set pause extra message - //extra = get_pause_print_msg(pause_print_msg, print_z); - //if (extra.empty()) return false; - pause_print_msg = extra; - } - else { - color = get_color_for_tick(TickCode{ tick }, type, extruder); - if (color.empty()) return false; - } - - if (mode == SingleExtruder) m_use_default_colors = true; - - ticks.emplace(TickCode{tick, type, extruder, color, extra}); - - return true; -} - -bool TickCodeInfo::edit_tick(std::set::iterator it, double print_z) -{ - std::string edited_value; - //TODO - /* BBS - if (it->type == ColorChange) - edited_value = get_new_color(it->color); - else if (it->type == PausePrint) - edited_value = get_pause_print_msg(it->extra, print_z); - else - edited_value = get_custom_code(it->type == Template ? gcode(Template) : it->extra, print_z); - */ - if (edited_value.empty()) return false; - - TickCode changed_tick = *it; - if (it->type == ColorChange) { - if (it->color == edited_value) return false; - changed_tick.color = edited_value; - } else if (it->type == Template) { - //if (gcode(Template) == edited_value) return false; - //changed_tick.extra = edited_value; - //changed_tick.type = Custom; - ; - } else if (it->type == Custom || it->type == PausePrint) { - if (it->extra == edited_value) return false; - changed_tick.extra = edited_value; - } - - ticks.erase(it); - ticks.emplace(changed_tick); - - return true; -} - -void TickCodeInfo::switch_code(Type type_from, Type type_to) -{ - for (auto it{ticks.begin()}, end{ticks.end()}; it != end;) - if (it->type == type_from) { - TickCode tick = *it; - tick.type = type_to; - tick.extruder = 1; - ticks.erase(it); - it = ticks.emplace(tick).first; - } else - ++it; -} - -bool TickCodeInfo::switch_code_for_tick(std::set::iterator it, Type type_to, const int extruder) -{ - const std::string color = get_color_for_tick(*it, type_to, extruder); - if (color.empty()) return false; - - TickCode changed_tick = *it; - changed_tick.type = type_to; - changed_tick.extruder = extruder; - changed_tick.color = color; - - ticks.erase(it); - ticks.emplace(changed_tick); - - return true; -} - -void TickCodeInfo::erase_all_ticks_with_code(Type type) -{ - for (auto it{ticks.begin()}, end{ticks.end()}; it != end;) { - if (it->type == type) - it = ticks.erase(it); - else - ++it; - } -} - -bool TickCodeInfo::has_tick_with_code(Type type) -{ - for (const TickCode &tick : ticks) - if (tick.type == type) return true; - - return false; -} - -bool TickCodeInfo::has_tick(int tick) { return ticks.find(TickCode{tick}) != ticks.end(); } - -ConflictType TickCodeInfo::is_conflict_tick(const TickCode &tick, Mode out_mode, int only_extruder, double print_z) -{ - if ((tick.type == ColorChange && ((mode == SingleExtruder && out_mode == MultiExtruder) || (mode == MultiExtruder && out_mode == SingleExtruder))) || - (tick.type == ToolChange && (mode == MultiAsSingle && out_mode != MultiAsSingle))) - return ctModeConflict; - - // check ColorChange tick - if (tick.type == ColorChange) { - // We should mark a tick as a "MeaninglessColorChange", - // if it has a ColorChange for unused extruder from current print to end of the print - std::set used_extruders_for_tick = get_used_extruders_for_tick(tick.tick, only_extruder, print_z, out_mode); - - if (used_extruders_for_tick.find(tick.extruder) == used_extruders_for_tick.end()) return ctMeaninglessColorChange; - - // We should mark a tick as a "Redundant", - // if it has a ColorChange for extruder that has not been used before - if (mode == MultiAsSingle && tick.extruder != std::max(only_extruder, 1)) { - auto it = ticks.lower_bound(tick); - if (it == ticks.begin() && it->type == ToolChange && tick.extruder == it->extruder) return ctNone; - - while (it != ticks.begin()) { - --it; - if (it->type == ToolChange && tick.extruder == it->extruder) return ctNone; - } - - return ctRedundant; - } - } - - // check ToolChange tick - if (mode == MultiAsSingle && tick.type == ToolChange) { - // We should mark a tick as a "MeaninglessToolChange", - // if it has a ToolChange to the same extruder - auto it = ticks.find(tick); - if (it == ticks.begin()) return tick.extruder == std::max(only_extruder, 1) ? ctMeaninglessToolChange : ctNone; - - while (it != ticks.begin()) { - --it; - if (it->type == ToolChange) return tick.extruder == it->extruder ? ctMeaninglessToolChange : ctNone; - } - } - - return ctNone; -} - -// Get used extruders for tick. -// Means all extruders(tools) which will be used during printing from current tick to the end -std::set TickCodeInfo::get_used_extruders_for_tick(int tick, int only_extruder, double print_z, Mode force_mode /* = Undef*/) const -{ - Mode e_mode = !force_mode ? mode : force_mode; - - if (e_mode == MultiExtruder) { - // #ys_FIXME: get tool ordering from _correct_ place - const ToolOrdering &tool_ordering = GUI::wxGetApp().plater()->fff_print().get_tool_ordering(); - - if (tool_ordering.empty()) return {}; - - std::set used_extruders; - - auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(print_z)); - for (; it_layer_tools != tool_ordering.end(); ++it_layer_tools) { - const std::vector &extruders = it_layer_tools->extruders; - for (const auto &extruder : extruders) used_extruders.emplace(extruder + 1); - } - - return used_extruders; - } - - const int default_initial_extruder = e_mode == MultiAsSingle ? std::max(only_extruder, 1) : 1; - if (ticks.empty() || e_mode == SingleExtruder) return {default_initial_extruder}; - - std::set used_extruders; - - auto it_start = ticks.lower_bound(TickCode{tick}); - auto it = it_start; - if (it == ticks.begin() && it->type == ToolChange && tick != it->tick) // In case of switch of ToolChange to ColorChange, when tick exists, - // we shouldn't change color for extruder, which will be deleted - { - used_extruders.emplace(it->extruder); - if (tick < it->tick) used_extruders.emplace(default_initial_extruder); - } - - while (it != ticks.begin()) { - --it; - if (it->type == ToolChange && tick != it->tick) { - used_extruders.emplace(it->extruder); - break; - } - } - - if (it == ticks.begin() && used_extruders.empty()) used_extruders.emplace(default_initial_extruder); - - for (it = it_start; it != ticks.end(); ++it) - if (it->type == ToolChange && tick != it->tick) used_extruders.emplace(it->extruder); - - return used_extruders; -} - IMSlider::IMSlider(int lowerValue, int higherValue, int minValue, int maxValue, long style) { m_lower_value = lowerValue; @@ -521,11 +215,6 @@ Info IMSlider::GetTicksValues() const void IMSlider::SetTicksValues(const Info &custom_gcode_per_print_z) { - if (!m_can_change_color) { - m_ticks.erase_all_ticks_with_code(ToolChange); - return; - } - if (m_values.empty()) { m_ticks.mode = m_mode; return; @@ -542,10 +231,12 @@ void IMSlider::SetTicksValues(const Info &custom_gcode_per_print_z) 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 - post_ticks_changed_event(); + ;// post_ticks_changed_event(); - // init extruder sequence in respect to the extruders count - if (m_ticks.empty()) m_extruders_sequence.init(m_extruder_colors.size()); + if (m_ticks.has_tick_with_code(ToolChange) && !m_can_change_color) { + m_ticks.erase_all_ticks_with_code(ToolChange); + post_ticks_changed_event(); + } if (custom_gcode_per_print_z.mode && !custom_gcode_per_print_z.gcodes.empty()) m_ticks.mode = custom_gcode_per_print_z.mode; @@ -955,10 +646,6 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) { ImTextureID pause_icon_id = m_pause_icon_id; ImVec2 icon_pos = ImVec2(slideable_region.GetCenter().x + icon_offset.x, tick_pos - icon_offset.y); button_with_pos(pause_icon_id, icon_size, icon_pos); - if (ImGui::IsMouseHoveringRect(icon_pos, icon_pos + icon_size)) { - if(context.IO.MouseClicked[0]) - int a = 0; - } } ++tick_it; } @@ -968,7 +655,6 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) { m_ticks.ticks.end(); if (tick_it != m_ticks.ticks.end()) { // draw delete icon - ImTextureID delete_icon_id = m_delete_icon_id; ImVec2 icon_pos = ImVec2(slideable_region.GetCenter().x + icon_offset.x, get_tick_pos(tick_it->tick) - icon_offset.y); button_with_pos(m_delete_icon_id, icon_size, icon_pos); if (ImGui::IsMouseHoveringRect(icon_pos, icon_pos + icon_size)) { @@ -1441,8 +1127,7 @@ void IMSlider::render_go_to_layer_dialog() void IMSlider::render_menu() { ImGuiWrapper::push_menu_style(m_scale); - std::vector colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); - int extruder_num = colors.size(); + int extruder_num = m_extruder_colors.size(); if (m_show_menu) { ImGui::OpenPopup("slider_menu_popup"); @@ -1482,7 +1167,7 @@ void IMSlider::render_menu() } else if (begin_menu(_u8L("Change Filament").c_str())) { for (int i = 0; i < extruder_num; i++) { - std::array rgba = decode_color_to_float_array(colors[i]); + std::array rgba = decode_color_to_float_array(m_extruder_colors[i]); ImU32 icon_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f); if (menu_item_with_icon((_u8L("Filament ") + std::to_string(i + 1)).c_str(), "", ImVec2(14, 14) * m_scale, icon_clr)) add_code_as_tick(ToolChange, i + 1); } diff --git a/src/slic3r/GUI/IMSlider.hpp b/src/slic3r/GUI/IMSlider.hpp index 73b36c43c..63bc00c6d 100644 --- a/src/slic3r/GUI/IMSlider.hpp +++ b/src/slic3r/GUI/IMSlider.hpp @@ -1,16 +1,9 @@ #ifndef slic3r_GUI_IMSlider_hpp_ #define slic3r_GUI_IMSlider_hpp_ -#include "libslic3r/CustomGCode.hpp" -#include "wxExtensions.hpp" -#include "IMSlider_Utils.hpp" +#include "TickCode.hpp" #include -#include -#include -#include -#include -#include #include class wxMenu; @@ -43,42 +36,6 @@ enum SelectedSlider { ssHigher = 2 }; -enum FocusedItem { - fiNone, - fiRevertIcon, - fiOneLayerIcon, - fiCogIcon, - fiColorBand, - fiActionIcon, - fiLowerThumb, - fiHigherThumb, - fiSmartWipeTower, - fiTick -}; - -enum ConflictType -{ - ctNone, - ctModeConflict, - ctMeaninglessColorChange, - ctMeaninglessToolChange, - ctRedundant -}; - -enum MouseAction -{ - maNone, - maAddMenu, // show "Add" context menu for NOTexist active tick - maEditMenu, // show "Edit" context menu for exist active tick - maCogIconMenu, // show context for "cog" icon - maForceColorEdit, // force color editing from colored band - maAddTick, // force tick adding - maDeleteTick, // force tick deleting - maCogIconClick, // LeftMouseClick on "cog" icon - maOneLayerIconClick, // LeftMouseClick on "one_layer" icon - maRevertIconClick, // LeftMouseClick on "revert" icon -}; - enum DrawMode { dmRegular, @@ -94,116 +51,6 @@ enum LabelType ltEstimatedTime, }; -enum VSliderMode -{ - Regular, - Colored, -}; - -struct TickCode -{ - bool operator<(const TickCode& other) const { return other.tick > this->tick; } - bool operator>(const TickCode& other) const { return other.tick < this->tick; } - - int tick = 0; - Type type = ColorChange; - int extruder = 0; - std::string color; - std::string extra; -}; - -class TickCodeInfo -{ - std::string custom_gcode; - std::string pause_print_msg; - bool m_suppress_plus = false; - bool m_suppress_minus = false; - bool m_use_default_colors= false; -// int m_default_color_idx = 0; - - std::vector* m_colors {nullptr}; - ColorGenerator color_generator; - - std::string get_color_for_tick(TickCode tick, Type type, const int extruder); - -public: - std::set ticks {}; - Mode mode = Undef; - - bool empty() const { return ticks.empty(); } - void set_pause_print_msg(const std::string& message) { pause_print_msg = message; } - - bool add_tick(const int tick, Type type, int extruder, double print_z); - bool edit_tick(std::set::iterator it, double print_z); - void switch_code(Type type_from, Type type_to); - bool switch_code_for_tick(std::set::iterator it, Type type_to, const int extruder); - void erase_all_ticks_with_code(Type type); - - bool has_tick_with_code(Type type); - bool has_tick(int tick); - ConflictType is_conflict_tick(const TickCode& tick, Mode out_mode, int only_extruder, double print_z); - - // Get used extruders for tick. - // Means all extruders(tools) which will be used during printing from current tick to the end - std::set get_used_extruders_for_tick(int tick, int only_extruder, double print_z, Mode force_mode = Undef) const; - - void suppress_plus (bool suppress) { m_suppress_plus = suppress; } - void suppress_minus(bool suppress) { m_suppress_minus = suppress; } - bool suppressed_plus () { return m_suppress_plus; } - bool suppressed_minus() { return m_suppress_minus; } - void set_default_colors(bool default_colors_on) { m_use_default_colors = default_colors_on; } - - void set_extruder_colors(std::vector* extruder_colors) { m_colors = extruder_colors; } -}; - - -struct ExtrudersSequence -{ - bool is_mm_intervals = true; - double interval_by_mm = 3.0; - int interval_by_layers = 10; - bool random_sequence { false }; - bool color_repetition { false }; - std::vector extruders = { 0 }; - - 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.random_sequence == this->random_sequence ) && - (other.color_repetition == this->color_repetition ) && - (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.random_sequence != this->random_sequence ) || - (other.color_repetition != this->color_repetition ) || - (other.extruders != this->extruders ) ; - } - - void add_extruder(size_t pos, size_t extruder_id = size_t(0)) - { - extruders.insert(extruders.begin() + pos+1, extruder_id); - } - - void delete_extruder(size_t pos) - { - if (extruders.size() == 1) - return;// last item can't be deleted - extruders.erase(extruders.begin() + pos); - } - - void init(size_t extruders_count) - { - extruders.clear(); - for (size_t extruder = 0; extruder < extruders_count; extruder++) - extruders.push_back(extruder); - } -}; class IMSlider { @@ -262,7 +109,7 @@ public: void UseDefaultColors(bool def_colors_on) { m_ticks.set_default_colors(def_colors_on); } void on_mouse_wheel(wxMouseEvent& evt); - void post_ticks_changed_event(Type type = Custom); + void post_ticks_changed_event(Type type = Unknown); bool check_ticks_changed_event(Type type); bool switch_one_layer_mode(); void show_go_to_layer(bool show) { m_show_go_to_layer_dialog = show; } @@ -279,7 +126,6 @@ public: } Type get_post_tick_event_type() { return m_tick_change_event_type; } - ExtrudersSequence m_extruders_sequence; float m_scale = 1.0; void set_scale(float scale = 1.0); void on_change_color_mode(bool is_dark); @@ -362,7 +208,6 @@ private: DrawMode m_draw_mode = dmRegular; Mode m_mode = SingleExtruder; - VSliderMode m_vslider_mode = Regular; int m_only_extruder = -1; long m_style; diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 1163c02ca..a33445b93 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -1255,11 +1255,14 @@ std::vector PartPlate::get_extruders(bool conside_custom_gcode) const } if (conside_custom_gcode) { - for (auto item : m_model->custom_gcode_per_print_z.gcodes) { - if (item.type == CustomGCode::Type::ToolChange) - plate_extruders.push_back(item.extruder); - } - } + //BBS + if (m_model->plates_custom_gcodes.find(m_plate_index) != m_model->plates_custom_gcodes.end()) { + for (auto item : m_model->plates_custom_gcodes.at(m_plate_index).gcodes) { + if (item.type == CustomGCode::Type::ToolChange) + plate_extruders.push_back(item.extruder); + } + } + } std::sort(plate_extruders.begin(), plate_extruders.end()); auto it_end = std::unique(plate_extruders.begin(), plate_extruders.end()); @@ -3080,7 +3083,11 @@ int PartPlateList::select_plate(int index) m_current_plate = index; m_plate_list[m_current_plate]->set_selected(); - + + //BBS + if(m_model) + m_model->curr_plate_index = index; + //BBS update bed origin if (m_intialized && m_plater) { Vec2d pos = compute_shape_position(index, m_plate_cols); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b7f92983f..d60eb65e6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2422,8 +2422,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); }); preview->get_wxglcanvas()->Bind(EVT_CUSTOMEVT_TICKSCHANGED, [this](wxCommandEvent& event) { Type tick_event_type = (Type)event.GetInt(); - Model &model = wxGetApp().plater()->model(); - model.custom_gcode_per_print_z = preview->get_canvas3d()->get_gcode_viewer().get_layers_slider()->GetTicksValues(); + Model& model = wxGetApp().plater()->model(); + //BBS: replace model custom gcode with current plate custom gcode + model.plates_custom_gcodes[model.curr_plate_index] = preview->get_canvas3d()->get_gcode_viewer().get_layers_slider()->GetTicksValues(); + preview->on_tick_changed(tick_event_type); // BBS set to invalid state only @@ -3215,8 +3217,8 @@ std::vector Plater::priv::load_files(const std::vector& input_ } if (!config_substitutions.empty()) show_substitutions_info(config_substitutions.substitutions, filename.string()); - this->model.custom_gcode_per_print_z = model.custom_gcode_per_print_z; // BBS + this->model.plates_custom_gcodes = model.plates_custom_gcodes; this->model.design_info = model.design_info; this->model.model_info = model.model_info; } @@ -4038,7 +4040,8 @@ void Plater::priv::delete_all_objects_from_model() sidebar->obj_list()->delete_all_objects_from_list(); object_list_changed(); - model.custom_gcode_per_print_z.gcodes.clear(); + //BBS + model.plates_custom_gcodes.clear(); } void Plater::priv::reset(bool apply_presets_change) @@ -4088,7 +4091,8 @@ void Plater::priv::reset(bool apply_presets_change) else wxGetApp().load_current_presets(false, false); - model.custom_gcode_per_print_z.gcodes.clear(); + //BBS + model.plates_custom_gcodes.clear(); // BBS m_saved_timestamp = m_backup_timestamp = size_t(-1); @@ -10270,7 +10274,6 @@ std::vector Plater::get_extruder_colors_from_plater_config(const GC std::vector Plater::get_colors_for_color_print(const GCodeProcessorResult* const result) const { std::vector colors = get_extruder_colors_from_plater_config(result); - colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.gcodes.size()); if (wxGetApp().is_gcode_viewer() && result != nullptr) { for (const CustomGCode::Item& code : result->custom_gcode_per_print_z) { @@ -10279,7 +10282,9 @@ std::vector Plater::get_colors_for_color_print(const GCodeProcessor } } else { - for (const CustomGCode::Item& code : p->model.custom_gcode_per_print_z.gcodes) { + //BBS + colors.reserve(colors.size() + p->model.get_curr_plate_custom_gcodes().gcodes.size()); + for (const CustomGCode::Item& code : p->model.get_curr_plate_custom_gcodes().gcodes) { if (code.type == CustomGCode::ColorChange) colors.emplace_back(code.color); } diff --git a/src/slic3r/GUI/TickCode.cpp b/src/slic3r/GUI/TickCode.cpp new file mode 100644 index 000000000..158afe7a1 --- /dev/null +++ b/src/slic3r/GUI/TickCode.cpp @@ -0,0 +1,193 @@ +#include "TickCode.hpp" + +namespace Slic3r { +namespace GUI { +std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int extruder) +{ + if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) { +#if 1 + if (ticks.empty()) return color_generator.get_opposite_color((*m_colors)[0]); + + auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick); + if (before_tick_it == ticks.end()) { + while (before_tick_it != ticks.begin()) + if (--before_tick_it; before_tick_it->type == ColorChange) break; + if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(before_tick_it->color); + return color_generator.get_opposite_color((*m_colors)[0]); + } + + if (before_tick_it == ticks.begin()) { + const std::string &frst_color = (*m_colors)[0]; + if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, before_tick_it->color); + + auto next_tick_it = before_tick_it; + while (next_tick_it != ticks.end()) + if (++next_tick_it; next_tick_it->type == ColorChange) break; + if (next_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, next_tick_it->color); + + return color_generator.get_opposite_color(frst_color); + } + + std::string frst_color = ""; + if (before_tick_it->type == ColorChange) + frst_color = before_tick_it->color; + else { + auto next_tick_it = before_tick_it; + while (next_tick_it != ticks.end()) + if (++next_tick_it; next_tick_it->type == ColorChange) { + frst_color = next_tick_it->color; + break; + } + } + + while (before_tick_it != ticks.begin()) + if (--before_tick_it; before_tick_it->type == ColorChange) break; + + if (before_tick_it->type == ColorChange) { + if (frst_color.empty()) return color_generator.get_opposite_color(before_tick_it->color); + return color_generator.get_opposite_color(before_tick_it->color, frst_color); + } + + if (frst_color.empty()) return color_generator.get_opposite_color((*m_colors)[0]); + return color_generator.get_opposite_color((*m_colors)[0], frst_color); +#else + const std::vector &colors = ColorPrintColors::get(); + if (ticks.empty()) return colors[0]; + m_default_color_idx++; + + return colors[m_default_color_idx % colors.size()]; +#endif + } + + std::string color = (*m_colors)[extruder - 1]; + + if (type == ColorChange) { + if (!ticks.empty()) { + auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick); + while (before_tick_it != ticks.begin()) { + --before_tick_it; + if (before_tick_it->type == ColorChange && before_tick_it->extruder == extruder) { + color = before_tick_it->color; + break; + } + } + } + + //TODO + //color = get_new_color(color); + } + return color; +} + + +bool TickCodeInfo::add_tick(const int tick, Type type, const int extruder, double print_z) +{ + std::string color; + std::string extra; + if (type == Custom) // custom Gcode + { + //extra = get_custom_code(custom_gcode, print_z); + //if (extra.empty()) return false; + //custom_gcode = extra; + } else if (type == PausePrint) { + //BBS do not set pause extra message + //extra = get_pause_print_msg(pause_print_msg, print_z); + //if (extra.empty()) return false; + pause_print_msg = extra; + } + else { + color = get_color_for_tick(TickCode{ tick }, type, extruder); + if (color.empty()) return false; + } + + if (mode == SingleExtruder) m_use_default_colors = true; + + ticks.emplace(TickCode{tick, type, extruder, color, extra}); + + return true; +} + +bool TickCodeInfo::edit_tick(std::set::iterator it, double print_z) +{ + std::string edited_value; + //TODO + /* BBS + if (it->type == ColorChange) + edited_value = get_new_color(it->color); + else if (it->type == PausePrint) + edited_value = get_pause_print_msg(it->extra, print_z); + else + edited_value = get_custom_code(it->type == Template ? gcode(Template) : it->extra, print_z); + */ + if (edited_value.empty()) return false; + + TickCode changed_tick = *it; + if (it->type == ColorChange) { + if (it->color == edited_value) return false; + changed_tick.color = edited_value; + } else if (it->type == Template) { + //if (gcode(Template) == edited_value) return false; + //changed_tick.extra = edited_value; + //changed_tick.type = Custom; + ; + } else if (it->type == Custom || it->type == PausePrint) { + if (it->extra == edited_value) return false; + changed_tick.extra = edited_value; + } + + ticks.erase(it); + ticks.emplace(changed_tick); + + return true; +} + +void TickCodeInfo::switch_code(Type type_from, Type type_to) +{ + for (auto it{ticks.begin()}, end{ticks.end()}; it != end;) + if (it->type == type_from) { + TickCode tick = *it; + tick.type = type_to; + tick.extruder = 1; + ticks.erase(it); + it = ticks.emplace(tick).first; + } else + ++it; +} + +bool TickCodeInfo::switch_code_for_tick(std::set::iterator it, Type type_to, const int extruder) +{ + const std::string color = get_color_for_tick(*it, type_to, extruder); + if (color.empty()) return false; + + TickCode changed_tick = *it; + changed_tick.type = type_to; + changed_tick.extruder = extruder; + changed_tick.color = color; + + ticks.erase(it); + ticks.emplace(changed_tick); + + return true; +} + +void TickCodeInfo::erase_all_ticks_with_code(Type type) +{ + for (auto it{ticks.begin()}, end{ticks.end()}; it != end;) { + if (it->type == type) + it = ticks.erase(it); + else + ++it; + } +} + +bool TickCodeInfo::has_tick_with_code(Type type) +{ + for (const TickCode &tick : ticks) + if (tick.type == type) return true; + + return false; +} + +bool TickCodeInfo::has_tick(int tick) { return ticks.find(TickCode{tick}) != ticks.end(); } + +}} \ No newline at end of file diff --git a/src/slic3r/GUI/TickCode.hpp b/src/slic3r/GUI/TickCode.hpp new file mode 100644 index 000000000..8616d7565 --- /dev/null +++ b/src/slic3r/GUI/TickCode.hpp @@ -0,0 +1,63 @@ +#ifndef slic3r_GUI_TickCode_hpp_ +#define slic3r_GUI_TickCode_hpp_ + +#include "libslic3r/CustomGCode.hpp" +#include "IMSlider_Utils.hpp" +#include + +namespace Slic3r { +using namespace CustomGCode; +namespace GUI { + +struct TickCode +{ + bool operator<(const TickCode& other) const { return other.tick > this->tick; } + bool operator>(const TickCode& other) const { return other.tick < this->tick; } + + int tick = 0; + Type type = ColorChange; + int extruder = 0; + std::string color; + std::string extra; +}; + +class TickCodeInfo +{ + std::string pause_print_msg; + bool m_suppress_plus = false; + bool m_suppress_minus = false; + bool m_use_default_colors = false; + + std::vector* m_colors{ nullptr };// reference to IMSlider::m_extruder_colors + ColorGenerator color_generator; + + std::string get_color_for_tick(TickCode tick, Type type, const int extruder); + +public: + std::set ticks{}; + Mode mode = Undef; + + bool empty() const { return ticks.empty(); } + void set_pause_print_msg(const std::string& message) { pause_print_msg = message; } + + bool add_tick(const int tick, Type type, int extruder, double print_z); + bool edit_tick(std::set::iterator it, double print_z); + void switch_code(Type type_from, Type type_to); + bool switch_code_for_tick(std::set::iterator it, Type type_to, const int extruder); + void erase_all_ticks_with_code(Type type); + + bool has_tick_with_code(Type type); + bool has_tick(int tick); + + void suppress_plus(bool suppress) { m_suppress_plus = suppress; } + void suppress_minus(bool suppress) { m_suppress_minus = suppress; } + bool suppressed_plus() { return m_suppress_plus; } + bool suppressed_minus() { return m_suppress_minus; } + void set_default_colors(bool default_colors_on) { m_use_default_colors = default_colors_on; } + + void set_extruder_colors(std::vector* extruder_colors) { m_colors = extruder_colors; } +}; + +}} // Slic3r + +#endif // slic3r_GUI_TickCode_hpp_ \ No newline at end of file