diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index b56247add..07315b457 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -606,6 +606,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st // do not insert gcode into machine start & end gcode unsigned int machine_start_gcode_end_line_id = (unsigned int)(-1); // mark the end line of machine start gcode unsigned int machine_end_gcode_start_line_id = (unsigned int)(-1); // mark the start line of machine end gcode + std::vector> skippable_blocks; // keeps track of last exported pair std::array, static_cast(PrintEstimatedStatistics::ETimeMode::Count)> last_exported_main; @@ -737,6 +738,13 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st else if (line == reserved_tag(ETags::MachineEndGCodeStart)) { machine_end_gcode_start_line_id = line_id; } + else if (line == custom_tags(CustomETags::SKIPPABLE_START)){ + skippable_blocks.emplace_back(0,0); + skippable_blocks.back().first = line_id; + } + else if (line == custom_tags(CustomETags::SKIPPABLE_END)){ + skippable_blocks.back().second = line_id; + } } if (!ret.empty()) @@ -1008,7 +1016,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st gcode_process(in, out, filename_in, filename_out, gcode_time_handler, nullptr, buffer_size_in_KB); // updates moves' gcode ids which have been modified by the insertion of the M73 lines - handle_offsets_of_first_process(offsets, moves, filament_blocks, extruder_blocks, machine_start_gcode_end_line_id, machine_end_gcode_start_line_id); + handle_offsets_of_first_process(offsets, moves, filament_blocks, extruder_blocks, skippable_blocks, machine_start_gcode_end_line_id, machine_end_gcode_start_line_id); // If not initialized, use the time from the previous move. { @@ -1095,6 +1103,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st context.pre_cooling_temp, context.cooling_rate, context.heating_rate, + skippable_blocks, machine_start_gcode_end_line_id, machine_end_gcode_start_line_id ); @@ -1165,7 +1174,14 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st } } -void GCodeProcessor::TimeProcessor::handle_offsets_of_first_process(const std::vector>& offsets, std::vector& moves, std::vector& filament_blocks, std::vector& extruder_blocks, unsigned int& machine_start_gcode_end_line_id, unsigned int& machine_end_gcode_start_line_id) +void GCodeProcessor::TimeProcessor::handle_offsets_of_first_process( + const std::vector>& offsets, + std::vector& moves, + std::vector& filament_blocks, + std::vector& extruder_blocks, + std::vector>& skippable_blocks, + unsigned int& machine_start_gcode_end_line_id, + unsigned int& machine_end_gcode_start_line_id) { // process moves { @@ -1209,6 +1225,11 @@ void GCodeProcessor::TimeProcessor::handle_offsets_of_first_process(const std::v block.post_extrusion_end_id += get_offset_before_line_id(block.post_extrusion_end_id); } + for(auto& block: skippable_blocks){ + block.first += get_offset_before_line_id(block.first); + block.second += get_offset_before_line_id(block.second); + } + machine_start_gcode_end_line_id += get_offset_before_line_id(machine_start_gcode_end_line_id); machine_end_gcode_start_line_id += get_offset_before_line_id(machine_end_gcode_start_line_id); } @@ -6004,19 +6025,75 @@ void GCodeProcessor::PreCoolingInjector::inject_cooling_heating_command(TimeProc return a.gcode_id < gcode_id; }; + auto find_skip_block_end = [&skippable_blocks = this->skippable_blocks](unsigned int gcode_id) -> unsigned int{ + auto it = std::upper_bound( + skippable_blocks.begin(), skippable_blocks.end(), gcode_id, + [](unsigned int id, const std::pair&block) { return id < block.first; } + ); + if (it != skippable_blocks.begin()) { + auto candidate = std::prev(it); + if (gcode_id >= candidate->first && gcode_id <= candidate->second) + return candidate->second; + } + return 0; + }; + + auto find_skip_block_start = [&skippable_blocks = this->skippable_blocks](unsigned int gcode_id) -> unsigned int { + auto it = std::upper_bound( + skippable_blocks.begin(), skippable_blocks.end(), gcode_id, + [](unsigned int id, const std::pair&block) { return id < block.first; } + ); + if (it != skippable_blocks.begin()) { + auto candidate = std::prev(it); + if (gcode_id >= candidate->first && gcode_id <= candidate->second) + return candidate->first; + } + return 0; + }; + + auto adjust_iter = [&](std::vector::const_iterator iter, + const std::vector::const_iterator& begin, + const std::vector::const_iterator& end, + bool forward) -> std::vector::const_iterator + { + if (forward) { + while (iter != end) { + unsigned current_id = iter->gcode_id; + unsigned skip_block_end = find_skip_block_end(current_id); + if(skip_block_end == 0) + break; + iter = std::lower_bound(iter, end, skip_block_end + 1, gcode_move_comp); + } + } + else { + while (iter != begin) { + unsigned current_id = iter->gcode_id; + unsigned skip_block_start = find_skip_block_start(current_id); + if(skip_block_start == 0) + break; + auto new_iter = std::lower_bound(begin, iter, skip_block_start, gcode_move_comp); + if(new_iter == begin) + break; + iter = std::prev(new_iter); + } + } + return iter; + }; + if (!pre_cooling && !pre_heating && block.free_upper_gcode_id <= block.free_lower_gcode_id) return; auto move_iter_lower = std::lower_bound(moves.begin(), moves.end(), block.free_lower_gcode_id, gcode_move_comp); auto move_iter_upper = std::lower_bound(moves.begin(), moves.end(), block.free_upper_gcode_id, gcode_move_comp); // closed iter - if (move_iter_lower == moves.end() || move_iter_upper == moves.end() || move_iter_upper == moves.begin()) + + if (move_iter_lower == moves.end() || move_iter_upper == moves.begin()) return; --move_iter_upper; auto partial_free_move_lower = std::lower_bound(moves.begin(), moves.end(), block.partial_free_lower_id, gcode_move_comp); auto partial_free_move_upper = std::lower_bound(moves.begin(), moves.end(), block.partial_free_upper_id, gcode_move_comp); // closed iter - if (partial_free_move_lower == moves.end() || partial_free_move_upper == moves.end() || partial_free_move_upper == moves.begin()) + if (partial_free_move_lower == moves.end() || partial_free_move_upper == moves.begin()) return; --partial_free_move_upper; @@ -6038,11 +6115,9 @@ void GCodeProcessor::PreCoolingInjector::inject_cooling_heating_command(TimeProc float ext_cooling_rate = cooling_rate[block.extruder_id]; if (apply_cooling_when_partial_free) { - if (partial_free_move_lower < partial_free_move_upper) { - float max_cooling_temp = std::min(curr_temp, std::min(get_partial_free_cooling_thres(block.last_filament_id), partial_free_time_gap * ext_cooling_rate)); - curr_temp -= max_cooling_temp; // set the temperature after doing cooling when post-extruding - inserted_operation_lines[partial_free_move_lower->gcode_id].emplace_back(format_line_M104(curr_temp, block.extruder_id, "Multi extruder pre cooling in post extrusion"), TimeProcessor::InsertLineType::PreCooling); - } + float max_cooling_temp = std::min(curr_temp, std::min(get_partial_free_cooling_thres(block.last_filament_id), partial_free_time_gap * ext_cooling_rate)); + curr_temp -= max_cooling_temp; // set the temperature after doing cooling when post-extruding + inserted_operation_lines[block.partial_free_lower_id].emplace_back(format_line_M104(curr_temp, block.extruder_id, "Multi extruder pre cooling in post extrusion"), TimeProcessor::InsertLineType::PreCooling); } if (pre_cooling && !pre_heating) { @@ -6058,11 +6133,12 @@ void GCodeProcessor::PreCoolingInjector::inject_cooling_heating_command(TimeProc return; float heating_start_time = move_iter_upper->time[valid_machine_id] - (target_temp - curr_temp) / ext_heating_rate; auto heating_move_iter = std::upper_bound(move_iter_lower, move_iter_upper + 1, heating_start_time, [valid_machine_id = this->valid_machine_id](float time, const GCodeProcessorResult::MoveVertex& a) {return time < a.time[valid_machine_id]; }); - if (heating_move_iter == move_iter_upper + 1 || heating_move_iter == move_iter_lower) { + if (heating_move_iter == move_iter_lower) { inserted_operation_lines[block.free_lower_gcode_id].emplace_back(format_line_M104(target_temp, block.extruder_id, "Multi extruder pre heating"), TimeProcessor::InsertLineType::PreHeating); } else { --heating_move_iter; + heating_move_iter = adjust_iter(heating_move_iter, move_iter_lower, move_iter_upper, false); inserted_operation_lines[heating_move_iter->gcode_id].emplace_back(format_line_M104(target_temp, block.extruder_id, "Multi extruder pre heating"), TimeProcessor::InsertLineType::PreHeating); } return; @@ -6072,10 +6148,11 @@ void GCodeProcessor::PreCoolingInjector::inject_cooling_heating_command(TimeProc float heating_temp = target_temp - mid_temp; float heating_start_time = move_iter_upper->time[valid_machine_id] - heating_temp / ext_heating_rate; auto heating_move_iter = std::upper_bound(move_iter_lower, move_iter_upper + 1, heating_start_time, [valid_machine_id = this->valid_machine_id](float time, const GCodeProcessorResult::MoveVertex& a) {return time < a.time[valid_machine_id]; }); - if (heating_move_iter == move_iter_lower || heating_move_iter == move_iter_upper + 1) + if (heating_move_iter == move_iter_lower) return; - --heating_move_iter; + heating_move_iter = adjust_iter(heating_move_iter, move_iter_lower, move_iter_upper, false); + // get the insert pos of heat cmd and recalculate time gap and delta temp float real_cooling_time = heating_move_iter->time[valid_machine_id] - move_iter_lower->time[valid_machine_id]; int real_delta_temp = std::min((int)(real_cooling_time * ext_cooling_rate), (int)curr_temp); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 93454baad..5458e3fe2 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -783,6 +783,7 @@ namespace Slic3r { std::vector& moves, std::vector& filament_blocks, std::vector& extruder_blocks, + std::vector>& skippable_blocks, unsigned int& machine_start_gcode_end_line_id, unsigned int& machine_end_gcode_start_line_id ); @@ -819,6 +820,7 @@ namespace Slic3r { const std::vector & pre_cooling_temp_, const std::vector& cooling_rate_, const std::vector& heating_rate_, + const std::vector>& skippable_blocks_, unsigned int machine_start_gcode_end_id_, unsigned int machine_end_gcode_start_id_ ) : @@ -832,6 +834,7 @@ namespace Slic3r { filament_pre_cooling_temps(pre_cooling_temp_), cooling_rate(cooling_rate_), heating_rate(heating_rate_), + skippable_blocks(skippable_blocks_), machine_start_gcode_end_id(machine_start_gcode_end_id_), machine_end_gcode_start_id(machine_end_gcode_start_id_) { @@ -849,7 +852,7 @@ namespace Slic3r { const std::vector& cooling_rate; const std::vector& heating_rate; const std::vector& filament_pre_cooling_temps; // target cooling temp during post extrusion - + const std::vector>& skippable_blocks; const unsigned int machine_start_gcode_end_id; const unsigned int machine_end_gcode_start_id;