ENH: add timelapse warning for multi-extruder printer

jira: none
Change-Id: I09a25f00eef6d3fab6ad948a13c8eb308f134dbb
This commit is contained in:
zhimin.zeng 2025-01-16 21:36:40 +08:00 committed by lane.wei
parent b0efa7f11f
commit d7acee50e8
7 changed files with 31 additions and 5 deletions

View File

@ -323,7 +323,6 @@ static constexpr const char* NOZZLE_DIAMETERS_ATTR = "nozzle_diameters";
static constexpr const char* SLICE_PREDICTION_ATTR = "prediction"; static constexpr const char* SLICE_PREDICTION_ATTR = "prediction";
static constexpr const char* SLICE_WEIGHT_ATTR = "weight"; static constexpr const char* SLICE_WEIGHT_ATTR = "weight";
static constexpr const char* TIMELAPSE_TYPE_ATTR = "timelapse_type"; static constexpr const char* TIMELAPSE_TYPE_ATTR = "timelapse_type";
static constexpr const char* TIMELAPSE_ERROR_CODE_ATTR = "timelapse_error_code";
static constexpr const char* OUTSIDE_ATTR = "outside"; static constexpr const char* OUTSIDE_ATTR = "outside";
static constexpr const char* SUPPORT_USED_ATTR = "support_used"; static constexpr const char* SUPPORT_USED_ATTR = "support_used";
static constexpr const char* LABEL_OBJECT_ENABLED_ATTR = "label_object_enabled"; static constexpr const char* LABEL_OBJECT_ENABLED_ATTR = "label_object_enabled";
@ -7863,7 +7862,6 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PRINTER_MODEL_ID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->printer_model_id << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PRINTER_MODEL_ID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->printer_model_id << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << NOZZLE_DIAMETERS_ATTR << "\" " << VALUE_ATTR << "=\"" << nozzle_diameters_str << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << NOZZLE_DIAMETERS_ATTR << "\" " << VALUE_ATTR << "=\"" << nozzle_diameters_str << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << TIMELAPSE_TYPE_ATTR << "\" " << VALUE_ATTR << "=\"" << timelapse_type << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << TIMELAPSE_TYPE_ATTR << "\" " << VALUE_ATTR << "=\"" << timelapse_type << "\"/>\n";
//stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << TIMELAPSE_ERROR_CODE_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->timelapse_warning_code << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SLICE_PREDICTION_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->get_gcode_prediction_str() << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SLICE_PREDICTION_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->get_gcode_prediction_str() << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SLICE_WEIGHT_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->get_gcode_weight_str() << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SLICE_WEIGHT_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->get_gcode_weight_str() << "\"/>\n";
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << OUTSIDE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->toolpath_outside << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << OUTSIDE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->toolpath_outside << "\"/>\n";

View File

