From b36c41e5146168325d8b7ec966eb97f1062442a7 Mon Sep 17 00:00:00 2001 From: "jiangkai.zhao" Date: Mon, 17 Feb 2025 11:47:41 +0800 Subject: [PATCH] ENH: reopen confilctchecker with adpative height. and fix conflict checking when the wipe tower's brim fully encloses the model jira: STUDIO-10237, STUDIO-10296 Change-Id: I6e2a6640c06ddb6b3af700c9048fa26434411631 --- src/libslic3r/GCode/ConflictChecker.cpp | 19 ++++++------ src/libslic3r/GCode/WipeTower.cpp | 11 +++---- src/libslic3r/GCode/WipeTower.hpp | 15 +++++----- src/libslic3r/Print.cpp | 39 +++++++++++++++++++++++-- src/libslic3r/Print.hpp | 16 ++-------- 5 files changed, 61 insertions(+), 39 deletions(-) diff --git a/src/libslic3r/GCode/ConflictChecker.cpp b/src/libslic3r/GCode/ConflictChecker.cpp index ee25879c6..03ea59e40 100644 --- a/src/libslic3r/GCode/ConflictChecker.cpp +++ b/src/libslic3r/GCode/ConflictChecker.cpp @@ -228,16 +228,15 @@ ConflictResultOpt ConflictChecker::find_inter_of_lines_in_diff_objs(PrintObjectP if (wtdptr.has_value()) { // wipe tower at 0 by default //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 - ExtrusionLayer el; - el.paths = wtpaths[i]; - el.bottom_z = wtpaths[i].front().height * (float) i; - el.layer = nullptr; - wtels.push_back(el); - } + ExtrusionLayers wtels = wtdptr.value()->getTrueExtrusionLayersFromWipeTower(); + //wtels.type = ExtrusionLayersType::WIPE_TOWER; + //for (int i = 0; i < wtpaths.size(); ++i) { // assume that wipe tower always has same height + // ExtrusionLayer el; + // el.paths = wtpaths[i]; + // el.bottom_z = wtpaths[i].front().height * (float) i; + // el.layer = nullptr; + // wtels.push_back(el); + //} conflictQueue.emplace_back_bucket(std::move(wtels), wtdptr.value(), {wtdptr.value()->plate_origin.x(), wtdptr.value()->plate_origin.y()}); } for (PrintObject *obj : objs) { diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 36f063680..ed070d45c 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -2971,7 +2971,8 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter, //} Polygon outer_wall; outer_wall = generate_support_wall_new(writer, wt_box, feedrate, first_layer, m_use_rib_wall, extrude_perimeter, m_use_gap_wall); - + if (extrude_perimeter) + m_outer_wall[m_z_pos].push_back(to_polyline(outer_wall)); // brim chamfer float spacing = m_perimeter_width - m_layer_height * float(1. - M_PI_4); // How many perimeters shall the brim have? @@ -2994,6 +2995,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter, for (size_t i = 0; i < loops_num; ++i) { outer_wall = offset(outer_wall, scaled(spacing)).front(); writer.polygon(outer_wall, feedrate); + m_outer_wall[m_z_pos].push_back(to_polyline(outer_wall)); } /*for (size_t i = 0; i < loops_num; ++i) { @@ -3012,10 +3014,6 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter, 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). @@ -3723,7 +3721,6 @@ void WipeTower::generate_new(std::vector layer_result; - m_outer_wall.reserve(m_plan.size()); int index = 0; std::unordered_set solid_blocks_id;// The contact surface of different bonded materials is solid. for (auto layer : m_plan) { @@ -4061,7 +4058,7 @@ WipeTower::ToolChangeResult WipeTower::only_generate_out_wall(bool is_new_mode) //else // writer.rectangle(wt_box, feedrate); outer_wall = generate_support_wall_new(writer, wt_box, feedrate, first_layer, m_use_rib_wall, true, m_use_gap_wall); - m_outer_wall.push_back( to_polyline(outer_wall)); + m_outer_wall[m_z_pos].push_back(to_polyline(outer_wall)); // 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))); diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index aa32b231b..4e5333a26 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -188,17 +188,18 @@ public: float get_depth() const { return m_wipe_tower_depth; } float get_brim_width() const { return m_wipe_tower_brim_width_real; } BoundingBoxf get_bbx() const { - BoundingBox box = get_extents(m_outer_wall.front()); + BoundingBox box = get_extents(m_outer_wall.begin()->second); BoundingBoxf res = BoundingBoxf(unscale(box.min), unscale(box.max)); res.translate(m_rib_offset.cast()); return res; } - Polylines get_outer_wall() const { - Polylines res = m_outer_wall; + std::map get_outer_wall() const + { + std::map res = m_outer_wall; Point trans = scaled(m_rib_offset); - for (auto &polyline : res) - for (auto &p : polyline.points) - p += trans; + for (auto &[h,polylines] : res) + for (auto &polyline : polylines) + polyline.translate(trans.x(), trans.y()); return res; } float get_height() const { return m_wipe_tower_height; } @@ -481,7 +482,7 @@ private: float m_extra_spacing = 1.f; float m_tpu_fixed_spacing = 2; std::vector m_wall_skip_points; - std::vector m_outer_wall; + std::map 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 d4e2658f2..e826ec065 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2024,8 +2024,7 @@ void Print::process(std::unordered_map* slice_time, bool break; } } - // TODO adaptive layer height won't work with conflict checker because m_fake_wipe_tower's path is generated using fixed layer height - if(!m_no_check && !has_adaptive_layer_height) + if(!m_no_check /*&& !has_adaptive_layer_height*/) { using Clock = std::chrono::high_resolution_clock; auto startTime = Clock::now(); @@ -4098,4 +4097,40 @@ Point PrintInstance::shift_without_plate_offset() const return shift - Point(scaled(plate_offset.x()), scaled(plate_offset.y())); } +ExtrusionLayers FakeWipeTower::getTrueExtrusionLayersFromWipeTower() const +{ + ExtrusionLayers wtels; + wtels.type = ExtrusionLayersType::WIPE_TOWER; + std::vector layer_heights; + layer_heights.reserve(outer_wall.size()); + auto pre = outer_wall.begin(); + for (auto it = outer_wall.begin(); it != outer_wall.end(); ++it) { + if (it == outer_wall.begin()) + layer_heights.push_back(it->first); + else { + layer_heights.push_back(it->first - pre->first); + ++pre; + } + } + Point trans = {scale_(pos.x()), scale_(pos.y())}; + for (auto it = outer_wall.begin(); it != outer_wall.end(); ++it) { + int index = std::distance(outer_wall.begin(), it); + ExtrusionLayer el; + ExtrusionPaths paths; + paths.reserve(it->second.size()); + for (auto &polyline : it->second) { + ExtrusionPath path(ExtrusionRole::erWipeTower, 0.0, 0.0, layer_heights[index]); + path.polyline = polyline; + for (auto &p : path.polyline.points) p += trans; + paths.push_back(path); + } + el.paths = std::move(paths); + el.bottom_z = it->first - layer_heights[index]; + el.layer = nullptr; + wtels.push_back(el); + } + return wtels; +} + + } // namespace Slic3r diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 4585bfc74..a8ac93f86 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -36,6 +36,7 @@ class SupportLayer; // BBS class TreeSupportData; class TreeSupport; +class ExtrusionLayers; #define MARGIN_HEIGHT 1.5 #define MAX_OUTER_NOZZLE_RADIUS 4 @@ -621,7 +622,7 @@ struct FakeWipeTower float depth; float brim_width; Vec2d plate_origin; - Polylines outer_wall; //wipe tower's true outer wall + std::map outer_wall; //wipe tower's true outer wall and brim void set_fake_extrusion_data(Vec2f p, float w, float h, float lh, float d, float bd, Vec2d o) { @@ -661,18 +662,7 @@ struct FakeWipeTower 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; - } + ExtrusionLayers getTrueExtrusionLayersFromWipeTower() const; }; struct WipeTowerData