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: