Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2017-09-12 16:55:38 +0300
committerbubnikv <bubnikv@gmail.com>2017-09-12 16:55:38 +0300
commitb08d6f1969f237432cd18c15ad6432e5b95fb640 (patch)
tree34f133a112ec0de5f6ab18696f7ba9c5647b5d17
parent6d4ec5c989851e442d58f896d4b0324129e7514a (diff)
The last priming area is shortened and the excess wipe is moved
into the wipe tower if there is enough space inside the wipe tower.
-rw-r--r--xs/src/libslic3r/BoundingBox.cpp30
-rw-r--r--xs/src/libslic3r/GCode.cpp6
-rw-r--r--xs/src/libslic3r/GCode/PrintExtents.cpp4
-rw-r--r--xs/src/libslic3r/GCode/PrintExtents.hpp4
-rw-r--r--xs/src/libslic3r/GCode/WipeTower.hpp11
-rw-r--r--xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp75
-rw-r--r--xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp17
-rw-r--r--xs/src/libslic3r/Print.cpp7
8 files changed, 115 insertions, 39 deletions
diff --git a/xs/src/libslic3r/BoundingBox.cpp b/xs/src/libslic3r/BoundingBox.cpp
index f268bb3fb..66beaa3d5 100644
--- a/xs/src/libslic3r/BoundingBox.cpp
+++ b/xs/src/libslic3r/BoundingBox.cpp
@@ -125,15 +125,17 @@ template void BoundingBoxBase<Pointf>::merge(const Pointfs &points);
template <class PointClass> void
BoundingBoxBase<PointClass>::merge(const BoundingBoxBase<PointClass> &bb)
{
- if (this->defined) {
- this->min.x = std::min(bb.min.x, this->min.x);
- this->min.y = std::min(bb.min.y, this->min.y);
- this->max.x = std::max(bb.max.x, this->max.x);
- this->max.y = std::max(bb.max.y, this->max.y);
- } else {
- this->min = bb.min;
- this->max = bb.max;
- this->defined = true;
+ if (bb.defined) {
+ if (this->defined) {
+ this->min.x = std::min(bb.min.x, this->min.x);
+ this->min.y = std::min(bb.min.y, this->min.y);
+ this->max.x = std::max(bb.max.x, this->max.x);
+ this->max.y = std::max(bb.max.y, this->max.y);
+ } else {
+ this->min = bb.min;
+ this->max = bb.max;
+ this->defined = true;
+ }
}
}
template void BoundingBoxBase<Point>::merge(const BoundingBoxBase<Point> &bb);
@@ -160,11 +162,13 @@ template void BoundingBox3Base<Pointf3>::merge(const Pointf3s &points);
template <class PointClass> void
BoundingBox3Base<PointClass>::merge(const BoundingBox3Base<PointClass> &bb)
{
- if (this->defined) {
- this->min.z = std::min(bb.min.z, this->min.z);
- this->max.z = std::max(bb.max.z, this->max.z);
+ if (bb.defined) {
+ if (this->defined) {
+ this->min.z = std::min(bb.min.z, this->min.z);
+ this->max.z = std::max(bb.max.z, this->max.z);
+ }
+ BoundingBoxBase<PointClass>::merge(bb);
}
- BoundingBoxBase<PointClass>::merge(bb);
}
template void BoundingBox3Base<Pointf3>::merge(const BoundingBox3Base<Pointf3> &bb);
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp
index a2e2f5607..478864e74 100644
--- a/xs/src/libslic3r/GCode.cpp
+++ b/xs/src/libslic3r/GCode.cpp
@@ -700,15 +700,17 @@ bool GCode::_do_export(Print &print, FILE *file)
BoundingBoxf bbox_prime(get_wipe_tower_priming_extrusions_extents(print));
bbox_prime.offset(0.5f);
// Beep for 500ms, tone 800Hz. Yet better, play some Morse.
+ write(file, this->retract());
fprintf(file, "M300 S800 P500\n");
if (bbox_prime.overlap(bbox_print)) {
// Wait for the user to remove the priming extrusions, otherwise they would
// get covered by the print.
- fprintf(file, "M1 Remove priming towers and click button.\n");
+ fprintf(file, "M1 Remove priming towers and click button.\nM117 Printing\n");
} else {
// Just wait for a bit to let the user check, that the priming succeeded.
- fprintf(file, "M0 S10\n");
+ fprintf(file, "M117 Verify extruder priming\nM0 S10\nM117 Printing\n");
}
+ write(file, this->unretract());
} else
write(file, WipeTowerIntegration::prime_single_color_print(print, initial_extruder_id, *this));
}
diff --git a/xs/src/libslic3r/GCode/PrintExtents.cpp b/xs/src/libslic3r/GCode/PrintExtents.cpp
index 98dc59f58..db33627ec 100644
--- a/xs/src/libslic3r/GCode/PrintExtents.cpp
+++ b/xs/src/libslic3r/GCode/PrintExtents.cpp
@@ -101,7 +101,7 @@ BoundingBoxf get_print_extrusions_extents(const Print &print)
return bbox;
}
-BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object, const coord_t max_print_z)
+BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object, const coordf_t max_print_z)
{
BoundingBoxf bbox;
for (const Layer *layer : print_object.layers) {
@@ -129,7 +129,7 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object
// Returns a bounding box of a projection of the wipe tower for the layers <= max_print_z.
// The projection does not contain the priming regions.
-BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coord_t max_print_z)
+BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z)
{
BoundingBoxf bbox;
for (const std::vector<WipeTower::ToolChangeResult> &tool_changes : print.m_wipe_tower_tool_changes) {
diff --git a/xs/src/libslic3r/GCode/PrintExtents.hpp b/xs/src/libslic3r/GCode/PrintExtents.hpp
index 2706e2cab..db507689d 100644
--- a/xs/src/libslic3r/GCode/PrintExtents.hpp
+++ b/xs/src/libslic3r/GCode/PrintExtents.hpp
@@ -16,11 +16,11 @@ class BoundingBoxf;
BoundingBoxf get_print_extrusions_extents(const Print &print);
// Returns a bounding box of a projection of the object extrusions at z <= max_print_z.
-BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object, const coord_t max_print_z);
+BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object, const coordf_t max_print_z);
// Returns a bounding box of a projection of the wipe tower for the layers <= max_print_z.
// The projection does not contain the priming regions.
-BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coord_t max_print_z);
+BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z);
// Returns a bounding box of the wipe tower priming extrusions.
BoundingBoxf get_wipe_tower_priming_extrusions_extents(const Print &print);
diff --git a/xs/src/libslic3r/GCode/WipeTower.hpp b/xs/src/libslic3r/GCode/WipeTower.hpp
index cccbe23d8..c5fa27392 100644
--- a/xs/src/libslic3r/GCode/WipeTower.hpp
+++ b/xs/src/libslic3r/GCode/WipeTower.hpp
@@ -105,7 +105,16 @@ public:
};
// Returns gcode to prime the nozzles at the front edge of the print bed.
- virtual ToolChangeResult prime(float first_layer_height, std::vector<unsigned int> tools, Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) = 0;
+ virtual ToolChangeResult prime(
+ // print_z of the first layer.
+ float first_layer_height,
+ // Extruder indices, in the order to be primed. The last extruder will later print the wipe tower brim, print brim and the object.
+ std::vector<unsigned int> tools,
+ // If true, the last priming are will be the same as the other priming areas, and the rest of the wipe will be performed inside the wipe tower.
+ // If false, the last priming are will be large enough to wipe the last extruder sufficiently.
+ bool last_wipe_inside_wipe_tower,
+ // May be used by a stand alone post processor.
+ Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) = 0;
// Returns gcode for toolchange and the end position.
// if new_tool == -1, just unload the current filament over the wipe tower.
diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
index 760ff03f0..14b67936d 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
@@ -364,7 +364,16 @@ WipeTowerPrusaMM::material_type WipeTowerPrusaMM::parse_material(const char *nam
}
// Returns gcode to prime the nozzles at the front edge of the print bed.
-WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(float first_layer_height, std::vector<unsigned int> tools, Purpose purpose)
+WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
+ // print_z of the first layer.
+ float first_layer_height,
+ // Extruder indices, in the order to be primed. The last extruder will later print the wipe tower brim, print brim and the object.
+ std::vector<unsigned int> tools,
+ // If true, the last priming are will be the same as the other priming areas, and the rest of the wipe will be performed inside the wipe tower.
+ // If false, the last priming are will be large enough to wipe the last extruder sufficiently.
+ bool last_wipe_inside_wipe_tower,
+ // May be used by a stand alone post processor.
+ Purpose purpose)
{
this->set_layer(first_layer_height, first_layer_height, tools.size(), true, false);
@@ -411,6 +420,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(float first_layer_height, st
.set_extruder_trimpot(750);
if (purpose == PURPOSE_EXTRUDE || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
+ float y_end = 0.f;
for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
unsigned int tool = tools[idx_tool];
// Select the tool, set a speed override for soluble and flex materials.
@@ -419,10 +429,20 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(float first_layer_height, st
toolchange_Load(writer, cleaning_box);
if (idx_tool + 1 == tools.size()) {
// Last tool should not be unloaded, but it should be wiped enough to become of a pure color.
- toolchange_Wipe(writer, cleaning_box);
+ if (last_wipe_inside_wipe_tower) {
+ // Shrink the last wipe area to the area of the other purge areas,
+ // remember the last initial wipe width to be purged into the 1st layer of the wipe tower.
+ this->m_initial_extra_wipe = std::max(0.f, wipe_area - (y_end + 0.5f * 0.85f * m_perimeter_width - cleaning_box.ld.y));
+ cleaning_box.lu.y -= this->m_initial_extra_wipe;
+ cleaning_box.ru.y -= this->m_initial_extra_wipe;
+ }
+ toolchange_Wipe(writer, cleaning_box, false);
} else {
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
+ writer.travel(writer.x(), writer.y() + m_perimeter_width, 7200);
toolchange_Unload(writer, cleaning_box, m_material[m_current_tool], m_first_layer_temperature[tool]);
+ // Save the y end of the non-last priming area.
+ y_end = writer.y();
cleaning_box.translate(m_wipe_tower_width, 0.f);
writer.travel(cleaning_box.ld, 7200);
}
@@ -546,7 +566,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
toolchange_Change(writer, tool, m_material[tool]);
toolchange_Load(writer, cleaning_box);
// Wipe the newly loaded filament until the end of the assigned wipe area.
- toolchange_Wipe(writer, cleaning_box);
+ toolchange_Wipe(writer, cleaning_box, false);
// Draw a perimeter around cleaning_box and wipe.
box_coordinates box = cleaning_box;
if (m_current_shape == SHAPE_REVERSED) {
@@ -647,6 +667,21 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(Purpose purpose, b
}
}
+ if (m_initial_extra_wipe > m_perimeter_width * 1.9f) {
+ box_coordinates cleaning_box(
+ m_wipe_tower_pos + xy(0.f, 0.5f * m_perimeter_width),
+ m_wipe_tower_width,
+ m_initial_extra_wipe - m_perimeter_width);
+ writer.travel(cleaning_box.ld + xy(m_perimeter_width, 0.5f * m_perimeter_width), 6000);
+ // Wipe the newly loaded filament until the end of the assigned wipe area.
+ toolchange_Wipe(writer, cleaning_box, true);
+ // Draw a perimeter around cleaning_box.
+ writer.travel(cleaning_box.lu, 7000)
+ .extrude(cleaning_box.ld, 3200).extrude(cleaning_box.rd)
+ .extrude(cleaning_box.ru).extrude(cleaning_box.lu);
+ m_current_wipe_start_y = m_initial_extra_wipe;
+ }
+
// Move to the front left corner.
writer.travel(wipeTower_box.ld, 7000);
@@ -786,6 +821,9 @@ void WipeTowerPrusaMM::toolchange_Load(
{
float xl = cleaning_box.ld.x + m_perimeter_width;
float xr = cleaning_box.rd.x - m_perimeter_width;
+ //FIXME flipping left / right side, so that the following toolchange_Wipe will start
+ // where toolchange_Load ends.
+ std::swap(xl, xr);
writer.append("; CP TOOLCHANGE LOAD\n")
// Load the filament while moving left / right,
@@ -819,7 +857,8 @@ void WipeTowerPrusaMM::toolchange_Load(
// Wipe the newly loaded filament until the end of the assigned wipe area.
void WipeTowerPrusaMM::toolchange_Wipe(
PrusaMultiMaterial::Writer &writer,
- const box_coordinates &cleaning_box)
+ const box_coordinates &cleaning_box,
+ bool skip_initial_y_move)
{
// Increase flow on first layer, slow down print.
writer.set_extrusion_flow(m_extrusion_flow * (m_is_first_layer ? 1.18f : 1.f))
@@ -833,23 +872,27 @@ void WipeTowerPrusaMM::toolchange_Wipe(
float wipe_speed_max = 4800.f;
// Y increment per wipe line.
float dy = ((m_current_shape == SHAPE_NORMAL) ? 1.f : -1.f) * m_perimeter_width * 0.8f;
- for (bool p = true; ; p = ! p) {
- wipe_speed = std::min(wipe_speed_max, wipe_speed + wipe_speed_inc);
- if (p) {
- writer.extrude(xl - m_perimeter_width / 2, writer.y() + dy, wipe_speed * wipe_coeff);
- writer.extrude(xr + m_perimeter_width, writer.y());
- } else {
- writer.extrude(xl - m_perimeter_width, writer.y() + dy, wipe_speed * wipe_coeff);
- writer.extrude(xr + m_perimeter_width * 2, writer.y());
- }
+ for (bool p = true;
+ // Next wipe line fits the cleaning box.
+ ((m_current_shape == SHAPE_NORMAL) ?
+ (writer.y() <= cleaning_box.lu.y - m_perimeter_width) :
+ (writer.y() >= cleaning_box.ld.y + m_perimeter_width));
+ p = ! p)
+ {
wipe_speed = std::min(wipe_speed_max, wipe_speed + wipe_speed_inc);
- writer.extrude(xr + m_perimeter_width, writer.y() + dy, wipe_speed * wipe_coeff);
- writer.extrude(xl - m_perimeter_width, writer.y());
+ if (skip_initial_y_move)
+ skip_initial_y_move = false;
+ else
+ writer.extrude(xl - (p ? m_perimeter_width / 2 : m_perimeter_width), writer.y() + dy, wipe_speed * wipe_coeff);
+ writer.extrude(xr + (p ? m_perimeter_width : m_perimeter_width * 2), writer.y(), wipe_speed * wipe_coeff);
+ // Next wipe line fits the cleaning box.
if ((m_current_shape == SHAPE_NORMAL) ?
(writer.y() > cleaning_box.lu.y - m_perimeter_width) :
(writer.y() < cleaning_box.ld.y + m_perimeter_width))
- // Next wipe line does not fit the cleaning box.
break;
+ wipe_speed = std::min(wipe_speed_max, wipe_speed + wipe_speed_inc);
+ writer.extrude(xr + m_perimeter_width, writer.y() + dy, wipe_speed * wipe_coeff);
+ writer.extrude(xl - m_perimeter_width, writer.y());
}
// Reset the extrusion flow.
writer.set_extrusion_flow(m_extrusion_flow);
diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
index c21c62486..15a96d367 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
@@ -108,7 +108,16 @@ public:
virtual bool finished() const { return m_max_color_changes == 0; }
// Returns gcode to prime the nozzles at the front edge of the print bed.
- virtual ToolChangeResult prime(float first_layer_height, std::vector<unsigned int> tools, Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE);
+ virtual ToolChangeResult prime(
+ // print_z of the first layer.
+ float first_layer_height,
+ // Extruder indices, in the order to be primed. The last extruder will later print the wipe tower brim, print brim and the object.
+ std::vector<unsigned int> tools,
+ // If true, the last priming are will be the same as the other priming areas, and the rest of the wipe will be performed inside the wipe tower.
+ // If false, the last priming are will be large enough to wipe the last extruder sufficiently.
+ bool last_wipe_inside_wipe_tower,
+ // May be used by a stand alone post processor.
+ Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE);
// Returns gcode for a toolchange and a final print head position.
// On the first layer, extrude a brim around the future wipe tower first.
@@ -176,6 +185,9 @@ private:
unsigned int m_current_tool = 0;
// Current y position at the wipe tower.
float m_current_wipe_start_y = 0.f;
+ // How much to wipe the 1st extruder over the wipe tower at the 1st layer
+ // after the wipe tower brim has been extruded?
+ float m_initial_extra_wipe = 0.f;
struct box_coordinates
{
@@ -230,7 +242,8 @@ private:
void toolchange_Wipe(
PrusaMultiMaterial::Writer &writer,
- const box_coordinates &cleaning_box);
+ const box_coordinates &cleaning_box,
+ bool skip_initial_y_move);
void toolchange_Perimeter();
};
diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp
index 766acbe9b..667a3b4ea 100644
--- a/xs/src/libslic3r/Print.cpp
+++ b/xs/src/libslic3r/Print.cpp
@@ -992,8 +992,13 @@ void Print::_make_wipe_tower()
this->config.temperature.get_at(i),
this->config.first_layer_temperature.get_at(i));
+ // When printing the first layer's wipe tower, the first extruder is expected to be active and primed.
+ // Therefore the number of wipe sections at the wipe tower will be (m_tool_ordering.front().extruders-1) at the 1st layer.
+ // The following variable is true if the last priming section cannot be squeezed inside the wipe tower.
+ bool last_priming_wipe_full = m_tool_ordering.front().extruders.size() > m_tool_ordering.front().wipe_tower_partitions;
+
m_wipe_tower_priming = Slic3r::make_unique<WipeTower::ToolChangeResult>(
- wipe_tower.prime(this->skirt_first_layer_height(), m_tool_ordering.all_extruders(), WipeTower::PURPOSE_EXTRUDE));
+ wipe_tower.prime(this->skirt_first_layer_height(), m_tool_ordering.all_extruders(), ! last_priming_wipe_full, WipeTower::PURPOSE_EXTRUDE));
// Generate the wipe tower layers.
m_wipe_tower_tool_changes.reserve(m_tool_ordering.layer_tools().size());