From 820f12a16be413b3a5497316b08966144b09c73e 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 (cherry picked from commit b36c41e5146168325d8b7ec966eb97f1062442a7) --- 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 55084dfc11..78a696f950 100644 --- a/src/libslic3r/GCode/ConflictChecker.cpp +++ b/src/libslic3r/GCode/ConflictChecker.cpp @@ -225,16 +225,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 db29103dd0..f5e9ec5458 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -2964,7 +2964,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? @@ -2987,6 +2988,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) { @@ -3005,10 +3007,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). @@ -3716,7 +3714,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) { @@ -4054,7 +4051,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 70b8971c55..8c4b11aef6 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -189,17 +189,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; } @@ -483,7 +484,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 381b7e88aa..4021a8fea0 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2263,8 +2263,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache) 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(); @@ -4616,4 +4615,40 @@ int PrintObjectRegions::FuzzySkinPaintedRegion::parent_print_object_region_id(co return this->parent_print_object_region(layer_range)->print_object_region_id(); } +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 5c8024b87c..fa5af27fc0 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -37,6 +37,7 @@ class SupportLayer; // BBS class TreeSupportData; class TreeSupport; +class ExtrusionLayers; #define MAX_OUTER_NOZZLE_DIAMETER 4 // BBS: move from PrintObjectSlice.cpp @@ -600,7 +601,7 @@ struct FakeWipeTower float rotation_angle; float cone_angle; 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) { @@ -654,18 +655,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; std::vector getFakeExtrusionPathsFromWipeTower2() const {