Fix of #2834 (unretracted wipes on wipe tower)

Wiping moves performed before moving away from the wipe tower were replaced by
scheduling a regular wipe that is performed after normal gcode generator regains
control. This makes it consistent with wipes on the model and gets rid of the
unretracted wipes.
This commit is contained in:
Lukas Matena 2020-09-21 13:43:47 +02:00
parent 230dbb7394
commit e7ae26fb8a
3 changed files with 79 additions and 19 deletions

View file

@ -294,13 +294,18 @@ namespace Slic3r {
// Toolchangeresult.gcode assumes the wipe tower corner is at the origin (except for priming lines)
// We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position
float alpha = m_wipe_tower_rotation / 180.f * float(M_PI);
auto transform_wt_pt = [&alpha, this](const Vec2f& pt) -> Vec2f {
Vec2f out = Eigen::Rotation2Df(alpha) * pt;
out += m_wipe_tower_pos;
return out;
};
Vec2f start_pos = tcr.start_pos;
Vec2f end_pos = tcr.end_pos;
if (!tcr.priming) {
start_pos = Eigen::Rotation2Df(alpha) * start_pos;
start_pos += m_wipe_tower_pos;
end_pos = Eigen::Rotation2Df(alpha) * end_pos;
end_pos += m_wipe_tower_pos;
start_pos = transform_wt_pt(start_pos);
end_pos = transform_wt_pt(end_pos);
}
Vec2f wipe_tower_offset = tcr.priming ? Vec2f::Zero() : m_wipe_tower_pos;
@ -403,7 +408,7 @@ namespace Slic3r {
else {
// Prepare a future wipe.
gcodegen.m_wipe.path.points.clear();
/*gcodegen.m_wipe.path.points.clear();
if (new_extruder_id >= 0) {
// Start the wipe at the current position.
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos));
@ -411,7 +416,10 @@ namespace Slic3r {
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen,
Vec2f((std::abs(m_left - end_pos.x()) < std::abs(m_right - end_pos.x())) ? m_right : m_left,
end_pos.y())));
}
}*/
gcodegen.m_wipe.reset_path();
for (const Vec2f& wipe_pt : tcr.wipe_path)
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, transform_wt_pt(wipe_pt)));
}
// Let the planner know we are traveling between objects.

View file

