From aba743de41e639c69ef8b452c964960d825498de Mon Sep 17 00:00:00 2001 From: Thomas Moore Date: Mon, 6 May 2019 23:33:09 -0400 Subject: [PATCH 1/3] Include wipe tower in skirt --- src/libslic3r/GCode/PrintExtents.cpp | 39 +++++++++++++++++++++++++++- src/libslic3r/GCode/PrintExtents.hpp | 4 +++ src/libslic3r/Print.cpp | 35 +++++++++++++++---------- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/GCode/PrintExtents.cpp b/src/libslic3r/GCode/PrintExtents.cpp index 07a71a0ea..aaa615c34 100644 --- a/src/libslic3r/GCode/PrintExtents.cpp +++ b/src/libslic3r/GCode/PrintExtents.cpp @@ -138,7 +138,7 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_ // We need to get position and angle of the wipe tower to transform them to actual position. Transform2d trafo = Eigen::Translation2d(print.config().wipe_tower_x.value, print.config().wipe_tower_y.value) * - Eigen::Rotation2Dd(print.config().wipe_tower_rotation_angle.value); + Eigen::Rotation2Dd(Geometry::deg2rad(print.config().wipe_tower_rotation_angle.value)); BoundingBoxf bbox; for (const std::vector &tool_changes : print.wipe_tower_data().tool_changes) { @@ -160,6 +160,43 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_ return bbox; } +// Returns a vector of points of a projection of the wipe tower for the layers <= max_print_z. +// The projection does not contain the priming regions. +std::vector get_wipe_tower_extrusions_points(const Print &print, const coordf_t max_print_z) +{ + // Wipe tower extrusions are saved as if the tower was at the origin with no rotation + // We need to get position and angle of the wipe tower to transform them to actual position. + Transform2d trafo = + Eigen::Translation2d(print.config().wipe_tower_x.value, print.config().wipe_tower_y.value) * + Eigen::Rotation2Dd(Geometry::deg2rad(print.config().wipe_tower_rotation_angle.value)); + + BoundingBoxf bbox; + for (const std::vector &tool_changes : print.wipe_tower_data().tool_changes) { + if (!tool_changes.empty() && tool_changes.front().print_z > max_print_z) + break; + for (const WipeTower::ToolChangeResult &tcr : tool_changes) { + for (size_t i = 1; i < tcr.extrusions.size(); ++i) { + const WipeTower::Extrusion &e = tcr.extrusions[i]; + if (e.width > 0) { + Vec2d delta = 0.5 * Vec2d(e.width, e.width); + Vec2d p1 = Vec2d((&e - 1)->pos.x, (&e - 1)->pos.y); + Vec2d p2 = Vec2d(e.pos.x, e.pos.y); + bbox.merge(p1.cwiseMin(p2) - delta); + bbox.merge(p1.cwiseMax(p2) + delta); + } + } + } + } + + std::vector points; + points.push_back(trafo * Vec2d(bbox.min.x(), bbox.max.y())); + points.push_back(trafo * Vec2d(bbox.max.x(), bbox.max.y())); + points.push_back(trafo * Vec2d(bbox.max.x(), bbox.min.y())); + points.push_back(trafo * Vec2d(bbox.min.x(), bbox.min.y())); + + return points; +} + // Returns a bounding box of the wipe tower priming extrusions. BoundingBoxf get_wipe_tower_priming_extrusions_extents(const Print &print) { diff --git a/src/libslic3r/GCode/PrintExtents.hpp b/src/libslic3r/GCode/PrintExtents.hpp index db507689d..cb60c939b 100644 --- a/src/libslic3r/GCode/PrintExtents.hpp +++ b/src/libslic3r/GCode/PrintExtents.hpp @@ -22,6 +22,10 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object // The projection does not contain the priming regions. BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z); +// Returns a vector of points of a projection of the wipe tower for the layers <= max_print_z. +// The projection does not contain the priming regions. +std::vector get_wipe_tower_extrusions_points(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/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 245b79e80..4403c7b26 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -11,6 +11,7 @@ #include "SupportMaterial.hpp" #include "GCode.hpp" #include "GCode/WipeTower.hpp" +#include "GCode/PrintExtents.hpp" #include "Utils.hpp" //#include "PrintExport.hpp" @@ -143,10 +144,7 @@ bool Print::invalidate_state_by_config_options(const std::vector steps_ignore; @@ -167,7 +165,10 @@ bool Print::invalidate_state_by_config_options(const std::vector 1) { bool has_custom_layering = false; @@ -1502,6 +1506,14 @@ void Print::process() obj->infill(); for (PrintObject *obj : m_objects) obj->generate_support_material(); + if (this->set_started(psWipeTower)) { + m_wipe_tower_data.clear(); + if (this->has_wipe_tower()) { + //this->set_status(95, L("Generating wipe tower")); + this->_make_wipe_tower(); + } + this->set_done(psWipeTower); + } if (this->set_started(psSkirt)) { m_skirt.clear(); if (this->has_skirt()) { @@ -1518,14 +1530,6 @@ void Print::process() } this->set_done(psBrim); } - if (this->set_started(psWipeTower)) { - m_wipe_tower_data.clear(); - if (this->has_wipe_tower()) { - //this->set_status(95, L("Generating wipe tower")); - this->_make_wipe_tower(); - } - this->set_done(psWipeTower); - } BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info(); } @@ -1602,6 +1606,11 @@ void Print::_make_skirt() } } + // Include the wipe tower. + if (has_wipe_tower()) + for (const Vec2d& point : get_wipe_tower_extrusions_points(*this, skirt_height_z)) + points.push_back(Point(scale_(point.x()), scale_(point.y()))); + if (points.size() < 3) // At least three points required for a convex hull. return; From fdf9272fbe377ae15e870d9c95c1d45db7cf43a7 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 8 Oct 2019 13:50:51 +0200 Subject: [PATCH 2/3] Wipe tower brim width is now part of WipeTowerData class, so it can be used wherever needed --- src/libslic3r/GCode/PrintExtents.cpp | 4 ++-- src/libslic3r/GCode/WipeTower.cpp | 8 +++++++- src/libslic3r/GCode/WipeTower.hpp | 2 ++ src/libslic3r/Print.cpp | 17 +++++++++++++++++ src/libslic3r/Print.hpp | 5 +++-- src/slic3r/GUI/GLCanvas3D.cpp | 22 +++++++++------------- 6 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/GCode/PrintExtents.cpp b/src/libslic3r/GCode/PrintExtents.cpp index aaa615c34..ed1d097e1 100644 --- a/src/libslic3r/GCode/PrintExtents.cpp +++ b/src/libslic3r/GCode/PrintExtents.cpp @@ -179,8 +179,8 @@ std::vector get_wipe_tower_extrusions_points(const Print &print, const co const WipeTower::Extrusion &e = tcr.extrusions[i]; if (e.width > 0) { Vec2d delta = 0.5 * Vec2d(e.width, e.width); - Vec2d p1 = Vec2d((&e - 1)->pos.x, (&e - 1)->pos.y); - Vec2d p2 = Vec2d(e.pos.x, e.pos.y); + Vec2d p1 = Vec2d((&e - 1)->pos.x(), (&e - 1)->pos.y()); + Vec2d p2 = Vec2d(e.pos.x(), e.pos.y()); bbox.merge(p1.cwiseMin(p2) - delta); bbox.merge(p1.cwiseMax(p2) + delta); } diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index ea8465f22..b464a39b8 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -787,8 +787,10 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of // The tool is supposed to be active and primed at the time when the wipe tower brim is extruded. // Extrude 4 rounds of a brim around the future wipe tower. box_coordinates box(wipeTower_box); + // the brim shall have 'normal' spacing with no extra void space + float spacing = m_perimeter_width - m_layer_height*float(1.-M_PI_4); for (size_t i = 0; i < 4; ++ i) { - box.expand(m_perimeter_width - m_layer_height*float(1.-M_PI_4)); // the brim shall have 'normal' spacing with no extra void space + box.expand(spacing); writer.travel (box.ld, 7000) .extrude(box.lu, 2100).extrude(box.ru) .extrude(box.rd ).extrude(box.ld); @@ -800,6 +802,10 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of writer.append("; CP WIPE TOWER FIRST LAYER BRIM END\n" ";-----------------------------------\n"); + // Save actual brim width to be later passed to the Print object, which will use it + // for skirt calculation and pass it to GLCanvas for precise preview box + m_wipe_tower_brim_width = wipeTower_box.ld.x() - box.ld.x() + spacing/2.f; + m_print_brim = false; // Mark the brim as extruded // Ask our writer about how much material was consumed: diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index 5477aa609..c1ea3f2b5 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -92,6 +92,7 @@ public: void generate(std::vector> &result); float get_depth() const { return m_wipe_tower_depth; } + float get_brim_width() const { return m_wipe_tower_brim_width; } @@ -203,6 +204,7 @@ private: Vec2f m_wipe_tower_pos; // Left front corner of the wipe tower in mm. float m_wipe_tower_width; // Width of the wipe tower. float m_wipe_tower_depth = 0.f; // Depth of the wipe tower + float m_wipe_tower_brim_width = 0.f; // Width of brim (mm) float m_wipe_tower_rotation_angle = 0.f; // Wipe tower rotation angle in degrees (with respect to x axis) float m_internal_rotation = 0.f; float m_y_shift = 0.f; // y shift passed to writer diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 4403c7b26..e7e813164 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1873,6 +1873,22 @@ bool Print::has_wipe_tower() const m_config.nozzle_diameter.values.size() > 1; } +const WipeTowerData& Print::wipe_tower_data(size_t extruders_cnt, double first_layer_height, double nozzle_diameter) const +{ + // If the wipe tower wasn't created yet, make sure the depth and brim_width members are set to default. + if (! is_step_done(psWipeTower) && extruders_cnt !=0) { + + float width = m_config.wipe_tower_width; + float brim_spacing = nozzle_diameter * 1.25f - first_layer_height * (1. - M_PI_4); + + const_cast(this)->m_wipe_tower_data.depth = (900.f/width) * float(extruders_cnt - 1); + const_cast(this)->m_wipe_tower_data.brim_width = 4.5f * brim_spacing; + } + + return m_wipe_tower_data; +} + + void Print::_make_wipe_tower() { m_wipe_tower_data.clear(); @@ -1981,6 +1997,7 @@ void Print::_make_wipe_tower() m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size()); wipe_tower.generate(m_wipe_tower_data.tool_changes); m_wipe_tower_data.depth = wipe_tower.get_depth(); + m_wipe_tower_data.brim_width = wipe_tower.get_brim_width(); // Unload the current filament over the purge tower. coordf_t layer_height = m_objects.front()->config().layer_height.value; diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index ce616a150..6d94a515f 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -226,6 +226,7 @@ struct WipeTowerData // Depth of the wipe tower to pass to GLCanvas3D for exact bounding box: float depth; + float brim_width; void clear() { tool_ordering.clear(); @@ -235,6 +236,7 @@ struct WipeTowerData used_filament.clear(); number_of_toolchanges = -1; depth = 0.f; + brim_width = 0.f; } }; @@ -314,7 +316,6 @@ public: bool has_infinite_skirt() const; bool has_skirt() const; - float get_wipe_tower_depth() const { return m_wipe_tower_data.depth; } // Returns an empty string if valid, otherwise returns an error message. std::string validate() const override; @@ -353,7 +354,7 @@ public: // Wipe tower support. bool has_wipe_tower() const; - const WipeTowerData& wipe_tower_data() const { return m_wipe_tower_data; } + const WipeTowerData& wipe_tower_data(size_t extruders_cnt = 0, double first_layer_height = 0., double nozzle_diameter = 0.) const; std::string output_filename(const std::string &filename_base = std::string()) const override; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 04ef6fd42..4a845a682 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1999,19 +1999,17 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re float a = dynamic_cast(m_config->option("wipe_tower_rotation_angle"))->value; const Print *print = m_process->fff_print(); - float depth = print->get_wipe_tower_depth(); - // Calculate wipe tower brim spacing. const DynamicPrintConfig &print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; double layer_height = print_config.opt_float("layer_height"); double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height); - float brim_spacing = print->config().nozzle_diameter.values[0] * 1.25f - first_layer_height * (1. - M_PI_4); + double nozzle_diameter = print->config().nozzle_diameter.values[0]; + float depth = print->wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).depth; + float brim_width = print->wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).brim_width; - if (!print->is_step_done(psWipeTower)) - depth = (900.f/w) * (float)(extruders_count - 1); int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), - brim_spacing * 4.5f, m_initialized); + brim_width, m_initialized); if (volume_idx_wipe_tower_old != -1) map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new; } @@ -5284,20 +5282,18 @@ void GLCanvas3D::_load_fff_shells() // adds wipe tower's volume double max_z = print->objects()[0]->model_object()->get_model()->bounding_box().max(2); const PrintConfig& config = print->config(); - unsigned int extruders_count = config.nozzle_diameter.size(); + size_t extruders_count = config.nozzle_diameter.size(); if ((extruders_count > 1) && config.wipe_tower && !config.complete_objects) { - float depth = print->get_wipe_tower_depth(); - // Calculate wipe tower brim spacing. const DynamicPrintConfig &print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; double layer_height = print_config.opt_float("layer_height"); double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height); - float brim_spacing = print->config().nozzle_diameter.values[0] * 1.25f - first_layer_height * (1. - M_PI_4); + double nozzle_diameter = print->config().nozzle_diameter.values[0]; + float depth = print->wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).depth; + float brim_width = print->wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).brim_width; - if (!print->is_step_done(psWipeTower)) - depth = (900.f/config.wipe_tower_width) * (float)(extruders_count - 1); m_volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, - !print->is_step_done(psWipeTower), brim_spacing * 4.5f, m_initialized); + !print->is_step_done(psWipeTower), brim_width, m_initialized); } } } From cf030e89580e815f4ba622db1f8449213f124c62 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 8 Oct 2019 14:04:50 +0200 Subject: [PATCH 3/3] Simplified inclusion of the wipe tower into skirt calculation --- src/libslic3r/GCode/PrintExtents.cpp | 37 ---------------------------- src/libslic3r/GCode/PrintExtents.hpp | 4 --- src/libslic3r/Print.cpp | 13 +++++++--- 3 files changed, 9 insertions(+), 45 deletions(-) diff --git a/src/libslic3r/GCode/PrintExtents.cpp b/src/libslic3r/GCode/PrintExtents.cpp index ed1d097e1..d44ef1aad 100644 --- a/src/libslic3r/GCode/PrintExtents.cpp +++ b/src/libslic3r/GCode/PrintExtents.cpp @@ -160,43 +160,6 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_ return bbox; } -// Returns a vector of points of a projection of the wipe tower for the layers <= max_print_z. -// The projection does not contain the priming regions. -std::vector get_wipe_tower_extrusions_points(const Print &print, const coordf_t max_print_z) -{ - // Wipe tower extrusions are saved as if the tower was at the origin with no rotation - // We need to get position and angle of the wipe tower to transform them to actual position. - Transform2d trafo = - Eigen::Translation2d(print.config().wipe_tower_x.value, print.config().wipe_tower_y.value) * - Eigen::Rotation2Dd(Geometry::deg2rad(print.config().wipe_tower_rotation_angle.value)); - - BoundingBoxf bbox; - for (const std::vector &tool_changes : print.wipe_tower_data().tool_changes) { - if (!tool_changes.empty() && tool_changes.front().print_z > max_print_z) - break; - for (const WipeTower::ToolChangeResult &tcr : tool_changes) { - for (size_t i = 1; i < tcr.extrusions.size(); ++i) { - const WipeTower::Extrusion &e = tcr.extrusions[i]; - if (e.width > 0) { - Vec2d delta = 0.5 * Vec2d(e.width, e.width); - Vec2d p1 = Vec2d((&e - 1)->pos.x(), (&e - 1)->pos.y()); - Vec2d p2 = Vec2d(e.pos.x(), e.pos.y()); - bbox.merge(p1.cwiseMin(p2) - delta); - bbox.merge(p1.cwiseMax(p2) + delta); - } - } - } - } - - std::vector points; - points.push_back(trafo * Vec2d(bbox.min.x(), bbox.max.y())); - points.push_back(trafo * Vec2d(bbox.max.x(), bbox.max.y())); - points.push_back(trafo * Vec2d(bbox.max.x(), bbox.min.y())); - points.push_back(trafo * Vec2d(bbox.min.x(), bbox.min.y())); - - return points; -} - // Returns a bounding box of the wipe tower priming extrusions. BoundingBoxf get_wipe_tower_priming_extrusions_extents(const Print &print) { diff --git a/src/libslic3r/GCode/PrintExtents.hpp b/src/libslic3r/GCode/PrintExtents.hpp index cb60c939b..db507689d 100644 --- a/src/libslic3r/GCode/PrintExtents.hpp +++ b/src/libslic3r/GCode/PrintExtents.hpp @@ -22,10 +22,6 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object // The projection does not contain the priming regions. BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z); -// Returns a vector of points of a projection of the wipe tower for the layers <= max_print_z. -// The projection does not contain the priming regions. -std::vector get_wipe_tower_extrusions_points(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/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index e7e813164..88645df15 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -11,7 +11,6 @@ #include "SupportMaterial.hpp" #include "GCode.hpp" #include "GCode/WipeTower.hpp" -#include "GCode/PrintExtents.hpp" #include "Utils.hpp" //#include "PrintExport.hpp" @@ -1607,9 +1606,15 @@ void Print::_make_skirt() } // Include the wipe tower. - if (has_wipe_tower()) - for (const Vec2d& point : get_wipe_tower_extrusions_points(*this, skirt_height_z)) - points.push_back(Point(scale_(point.x()), scale_(point.y()))); + if (has_wipe_tower() && ! m_wipe_tower_data.tool_changes.empty()) { + double width = m_config.wipe_tower_width + 2*m_wipe_tower_data.brim_width; + double depth = m_wipe_tower_data.depth + 2*m_wipe_tower_data.brim_width; + Vec2d pt = Vec2d(m_config.wipe_tower_x-m_wipe_tower_data.brim_width, m_config.wipe_tower_y-m_wipe_tower_data.brim_width); + points.push_back(Point(scale_(pt.x()), scale_(pt.y()))); + points.push_back(Point(scale_(pt.x()+width), scale_(pt.y()))); + points.push_back(Point(scale_(pt.x()+width), scale_(pt.y()+depth))); + points.push_back(Point(scale_(pt.x()), scale_(pt.y()+depth))); + } if (points.size() < 3) // At least three points required for a convex hull.