diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 17af0da28..a731cd12e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2825,7 +2825,7 @@ void GCode::process_layer( // 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(gcode, layer.id(), (support_layer != nullptr && object_layer == nullptr)); #if !ENABLE_GCODE_VIEWER // add tag for analyzer diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index 4afe65389..6af7f0b2b 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -88,7 +88,7 @@ struct PerExtruderAdjustments { // Calculate the total elapsed time per this extruder, adjusted for the slowdown. float elapsed_time_total() const { - float time_total = 0.f; + float time_total = time_support; for (const CoolingLine &line : lines) time_total += line.time; return time_total; @@ -96,7 +96,7 @@ struct PerExtruderAdjustments // Calculate the total elapsed time when slowing down // to the minimum extrusion feed rate defined for the current material. float maximum_time_after_slowdown(bool slowdown_external_perimeters) const { - float time_total = 0.f; + float time_total = time_support; for (const CoolingLine &line : lines) if (line.adjustable(slowdown_external_perimeters)) { if (line.time_max == FLT_MAX) @@ -117,7 +117,7 @@ struct PerExtruderAdjustments } // Calculate the non-adjustable part of the total time. float non_adjustable_time(bool slowdown_external_perimeters) const { - float time_total = 0.f; + float time_total = time_support; for (const CoolingLine &line : lines) if (! line.adjustable(slowdown_external_perimeters)) time_total += line.time; @@ -126,7 +126,7 @@ struct PerExtruderAdjustments // Slow down the adjustable extrusions to the minimum feedrate allowed for the current extruder material. // Used by both proportional and non-proportional slow down. float slowdown_to_minimum_feedrate(bool slowdown_external_perimeters) { - float time_total = 0.f; + float time_total = time_support; for (CoolingLine &line : lines) { if (line.adjustable(slowdown_external_perimeters)) { assert(line.time_max >= 0.f && line.time_max < FLT_MAX); @@ -142,7 +142,7 @@ struct PerExtruderAdjustments // Used by the proportional slow down. float slow_down_proportional(float factor, bool slowdown_external_perimeters) { assert(factor >= 1.f); - float time_total = 0.f; + float time_total = time_support; for (CoolingLine &line : lines) { if (line.adjustable(slowdown_external_perimeters)) { line.slowdown = true; @@ -225,7 +225,9 @@ struct PerExtruderAdjustments // Current total time for this extruder. float time_total = 0; // Maximum time for this extruder, when the maximum slow down is applied. - float time_maximum = 0; + float time_maximum = 0; + //time spent on support from the previous layer + float time_support = 0; // Temporaries for processing the slow down. Both thresholds go from 0 to n_lines_adjustable. size_t idx_line_begin = 0; @@ -289,10 +291,45 @@ finished: return new_feedrate; } -std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id) +std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id, bool is_support_only) { + auto& previous_layer_time = is_support_only ? saved_layer_time_object : saved_layer_time_support; + auto my_previous_layer_time = is_support_only ? saved_layer_time_support : saved_layer_time_object; + auto& my_layer_time = is_support_only ? saved_layer_time_support : saved_layer_time_object; std::vector per_extruder_adjustments = this->parse_layer_gcode(gcode, m_current_pos); + //save our layer time in case of unchync + my_layer_time.clear(); + for (PerExtruderAdjustments& adj : per_extruder_adjustments) { + my_layer_time[adj.extruder_id] = adj.elapsed_time_total(); + auto it = my_previous_layer_time.find(adj.extruder_id); + if (it != my_previous_layer_time.end()) { + my_previous_layer_time[adj.extruder_id] = (my_previous_layer_time[adj.extruder_id] + my_layer_time[adj.extruder_id]) / 2 - my_layer_time[adj.extruder_id]; + } else { + my_previous_layer_time[adj.extruder_id] = 0; + } + } + //add unsynch layer time + if (!previous_layer_time.empty()) { + for (PerExtruderAdjustments& adj : per_extruder_adjustments) { + auto it = previous_layer_time.find(adj.extruder_id); + if (it != previous_layer_time.end()) { + adj.time_support = it->second; + } + } + previous_layer_time.clear(); + } + //add half diff with previous one, to avoid suddent change in fan speed. + if (!my_previous_layer_time.empty()) { + for (PerExtruderAdjustments& adj : per_extruder_adjustments) { + auto it = my_previous_layer_time.find(adj.extruder_id); + if (it != my_previous_layer_time.end()) { + adj.time_support += it->second; + } + } + } + //compute slowdown float layer_time_stretched = this->calculate_layer_slowdown(per_extruder_adjustments); + //compute fans & gcode return this->apply_layer_cooldown(gcode, layer_id, layer_time_stretched, per_extruder_adjustments); } diff --git a/src/libslic3r/GCode/CoolingBuffer.hpp b/src/libslic3r/GCode/CoolingBuffer.hpp index b0c35ecc5..c89e400e5 100644 --- a/src/libslic3r/GCode/CoolingBuffer.hpp +++ b/src/libslic3r/GCode/CoolingBuffer.hpp @@ -25,7 +25,9 @@ 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); + /// process the laer :check the time and apply fan / speed change + /// append_time_only: if he layer is only support, then you can put this at true to not process the layer but just append its time to the next one. + std::string process_layer(const std::string &gcode, size_t layer_id, bool append_time_only = false); GCode* gcodegen() { return &m_gcodegen; } private: @@ -44,6 +46,11 @@ private: std::vector m_current_pos; unsigned int m_current_extruder; + //saved previous unslowed layer + std::map saved_layer_time_support; + std::map saved_layer_time_object; + + // Old logic: proportional. bool m_cooling_logic_proportional = false; };