From 0a20f1fe6d6d63cdcb13bc19fd9ae553f45b6f59 Mon Sep 17 00:00:00 2001 From: "jiangkai.zhao" Date: Mon, 10 Feb 2025 15:58:34 +0800 Subject: [PATCH] ENH: Change the collision calculation of the wipe tower's outer wall to use the actual outer wall path. jira: none Change-Id: Ib45ecbc328c88c1abe6d9e8567f715331a3ddd37 --- src/libslic3r/GCode/ConflictChecker.cpp | 3 +- src/libslic3r/GCode/WipeTower.cpp | 26 ++++++---------- src/libslic3r/GCode/WipeTower.hpp | 16 ++++++++-- src/libslic3r/Print.cpp | 3 +- src/libslic3r/Print.hpp | 40 ++++++++++++++----------- 5 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/libslic3r/GCode/ConflictChecker.cpp b/src/libslic3r/GCode/ConflictChecker.cpp index 1c0c7f3d8..ee25879c6 100644 --- a/src/libslic3r/GCode/ConflictChecker.cpp +++ b/src/libslic3r/GCode/ConflictChecker.cpp @@ -227,7 +227,8 @@ ConflictResultOpt ConflictChecker::find_inter_of_lines_in_diff_objs(PrintObjectP LinesBucketQueue conflictQueue; if (wtdptr.has_value()) { // wipe tower at 0 by default - auto wtpaths = wtdptr.value()->getFakeExtrusionPathsFromWipeTower(); + //auto wtpaths = wtdptr.value()->getFakeExtrusionPathsFromWipeTower(); + auto wtpaths = wtdptr.value()->getTrueExtrusionPathsFromWipeTower(); ExtrusionLayers wtels; wtels.type = ExtrusionLayersType::WIPE_TOWER; for (int i = 0; i < wtpaths.size(); ++i) { // assume that wipe tower always has same height diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index e25ba25df..e31ca038e 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -2966,26 +2966,17 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter, // for skirt calculation and pass it to GLCanvas for precise preview box m_wipe_tower_brim_width_real = loops_num * spacing + spacing / 2.f; //m_wipe_tower_brim_width_real = wt_box.ld.x() - box.ld.x() + spacing / 2.f; - - // set wipe_tower_bbx - auto real_polygon = outer_wall; - real_polygon = offset(real_polygon, scaled(spacing/2.f)).front(); - auto real_box = get_extents(real_polygon); - m_wipe_tower_bbx = BoundingBoxf(unscale(real_box.min), unscale(real_box.max)); } //wt_box = box; } - else { - if (first_layer) { - auto real_polygon = outer_wall; - real_polygon = offset(real_polygon, scaled(spacing / 2.f)).front(); - auto real_box = get_extents(real_polygon); - m_wipe_tower_bbx = BoundingBoxf(unscale(real_box.min), unscale(real_box.max)); - } - } - if (extrude_perimeter || loops_num > 0) + if (extrude_perimeter || loops_num > 0) { writer.add_wipe_path(outer_wall, m_filpar[m_current_tool].wipe_dist); + if (!extrude_perimeter) + m_outer_wall.back() = to_polyline(outer_wall); + else + m_outer_wall.push_back(to_polyline(outer_wall)); + } else { // Now prepare future wipe. box contains rectangle that was extruded last (ccw). Vec2f target = (writer.pos() == wt_box.ld ? wt_box.rd : (writer.pos() == wt_box.rd ? wt_box.ru : (writer.pos() == wt_box.ru ? wt_box.lu : wt_box.ld))); @@ -3637,7 +3628,7 @@ void WipeTower::generate_new(std::vector layer_result; - + m_outer_wall.reserve(m_plan.size()); int index = 0; for (auto layer : m_plan) { reset_block_status(); @@ -3797,6 +3788,7 @@ void WipeTower::generate_new(std::vector m_wall_skip_points; + std::vector m_outer_wall; bool is_first_layer() const { return size_t(m_layer_info - m_plan.begin()) == m_first_layer_idx; } // Calculates length of extrusion line to extrude given volume diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index dcd6fbc87..e4093a93a 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2027,7 +2027,6 @@ void Print::process(std::unordered_map* slice_time, bool std::optional wipe_tower_opt = {}; if (this->has_wipe_tower()) { m_fake_wipe_tower.set_pos({m_config.wipe_tower_x.get_at(m_plate_index), m_config.wipe_tower_y.get_at(m_plate_index)}); - m_fake_wipe_tower.set_bbx(); wipe_tower_opt = std::make_optional(&m_fake_wipe_tower); } auto conflictRes = ConflictChecker::find_inter_of_lines_in_diff_objs(m_objects, wipe_tower_opt); @@ -2751,7 +2750,7 @@ void Print::_make_wipe_tower() const Vec3d origin = this->get_plate_origin(); m_fake_wipe_tower.set_fake_extrusion_data(wipe_tower.position(), wipe_tower.width(), wipe_tower.get_height(), wipe_tower.get_layer_height(), m_wipe_tower_data.depth, m_wipe_tower_data.brim_width, {scale_(origin.x()), scale_(origin.y())}); - m_fake_wipe_tower.real_bbx = wipe_tower.get_bbx(); + m_fake_wipe_tower.outer_wall = wipe_tower.get_outer_wall(); } // Generate a recommended G-code output file name based on the format template, default extension, and template parameters diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 81e2198a3..931e42f76 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -614,7 +614,7 @@ struct FakeWipeTower float depth; float brim_width; Vec2d plate_origin; - BoundingBoxf real_bbx; + Polylines outer_wall; //wipe tower's true outer wall void set_fake_extrusion_data(Vec2f p, float w, float h, float lh, float d, float bd, Vec2d o) { @@ -626,11 +626,6 @@ struct FakeWipeTower brim_width = bd; plate_origin = o; } - void set_bbx() - { - real_bbx.min += pos.cast(); - real_bbx.max += pos.cast(); - } void set_pos(Vec2f p) { pos = p; } @@ -639,10 +634,8 @@ struct FakeWipeTower int d = scale_(depth); int w = scale_(width); int bd = scale_(brim_width); - //Point minCorner = {scale_(pos.x()), scale_(pos.y())}; - //Point maxCorner = {minCorner.x() + w, minCorner.y() + d}; - Point minCorner = {scale_(real_bbx.min.x()), scale_(real_bbx.min.y())}; - Point maxCorner = {scale_(real_bbx.max.x()), scale_(real_bbx.max.y())}; + Point minCorner = {scale_(pos.x()), scale_(pos.y())}; + Point maxCorner = {minCorner.x() + w, minCorner.y() + d}; std::vector paths; for (float h = 0.f; h < height; h += layer_height) { @@ -650,13 +643,26 @@ struct FakeWipeTower path.polyline = {minCorner, {maxCorner.x(), minCorner.y()}, maxCorner, {minCorner.x(), maxCorner.y()}, minCorner}; paths.push_back({path}); - //if (h == 0.f) { // add brim - // ExtrusionPath fakeBrim(ExtrusionRole::erBrim, 0.0, 0.0, layer_height); - // Point wtbminCorner = {minCorner - Point{bd, bd}}; - // Point wtbmaxCorner = {maxCorner + Point{bd, bd}}; - // fakeBrim.polyline = {wtbminCorner, {wtbmaxCorner.x(), wtbminCorner.y()}, wtbmaxCorner, {wtbminCorner.x(), wtbmaxCorner.y()}, wtbminCorner}; - // paths.back().push_back(fakeBrim); - //} + if (h == 0.f) { // add brim + ExtrusionPath fakeBrim(ExtrusionRole::erBrim, 0.0, 0.0, layer_height); + Point wtbminCorner = {minCorner - Point{bd, bd}}; + Point wtbmaxCorner = {maxCorner + Point{bd, bd}}; + fakeBrim.polyline = {wtbminCorner, {wtbmaxCorner.x(), wtbminCorner.y()}, wtbmaxCorner, {wtbminCorner.x(), wtbmaxCorner.y()}, wtbminCorner}; + paths.back().push_back(fakeBrim); + } + } + return paths; + } + + std::vector getTrueExtrusionPathsFromWipeTower() const + { + std::vector paths; + Point trans = {scale_(pos.x()), scale_(pos.y())}; + for (auto &polyline : outer_wall) { + ExtrusionPath path(ExtrusionRole::erWipeTower, 0.0, 0.0, layer_height); + path.polyline.points.reserve( polyline.points.size()); + for (auto &p : polyline.points) path.polyline.points.push_back(p + trans); + paths.push_back({path}); } return paths; }