diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 1e17f8395d..5afe6b34c4 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3074,46 +3074,49 @@ std::string GCodeGenerator::_extrude( auto end = path.end(); const bool emit_radius = m_config.arc_fitting == ArcFittingType::EmitRadius; for (++ it; it != end; ++ it) { - Vec2d p = this->point_to_gcode_quantized(it->point); - // Center of the radius to be emitted into the G-code: Either by radius or by center offset. - double radius = 0; - Vec2d ij; - if (it->radius != 0) { - // Extrude an arc. - assert(m_config.arc_fitting == ArcFittingType::EmitCenter || - m_config.arc_fitting == ArcFittingType::EmitRadius); - radius = unscaled(it->radius); - if (emit_radius) { - // Only quantize radius if emitting it directly into G-code. Otherwise use the exact radius for calculating the IJ values. - radius = GCodeFormatter::quantize_xyzf(radius); + Vec2d p = this->point_to_gcode_quantized(it->point); + assert(p != prev); + if (p != prev) { + // Center of the radius to be emitted into the G-code: Either by radius or by center offset. + double radius = 0; + Vec2d ij; + if (it->radius != 0) { + // Extrude an arc. + assert(m_config.arc_fitting == ArcFittingType::EmitCenter || + m_config.arc_fitting == ArcFittingType::EmitRadius); + radius = unscaled(it->radius); + if (emit_radius) { + // Only quantize radius if emitting it directly into G-code. Otherwise use the exact radius for calculating the IJ values. + radius = GCodeFormatter::quantize_xyzf(radius); + } else { + // Calculate quantized IJ circle center offset. + ij = GCodeFormatter::quantize(Vec2d( + Geometry::ArcWelder::arc_center(prev.cast(), p.cast(), double(radius), it->ccw()) + - prev)); + if (ij == Vec2d::Zero()) + // Don't extrude a degenerated circle. + radius = 0; + } + } + if (radius == 0) { + // Extrude line segment. + if (const double line_length = (p - prev).norm(); line_length > 0) { + path_length += line_length; + gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length, comment); + } } else { - // Calculate quantized IJ circle center offset. - ij = GCodeFormatter::quantize(Vec2d( - Geometry::ArcWelder::arc_center(prev.cast(), p.cast(), double(radius), it->ccw()) - - prev)); - if (ij == Vec2d::Zero()) - // Don't extrude a degenerated circle. - radius = 0; - } - } - if (radius == 0) { - // Extrude line segment. - if (const double line_length = (p - prev).norm(); line_length > 0) { + double angle = Geometry::ArcWelder::arc_angle(prev.cast(), p.cast(), double(radius)); + assert(angle > 0); + const double line_length = angle * std::abs(radius); path_length += line_length; - gcode += m_writer.extrude_to_xy(p, e_per_mm * line_length, comment); + const double dE = e_per_mm * line_length; + assert(dE > 0); + gcode += emit_radius ? + m_writer.extrude_to_xy_G2G3R(p, radius, it->ccw(), dE, comment) : + m_writer.extrude_to_xy_G2G3IJ(p, ij, it->ccw(), dE, comment); } - } else { - double angle = Geometry::ArcWelder::arc_angle(prev.cast(), p.cast(), double(radius)); - assert(angle > 0); - const double line_length = angle * std::abs(radius); - path_length += line_length; - const double dE = e_per_mm * line_length; - assert(dE > 0); - gcode += emit_radius ? - m_writer.extrude_to_xy_G2G3R(p, radius, it->ccw(), dE, comment) : - m_writer.extrude_to_xy_G2G3IJ(p, ij, it->ccw(), dE, comment); + prev = p; } - prev = p; } if (m_enable_cooling_markers)