@ -441,9 +441,26 @@ public:
WipeTowerWriter& append(const std::string& text) { m_gcode += text; return *this; }
std::vector<Vec2f> wipe_path() const
{
return m_wipe_path;
}
WipeTowerWriter& add_wipe_point(const Vec2f& pt)
{
m_wipe_path.push_back(rotate(pt));
return *this;
}
WipeTowerWriter& add_wipe_point(float x, float y)
{
return add_wipe_point(Vec2f(x, y));
}
private:
Vec2f m_start_pos;
Vec2f m_current_pos;
std::vector<Vec2f> m_wipe_path;
float m_current_z;
float m_current_feedrate;
size_t m_current_tool;
@ -790,7 +807,10 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_lay
else {
writer.rectangle(Vec2f::Zero(), m_wipe_tower_width, m_layer_info->depth + m_perimeter_width);
if (layer_finished()) { // no finish_layer will be called, we must wipe the nozzle
writer.travel(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y());
//writer.travel(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y());
writer.add_wipe_point(writer.x(), writer.y())
.add_wipe_point(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y());
}
}
}
@ -820,6 +840,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_lay
result.extrusions = writer.extrusions();
result.start_pos = writer.start_pos_rotated();
result.end_pos = writer.pos_rotated();
result.wipe_path = writer.wipe_path();
return result;
}
@ -853,13 +874,20 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
for (size_t i = 0; i < 4; ++ i) {
box.expand(spacing);
writer.travel (box.ld, 7000)
.extrude(box.lu, 2100).extrude(box.ru)
.extrude(box.rd ).extrude(box.ld);
.extrude(box.lu, 2100).extrude(box.ru)
.extrude(box.rd ).extrude(box.ld);
}
writer.travel(wipeTower_box.ld, 7000); // Move to the front left corner.
writer.travel(wipeTower_box.rd) // Always wipe the nozzle with a long wipe to reduce stringing when moving away from the wipe tower.
.travel(wipeTower_box.ld);
//writer.travel(wipeTower_box.ld, 7000); // Move to the front left corner.
//writer.travel(wipeTower_box.rd) // Always wipe the nozzle with a long wipe to reduce stringing when moving away from the wipe tower.
//.travel(wipeTower_box.ld);
box.expand(-spacing);
writer.add_wipe_point(writer.x(), writer.y())
.add_wipe_point(box.ld)
.add_wipe_point(box.rd);
writer.append("; CP WIPE TOWER FIRST LAYER BRIM END\n"
";-----------------------------------\n");
@ -884,6 +912,7 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
result.extrusions = writer.extrusions();
result.start_pos = writer.start_pos_rotated();
result.end_pos = writer.pos_rotated();
result.wipe_path = writer.wipe_path();
return result;
}
@ -1170,11 +1199,18 @@ void WipeTower::toolchange_Wipe(
m_left_to_right = !m_left_to_right;
}
// this is neither priming nor not the last toolchange on this layer - we are going back to the model - wipe the nozzle
// this is neither priming nor not the last toolchange on this layer - we are
// going back to the model - wipe the nozzle.
if (m_layer_info != m_plan.end() && m_current_tool != m_layer_info->tool_changes.back().new_tool) {
m_left_to_right = !m_left_to_right;
writer.travel(writer.x(), writer.y() - dy)
.travel(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y());
//writer.comment_with_value("starting wipe tower wipe ", 0)
// .travel(writer.x(), writer.y() - dy)
// .travel(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y())
// .comment_with_value("finished wipe tower wipe ", 0);
writer.add_wipe_point(writer.x(), writer.y())
.add_wipe_point(writer.x(), writer.y() - dy)
.add_wipe_point(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y() - dy);
}
writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
@ -1238,7 +1274,9 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
writer.extrude(box.rd.x() - m_perimeter_width / 2.f, writer.y() + 0.5f * step);
writer.extrude(box.ld.x() + m_perimeter_width / 2.f, writer.y());
}
writer.travel(box.rd.x()-m_perimeter_width/2.f,writer.y()); // wipe the nozzle
//writer.travel(box.rd.x()-m_perimeter_width/2.f,writer.y()); // wipe the nozzle
writer.add_wipe_point(writer.x(), writer.y())
.add_wipe_point(box.rd.x()-m_perimeter_width/2.f,writer.y());
}
else { // Extrude a sparse infill to support the material to be printed above.
const float dy = (fill_box.lu.y() - fill_box.ld.y() - m_perimeter_width);
@ -1257,10 +1295,15 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
writer.travel(x,writer.y());
writer.extrude(x,i%2 ? fill_box.rd.y() : fill_box.ru.y());
}
writer.travel(left,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower
writer.add_wipe_point(Vec2f(writer.x(), writer.y()))
.add_wipe_point(Vec2f(left, writer.y()));
//writer.travel(left,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower
}
else {
writer.add_wipe_point(Vec2f(writer.x(), writer.y()))
.add_wipe_point(Vec2f(right, writer.y()));
// writer.travel(right,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower
}
else
writer.travel(right,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower
}
writer.append("; CP EMPTY GRID END\n"
";------------------\n\n\n\n\n\n\n");
@ -1285,6 +1328,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
result.extrusions = writer.extrusions();
result.start_pos = writer.start_pos_rotated();
result.end_pos = writer.pos_rotated();
result.wipe_path = writer.wipe_path();
return result;
}
@ -1432,6 +1476,7 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
last_toolchange.gcode += finish_layer_toolchange.gcode;
last_toolchange.extrusions.insert(last_toolchange.extrusions.end(), finish_layer_toolchange.extrusions.begin(), finish_layer_toolchange.extrusions.end());
last_toolchange.end_pos = finish_layer_toolchange.end_pos;
last_toolchange.wipe_path = finish_layer_toolchange.wipe_path;
}
else
layer_result.emplace_back(std::move(finish_layer_toolchange));

View file

@ -57,6 +57,13 @@ public:
// Is this a priming extrusion? (If so, the wipe tower rotation & translation will not be applied later)
bool priming;
// Pass a polyline so that normal G-code generator can do a wipe for us.
// The wipe cannot be done by the wipe tower because it has to pass back
// a loaded extruder, so it would have to either do a wipe with no retraction
// (leading to https://github.com/prusa3d/PrusaSlicer/issues/2834) or do
// an extra retraction-unretraction pair.
std::vector<Vec2f> wipe_path;
// Initial tool
int initial_tool;