diff --git a/doc/print_settings/quality/quality_settings_wall_and_surfaces.md b/doc/print_settings/quality/quality_settings_wall_and_surfaces.md index 5674f41e0b..fce72eff22 100644 --- a/doc/print_settings/quality/quality_settings_wall_and_surfaces.md +++ b/doc/print_settings/quality/quality_settings_wall_and_surfaces.md @@ -60,7 +60,9 @@ Set this to any option other than Auto will force the wall direction regardless ## Surface flow ratio This factor affects the amount of material for [top or bottom solid infill](strength_settings_top_bottom_shells). You can decrease it slightly to have smooth surface finish. -The actual top surface flow used is calculated by multiplying this value with the filament flow ratio, and if set, the object's flow ratio. +The actual top or bottom surface flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio. + +Other flow ratios, such as ratios for the first layer (does not affect brims and skirts), outer and inner walls, overhang perimeters, sparse infill, internal solid infill, gap fill, support, and support interfaces, can also be adjusted after enabling the "Set other flow ratios" option. > [!TIP] > Before using a value other than 1, it is recommended to [calibrate the flow ratio](flow-rate-calib) to ensure that the flow ratio is set correctly for your printer and filament. diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index e0dd3d71f5..c229b452fc 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5854,9 +5854,9 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, sloped == nullptr ? DBL_MAX : get_sloped_z(sloped->slope_begin.z_ratio) ); m_need_change_layer_lift_z = false; - // Orca: force restore Z after unknown last pos + // Orca: ensure Z matches planned layer height if (_last_pos_undefined && !slope_need_z_travel) { - gcode += this->writer().travel_to_z(m_last_layer_z, "force restore Z after unknown last pos", true); + gcode += this->writer().travel_to_z(m_nominal_z, "ensure Z matches planned layer height", true); } } @@ -5930,21 +5930,47 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, // We set _mm3_per_mm to effectove flow = Geometric volume * print flow ratio * filament flow ratio * role-based-flow-ratios auto _mm3_per_mm = path.mm3_per_mm * this->config().print_flow_ratio; _mm3_per_mm *= filament_flow_ratio; - if (path.role() == erTopSolidInfill) + + if (path.role() == erTopSolidInfill) { _mm3_per_mm *= m_config.top_solid_infill_flow_ratio; - else if (path.role() == erBottomSurface) + } else if (path.role() == erBottomSurface) { _mm3_per_mm *= m_config.bottom_solid_infill_flow_ratio; - else if (path.role() == erInternalBridgeInfill) + } else if (path.role() == erInternalBridgeInfill) { _mm3_per_mm *= m_config.internal_bridge_flow; - else if(sloped) + } else if (sloped) { _mm3_per_mm *= m_config.scarf_joint_flow_ratio; + } + + if (m_config.set_other_flow_ratios) { + if (path.role() == erExternalPerimeter) { + _mm3_per_mm *= m_config.outer_wall_flow_ratio; + } else if (path.role() == erPerimeter) { + _mm3_per_mm *= m_config.inner_wall_flow_ratio; + } else if (path.role() == erOverhangPerimeter) { + _mm3_per_mm *= m_config.overhang_flow_ratio; + } else if (path.role() == erInternalInfill) { + _mm3_per_mm *= m_config.sparse_infill_flow_ratio; + } else if (path.role() == erSolidInfill) { + _mm3_per_mm *= m_config.internal_solid_infill_flow_ratio; + } else if (path.role() == erGapFill) { + _mm3_per_mm *= m_config.gap_fill_flow_ratio; + } else if (path.role() == erSupportMaterial) { // Should this condition also cover erSupportTransition? + _mm3_per_mm *= m_config.support_flow_ratio; + } else if (path.role() == erSupportMaterialInterface) { + _mm3_per_mm *= m_config.support_interface_flow_ratio; + } + + // Additionally, adjust the value if we are on the first layer (except for brims and skirts) + if (this->on_first_layer() && (path.role() != erBrim && path.role() != erSkirt)) { + _mm3_per_mm *= m_config.first_layer_flow_ratio; + } + } + // Effective extrusion length per distance unit = (filament_flow_ratio/cross_section) * mm3_per_mm / print flow ratio // m_writer.extruder()->e_per_mm3() below is (filament flow ratio / cross-sectional area) double e_per_mm = m_writer.filament()->e_per_mm3() * _mm3_per_mm; e_per_mm /= filament_flow_ratio; - - // set speed if (speed == -1) { if (path.role() == erPerimeter) { diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 3071bbfc11..81000157bf 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -930,6 +930,7 @@ static std::vector s_Preset_print_options { "small_perimeter_speed", "small_perimeter_threshold","bridge_angle","internal_bridge_angle", "filter_out_gap_fill", "travel_acceleration","inner_wall_acceleration", "min_width_top_surface", "default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk","travel_jerk","default_junction_deviation", "top_solid_infill_flow_ratio","bottom_solid_infill_flow_ratio","only_one_wall_first_layer", "print_flow_ratio", "seam_gap", + "set_other_flow_ratios", "first_layer_flow_ratio", "outer_wall_flow_ratio", "inner_wall_flow_ratio", "overhang_flow_ratio", "sparse_infill_flow_ratio", "internal_solid_infill_flow_ratio", "gap_fill_flow_ratio", "support_flow_ratio", "support_interface_flow_ratio", "role_based_wipe_speed", "wipe_speed", "accel_to_decel_enable", "accel_to_decel_factor", "wipe_on_loops", "wipe_before_external_loop", "bridge_density","internal_bridge_density", "precise_outer_wall", "bridge_acceleration", "sparse_infill_acceleration", "internal_solid_infill_acceleration", "tree_support_adaptive_layer_height", "tree_support_auto_brim", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 1084617c8a..bf9266b4dc 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1228,6 +1228,102 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(1)); + def = this->add("set_other_flow_ratios", coBool); + def->label = L("Set other flow ratios"); + def->category = L("Advanced"); + def->tooltip = L("Change flow ratios for other extrusion path types."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("first_layer_flow_ratio", coFloat); + def->label = L("First layer flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material on the first layer for the extrusion path roles listed in this section.\n\n" + "For the first layer, the actual flow ratio for each path role (does not affect brims and skirts) will be multiplied by this value."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); + + def = this->add("outer_wall_flow_ratio", coFloat); + def->label = L("Outer wall flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material for outer walls.\n\n" + "The actual outer wall flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); + + def = this->add("inner_wall_flow_ratio", coFloat); + def->label = L("Inner wall flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material for inner walls.\n\n" + "The actual inner wall flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); + + def = this->add("overhang_flow_ratio", coFloat); + def->label = L("Overhang flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material for overhangs.\n\n" + "The actual overhang flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); + + def = this->add("sparse_infill_flow_ratio", coFloat); + def->label = L("Sparse infill flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material for sparse infill.\n\n" + "The actual sparse infill flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); + + def = this->add("internal_solid_infill_flow_ratio", coFloat); + def->label = L("Internal solid infill flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material for internal solid infill.\n\n" + "The actual internal solid infill flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); + + def = this->add("gap_fill_flow_ratio", coFloat); + def->label = L("Gap fill flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material for filling the gaps.\n\n" + "The actual gap filling flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); + + def = this->add("support_flow_ratio", coFloat); + def->label = L("Support flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material for support.\n\n" + "The actual support flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); + + def = this->add("support_interface_flow_ratio", coFloat); + def->label = L("Support interface flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of material for the support interface.\n\n" + "The actual support interface flow used is calculated by multiplying this value by the filament flow ratio, and if set, the object's flow ratio."); + def->min = 0; + def->max = 2; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(1)); def = this->add("precise_outer_wall",coBool); def->label = L("Precise wall"); @@ -2345,7 +2441,8 @@ void PrintConfigDef::init_fff_params() "\nBe sure to allow enough space between objects, as this compensation is done after the checks."); def->sidetext = "%"; def->ratio_over = ""; - def->min = 10; + def->min = 50; + def->max = 150; def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercents{ 100 }); @@ -2356,7 +2453,8 @@ void PrintConfigDef::init_fff_params() " The part will be scaled in Z to compensate."); def->sidetext = "%"; def->ratio_over = ""; - def->min = 10; + def->min = 50; + def->max = 150; def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercents{ 100 }); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 008e73c436..e70ff7fdf0 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1147,6 +1147,18 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionBool, small_area_infill_flow_compensation)) ((ConfigOptionEnum, wall_direction)) + // Orca: flow ratios + ((ConfigOptionBool, set_other_flow_ratios)) + ((ConfigOptionFloat, first_layer_flow_ratio)) + ((ConfigOptionFloat, outer_wall_flow_ratio)) + ((ConfigOptionFloat, inner_wall_flow_ratio)) + ((ConfigOptionFloat, overhang_flow_ratio)) + ((ConfigOptionFloat, sparse_infill_flow_ratio)) + ((ConfigOptionFloat, internal_solid_infill_flow_ratio)) + ((ConfigOptionFloat, gap_fill_flow_ratio)) + ((ConfigOptionFloat, support_flow_ratio)) + ((ConfigOptionFloat, support_interface_flow_ratio)) + // Orca: seam slopes ((ConfigOptionEnum, seam_slope_type)) ((ConfigOptionBool, seam_slope_conditional)) diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index 17e7fb044f..50272009cd 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -1529,7 +1529,7 @@ void TreeSupport::generate_toolpaths() need_infill &= area_group.need_infill; std::shared_ptr filler_support = std::shared_ptr(Fill::new_from_type(layer_id == 0 ? ipConcentric : m_support_params.base_fill_pattern)); filler_support->set_bounding_box(bbox_object); - filler_support->spacing = object_config.support_base_pattern_spacing.value * support_density;// constant spacing to align support infill lines + filler_support->spacing = support_spacing * support_density; // constant spacing to align support infill lines filler_support->angle = Geometry::deg2rad(object_config.support_angle.value); Polygons loops = to_polygons(poly); diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 0851946dad..bcfbecb9b3 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -822,6 +822,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co bool have_avoid_crossing_perimeters = config->opt_bool("reduce_crossing_wall"); toggle_line("max_travel_detour_distance", have_avoid_crossing_perimeters); + bool has_set_other_flow_ratios = config->opt_bool("set_other_flow_ratios"); + for (auto el : {"first_layer_flow_ratio", "outer_wall_flow_ratio", "inner_wall_flow_ratio", "overhang_flow_ratio", "sparse_infill_flow_ratio", "internal_solid_infill_flow_ratio", "gap_fill_flow_ratio", "support_flow_ratio", "support_interface_flow_ratio"}) + toggle_line(el, has_set_other_flow_ratios); + bool has_overhang_speed = config->opt_bool("enable_overhang_speed"); for (auto el : {"overhang_1_4_speed", "overhang_2_4_speed", "overhang_3_4_speed", "overhang_4_4_speed"}) toggle_line(el, has_overhang_speed); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index e4c8e94542..9f118dbc5f 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2353,6 +2353,16 @@ void TabPrint::build() optgroup->append_single_option_line("print_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); optgroup->append_single_option_line("top_solid_infill_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); optgroup->append_single_option_line("bottom_solid_infill_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("set_other_flow_ratios", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("first_layer_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("outer_wall_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("inner_wall_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("overhang_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("sparse_infill_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("internal_solid_infill_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("gap_fill_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("support_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); + optgroup->append_single_option_line("support_interface_flow_ratio", "quality_settings_wall_and_surfaces#surface-flow-ratio"); optgroup->append_single_option_line("only_one_wall_top", "quality_settings_wall_and_surfaces#only-one-wall"); optgroup->append_single_option_line("min_width_top_surface", "quality_settings_wall_and_surfaces#threshold"); optgroup->append_single_option_line("only_one_wall_first_layer", "quality_settings_wall_and_surfaces#only-one-wall");