ArcWelder: Hot fix for producing extremely short arches, that get

quantized to zero length by the G-code export.
This commit is contained in:
Vojtech Bubnik 2023-09-19 13:53:38 +02:00
parent 361ef22b6d
commit 9824d0e4cc

View File

@ -3074,46 +3074,49 @@ std::string GCodeGenerator::_extrude(
auto end = path.end(); auto end = path.end();
const bool emit_radius = m_config.arc_fitting == ArcFittingType::EmitRadius; const bool emit_radius = m_config.arc_fitting == ArcFittingType::EmitRadius;
for (++ it; it != end; ++ it) { for (++ it; it != end; ++ it) {
Vec2d p = this->point_to_gcode_quantized(it->point); 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. assert(p != prev);
double radius = 0; if (p != prev) {
Vec2d ij; // Center of the radius to be emitted into the G-code: Either by radius or by center offset.
if (it->radius != 0) { double radius = 0;
// Extrude an arc. Vec2d ij;
assert(m_config.arc_fitting == ArcFittingType::EmitCenter || if (it->radius != 0) {
m_config.arc_fitting == ArcFittingType::EmitRadius); // Extrude an arc.
radius = unscaled<double>(it->radius); assert(m_config.arc_fitting == ArcFittingType::EmitCenter ||
if (emit_radius) { m_config.arc_fitting == ArcFittingType::EmitRadius);
// Only quantize radius if emitting it directly into G-code. Otherwise use the exact radius for calculating the IJ values. radius = unscaled<double>(it->radius);
radius = GCodeFormatter::quantize_xyzf(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<double>(), p.cast<double>(), 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 { } else {
// Calculate quantized IJ circle center offset. double angle = Geometry::ArcWelder::arc_angle(prev.cast<double>(), p.cast<double>(), double(radius));
ij = GCodeFormatter::quantize(Vec2d( assert(angle > 0);
Geometry::ArcWelder::arc_center(prev.cast<double>(), p.cast<double>(), double(radius), it->ccw()) const double line_length = angle * std::abs(radius);
- 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; 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 { prev = p;
double angle = Geometry::ArcWelder::arc_angle(prev.cast<double>(), p.cast<double>(), 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;
} }
if (m_enable_cooling_markers) if (m_enable_cooling_markers)