ENH: enable thick bridge for wipe tower

Change-Id: I96dae7753995af1862fe4ad33a00fa56cfbb7d3c
(cherry picked from commit 5f98ff50613e3358de10fa1b6d4429ce71e526c2)
This commit is contained in:
zhimin.zeng 2022-11-11 12:15:18 +08:00 committed by Lane.Wei
parent 148f6ba05d
commit 2f12ad7bf2
2 changed files with 96 additions and 9 deletions

View File

@ -240,6 +240,44 @@ public:
return (*this);
}
WipeTowerWriter &rectangle_fill_box(const WipeTower* wipe_tower, const Vec2f &ld, float width, float height, const float f = 0.f)
{
bool need_change_flow = wipe_tower->need_thick_bridge_flow(ld.y());
Vec2f corners[4];
corners[0] = ld;
corners[1] = ld + Vec2f(width, 0.f);
corners[2] = ld + Vec2f(width, height);
corners[3] = ld + Vec2f(0.f, height);
int index_of_closest = 0;
if (x() - ld.x() > ld.x() + width - x()) // closer to the right
index_of_closest = 1;
if (y() - ld.y() > ld.y() + height - y()) // closer to the top
index_of_closest = (index_of_closest == 0 ? 3 : 2);
travel(corners[index_of_closest].x(), y()); // travel to the closest corner
travel(x(), corners[index_of_closest].y());
int i = index_of_closest;
bool flow_changed = false;
do {
++i;
if (i == 4) i = 0;
if (need_change_flow) {
if (i == 1) {
set_extrusion_flow(wipe_tower->extrusion_flow(0.2));
append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) + std::to_string(0.2) + "\n");
flow_changed = true;
} else if (i == 2 && flow_changed) {
set_extrusion_flow(wipe_tower->get_extrusion_flow());
append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) + std::to_string(m_layer_height) + "\n");
}
}
extrude(corners[i], f);
} while (i != index_of_closest);
return (*this);
}
WipeTowerWriter& rectangle(const WipeTower::box_coordinates& box, const float f = 0.f)
{
rectangle(Vec2f(box.ld.x(), box.ld.y()),
@ -976,6 +1014,11 @@ void WipeTower::toolchange_Wipe(
// Increase flow on first layer, slow down print.
writer.set_extrusion_flow(m_extrusion_flow * (is_first_layer() ? 1.15f : 1.f))
.append("; CP TOOLCHANGE WIPE\n");
if (is_first_layer()) {
writer.append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Width) + std::to_string(1.15 * m_perimeter_width) + "\n");
}
const float& xl = cleaning_box.ld.x();
const float& xr = cleaning_box.rd.x();
@ -1007,6 +1050,7 @@ void WipeTower::toolchange_Wipe(
writer.travel(xl, writer.y() + dy);
#endif
bool need_change_flow = false;
// now the wiping itself:
for (int i = 0; true; ++i) {
if (i!=0) {
@ -1016,11 +1060,22 @@ void WipeTower::toolchange_Wipe(
else wipe_speed = std::min(target_speed, wipe_speed + 50.f);
}
if (need_change_flow || need_thick_bridge_flow(writer.y())) {
writer.set_extrusion_flow(extrusion_flow(0.2));
writer.append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) + std::to_string(0.2) + "\n");
need_change_flow = true;
}
if (m_left_to_right)
writer.extrude(xr + 0.25f * m_perimeter_width, writer.y(), wipe_speed);
else
writer.extrude(xl - 0.25f * m_perimeter_width, writer.y(), wipe_speed);
if (need_change_flow) {
writer.set_extrusion_flow(m_extrusion_flow);
writer.append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) + std::to_string(m_layer_height) + "\n");
}
if (writer.y() - float(EPSILON) > cleaning_box.lu.y())
break; // in case next line would not fit
@ -1046,6 +1101,9 @@ void WipeTower::toolchange_Wipe(
m_left_to_right = !m_left_to_right;
writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
if (is_first_layer()) {
writer.append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Width) + std::to_string(m_perimeter_width) + "\n");
}
}
@ -1101,7 +1159,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer(bool extrude_perimeter, bool
// inner perimeter of the sparse section, if there is space for it:
if (fill_box.ru.y() - fill_box.rd.y() > m_perimeter_width - WT_EPSILON)
writer.rectangle(fill_box.ld, fill_box.rd.x() - fill_box.ld.x(), fill_box.ru.y() - fill_box.rd.y(), feedrate);
writer.rectangle_fill_box(this, fill_box.ld, fill_box.rd.x() - fill_box.ld.x(), fill_box.ru.y() - fill_box.rd.y(), feedrate);
// we are in one of the corners, travel to ld along the perimeter:
if (writer.x() > fill_box.ld.x() + EPSILON) writer.travel(fill_box.ld.x(), writer.y());
@ -1593,4 +1651,30 @@ WipeTower::ToolChangeResult WipeTower::only_generate_out_wall()
return construct_tcr(writer, false, old_tool, true, 0.f);
}
bool WipeTower::get_floating_area(float &start_pos_y, float &end_pos_y) const {
if (m_layer_info == m_plan.begin() || (m_layer_info - 1) == m_plan.begin())
return false;
float last_layer_fill_box_y = (m_layer_info - 1)->toolchanges_depth() + m_perimeter_width;
float last_layer_wipe_depth = (m_layer_info - 1)->depth;
if (last_layer_wipe_depth - last_layer_fill_box_y <= 2 * m_perimeter_width)
return false;
start_pos_y = last_layer_fill_box_y + m_perimeter_width;
end_pos_y = last_layer_wipe_depth - m_perimeter_width;
return true;
}
bool WipeTower::need_thick_bridge_flow(float pos_y) const {
if (m_extrusion_flow >= extrusion_flow(0.2))
return false;
float y_min = 0., y_max = 0.;
if (get_floating_area(y_min, y_max)) {
return pos_y > y_min && pos_y < y_max;
}
return false;
}
} // namespace Slic3r

View File

@ -223,6 +223,17 @@ public:
// Call this method only if layer_finished() is false.
ToolChangeResult finish_layer(bool extruder_perimeter = true, bool extruder_fill = true);
// Calculates extrusion flow needed to produce required line width for given layer height
float extrusion_flow(float layer_height = -1.f) const // negative layer_height - return current m_extrusion_flow
{
if (layer_height < 0) return m_extrusion_flow;
return layer_height * (m_perimeter_width - layer_height * (1.f - float(M_PI) / 4.f)) / filament_area();
}
bool get_floating_area(float& start_pos_y, float& end_pos_y) const;
bool need_thick_bridge_flow(float pos_y) const;
float get_extrusion_flow() const { return m_extrusion_flow; }
// Is the current layer finished?
bool layer_finished() const {
return m_current_layer_finished;
@ -336,14 +347,6 @@ private:
bool is_first_layer() const { return size_t(m_layer_info - m_plan.begin()) == m_first_layer_idx; }
// Calculates extrusion flow needed to produce required line width for given layer height
float extrusion_flow(float layer_height = -1.f) const // negative layer_height - return current m_extrusion_flow
{
if ( layer_height < 0 )
return m_extrusion_flow;
return layer_height * ( m_perimeter_width - layer_height * (1.f-float(M_PI)/4.f)) / filament_area();
}
// Calculates length of extrusion line to extrude given volume
float volume_to_length(float volume, float line_width, float layer_height) const {
return std::max(0.f, volume / (layer_height * (line_width - layer_height * (1.f - float(M_PI) / 4.f))));