From ed7bfd3ff6732efe6c7e9eb96901be1db00bb3d0 Mon Sep 17 00:00:00 2001 From: "jiangkai.zhao" Date: Wed, 12 Feb 2025 21:00:15 +0800 Subject: [PATCH] ENH: add solid infill before nozzlechange and set the contact surfaces of different material types as solid, and reduce the nozzlechange speed if it occurs at the contact surface, and recuce the toolchange speed if it occurs at the contact surface. jira: none Change-Id: I884d60f4114544dfa959bd654ecc985f5fb9aac4 --- src/libslic3r/GCode/WipeTower.cpp | 109 ++++++++++++++++++++++++------ src/libslic3r/GCode/WipeTower.hpp | 8 ++- 2 files changed, 93 insertions(+), 24 deletions(-) diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 2c715eedd..f2695a02a 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -2624,11 +2624,11 @@ void WipeTower::get_wall_skip_points(const WipeTowerInfo &layer) } } -WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool) +WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool, bool solid_change) { m_nozzle_change_result.gcode.clear(); if (!m_filament_map.empty() && new_tool < m_filament_map.size() && m_filament_map[m_current_tool] != m_filament_map[new_tool]) { - m_nozzle_change_result = nozzle_change_new(m_current_tool, new_tool); + m_nozzle_change_result = nozzle_change_new(m_current_tool, new_tool, solid_change); } size_t old_tool = m_current_tool; @@ -2649,8 +2649,8 @@ WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool) } WipeTowerBlock &block = get_block_by_category(m_filpar[new_tool].category); - m_cur_block = █ - box_coordinates cleaning_box(Vec2f(m_perimeter_width, block.cur_depth), m_wipe_tower_width - 2 * m_perimeter_width, block.depth); + m_cur_block = █ + box_coordinates cleaning_box(Vec2f(m_perimeter_width, block.cur_depth), m_wipe_tower_width - 2 * m_perimeter_width, wipe_depth-m_layer_info->extra_spacing*nozzle_change_depth); WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar); writer.set_extrusion_flow(m_extrusion_flow) @@ -2714,7 +2714,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool) writer.travel(initial_position); } - toolchange_wipe_new(writer, cleaning_box, wipe_length); + toolchange_wipe_new(writer, cleaning_box, wipe_length, solid_change); writer.append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_Tower_End) + "\n"); ++m_num_tool_changes; @@ -2740,7 +2740,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool) return construct_tcr(writer, false, old_tool, false, true, purge_volume); } -WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id, int new_filament_id) +WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id, int new_filament_id, bool solid_infill) { int nozzle_change_line_count = 0; if (new_filament_id != (unsigned int) (-1)) { @@ -2767,13 +2767,13 @@ WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id, float nz_extrusion_flow = nozzle_change_extrusion_flow(m_layer_height); float nozzle_change_speed = 60.0f * m_filpar[m_current_tool].max_e_speed / nz_extrusion_flow; - + nozzle_change_speed = solid_infill ? 40.f * 60.f : nozzle_change_speed; float bridge_speed = 60.f * 50; // limit the bridge speed to 50 for nozzle change //float nozzle_change_speed = is_first_layer() ? std::min(m_first_layer_speed * 60.f, 4800.f) : 4800.f; if (is_tpu_filament(m_current_tool)) { nozzle_change_speed *= 0.25; } - bridge_speed = std::min(bridge_speed, nozzle_change_speed); + bridge_speed = nozzle_change_speed; WipeTowerWriter writer(m_layer_height, m_nozzle_change_perimeter_width, m_gcode_flavor, m_filpar); writer.set_extrusion_flow(nz_extrusion_flow) @@ -2796,9 +2796,19 @@ WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id, float dy = m_layer_info->extra_spacing * m_nozzle_change_perimeter_width; if (has_tpu_filament() && m_extra_spacing < m_tpu_fixed_spacing) dy = m_tpu_fixed_spacing * m_nozzle_change_perimeter_width; - + dy = solid_infill ? m_nozzle_change_perimeter_width : dy; + nozzle_change_line_count = solid_infill ? std::numeric_limits::max() : nozzle_change_line_count; m_left_to_right = true; for (int i = 0; true; ++i) { +#if 0 + if (need_thick_bridge_flow(writer.pos().y())) { + writer.set_extrusion_flow(extrusion_flow(0.2)); + nozzle_change_speed = 60.0f * m_filpar[m_current_tool].max_e_speed / extrusion_flow(0.2); + } else { + writer.set_extrusion_flow(get_extrusion_flow()); + nozzle_change_speed = 60.0f * m_filpar[m_current_tool].max_e_speed / get_extrusion_flow(); + } +#endif bool need_change_flow = need_thick_bridge_flow(writer.y()); if (m_left_to_right) writer.extrude(xr + wipe_tower_wall_infill_overlap * m_perimeter_width, writer.y(), need_change_flow ? bridge_speed : nozzle_change_speed); @@ -2807,7 +2817,7 @@ WipeTower::NozzleChangeResult WipeTower::nozzle_change_new(int old_filament_id, if (i == nozzle_change_line_count - 1) break; - + if (writer.y() + dy - float(EPSILON) > cleaning_box.ru.y() - m_nozzle_change_perimeter_width) break; writer.travel(writer.x(), writer.y() + dy, nozzle_change_speed); m_left_to_right = !m_left_to_right; } @@ -3209,7 +3219,7 @@ WipeTower::ToolChangeResult WipeTower::finish_block_solid(const WipeTowerBlock & return construct_block_tcr(writer, false, filament_id, true, 0.f); } -void WipeTower::toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinates &cleaning_box, float wipe_length) +void WipeTower::toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinates &cleaning_box, float wipe_length,bool solid_tool_toolchange) { writer.set_extrusion_flow(m_extrusion_flow * (is_first_layer() ? 1.15f : 1.f)).append("; CP TOOLCHANGE WIPE\n"); @@ -3227,12 +3237,14 @@ void WipeTower::toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinat const float &xr = cleaning_box.rd.x(); float x_to_wipe = wipe_length; - float dy = m_layer_info->extra_spacing * m_perimeter_width; - - const float target_speed = is_first_layer() ? std::min(m_first_layer_speed * 60.f, 4800.f) : 4800.f; + float dy = solid_tool_toolchange ? m_perimeter_width :m_layer_info->extra_spacing * m_perimeter_width; + x_to_wipe = solid_tool_toolchange ? std::numeric_limits::max(): x_to_wipe; + float target_speed = is_first_layer() ? std::min(m_first_layer_speed * 60.f, 4800.f) : 4800.f; + target_speed = solid_tool_toolchange ? 40.f*60.f : target_speed; float wipe_speed = 0.33f * target_speed; m_left_to_right = ((m_cur_layer_id + 3) % 4 >= 2); + bool is_from_up = (m_cur_layer_id % 2 == 1); // now the wiping itself: @@ -3301,10 +3313,10 @@ void WipeTower::toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinat writer.append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) + std::to_string(m_layer_height) + "\n"); } - if (!is_from_up && (writer.y() - float(EPSILON) > cleaning_box.lu.y())) + if (!is_from_up && (writer.y() + dy - float(EPSILON) > cleaning_box.lu.y() - m_perimeter_width)) break; // in case next line would not fit - if (is_from_up && (writer.y() + float(EPSILON) < cleaning_box.ld.y())) + if (is_from_up && (writer.y() - dy + float(EPSILON) < cleaning_box.ld.y() + m_perimeter_width)) break; x_to_wipe -= (xr - xl); @@ -3469,14 +3481,31 @@ void WipeTower::generate_wipe_tower_blocks() block.layer_depths.resize(all_layer_category_to_depth.size(), 0); block.solid_infill.resize(all_layer_category_to_depth.size(), false); block.finish_depth.resize(all_layer_category_to_depth.size(), 0); + block.solid_infill_lower_h_nozzlechange.resize(all_layer_category_to_depth.size(), false); + block.has_nozzle_change.resize(all_layer_category_to_depth.size(), false); } block.depth = std::max(block.depth, iter->second); block.layer_depths[layer_id] = iter->second; } } + //set block has_nozzle_change + for (int layer_id = 0; layer_id < all_layer_category_to_depth.size(); ++layer_id) { + for(int i = 0; i < m_plan[layer_id].tool_changes.size(); i++) { + const WipeTowerInfo::ToolChange &tool_change = m_plan[layer_id].tool_changes[i]; + size_t old_filament = tool_change.old_tool; + size_t new_filament = tool_change.new_tool; + if (!m_filament_map.empty() && new_filament < m_filament_map.size() && m_filament_map[old_filament] != m_filament_map[new_filament]) { + auto &block = get_block_by_category(m_filpar[old_filament].category); + block.has_nozzle_change[layer_id] = true; + } + } + } + // add solid infill flag - int solid_infill_layer = 2; + // if the upper layer has a lower layer height and has_nozzle_change + int solid_infill_layer = 3; + float lower_layer_height = 0.2 - WT_EPSILON; for (WipeTowerBlock& block : m_wipe_tower_blocks) { for (int layer_id = 0; layer_id < all_layer_category_to_depth.size(); ++layer_id) { std::unordered_map &category_to_depth = all_layer_category_to_depth[layer_id]; @@ -3495,6 +3524,27 @@ void WipeTower::generate_wipe_tower_blocks() } } } + solid_infill_layer = 2; + for (WipeTowerBlock &block : m_wipe_tower_blocks) { + for (int layer_id = 0; layer_id < all_layer_category_to_depth.size(); ++layer_id) { + std::unordered_map &category_to_depth = all_layer_category_to_depth[layer_id]; + if (is_approx(category_to_depth[block.filament_adhesiveness_category], 0.f)) { + int layer_count = solid_infill_layer; + while (layer_count > 0) { + if (layer_id + layer_count < all_layer_category_to_depth.size()) { + std::unordered_map &up_layer_depth = all_layer_category_to_depth[layer_id + layer_count]; + float up_layer_height = m_plan[layer_id + layer_count].height; + bool has_nozzlechange = block.has_nozzle_change[layer_id + layer_count]; + if (up_layer_height < lower_layer_height && has_nozzlechange) { + block.solid_infill_lower_h_nozzlechange[layer_id] = true; + break; + } + } + --layer_count; + } + } + } + } // 4. get real depth for every layer for (int layer_id = m_plan.size() - 1; layer_id >= 0; --layer_id) { @@ -3669,6 +3719,7 @@ 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) { reset_block_status(); m_cur_layer_id = index++; @@ -3718,7 +3769,8 @@ void WipeTower::generate_new(std::vector layer_depths; std::vector solid_infill; + std::vector solid_infill_lower_h_nozzlechange; + std::vector has_nozzle_change; std::vector finish_depth{0}; // the start pos of finish frame for every layer float depth{0}; float start_depth{0}; @@ -369,12 +371,12 @@ public: void generate_wipe_tower_blocks(); void update_all_layer_depth(float wipe_tower_depth); - ToolChangeResult tool_change_new(size_t new_tool); - NozzleChangeResult nozzle_change_new(int old_filament_id, int new_filament_id); + ToolChangeResult tool_change_new(size_t new_tool, bool solid_change = false); + NozzleChangeResult nozzle_change_new(int old_filament_id, int new_filament_id, bool solid_change = false); ToolChangeResult finish_layer_new(bool extrude_perimeter = true, bool extrude_fill = true, bool extrude_fill_wall = true); ToolChangeResult finish_block(const WipeTowerBlock &block, int filament_id, bool extrude_fill = true); ToolChangeResult finish_block_solid(const WipeTowerBlock &block, int filament_id, bool extrude_fill = true); - void toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinates &cleaning_box, float wipe_length); + void toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinates &cleaning_box, float wipe_length,bool solid_toolchange=false); Vec2f get_rib_offset() const { return m_rib_offset; } private: