SPE-2184: Fix traveling outside the print area during wiping with enabled arcs.

This commit is contained in:
Lukáš Hejl 2024-03-05 14:33:24 +01:00 committed by Lukas Matena
parent ea65285999
commit b1f5ef354b
5 changed files with 30 additions and 36 deletions

View File

@ -2891,7 +2891,7 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GC
if (m_wipe.enabled()) {
// Wipe will hide the seam.
m_wipe.set_path(std::move(smooth_path), false);
m_wipe.set_path(std::move(smooth_path));
} else if (loop_src.paths.back().role().is_external_perimeter() && m_layer != nullptr && m_config.perimeters.value > 1) {
// Only wipe inside if the wipe along the perimeter is disabled.
// Make a little move inwards before leaving loop.
@ -2939,7 +2939,7 @@ std::string GCodeGenerator::extrude_skirt(
if (m_wipe.enabled())
// Wipe will hide the seam.
m_wipe.set_path(std::move(smooth_path), false);
m_wipe.set_path(std::move(smooth_path));
return gcode;
}
@ -2958,7 +2958,10 @@ std::string GCodeGenerator::extrude_multi_path(const ExtrusionMultiPath &multipa
std::string gcode;
for (GCode::SmoothPathElement &el : smooth_path)
gcode += this->_extrude(el.path_attributes, el.path, description, speed);
m_wipe.set_path(std::move(smooth_path), true);
GCode::reverse(smooth_path);
m_wipe.set_path(std::move(smooth_path));
// reset acceleration
gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
return gcode;

View File

@ -133,6 +133,12 @@ double clip_end(SmoothPath &path, double distance, double min_point_distance_thr
return distance;
}
void reverse(SmoothPath &path) {
std::reverse(path.begin(), path.end());
for (SmoothPathElement &path_element : path)
Geometry::ArcWelder::reverse(path_element.path);
}
void SmoothPathCache::interpolate_add(const ExtrusionPath &path, const InterpolationParameters &params)
{
double tolerance = params.tolerance;

View File

@ -33,6 +33,8 @@ std::optional<Point> sample_path_point_at_distance_from_end(const SmoothPath &pa
// rather discard such a degenerate segment.
double clip_end(SmoothPath &path, double distance, double min_point_distance_threshold);
void reverse(SmoothPath &path);
class SmoothPathCache
{
public:

View File

@ -32,40 +32,23 @@ void Wipe::init(const PrintConfig &config, const std::vector<unsigned int> &extr
this->enable(wipe_xy);
}
void Wipe::set_path(SmoothPath &&path, bool reversed)
{
void Wipe::set_path(SmoothPath &&path) {
this->reset_path();
if (this->enabled() && ! path.empty()) {
if (coord_t wipe_len_max_scaled = scaled(m_wipe_len_max); reversed) {
m_path = std::move(path.back().path);
Geometry::ArcWelder::reverse(m_path);
int64_t len = Geometry::ArcWelder::estimate_path_length(m_path);
for (auto it = std::next(path.rbegin()); len < wipe_len_max_scaled && it != path.rend(); ++ it) {
if (it->path_attributes.role.is_bridge())
break; // Do not perform a wipe on bridges.
assert(it->path.size() >= 2);
assert(m_path.back().point == it->path.back().point);
if (m_path.back().point != it->path.back().point)
// ExtrusionMultiPath is interrupted in some place. This should not really happen.
break;
len += Geometry::ArcWelder::estimate_path_length(it->path);
m_path.insert(m_path.end(), it->path.rbegin() + 1, it->path.rend());
}
} else {
m_path = std::move(path.front().path);
int64_t len = Geometry::ArcWelder::estimate_path_length(m_path);
for (auto it = std::next(path.begin()); len < wipe_len_max_scaled && it != path.end(); ++ it) {
if (it->path_attributes.role.is_bridge())
break; // Do not perform a wipe on bridges.
assert(it->path.size() >= 2);
assert(m_path.back().point == it->path.front().point);
if (m_path.back().point != it->path.front().point)
// ExtrusionMultiPath is interrupted in some place. This should not really happen.
break;
len += Geometry::ArcWelder::estimate_path_length(it->path);
m_path.insert(m_path.end(), it->path.begin() + 1, it->path.end());
}
if (this->enabled() && !path.empty()) {
const coord_t wipe_len_max_scaled = scaled(m_wipe_len_max);
m_path = std::move(path.front().path);
int64_t len = Geometry::ArcWelder::estimate_path_length(m_path);
for (auto it = std::next(path.begin()); len < wipe_len_max_scaled && it != path.end(); ++it) {
if (it->path_attributes.role.is_bridge())
break; // Do not perform a wipe on bridges.
assert(it->path.size() >= 2);
assert(m_path.back().point == it->path.front().point);
if (m_path.back().point != it->path.front().point)
// ExtrusionMultiPath is interrupted in some place. This should not really happen.
break;
len += Geometry::ArcWelder::estimate_path_length(it->path);
m_path.insert(m_path.end(), it->path.begin() + 1, it->path.end());
}
}

View File

@ -42,7 +42,7 @@ public:
if (this->enabled() && path.size() > 1)
m_path = std::move(path);
}
void set_path(SmoothPath &&path, bool reversed);
void set_path(SmoothPath &&path);
void offset_path(const Point &v) { m_offset += v; }
std::string wipe(GCodeGenerator &gcodegen, bool toolchange);