From 9fe42ecbdc7927aec643d7a9449b42ffbb7a2af8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 18 Jul 2023 15:23:40 +0200 Subject: [PATCH] Method GCodeProcessor::process_G2_G3() modified to process lines G2/G3 R --- src/libslic3r/GCode/GCodeProcessor.cpp | 44 +++++++++++++++++++------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index c8485a319c..e654d88f93 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -6,6 +6,7 @@ #include "libslic3r/I18N.hpp" #include "libslic3r/GCode/GCodeWriter.hpp" #include "libslic3r/I18N.hpp" +#include "libslic3r/Geometry/ArcWelder.hpp" #include "GCodeProcessor.hpp" #include @@ -2698,13 +2699,39 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise) { - if (!line.has('I') || !line.has('J')) + enum class EFitting { None, IJ, R }; + const EFitting fitting = line.has('R') ? EFitting::R : (line.has('I') && line.has('J')) ? EFitting::IJ : EFitting::None; + + if (fitting == EFitting::None) return; + const float filament_diameter = (static_cast(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back(); + const float filament_radius = 0.5f * filament_diameter; + const float area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); + + AxisCoords end_position = m_start_position; + for (unsigned char a = X; a <= E; ++a) { + end_position[a] = extract_absolute_position_on_axis((Axis)a, line, double(area_filament_cross_section)); + } + // relative center Vec3f rel_center = Vec3f::Zero(); - if (!line.has_value('I', rel_center.x()) || !line.has_value('J', rel_center.y())) - return; + double radius = 0.0; + if (fitting == EFitting::R) { + float r; + if (!line.has_value('R', r) || r == 0.0f) + return; + radius = (double)std::abs(r); + const Vec2f start_pos((float)m_start_position[X], (float)m_start_position[Y]); + const Vec2f end_pos((float)end_position[X], (float)end_position[Y]); + const Vec2f c = Geometry::ArcWelder::arc_center(start_pos, end_pos, r, !clockwise); + rel_center.x() = c.x() - m_start_position[X]; + 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())) + return; + } // scale center, if needed if (m_units == EUnits::Inches) @@ -2740,15 +2767,6 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc // arc center arc.center = arc.start + rel_center.cast(); - const float filament_diameter = (static_cast(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back(); - const float filament_radius = 0.5f * filament_diameter; - const float area_filament_cross_section = static_cast(M_PI) * sqr(filament_radius); - - AxisCoords end_position = m_start_position; - for (unsigned char a = X; a <= E; ++a) { - end_position[a] = extract_absolute_position_on_axis((Axis)a, line, double(area_filament_cross_section)); - } - // arc end endpoint arc.end = Vec3d(end_position[X], end_position[Y], end_position[Z]); @@ -2757,6 +2775,8 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool cloc // what to do ??? } + assert(fitting != EFitting::R || std::abs(radius - arc.start_radius()) < EPSILON); + // updates feedrate from line std::optional feedrate; if (line.has_f())