From 89b59f1c41e0f360457622438a09237bfa1eaa18 Mon Sep 17 00:00:00 2001 From: "jiangkai.zhao" Date: Sat, 8 Feb 2025 10:04:41 +0800 Subject: [PATCH] ENH: add wipe_tower infll gap and fix wipe error when enable timelapse and in single color and set rib wall as default jira: none Change-Id: Ic365bb7ee0ee6715c9d4f4f00b4bca9fd472c61a --- src/libslic3r/GCode/WipeTower.cpp | 56 +++++++-------------------- src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 10 ++++- src/libslic3r/PrintConfig.hpp | 1 + src/slic3r/GUI/ConfigManipulation.cpp | 2 +- src/slic3r/GUI/PartPlate.cpp | 41 +++----------------- src/slic3r/GUI/Plater.cpp | 2 +- src/slic3r/GUI/Tab.cpp | 1 + 8 files changed, 34 insertions(+), 81 deletions(-) diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 3a83d84f5..0599147f9 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -1352,9 +1352,10 @@ WipeTower::WipeTower(const PrintConfig& config, int plate_idx, Vec3d plate_origi m_is_multi_extruder(config.nozzle_diameter.size() > 1), m_use_gap_wall(config.prime_tower_skip_points.value), m_use_rib_wall(config.prime_tower_rib_wall.value), - m_extra_rib_length(config.prime_tower_extra_rib_length.value), - m_rib_width(config.prime_tower_rib_width.value), - m_used_fillet(config.prime_tower_fillet_wall.value) + m_extra_rib_length((float)config.prime_tower_extra_rib_length.value), + m_rib_width((float)config.prime_tower_rib_width.value), + m_used_fillet(config.prime_tower_fillet_wall.value), + m_extra_spacing((float)config.prime_tower_infill_gap.value/100.f) { // Read absolute value of first layer speed, if given as percentage, // it is taken over following default. Speeds from config are not @@ -2983,7 +2984,8 @@ WipeTower::ToolChangeResult WipeTower::finish_layer_new(bool extrude_perimeter, } } - if (extrude_perimeter) writer.add_wipe_path(outer_wall, m_filpar[m_current_tool].wipe_dist); + if (extrude_perimeter || loops_num > 0) + writer.add_wipe_path(outer_wall, m_filpar[m_current_tool].wipe_dist); 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))); @@ -3482,7 +3484,7 @@ void WipeTower::plan_tower_new() // recalculate wipe_tower_with and layer's depth generate_wipe_tower_blocks(); float max_depth = std::accumulate(m_wipe_tower_blocks.begin(), m_wipe_tower_blocks.end(), 0.f, [](float a, const auto &t) { return a + t.depth; }) + m_perimeter_width; - float square_width = align_ceil(std::sqrt(max_depth * m_wipe_tower_width), m_perimeter_width); + float square_width = align_ceil(std::sqrt(max_depth * m_wipe_tower_width * m_extra_spacing), m_perimeter_width); //std::cout << " before m_wipe_tower_width = " << m_wipe_tower_width << " max_depth = " << max_depth << std::endl; m_wipe_tower_width = square_width; float width = m_wipe_tower_width - 2 * m_perimeter_width; @@ -3515,37 +3517,7 @@ void WipeTower::plan_tower_new() } //std::cout << " after square " << m_wipe_tower_width << " depth " << max_depth << std::endl; - float min_wipe_tower_depth = 0.f; - auto iter = WipeTower::min_depth_per_height.begin(); - while (iter != WipeTower::min_depth_per_height.end()) { - auto curr_height_to_depth = *iter; - - // This is the case that wipe tower height is lower than the first min_depth_to_height member. - if (curr_height_to_depth.first >= m_wipe_tower_height) { - min_wipe_tower_depth = curr_height_to_depth.second; - break; - } - - iter++; - - // If curr_height_to_depth is the last member, use its min_depth. - if (iter == WipeTower::min_depth_per_height.end()) { - min_wipe_tower_depth = curr_height_to_depth.second; - break; - } - - // If wipe tower height is between the current and next member, set the min_depth as linear interpolation between them - auto next_height_to_depth = *iter; - if (next_height_to_depth.first > m_wipe_tower_height) { - float height_base = curr_height_to_depth.first; - float height_diff = next_height_to_depth.first - curr_height_to_depth.first; - float min_depth_base = curr_height_to_depth.second; - float depth_diff = next_height_to_depth.second - curr_height_to_depth.second; - - min_wipe_tower_depth = min_depth_base + (m_wipe_tower_height - curr_height_to_depth.first) / height_diff * depth_diff; - break; - } - } + float min_wipe_tower_depth = get_limit_depth_by_height(m_wipe_tower_height); // only for get m_extra_spacing { @@ -3555,11 +3527,11 @@ void WipeTower::plan_tower_new() } if (max_depth + EPSILON < min_wipe_tower_depth) { - m_extra_spacing = min_wipe_tower_depth / max_depth; - if (m_use_rib_wall) { - m_rib_length = std::max(m_rib_length, min_wipe_tower_depth * (float) std::sqrt(2)); - m_extra_spacing = 1.f; - } + //if enable rib_wall, there is no need to set extra_spacing + if (m_use_rib_wall) + m_rib_length = std::max(m_rib_length, min_wipe_tower_depth * (float) std::sqrt(2)); + else + m_extra_spacing = std::max(min_wipe_tower_depth / max_depth, m_extra_spacing); } for (int idx = 0; idx < m_plan.size(); idx++) { @@ -3646,7 +3618,7 @@ void WipeTower::generate_new(std::vector s_Preset_print_options { "top_surface_line_width", "support_line_width", "infill_wall_overlap", "bridge_flow", "elefant_foot_compensation", "xy_contour_compensation", "xy_hole_compensation", "resolution", "enable_prime_tower", "prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", - "prime_tower_rib_wall","prime_tower_extra_rib_length","prime_tower_rib_width","prime_tower_fillet_wall", + "prime_tower_rib_wall","prime_tower_extra_rib_length","prime_tower_rib_width","prime_tower_fillet_wall","prime_tower_infill_gap", "enable_circle_compensation", "circle_compensation_speed", "circle_compensation_manual_offset", "apply_scarf_seam_on_circles", "counter_coef_1", "counter_coef_2", "counter_coef_3", "hole_coef_1", "hole_coef_2", "hole_coef_3", "counter_limit_min", "counter_limit_max", "hole_limit_min", "hole_limit_max", "diameter_limit", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 6b8ebab1c..c4786ccf5 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4405,7 +4405,7 @@ void PrintConfigDef::init_fff_params() def->label = L("rib wall"); def->tooltip = L("The wall of prime tower will add four ribs"); def->mode = comAdvanced; - def->set_default_value(new ConfigOptionBool(false)); + def->set_default_value(new ConfigOptionBool(true)); def = this->add("prime_tower_fillet_wall", coBool); def->label = L("fillet wall"); @@ -4413,6 +4413,14 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(true)); + def = this->add("prime_tower_infill_gap", coPercent); + def->label = L("Infill gap"); + def->tooltip = L("Infill gap"); + def->sidetext = L("%"); + def->mode = comAdvanced; + def->min = 100; + def->set_default_value(new ConfigOptionPercent(150)); + def = this->add("flush_into_infill", coBool); def->category = L("Flush options"); def->label = L("Flush into objects' infill"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 0e96a12f6..9f8b31e99 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1206,6 +1206,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionFloat, prime_tower_brim_width)) ((ConfigOptionFloat, prime_tower_extra_rib_length)) ((ConfigOptionFloat, prime_tower_rib_width)) + ((ConfigOptionPercent, prime_tower_infill_gap)) ((ConfigOptionBool, prime_tower_skip_points)) ((ConfigOptionBool, prime_tower_rib_wall)) ((ConfigOptionBool, prime_tower_fillet_wall)) diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index c2340c579..cbc69dfd7 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -678,7 +678,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in toggle_field("standby_temperature_delta", have_ooze_prevention); bool have_prime_tower = config->opt_bool("enable_prime_tower"); - for (auto el : {"prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", "prime_tower_rib_wall"}) + for (auto el : {"prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", "prime_tower_rib_wall", "prime_tower_infill_gap"}) toggle_line(el, have_prime_tower); bool have_rib_wall = config->opt_bool("prime_tower_rib_wall")&&have_prime_tower; diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index e4167baf0..38d099a8e 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -1410,7 +1410,8 @@ Vec3d PartPlate::calculate_wipe_tower_size(const DynamicPrintConfig &config, con auto timelapse_type = config.option>("timelapse_type"); bool timelapse_enabled = timelapse_type ? (timelapse_type->value == TimelapseType::tlSmooth) : false; int nozzle_nums = wxGetApp().preset_bundle->get_printer_extruder_count(); - double depth = std::sqrt(wipe_volume * (nozzle_nums == 2 ? plate_extruder_size : (plate_extruder_size - 1)) / layer_height); + double extra_spacing = config.option("prime_tower_infill_gap")->getFloat() / 100.; + double depth = std::sqrt(wipe_volume * (nozzle_nums == 2 ? plate_extruder_size : (plate_extruder_size - 1)) / layer_height * extra_spacing); if (timelapse_enabled || plate_extruder_size > 1) { float min_wipe_tower_depth = WipeTower::get_limit_depth_by_height(max_height); depth = std::max((double) min_wipe_tower_depth, depth); @@ -1454,41 +1455,11 @@ Vec3d PartPlate::estimate_wipe_tower_size(const DynamicPrintConfig & config, con //const DynamicPrintConfig &dconfig = wxGetApp().preset_bundle->prints.get_edited_preset().config; auto timelapse_type = config.option>("timelapse_type"); bool timelapse_enabled = timelapse_type ? (timelapse_type->value == TimelapseType::tlSmooth) : false; - - double depth = wipe_volume * (plate_extruder_size - 1) / (layer_height * w); + double extra_spacing = config.option("prime_tower_infill_gap")->getFloat() / 100.; + double depth = wipe_volume * (plate_extruder_size - 1) / (layer_height * w) *extra_spacing; if (timelapse_enabled || depth > EPSILON) { - float min_wipe_tower_depth = 0.f; - auto iter = WipeTower::min_depth_per_height.begin(); - while (iter != WipeTower::min_depth_per_height.end()) { - auto curr_height_to_depth = *iter; - - // This is the case that wipe tower height is lower than the first min_depth_to_height member. - if (curr_height_to_depth.first >= max_height) { - min_wipe_tower_depth = curr_height_to_depth.second; - break; - } - - iter++; - - // If curr_height_to_depth is the last member, use its min_depth. - if (iter == WipeTower::min_depth_per_height.end()) { - min_wipe_tower_depth = curr_height_to_depth.second; - break; - } - - // If wipe tower height is between the current and next member, set the min_depth as linear interpolation between them - auto next_height_to_depth = *iter; - if (next_height_to_depth.first > max_height) { - float height_base = curr_height_to_depth.first; - float height_diff = next_height_to_depth.first - curr_height_to_depth.first; - float min_depth_base = curr_height_to_depth.second; - float depth_diff = next_height_to_depth.second - curr_height_to_depth.second; - - min_wipe_tower_depth = min_depth_base + (max_height - curr_height_to_depth.first) / height_diff * depth_diff; - break; - } - } - depth = std::max((double)min_wipe_tower_depth, depth); + float min_wipe_tower_depth = WipeTower::get_limit_depth_by_height(max_height); + depth = std::max((double)min_wipe_tower_depth, depth); } wipe_tower_size(1) = depth; return wipe_tower_size; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6f5344484..d4e1b8450 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4122,7 +4122,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) "nozzle_height", "skirt_loops", "skirt_distance", "brim_width", "brim_object_gap", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", - "prime_tower_rib_wall","prime_tower_extra_rib_length", "prime_tower_rib_width","prime_tower_fillet_wall", "filament_prime_volume", + "prime_tower_rib_wall","prime_tower_extra_rib_length", "prime_tower_rib_width","prime_tower_fillet_wall", "prime_tower_infill_gap","filament_prime_volume", "extruder_colour", "filament_colour", "filament_type", "material_colour", "printable_height", "extruder_printable_height", "printer_model", "printer_technology", // These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor. "layer_height", "initial_layer_print_height", "min_layer_height", "max_layer_height", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 1b73bd872..33f45d776 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2228,6 +2228,7 @@ void TabPrint::build() optgroup->append_single_option_line("prime_tower_skip_points", "parameter/prime-tower"); optgroup->append_single_option_line("prime_tower_width","parameter/prime-tower"); optgroup->append_single_option_line("prime_tower_brim_width","parameter/prime-tower"); + optgroup->append_single_option_line("prime_tower_infill_gap","parameter/prime-tower"); optgroup->append_single_option_line("prime_tower_rib_wall", "parameter/prime-tower"); optgroup->append_single_option_line("prime_tower_extra_rib_length","parameter/prime-tower"); optgroup->append_single_option_line("prime_tower_rib_width","parameter/prime-tower");