diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 4691af7e0e..996761c26f 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -614,6 +614,8 @@ void GCodeProcessor::TimeMachine::calculate_time(GCodeProcessorResult& result, P float leftover = 0.0f; for (size_t i = additional_buffer_idx; i < additional_buffer.size(); ++i) leftover += additional_buffer[i].second; + BOOST_LOG_TRIVIAL(debug) << "calculate_time(is_final): leftover=" << leftover + << "s from " << (additional_buffer.size() - additional_buffer_idx) << " items"; time += double(leftover); gcode_time.cache += leftover; } else { @@ -1527,7 +1529,15 @@ void GCodeProcessor::run_post_process() tag.remove_suffix(1); tag.remove_prefix(1); // strip leading ';' if (tag == Machine_Start_GCode_End_Tag) { m_machine_start_gcode_end_line_id = line_id; return; } - if (tag == Machine_End_GCode_Start_Tag) { m_machine_end_gcode_start_line_id = line_id; return; } + if (tag == Machine_End_GCode_Start_Tag) { + m_machine_end_gcode_start_line_id = line_id; + // End gcode M400 delays (air purification, timelapse, sound) are post-print + // by definition. Skip them so M73 reports print completion time. + // Reference to BBS: BambuStudio/src/libslic3r/GCode/GCodeProcessor.cpp — + // BBS drops leftover in calculate_time(is_final=true), achieving the same. + m_skip_end_gcode_delays = true; + return; + } } // filament-change commands: T, ;VT, M1020 S, each optionally " H" @@ -2922,6 +2932,8 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_preheat_steps = 1; m_result.backtrace_enabled = config.ooze_prevention && m_preheat_time > 0 && (m_is_XL_printer || (!m_single_extruder_multi_material && filament_count > 1)); + m_support_air_filtration = config.support_air_filtration.value; + assert(config.nozzle_volume.size() == config.nozzle_diameter.size()); m_nozzle_volume.resize(config.nozzle_volume.size()); for (size_t idx = 0; idx < config.nozzle_volume.size(); ++idx) @@ -3075,6 +3087,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) const ConfigOptionInt *nozzle_HRC = config.option("nozzle_hrc"); if (nozzle_HRC != nullptr) m_result.nozzle_hrc = nozzle_HRC->value; + const ConfigOptionBool *support_air_filt = config.option("support_air_filtration"); + if (support_air_filt != nullptr) + m_support_air_filtration = support_air_filt->value; + const ConfigOptionInts* physical_extruder_map = config.option("physical_extruder_map"); if (physical_extruder_map != nullptr) { m_physical_extruder_map = physical_extruder_map->values; @@ -3492,6 +3508,8 @@ void GCodeProcessor::reset() m_extruder_blocks.clear(); m_machine_start_gcode_end_line_id = (unsigned int) (-1); m_machine_end_gcode_start_line_id = (unsigned int) (-1); + m_support_air_filtration = false; + m_skip_end_gcode_delays = false; m_remaining_volume = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0.f); m_line_id = 0; @@ -4219,6 +4237,15 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers return; } + // End gcode marker: skip M400 S/P delays after this point so M73 reports + // print completion time, not post-print filtration/cooldown time. + // Reference to BBS: BambuStudio/src/libslic3r/GCode/GCodeProcessor.cpp — + // BBS drops leftover in calculate_time(is_final=true), achieving the same. + if (comment == Machine_End_GCode_Start_Tag) { + m_skip_end_gcode_delays = true; + return; + } + // Orca: Integrate filament consumption for purging performed to an external device and controlled via macros // (eg. Happy Hare) in the filament consumption stats. if (boost::starts_with(comment, GCodeProcessor::External_Purge_Tag)) { @@ -6401,6 +6428,18 @@ void GCodeProcessor::process_M400(const GCodeReader::GCodeLine& line) float value_p = 0.0; if (line.has_value('S', value_s) || line.has_value('P', value_p)) { value_s += value_p * 0.001; + + + // End gcode M400 delays (air purification M400 S180, timelapse M400 S5, + // sound M400 S1) are post-print by definition. Skip them so M73 reports + // print completion time, not post-print filtration/cooldown time. + // Reference to BBS: BambuStudio/src/libslic3r/GCode/GCodeProcessor.cpp — + // BBS drops leftover in calculate_time(is_final=true), achieving the same + // effect of excluding end gcode delays from M73 total. We skip at the + // source instead, leaving calculate_time unchanged for all printers. + if (m_skip_end_gcode_delays) + return; + simulate_st_synchronize(value_s); } } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 8a66cdc9e4..aa10bb7ec1 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -1109,6 +1109,15 @@ class Print; std::vector m_extruder_blocks; unsigned int m_machine_start_gcode_end_line_id{ (unsigned int) (-1) }; unsigned int m_machine_end_gcode_start_line_id{ (unsigned int) (-1) }; + // End gcode M400 delays (air purification, timelapse, sound) are post-print + // by definition. M73 should report print completion time, not post-print time. + // m_skip_end_gcode_delays is set when MACHINE_END_GCODE_START tag is encountered + // during the streaming parse (process_tags), telling process_M400 to skip timed + // delays in the end gcode scope. + // Reference to BBS: BambuStudio/src/libslic3r/GCode/GCodeProcessor.cpp — + // BBS drops leftover in calculate_time(is_final=true), achieving the same effect. + bool m_support_air_filtration{ false }; + bool m_skip_end_gcode_delays{ false }; // Tracks, during the stream, which filament sits in each physical nozzle and which nozzle each // extruder currently carries. Written by both branches of the two-arg process_filament_change // (the fallback branch does occupancy bookkeeping only); read by the richer change-time model