diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 9504860944..6baee30403 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1,9 +1,8 @@ -///|/ Copyright (c) Prusa Research 2020 - 2023 Enrico Turri @enricoturri1966, Vojtěch Bubník @bubnikv, Pavel Mikuš @Godrak, Lukáš Matěna @lukasmatena, Filip Sykala @Jony01, Oleksandra Iushchenko @YuSanka -///|/ Copyright (c) SuperSlicer 2023 Remi Durand @supermerill -///|/ -///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher -///|/ -#include "libslic3r/libslic3r.h" +///|/ Copyright (c) Prusa Research 2020 - 2023 Enrico Turri @enricoturri1966, Vojtěch Bubník @bubnikv, Pavel Mikuš @Godrak, Lukáš Matěna @lukasmatena, Filip Sykala @Jony01, Oleksandra Iushchenko @YuSanka +///|/ Copyright (c) SuperSlicer 2023 Remi Durand @supermerill +///|/ +///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher +///|/#include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" #include "libslic3r/Print.hpp" #include "libslic3r/LocalesUtils.hpp" @@ -2888,7 +2887,17 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise) { enum class EFitting { None, IJ, R }; - const EFitting fitting = line.has('R') ? EFitting::R : (line.has('I') && line.has('J')) ? EFitting::IJ : EFitting::None; + const char *axis_pos_I = nullptr; + const char *axis_pos_J = nullptr; + EFitting fitting = EFitting::None; + if (line.has('R')) { + fitting = EFitting::R; + } else { + axis_pos_I = line.axis_pos('I'); + axis_pos_J = line.axis_pos('J'); + if (axis_pos_I || axis_pos_J) + fitting = EFitting::IJ; + } if (fitting == EFitting::None) return; @@ -2921,7 +2930,10 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc rel_center.y() = c.y() - m_start_position[Y]; } else { - if (!line.has_value('I', rel_center.x()) || !line.has_value('J', rel_center.y())) + assert(fitting == EFitting::IJ); + if (axis_pos_I && ! line.has_value(axis_pos_I, rel_center.x())) + return; + if (axis_pos_J && ! line.has_value(axis_pos_J, rel_center.y())) return; } diff --git a/src/libslic3r/GCodeReader.cpp b/src/libslic3r/GCodeReader.cpp index 8938d3e22b..ed10f0de8c 100644 --- a/src/libslic3r/GCodeReader.cpp +++ b/src/libslic3r/GCodeReader.cpp @@ -237,42 +237,54 @@ const char* GCodeReader::axis_pos(const char *raw_str, char axis) bool GCodeReader::GCodeLine::has(char axis) const { - const char *c = axis_pos(m_raw.c_str(), axis); - return c != nullptr; + return this->axis_pos(axis); +} + +const char* GCodeReader::GCodeLine::axis_pos(char axis) const +{ + return GCodeReader::axis_pos(this->raw().c_str(), axis); +} + +static bool GCodeReader::GCodeLine::has_value(const char *axis_pos, float &value) +{ + if (const char *c = axis_pos; c) { + // Try to parse the numeric value. + double v = 0.; + const char *end = m_raw.c_str() + m_raw.size(); + auto [pend, ec] = fast_float::from_chars(++ c, end, v); + if (pend != c && is_end_of_word(*pend)) { + // The axis value has been parsed correctly. + value = float(v); + return true; + } + } + return false; } bool GCodeReader::GCodeLine::has_value(char axis, float &value) const { assert(is_decimal_separator_point()); - const char *c = axis_pos(m_raw.c_str(), axis); - if (c == nullptr) - return false; - // Try to parse the numeric value. - double v = 0.; - const char* end = m_raw.c_str() + m_raw.size(); - auto [pend, ec] = fast_float::from_chars(++c, end, v); - if (pend != c && is_end_of_word(*pend)) { - // The axis value has been parsed correctly. - value = float(v); - return true; + return this->has_value(this->axis_pos(axis), value); +} + +static bool GCodeReader::GCodeLine::has_value(const char *axis_pos, int &value) +{ + if (const char *c = axis_pos; c) { + // Try to parse the numeric value. + char *pend = nullptr; + long v = strtol(++ c, &pend, 10); + if (pend != nullptr && is_end_of_word(*pend)) { + // The axis value has been parsed correctly. + value = int(v); + return true; + } } return false; } bool GCodeReader::GCodeLine::has_value(char axis, int &value) const { - const char *c = axis_pos(m_raw.c_str(), axis); - if (c == nullptr) - return false; - // Try to parse the numeric value. - char *pend = nullptr; - long v = strtol(++ c, &pend, 10); - if (pend != nullptr && is_end_of_word(*pend)) { - // The axis value has been parsed correctly. - value = int(v); - return true; - } - return false; + return this->has_value(this->axis_pos(axis), value); } void GCodeReader::GCodeLine::set(const GCodeReader &reader, const Axis axis, const float new_value, const int decimal_digits) diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index 1207f03912..0919043f44 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -30,11 +30,16 @@ public: const std::string_view comment() const { size_t pos = m_raw.find(';'); return (pos == std::string::npos) ? std::string_view() : std::string_view(m_raw).substr(pos + 1); } + // Return position in this->raw() string starting with the "axis" character. + const char* axis_pos(char axis) const; bool has(Axis axis) const { return (m_mask & (1 << int(axis))) != 0; } float value(Axis axis) const { return m_axis[axis]; } bool has(char axis) const; bool has_value(char axis, float &value) const; bool has_value(char axis, int &value) const; + // Parse value of an axis from raw string starting at axis_pos. + static bool has_value(const char *axis_pos, float &value); + static bool has_value(const char *axis_pos, int &value); float new_X(const GCodeReader &reader) const { return this->has(X) ? this->x() : reader.x(); } float new_Y(const GCodeReader &reader) const { return this->has(Y) ? this->y() : reader.y(); } float new_Z(const GCodeReader &reader) const { return this->has(Z) ? this->z() : reader.z(); }