From 2adea5b08d0a2f19352d414b98f2d5fbd9873993 Mon Sep 17 00:00:00 2001 From: supermerill Date: Wed, 4 Nov 2020 00:51:07 +0100 Subject: [PATCH] #439 add support layer time to next object layer time if unsynchronized and don't slowdown support layers if unsynchronized and add half of time diff with previous layer to prevent spikes --- src/libslic3r/GCode.cpp | 2 +- src/libslic3r/GCode/CoolingBuffer.cpp | 51 +++++++++++++++++++++++---- src/libslic3r/GCode/CoolingBuffer.hpp | 9 ++++- 3 files changed, 53 insertions(+), 9 deletions(-) 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; };