From 9f9cbb46f9415b052db9de0f22ee08ba475c418b Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 9 Aug 2021 17:37:25 +0200 Subject: [PATCH] Suppor of "No extrusion" firmware flavor by not emitting the E axis. Fix of https://github.com/prusa3d/PrusaSlicer/issues/6023 The fix is partial: No extrusions are shown by the final G-code preview. --- src/libslic3r/GCode.cpp | 4 +++- src/libslic3r/GCodeReader.cpp | 21 ++++++++++++++++----- src/libslic3r/GCodeReader.hpp | 3 ++- src/libslic3r/GCodeWriter.cpp | 16 ++++++++++------ src/libslic3r/GCodeWriter.hpp | 1 + 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 9e74d217d2..abdbafd31f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2714,7 +2714,9 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // calculate extrusion length per distance unit double e_per_mm = m_writer.extruder()->e_per_mm3() * path.mm3_per_mm; - if (m_writer.extrusion_axis().empty()) e_per_mm = 0; + if (m_writer.extrusion_axis().empty()) + // gcfNoExtrusion + e_per_mm = 0; // set speed if (speed == -1) { diff --git a/src/libslic3r/GCodeReader.cpp b/src/libslic3r/GCodeReader.cpp index 3c76e05c78..7dc3c9a8ac 100644 --- a/src/libslic3r/GCodeReader.cpp +++ b/src/libslic3r/GCodeReader.cpp @@ -12,16 +12,24 @@ namespace Slic3r { +static inline char get_extrusion_axis_char(const GCodeConfig &config) +{ + std::string axis = get_extrusion_axis(config); + assert(axis.size() <= 1); + // Return 0 for gcfNoExtrusion + return axis.empty() ? 0 : axis[0]; +} + void GCodeReader::apply_config(const GCodeConfig &config) { m_config = config; - m_extrusion_axis = get_extrusion_axis(m_config)[0]; + m_extrusion_axis = get_extrusion_axis_char(m_config); } void GCodeReader::apply_config(const DynamicPrintConfig &config) { m_config.apply(config, true); - m_extrusion_axis = get_extrusion_axis(m_config)[0]; + m_extrusion_axis = get_extrusion_axis_char(m_config); } const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair &command) @@ -52,9 +60,10 @@ const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, case 'Z': axis = Z; break; case 'F': axis = F; break; default: - if (*c == m_extrusion_axis) - axis = E; - else if (*c >= 'A' && *c <= 'Z') + if (*c == m_extrusion_axis) { + if (m_extrusion_axis != 0) + axis = E; + } else if (*c >= 'A' && *c <= 'Z') // Unknown axis, but we still want to remember that such a axis was seen. axis = UNKNOWN_AXIS; break; @@ -190,6 +199,8 @@ void GCodeReader::GCodeLine::set(const GCodeReader &reader, const Axis axis, con match[1] = 'F'; else { assert(axis == E); + // Extruder axis is set. + assert(reader.extrusion_axis() != 0); match[1] = reader.extrusion_axis(); } diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index ad9b7195a8..6b58608e61 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -122,8 +122,9 @@ public: float& f() { return m_position[F]; } float f() const { return m_position[F]; } + // Returns 0 for gcfNoExtrusion. char extrusion_axis() const { return m_extrusion_axis; } - void set_extrusion_axis(char axis) { m_extrusion_axis = axis; } +// void set_extrusion_axis(char axis) { m_extrusion_axis = axis; } private: const char* parse_line_internal(const char *ptr, GCodeLine &gline, std::pair &command); diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index bbb45c96d0..24549fd895 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -405,8 +405,10 @@ std::string GCodeWriter::extrude_to_xy(const Vec2d &point, double dE, const std: std::ostringstream gcode; gcode << "G1 X" << XYZF_NUM(point(0)) - << " Y" << XYZF_NUM(point(1)) - << " " << m_extrusion_axis << E_NUM(m_extruder->E()); + << " Y" << XYZF_NUM(point(1)); + if (! m_extrusion_axis.empty()) + // not gcfNoExtrusion + gcode << " " << m_extrusion_axis << E_NUM(m_extruder->E()); COMMENT(comment); gcode << "\n"; return gcode.str(); @@ -421,8 +423,10 @@ std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std std::ostringstream gcode; gcode << "G1 X" << XYZF_NUM(point(0)) << " Y" << XYZF_NUM(point(1)) - << " Z" << XYZF_NUM(point(2)) - << " " << m_extrusion_axis << E_NUM(m_extruder->E()); + << " Z" << XYZF_NUM(point(2)); + if (! m_extrusion_axis.empty()) + // not gcfNoExtrusion + gcode << " " << m_extrusion_axis << E_NUM(m_extruder->E()); COMMENT(comment); gcode << "\n"; return gcode.str(); @@ -474,7 +478,7 @@ std::string GCodeWriter::_retract(double length, double restart_extra, const std gcode << "G22 ; retract\n"; else gcode << "G10 ; retract\n"; - } else { + } else if (! m_extrusion_axis.empty()) { gcode << "G1 " << m_extrusion_axis << E_NUM(m_extruder->E()) << " F" << XYZF_NUM(m_extruder->retract_speed() * 60.); COMMENT(comment); @@ -503,7 +507,7 @@ std::string GCodeWriter::unretract() else gcode << "G11 ; unretract\n"; gcode << this->reset_e(); - } else { + } else if (! m_extrusion_axis.empty()) { // use G1 instead of G0 because G0 will blend the restart with the previous travel move gcode << "G1 " << m_extrusion_axis << E_NUM(m_extruder->E()) << " F" << XYZF_NUM(m_extruder->deretract_speed() * 60.); diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 3a57c8bd29..2de95ecc5b 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -25,6 +25,7 @@ public: Extruder* extruder() { return m_extruder; } const Extruder* extruder() const { return m_extruder; } + // Returns empty string for gcfNoExtrusion. std::string extrusion_axis() const { return m_extrusion_axis; } void apply_print_config(const PrintConfig &print_config); // Extruders are expected to be sorted in an increasing order.