diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 40392466d..d836bb14f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1224,7 +1224,8 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu for (const LayerToPrint <p : layers_to_print) { std::vector lrs; lrs.emplace_back(std::move(ltp)); - this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), nullptr, *print_object_instance_sequential_active - object.instances().data()); + this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), <p == &layers_to_print.back(), + nullptr, *print_object_instance_sequential_active - object.instances().data()); print.throw_if_canceled(); } #ifdef HAS_PRESSURE_EQUALIZER @@ -1288,7 +1289,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu const LayerTools &layer_tools = tool_ordering.tools_for_layer(layer.first); if (m_wipe_tower && layer_tools.has_wipe_tower) m_wipe_tower->next_layer(); - this->process_layer(file, print, layer.second, layer_tools, &print_object_instances_ordering, size_t(-1)); + this->process_layer(file, print, layer.second, layer_tools, &layer == &layers_to_print.back(), &print_object_instances_ordering, size_t(-1)); print.throw_if_canceled(); } #ifdef HAS_PRESSURE_EQUALIZER @@ -1757,6 +1758,7 @@ void GCode::process_layer( // Set of object & print layers of the same PrintObject and with the same print_z. const std::vector &layers, const LayerTools &layer_tools, + const bool last_layer, // Pairs of PrintObject index and its instance index. const std::vector *ordering, // If set to size_t(-1), then print all copies of all objects. @@ -2140,11 +2142,13 @@ void GCode::process_layer( // we apply spiral vase at this stage because it requires a full layer. // Just a reminder: A spiral vase mode is allowed for a single object per layer, single material print only. if (m_spiral_vase) - gcode = m_spiral_vase->process_layer(gcode); + gcode = m_spiral_vase->process_layer(std::move(gcode)); // Apply cooling logic; this may alter speeds. if (m_cooling_buffer) - gcode = m_cooling_buffer->process_layer(gcode, layer.id()); + gcode = m_cooling_buffer->process_layer(std::move(gcode), layer.id(), + // Flush the cooling buffer at each object layer or possibly at the last layer, even if it contains just supports (This should not happen). + object_layer || last_layer); #ifdef HAS_PRESSURE_EQUALIZER // Apply pressure equalization if enabled; @@ -2156,7 +2160,7 @@ void GCode::process_layer( _write(file, gcode); BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << - log_memory_info(); + log_memory_info(); } void GCode::apply_print_config(const PrintConfig &print_config) diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 1dbb153dd..483fb3dac 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -201,6 +201,7 @@ private: // Set of object & print layers of the same PrintObject and with the same print_z. const std::vector &layers, const LayerTools &layer_tools, + const bool last_layer, // Pairs of PrintObject index and its instance index. const std::vector *ordering, // If set to size_t(-1), then print all copies of all objects. diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index 3c9c62fc5..7f48aae80 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -279,11 +279,24 @@ finished: return new_feedrate; } -std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id) +std::string CoolingBuffer::process_layer(std::string &&gcode, size_t layer_id, bool flush) { - std::vector per_extruder_adjustments = this->parse_layer_gcode(gcode, m_current_pos); - float layer_time_stretched = this->calculate_layer_slowdown(per_extruder_adjustments); - return this->apply_layer_cooldown(gcode, layer_id, layer_time_stretched, per_extruder_adjustments); + // Cache the input G-code. + if (m_gcode.empty()) + m_gcode = std::move(gcode); + else + m_gcode += gcode; + + std::string out; + if (flush) { + // This is either an object layer or the very last print layer. Calculate cool down over the collected support layers + // and one object layer. + std::vector per_extruder_adjustments = this->parse_layer_gcode(m_gcode, m_current_pos); + float layer_time_stretched = this->calculate_layer_slowdown(per_extruder_adjustments); + out = this->apply_layer_cooldown(m_gcode, layer_id, layer_time_stretched, per_extruder_adjustments); + m_gcode.clear(); + } + return out; } // Parse the layer G-code for the moves, which could be adjusted. diff --git a/src/libslic3r/GCode/CoolingBuffer.hpp b/src/libslic3r/GCode/CoolingBuffer.hpp index b0c35ecc5..0932d62d3 100644 --- a/src/libslic3r/GCode/CoolingBuffer.hpp +++ b/src/libslic3r/GCode/CoolingBuffer.hpp @@ -25,7 +25,7 @@ public: CoolingBuffer(GCode &gcodegen); void reset(); void set_current_extruder(unsigned int extruder_id) { m_current_extruder = extruder_id; } - std::string process_layer(const std::string &gcode, size_t layer_id); + std::string process_layer(std::string &&gcode, size_t layer_id, bool flush); GCode* gcodegen() { return &m_gcodegen; } private: @@ -37,6 +37,7 @@ private: std::string apply_layer_cooldown(const std::string &gcode, size_t layer_id, float layer_time, std::vector &per_extruder_adjustments); GCode& m_gcodegen; + // G-code snippet cached for the support layers preceding an object layer. std::string m_gcode; // Internal data. // X,Y,Z,E,F