@ -1477,9 +1477,13 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
if (m_config.printer_structure.value == PrinterStructure::psI3 && m_spiral_vase) { if (m_config.printer_structure.value == PrinterStructure::psI3 && m_spiral_vase) {
m_timelapse_warning_code += 1; m_timelapse_warning_code += 1;
} }
if (m_config.printer_structure.value == PrinterStructure::psI3 && print->config().print_sequence == PrintSequence::ByObject) { if ((m_config.printer_structure.value == PrinterStructure::psI3 || m_config.nozzle_diameter.size() == 2)
&& print->config().print_sequence == PrintSequence::ByObject) {
m_timelapse_warning_code += (1 << 1); m_timelapse_warning_code += (1 << 1);
} }
if (m_config.timelapse_type.value == TimelapseType::tlSmooth && !m_config.enable_prime_tower.value) {
m_timelapse_warning_code += (1 << 2);
}
m_processor.result().timelapse_warning_code = m_timelapse_warning_code; m_processor.result().timelapse_warning_code = m_timelapse_warning_code;
m_processor.result().support_traditional_timelapse = m_support_traditional_timelapse; m_processor.result().support_traditional_timelapse = m_support_traditional_timelapse;
@ -4311,9 +4315,18 @@ GCode::LayerResult GCode::process_layer(
log_memory_info(); log_memory_info();
if (need_insert_timelapse_gcode_for_traditional && !has_insert_timelapse_gcode) { if (need_insert_timelapse_gcode_for_traditional && !has_insert_timelapse_gcode) {
// The traditional model of thin-walled object will have flaws for I3
if (m_support_traditional_timelapse && printer_structure == PrinterStructure::psI3) if (m_support_traditional_timelapse && printer_structure == PrinterStructure::psI3)
m_support_traditional_timelapse = false; m_support_traditional_timelapse = false;
// The traditional model will have flaws for multi_extruder when switching extruder
if (m_config.nozzle_diameter.values.size() == 2
&& m_support_traditional_timelapse
&& m_config.timelapse_type.value == TimelapseType::tlTraditional
&& (writer().filament() && get_extruder_id(writer().filament()->id()) != most_used_extruder)) {
m_support_traditional_timelapse = false;
}
gcode += this->retract(false, false, LiftType::SpiralLift); gcode += this->retract(false, false, LiftType::SpiralLift);
m_writer.add_object_change_labels(gcode); m_writer.add_object_change_labels(gcode);

View File

@ -543,6 +543,9 @@ private:
std::vector<size_t> m_label_objects_ids; std::vector<size_t> m_label_objects_ids;
std::string _encode_label_ids_to_base64(std::vector<size_t> ids); std::string _encode_label_ids_to_base64(std::vector<size_t> ids);
// 1 << 0: A1 series cannot supprot traditional timelapse when printing by object (cannot turn on timelapse)
// 1 << 1: A1 series cannot supprot traditional timelapse with spiral vase mode (cannot turn on timelapse)
// 1 << 2: Timelapse in smooth mode without wipe tower (turn on with prompt)
int m_timelapse_warning_code = 0; int m_timelapse_warning_code = 0;
bool m_support_traditional_timelapse = true; bool m_support_traditional_timelapse = true;

View File

@ -5760,6 +5760,7 @@ void GCodeProcessor::update_slice_warnings()
warning.params.clear(); warning.params.clear();
warning.level = 1; warning.level = 1;
if (!m_result.support_traditional_timelapse) { if (!m_result.support_traditional_timelapse) {
warning.level = 2;
warning.msg = NOT_SUPPORT_TRADITIONAL_TIMELAPSE; warning.msg = NOT_SUPPORT_TRADITIONAL_TIMELAPSE;
warning.error_code = "1000C003"; warning.error_code = "1000C003";
m_result.warnings.push_back(warning); m_result.warnings.push_back(warning);
@ -5767,16 +5768,23 @@ void GCodeProcessor::update_slice_warnings()
if (m_result.timelapse_warning_code != 0) { if (m_result.timelapse_warning_code != 0) {
if (m_result.timelapse_warning_code & 1) { if (m_result.timelapse_warning_code & 1) {
warning.level = 1;
warning.msg = NOT_GENERATE_TIMELAPSE; warning.msg = NOT_GENERATE_TIMELAPSE;
warning.error_code = "1001C001"; warning.error_code = "1001C001";
m_result.warnings.push_back(warning); m_result.warnings.push_back(warning);
} }
if ((m_result.timelapse_warning_code >> 1) & 1) { if ((m_result.timelapse_warning_code >> 1) & 1) {
warning.level = 1;
warning.msg = NOT_GENERATE_TIMELAPSE; warning.msg = NOT_GENERATE_TIMELAPSE;
warning.error_code = "1001C002"; warning.error_code = "1001C002";
m_result.warnings.push_back(warning); m_result.warnings.push_back(warning);
} }
if ((m_result.timelapse_warning_code >> 2) & 1) {
warning.level = 2;
warning.msg = SMOOTH_TIMELAPSE_WITHOUT_PRIME_TOWER;
warning.error_code = "1001C004";
m_result.warnings.push_back(warning);
}
} }
m_result.warnings.shrink_to_fit(); m_result.warnings.shrink_to_fit();

View File

@ -23,6 +23,7 @@ namespace Slic3r {
#define BED_TEMP_TOO_HIGH_THAN_FILAMENT "bed_temperature_too_high_than_filament" #define BED_TEMP_TOO_HIGH_THAN_FILAMENT "bed_temperature_too_high_than_filament"
#define NOT_SUPPORT_TRADITIONAL_TIMELAPSE "not_support_traditional_timelapse" #define NOT_SUPPORT_TRADITIONAL_TIMELAPSE "not_support_traditional_timelapse"
#define NOT_GENERATE_TIMELAPSE "not_generate_timelapse" #define NOT_GENERATE_TIMELAPSE "not_generate_timelapse"
#define SMOOTH_TIMELAPSE_WITHOUT_PRIME_TOWER "smooth_timelapse_without_prime_tower"
#define LONG_RETRACTION_WHEN_CUT "activate_long_retraction_when_cut" #define LONG_RETRACTION_WHEN_CUT "activate_long_retraction_when_cut"
enum class EMoveType : unsigned char enum class EMoveType : unsigned char

View File

@ -4477,6 +4477,8 @@ wxString Plater::get_slice_warning_string(GCodeProcessorResult::SliceWarning& wa
return _L("Enabling traditional timelapse photography may cause surface imperfections. It is recommended to change to smooth mode."); return _L("Enabling traditional timelapse photography may cause surface imperfections. It is recommended to change to smooth mode.");
} else if (warning.msg == NOT_GENERATE_TIMELAPSE) { } else if (warning.msg == NOT_GENERATE_TIMELAPSE) {
return wxString(); return wxString();
} else if (warning.msg == SMOOTH_TIMELAPSE_WITHOUT_PRIME_TOWER) {
return _L("Smooth mode for timelapse is enabled, but the prime tower is off, which may cause print defects. Please enable the prime tower, re-slice and print again.");
} }
else { else {
return wxString(warning.msg); return wxString(warning.msg);

View File

@ -1484,7 +1484,8 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
if (opt_key == "print_sequence" && m_config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject) { if (opt_key == "print_sequence" && m_config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject) {
auto printer_structure_opt = m_preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<PrinterStructure>>("printer_structure"); auto printer_structure_opt = m_preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnum<PrinterStructure>>("printer_structure");
if (printer_structure_opt && printer_structure_opt->value == PrinterStructure::psI3) { if ((printer_structure_opt && printer_structure_opt->value == PrinterStructure::psI3)
|| m_preset_bundle->get_printer_extruder_count() == 2) {
wxString msg_text = _(L("Timelapse is not supported because Print sequence is set to \"By object\".")); wxString msg_text = _(L("Timelapse is not supported because Print sequence is set to \"By object\"."));
msg_text += "\n\n" + _(L("Still print by object?")); msg_text += "\n\n" + _(L("Still print by object?"));