diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index ee72c16a9..8cb95ea6c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2916,7 +2916,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de bool variable_speed = false; std::vector new_points{}; if (this->m_config.enable_dynamic_overhang_speeds && !this->on_first_layer() && is_perimeter(path.role())) { - new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, m_config.overhang_overlaps, + new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, m_config.overhang_steepness_levels, m_config.dynamic_overhang_speeds, m_config.get_abs_value("external_perimeter_speed"), speed); variable_speed = std::any_of(new_points.begin(), new_points.end(), [speed](const ProcessedPoint &p) { return p.speed != speed; }); diff --git a/src/libslic3r/GCode/ExtrusionProcessor.hpp b/src/libslic3r/GCode/ExtrusionProcessor.hpp index e44083c68..46ec4ec4d 100644 --- a/src/libslic3r/GCode/ExtrusionProcessor.hpp +++ b/src/libslic3r/GCode/ExtrusionProcessor.hpp @@ -129,35 +129,48 @@ std::vector estimate_points_properties(const std::vector

next_point.distance = distance + boundary_offset; next_point.nearest_prev_layer_line = nearest_line; - if (ADD_INTERSECTIONS) { + if (ADD_INTERSECTIONS && + ((points.back().distance > boundary_offset + EPSILON) != (next_point.distance > boundary_offset + EPSILON))) { const ExtendedPoint &prev_point = points.back(); - if ((prev_point.distance < min_malformation_dist) != (next_point.distance < min_malformation_dist)) { // one in air, one not - auto intersections = unscaled_prev_layer.template intersections_with_line(L{prev_point.position, next_point.position}); - for (const auto &intersection : intersections) { points.emplace_back(intersection, boundary_offset, 1.0); } - } - - if (PREV_LAYER_BOUNDARY_ONLY && prev_point.distance > min_malformation_dist && - next_point.distance > min_malformation_dist) { // both in air - double line_len = (prev_point.position - next_point.position).norm(); - if (line_len > 3.0) { - double a0 = std::clamp((boundary_offset + prev_point.distance) / line_len, 0.0, 1.0); - double a1 = std::clamp((boundary_offset + next_point.distance) / line_len, 0.0, 1.0); - double t0 = std::min(a0, a1); - double t1 = std::max(a0, a1); - - auto p0 = prev_point.position + t0 * (next_point.position - prev_point.position); - auto [p0_dist, p0_near_l, p0_x] = unscaled_prev_layer.signed_distance_from_lines_extra(p0); - points.push_back(ExtendedPoint{p0, float(p0_dist + boundary_offset), p0_near_l}); - - auto p1 = prev_point.position + t1 * (next_point.position - prev_point.position); - auto [p1_dist, p1_near_l, p1_x] = unscaled_prev_layer.signed_distance_from_lines_extra(p1); - points.push_back(ExtendedPoint{p1, float(p1_dist + boundary_offset), p1_near_l}); - } + auto intersections = unscaled_prev_layer.template intersections_with_line(L{prev_point.position, next_point.position}); + for (const auto &intersection : intersections) { + points.emplace_back(intersection, boundary_offset); } } points.push_back(next_point); } + if (PREV_LAYER_BOUNDARY_ONLY && ADD_INTERSECTIONS) { + std::vector new_points; + new_points.reserve(points.size() * 2); + new_points.push_back(points.front()); + for (int point_idx = 0; point_idx < int(points.size()) - 1; ++point_idx) { + const ExtendedPoint &curr = points[point_idx]; + const ExtendedPoint &next = points[point_idx + 1]; + + if ((curr.distance > 0 && curr.distance < boundary_offset + 2.0f) && + (next.distance > 0 && next.distance < boundary_offset + 2.0f)) { + double line_len = (next.position - curr.position).norm(); + if (line_len > 4.0f) { + double a0 = std::clamp((curr.distance + 2 * boundary_offset) / line_len, 0.0, 1.0); + double a1 = std::clamp(1.0f - (next.distance + 2 * boundary_offset) / line_len, 0.0, 1.0); + double t0 = std::min(a0, a1); + double t1 = std::max(a0, a1); + + auto p0 = curr.position + t0 * (next.position - curr.position); + auto [p0_dist, p0_near_l, p0_x] = unscaled_prev_layer.signed_distance_from_lines_extra(p0); + new_points.push_back(ExtendedPoint{p0, float(p0_dist + boundary_offset), p0_near_l}); + + auto p1 = curr.position + t1 * (next.position - curr.position); + auto [p1_dist, p1_near_l, p1_x] = unscaled_prev_layer.signed_distance_from_lines_extra(p1); + new_points.push_back(ExtendedPoint{p1, float(p1_dist + boundary_offset), p1_near_l}); + } + } + new_points.push_back(next); + } + points = std::move(new_points); + } + for (int point_idx = 0; point_idx < int(points.size()); ++point_idx) { ExtendedPoint &a = points[point_idx]; ExtendedPoint &prev = points[point_idx > 0 ? point_idx - 1 : point_idx]; @@ -255,7 +268,7 @@ public: return final_speed; }; - float extrusion_speed = (calculate_speed(curr.distance) + calculate_speed(next.distance)) / 2.0f; + float extrusion_speed = std::min(calculate_speed(curr.distance), calculate_speed(next.distance)); processed_points.push_back({scaled(curr.position), extrusion_speed}); } diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 1a181a3fd..842638efc 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -429,7 +429,7 @@ static std::vector s_Preset_print_options { "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_dist", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed", - "enable_dynamic_overhang_speeds", "dynamic_overhang_speeds", "overhang_overlaps", + "enable_dynamic_overhang_speeds", "dynamic_overhang_speeds", "overhang_steepness_levels", "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed", "bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration", "bridge_acceleration", "first_layer_acceleration", "first_layer_acceleration_over_raft", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 7a19a0a42..a3159ea11 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -535,11 +535,11 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(true)); - def = this->add("overhang_overlaps", coPercents); - def->full_label = L("Overhang overlap percentage"); + def = this->add("overhang_steepness_levels", coPercents); + def->full_label = L("Steepness levels of overhangs"); def->category = L("Speed"); - def->tooltip = L("Controls percentage of overhang extrusion overlap with the previous layer." - "Each overlap size then corresponds with the overhang speed set below."); + def->tooltip = L("Controls overhang steepness, expressed as percentage of overlap of the extrusion with the previous layer. " + "Each overhang level then corresponds with the overhang speed below."); def->sidetext = L("%"); def->min = 0; def->max = 100; @@ -549,9 +549,8 @@ void PrintConfigDef::init_fff_params() def = this->add("dynamic_overhang_speeds", coFloatsOrPercents); def->full_label = L("Dynamic speed on overhangs"); def->category = L("Speed"); - def->tooltip = L("This setting controls the speed of the overhangs for overlap values set above." - "The final speed is calculated as an interpolation of the set speed values." - "If set as percentage, the speeds are calculated over the external perimeter speed." + def->tooltip = L("This setting controls the speed on the overhang with steepness value above. " + "If set as percentage, the speed is calculated over the external perimeter speed." ); def->sidetext = L("mm/s or %"); def->min = 0; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index ba4d1d26b..13dab3fe1 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -565,7 +565,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloatOrPercent, external_perimeter_extrusion_width)) ((ConfigOptionFloatOrPercent, external_perimeter_speed)) ((ConfigOptionBool, enable_dynamic_overhang_speeds)) - ((ConfigOptionPercents, overhang_overlaps)) + ((ConfigOptionPercents, overhang_steepness_levels)) ((ConfigOptionFloatsOrPercents, dynamic_overhang_speeds)) ((ConfigOptionBool, external_perimeters_first)) ((ConfigOptionBool, extra_perimeters)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 6f771b1d2..24a4191c1 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -749,7 +749,7 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "support_material_interface_speed" || opt_key == "bridge_speed" || opt_key == "enable_dynamic_overhang_speeds" - || opt_key == "overhang_overlaps" + || opt_key == "overhang_steepness_levels" || opt_key == "dynamic_overhang_speeds" || opt_key == "external_perimeter_speed" || opt_key == "infill_speed" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 131adee60..482f000f0 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -7,6 +7,7 @@ #include "libslic3r/PresetBundle.hpp" #include "MsgDialog.hpp" +#include #include namespace Slic3r { @@ -220,11 +221,13 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) bool have_perimeters = config->opt_int("perimeters") > 0; for (auto el : { "extra_perimeters","extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "thin_walls", "overhangs", "seam_position","staggered_inner_seams", "external_perimeters_first", "external_perimeter_extrusion_width", - "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "enable_dynamic_overhang_speeds", "overhang_overlaps", "dynamic_overhang_speeds" }) + "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "enable_dynamic_overhang_speeds", "overhang_steepness_levels", "dynamic_overhang_speeds" }) toggle_field(el, have_perimeters); - toggle_field("overhang_overlaps", config->opt_bool("enable_dynamic_overhang_speeds")); - toggle_field("dynamic_overhang_speeds", config->opt_bool("enable_dynamic_overhang_speeds")); + for (size_t i = 0; i < 4; i++) { + toggle_field("overhang_steepness_levels#" + std::to_string(i), config->opt_bool("enable_dynamic_overhang_speeds")); + toggle_field("dynamic_overhang_speeds#" + std::to_string(i), config->opt_bool("enable_dynamic_overhang_speeds")); + } bool have_infill = config->option("fill_density")->value > 0; // infill_extruder uses the same logic as in Print::extruders() diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index fd1c0cf3c..43f42c5b3 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1538,7 +1538,7 @@ void TabPrint::build() optgroup->append_line(line); }; optgroup->append_single_option_line("enable_dynamic_overhang_speeds"); - append_option_line(optgroup,"overhang_overlaps"); + append_option_line(optgroup,"overhang_steepness_levels"); append_option_line(optgroup,"dynamic_overhang_speeds"); optgroup = page->new_optgroup(L("Speed for non-print moves"));