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:
parent
230dbb7394
commit
e7ae26fb8a
3 changed files with 79 additions and 19 deletions
|
@ -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.
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue