From 0ad4e9d51f3171d68efea5249f1831b749ea97c8 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 30 Jun 2017 20:01:32 +0200 Subject: [PATCH] Refactored the cooling buffer: Removed ElapsedTime. --- xs/src/libslic3r/GCode.cpp | 26 ------------- xs/src/libslic3r/GCode/CoolingBuffer.cpp | 33 ++++++++-------- xs/src/libslic3r/GCode/CoolingBuffer.hpp | 48 ------------------------ xs/src/libslic3r/GCodeWriter.cpp | 9 ----- xs/src/libslic3r/GCodeWriter.hpp | 8 +--- 5 files changed, 19 insertions(+), 105 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 635a017eb..fd286d4ae 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -168,11 +168,6 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T // Let the m_writer know the current extruder_id, but ignore the generated G-code. if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id)) gcodegen.writer().toolchange(new_extruder_id); - // Accumulate the elapsed time for the correct calculation of layer cooling. - //FIXME currently disabled as Slic3r PE needs to be updated to differentiate the moves it could slow down - // from the moves it could not. - gcodegen.writer().elapsed_time()->total += tcr.elapsed_time; - gcodegen.writer().elapsed_time()->other += tcr.elapsed_time; // A phony move to the end position at the wipe tower. gcodegen.writer().travel_to_xy(Pointf(tcr.end_pos.x, tcr.end_pos.y)); gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos)); @@ -1868,24 +1863,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, gcode += is_bridge(path.role()) ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n"; this->set_last_pos(path.last_point()); - - if (m_config.cooling.values.front()) { - float t = float(path_length / F * 60); - m_writer.elapsed_time()->total += t; - assert(! (is_bridge(path.role()) && path.role() == erExternalPerimeter)); - if (is_bridge(path.role())) - m_writer.elapsed_time()->bridges += t; - else { - // Maximum print time of this extrusion, respecting the min_print_speed. - float t_max = std::max(t, float(path_length / std::max(0.1, EXTRUDER_CONFIG(min_print_speed)))); - if (path.role() == erExternalPerimeter) - m_writer.elapsed_time()->external_perimeters += t; - else - m_writer.elapsed_time()->max_stretch_time_no_ext_perimetes += t_max; - m_writer.elapsed_time()->max_stretch_time_total += t_max; - } - } - return gcode; } @@ -1931,9 +1908,6 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) gcode += m_writer.travel_to_xy(this->point_to_gcode(line->b), comment); - if (m_config.cooling.values.front()) - m_writer.elapsed_time()->travel += unscale(travel.length()) / m_config.get_abs_value("travel_speed"); - return gcode; } diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.cpp b/xs/src/libslic3r/GCode/CoolingBuffer.cpp index e5ea38fcb..08d5daa7f 100644 --- a/xs/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/xs/src/libslic3r/GCode/CoolingBuffer.cpp @@ -34,13 +34,13 @@ void CoolingBuffer::reset() std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id) { - const FullPrintConfig &config = m_gcodegen.config(); - const auto &elapsed_times = m_gcodegen.writer().elapsed_times(); - const size_t num_extruders = elapsed_times.size(); + const FullPrintConfig &config = m_gcodegen.config(); + const std::vector &extruders = m_gcodegen.writer().extruders(); + const size_t num_extruders = extruders.size(); // Calculate the required per extruder time stretches. struct Adjustment { - Adjustment() {} + Adjustment(unsigned int extruder_id = 0) : extruder_id(extruder_id) {} // Calculate the total elapsed time per this extruder, adjusted for the slowdown. float elapsed_time_total() { float time_total = 0.f; @@ -94,6 +94,8 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_ return time_total; } + bool operator<(const Adjustment &rhs) const { return this->extruder_id < rhs.extruder_id; } + struct Line { enum Type { @@ -135,16 +137,19 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_ bool slowdown; }; + // Extruder, for which the G-code will be adjusted. + unsigned int extruder_id; // Parsed lines. std::vector lines; }; std::vector adjustments(num_extruders, Adjustment()); + for (size_t i = 0; i < num_extruders; ++ i) + adjustments[i].extruder_id = extruders[i].id(); const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix(); // Parse the layer G-code for the moves, which could be adjusted. { float min_print_speed = float(EXTRUDER_CONFIG(min_print_speed)); - auto it_elapsed_time = std::lower_bound(elapsed_times.begin(), elapsed_times.end(), ElapsedTime(m_current_extruder)); - Adjustment *adjustment = &adjustments[it_elapsed_time - elapsed_times.begin()]; + auto adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder)); unsigned int initial_extruder = m_current_extruder; const char *line_start = gcode.c_str(); const char *line_end = line_start; @@ -242,8 +247,7 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_ if (new_extruder != m_current_extruder) { m_current_extruder = new_extruder; min_print_speed = float(EXTRUDER_CONFIG(min_print_speed)); - it_elapsed_time = std::lower_bound(elapsed_times.begin(), elapsed_times.end(), ElapsedTime(m_current_extruder)); - adjustment = &adjustments[it_elapsed_time - elapsed_times.begin()]; + adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder)); } } else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) { line.type = Adjustment::Line::TYPE_BRIDGE_FAN_START; @@ -273,15 +277,15 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_ // Collect total print time of non-adjustable extruders. float elapsed_time_total_non_adjustable = 0.f; for (size_t i = 0; i < num_extruders; ++ i) { - if (config.cooling.get_at(elapsed_times[i].extruder_id)) + if (config.cooling.get_at(extruders[i].id())) by_slowdown_layer_time.emplace_back(i); else elapsed_time_total_non_adjustable += adjustments[i].elapsed_time_total(); } std::sort(by_slowdown_layer_time.begin(), by_slowdown_layer_time.end(), - [&config, &elapsed_times](const size_t idx1, const size_t idx2){ - return config.slowdown_below_layer_time.get_at(elapsed_times[idx1].extruder_id) < - config.slowdown_below_layer_time.get_at(elapsed_times[idx2].extruder_id); + [&config, &extruders](const size_t idx1, const size_t idx2){ + return config.slowdown_below_layer_time.get_at(extruders[idx1].id()) < + config.slowdown_below_layer_time.get_at(extruders[idx2].id()); }); // Elapsed time after adjustment. @@ -290,7 +294,7 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_ // Elapsed time for the already adjusted extruders. float elapsed_time_total0 = elapsed_time_total_non_adjustable; for (size_t i_by_slowdown_layer_time = 0; i_by_slowdown_layer_time < by_slowdown_layer_time.size(); ++ i_by_slowdown_layer_time) { - // Idx in elapsed_times and adjustments. + // Idx in adjustments. size_t idx = by_slowdown_layer_time[i_by_slowdown_layer_time]; // Macro to sum or adjust all sections starting with i_by_slowdown_layer_time. #define FORALL_UNPROCESSED(ACCUMULATOR, ACTION) \ @@ -300,7 +304,7 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_ // Calculate the current adjusted elapsed_time_total over the non-finalized extruders. float total; FORALL_UNPROCESSED(total, elapsed_time_total()); - float slowdown_below_layer_time = float(config.slowdown_below_layer_time.get_at(elapsed_times[idx].extruder_id)) * 1.001f; + float slowdown_below_layer_time = float(config.slowdown_below_layer_time.get_at(adjustments[idx].extruder_id)) * 1.001f; if (total > slowdown_below_layer_time) { // The current total time is above the minimum threshold of the rest of the extruders, don't adjust anything. } else { @@ -462,7 +466,6 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_ if (pos < gcode.size()) new_gcode.append(gcode.c_str() + pos, gcode.size() - pos); - m_gcodegen.writer().reset_elapsed_times(); return new_gcode; } diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.hpp b/xs/src/libslic3r/GCode/CoolingBuffer.hpp index baabf597b..f85c470b3 100644 --- a/xs/src/libslic3r/GCode/CoolingBuffer.hpp +++ b/xs/src/libslic3r/GCode/CoolingBuffer.hpp @@ -10,54 +10,6 @@ namespace Slic3r { class GCode; class Layer; -struct ElapsedTime -{ - ElapsedTime(unsigned int extruder_id = 0) : extruder_id(extruder_id) { this->reset(); } - void reset() { - total = bridges = external_perimeters = travel = other = 0.f; - max_stretch_time_total = max_stretch_time_no_ext_perimetes = 0.f; - } - - ElapsedTime& operator+=(const ElapsedTime &rhs) { - this->total += rhs.total; - this->bridges += rhs.bridges; - this->external_perimeters += rhs.external_perimeters; - this->travel += rhs.travel; - this->other += rhs.other; - this->max_stretch_time_total += rhs.max_stretch_time_total; - this->max_stretch_time_no_ext_perimetes += rhs.max_stretch_time_no_ext_perimetes; - return *this; - } - - // Potion of the total time, which cannot be stretched to heed the minimum layer print time. - float non_stretchable(bool stretch_external_perimeters = true) const - { return this->bridges + this->travel + this->other + (stretch_external_perimeters ? 0.f : this->external_perimeters); } - // Potion of the total time, which could be stretched to heed the minimum layer print time. - float stretchable(bool stretch_external_perimeters = true) const - { return this->total - this->non_stretchable(stretch_external_perimeters); } - - // For which extruder ID has this statistics been collected? - unsigned int extruder_id; - // Total time. - float total; - // Per feature time slices. - float bridges; - float external_perimeters; - float travel; - float other; - // Per feature maximum time, to which the extrusion could be stretched to respect the extruder specific min_print_speed. - // Maximum stretch time, to which the time this->stretchable() could be extended. - float max_stretch_time_total; - // Maximum stretch time, to which the time (this->stretchable() - external_perimeters) could be extended. - float max_stretch_time_no_ext_perimetes; -}; - -// Sort ElapsedTime objects by the extruder id by default. -inline bool operator==(const ElapsedTime &e1, const ElapsedTime &e2) { return e1.extruder_id == e2.extruder_id; } -inline bool operator!=(const ElapsedTime &e1, const ElapsedTime &e2) { return e1.extruder_id != e2.extruder_id; } -inline bool operator< (const ElapsedTime &e1, const ElapsedTime &e2) { return e1.extruder_id < e2.extruder_id; } -inline bool operator> (const ElapsedTime &e1, const ElapsedTime &e2) { return e1.extruder_id > e2.extruder_id; } - /* A standalone G-code filter, to control cooling of the print. The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited diff --git a/xs/src/libslic3r/GCodeWriter.cpp b/xs/src/libslic3r/GCodeWriter.cpp index fa8fbd208..40500d084 100644 --- a/xs/src/libslic3r/GCodeWriter.cpp +++ b/xs/src/libslic3r/GCodeWriter.cpp @@ -26,11 +26,6 @@ void GCodeWriter::set_extruders(const std::vector &extruder_ids) m_extruders.reserve(extruder_ids.size()); for (unsigned int extruder_id : extruder_ids) m_extruders.emplace_back(Extruder(extruder_id, &this->config)); - - m_elapsed_times.clear(); - m_elapsed_times.reserve(extruder_ids.size()); - for (unsigned int extruder_id : extruder_ids) - m_elapsed_times.emplace_back(ElapsedTime(extruder_id)); /* we enable support for multiple extruder if any extruder greater than 0 is used (even if prints only uses that one) since we need to output Tx commands @@ -249,10 +244,6 @@ std::string GCodeWriter::toolchange(unsigned int extruder_id) assert(it_extruder != m_extruders.end()); m_extruder = const_cast(&*it_extruder); - auto it_elapsed_time = std::lower_bound(m_elapsed_times.begin(), m_elapsed_times.end(), ElapsedTime(extruder_id)); - assert(it_elapsed_time != m_elapsed_times.end()); - m_elapsed_time = const_cast(&*it_elapsed_time); - // return the toolchange command // if we are running a single-extruder setup, just set the extruder and return nothing std::ostringstream gcode; diff --git a/xs/src/libslic3r/GCodeWriter.hpp b/xs/src/libslic3r/GCodeWriter.hpp index f31d20245..78e9c9323 100644 --- a/xs/src/libslic3r/GCodeWriter.hpp +++ b/xs/src/libslic3r/GCodeWriter.hpp @@ -16,7 +16,7 @@ public: bool multiple_extruders; GCodeWriter() : - multiple_extruders(false), m_extrusion_axis("E"), m_extruder(nullptr), m_elapsed_time(nullptr), + multiple_extruders(false), m_extrusion_axis("E"), m_extruder(nullptr), m_single_extruder_multi_material(false), m_last_acceleration(0), m_last_fan_speed(0), m_last_bed_temperature(0), m_last_bed_temperature_reached(true), @@ -24,10 +24,6 @@ public: {} Extruder* extruder() { return m_extruder; } const Extruder* extruder() const { return m_extruder; } - ElapsedTime* elapsed_time() { return m_elapsed_time; } - const ElapsedTime* elapsed_time() const { return m_elapsed_time; } - const std::vector& elapsed_times() const { return m_elapsed_times; } - void reset_elapsed_times() { for (auto &et : m_elapsed_times) et.reset(); } std::string extrusion_axis() const { return m_extrusion_axis; } void apply_print_config(const PrintConfig &print_config); @@ -74,11 +70,9 @@ public: private: std::vector m_extruders; - std::vector m_elapsed_times; std::string m_extrusion_axis; bool m_single_extruder_multi_material; Extruder* m_extruder; - ElapsedTime* m_elapsed_time; unsigned int m_last_acceleration; unsigned int m_last_fan_speed; unsigned int m_last_bed_temperature;