ENH: custom gcode info should be owned by every plate

Change-Id: I5e5b000b7d04354d3c3cc311d089cb591a37501e
This commit is contained in:
liz.li 2023-02-01 17:38:02 +08:00 committed by Lane.Wei
parent 5f71eba979
commit e7ea07944f
16 changed files with 545 additions and 680 deletions

View file

@ -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<std::string>("<xmlattr>.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<std::string>("<xmlattr>.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<double> ("<xmlattr>.print_z" );
int extruder = tree.get<int> ("<xmlattr>.extruder");
std::string color = tree.get<std::string> ("<xmlattr>.color" );
// pt::ptree tree = code.second;
// double print_z = tree.get<double> ("<xmlattr>.print_z" );
// int extruder = tree.get<int> ("<xmlattr>.extruder");
// std::string color = tree.get<std::string> ("<xmlattr>.color" );
CustomGCode::Type type;
std::string extra;
pt::ptree attr_tree = tree.find("<xmlattr>")->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<std::string> ("<xmlattr>.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<CustomGCode::Type>(tree.get<int>("<xmlattr>.type"));
extra = tree.get<std::string>("<xmlattr>.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("<xmlattr>")->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<std::string> ("<xmlattr>.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<CustomGCode::Type>(tree.get<int>("<xmlattr>.type"));
// extra = tree.get<std::string>("<xmlattr>.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("<xmlattr>.print_z" , code.print_z );
code_tree.put("<xmlattr>.type" , static_cast<int>(code.type));
code_tree.put("<xmlattr>.extruder" , code.extruder );
code_tree.put("<xmlattr>.color" , code.color );
code_tree.put("<xmlattr>.extra" , code.extra );
// // store data of custom_gcode_per_print_z
// code_tree.put("<xmlattr>.print_z" , code.print_z );
// code_tree.put("<xmlattr>.type" , static_cast<int>(code.type));
// code_tree.put("<xmlattr>.extruder" , code.extruder );
// code_tree.put("<xmlattr>.color" , code.color );
// code_tree.put("<xmlattr>.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("<xmlattr>.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("<xmlattr>.gcode" , gcode );
// }
pt::ptree& mode_tree = main_tree.add("mode", "");
// store mode of a custom_gcode_per_print_z
mode_tree.put("<xmlattr>.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("<xmlattr>.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.

View file

@ -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<std::string>("<xmlattr>.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<double>("<xmlattr>.top_z");
int extruder = tree.get<int>("<xmlattr>.extruder");
std::string color = tree.get<std::string>("<xmlattr>.color");
for (const auto& code : code_tree) {
if (code.first == "mode") {
pt::ptree tree = code.second;
std::string mode = tree.get<std::string>("<xmlattr>.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("<xmlattr>")->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<std::string>("<xmlattr>.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<CustomGCode::Type>(tree.get<int>("<xmlattr>.type"));
extra = tree.get<std::string>("<xmlattr>.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<double> ("<xmlattr>.top_z" );
int extruder = tree.get<int> ("<xmlattr>.extruder");
std::string color = tree.get<std::string> ("<xmlattr>.color" );
m_model->plates_custom_gcodes.clear();
CustomGCode::Type type;
std::string extra;
pt::ptree attr_tree = tree.find("<xmlattr>")->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<std::string> ("<xmlattr>.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<int>("<xmlattr>.id");
}
}
if (plate_id == -1)
continue;
extract_code(plate_id, code_tree);
}
else {
type = static_cast<CustomGCode::Type>(tree.get<int>("<xmlattr>.type"));
extra = tree.get<std::string>("<xmlattr>.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("<xmlattr>.id", custom_gcodes.first + 1);
// store data of custom_gcode_per_print_z
code_tree.put("<xmlattr>.top_z" , code.print_z );
code_tree.put("<xmlattr>.type" , static_cast<int>(code.type));
code_tree.put("<xmlattr>.extruder" , code.extruder );
code_tree.put("<xmlattr>.color" , code.color );
code_tree.put("<xmlattr>.extra" , code.extra );
for (const CustomGCode::Item& code : custom_gcodes.second.gcodes) {
pt::ptree& code_tree = plate_tree.add("layer", "");
code_tree.put("<xmlattr>.top_z", code.print_z);
code_tree.put("<xmlattr>.type", static_cast<int>(code.type));
code_tree.put("<xmlattr>.extruder", code.extruder);
code_tree.put("<xmlattr>.color", code.color);
code_tree.put("<xmlattr>.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("<xmlattr>.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("<xmlattr>.gcode", gcode);
}
pt::ptree& mode_tree = main_tree.add("mode", "");
// store mode of a custom_gcode_per_print_z
mode_tree.put("<xmlattr>.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("<xmlattr>.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()) {

View file

@ -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<unsigned char> 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

View file

@ -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) {

View file

@ -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<int, CustomGCode::Info> plates_custom_gcodes; //map<plate_index, CustomGCode::Info>
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()); }

View file

@ -336,9 +336,12 @@ std::vector<unsigned int> 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);
}
}
}

View file

@ -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.