make fixed overlap levels for dynamic overhang speed

This commit is contained in:
Pavel Mikus 2023-02-22 14:57:22 +01:00 committed by Pavel Mikuš
parent d4055cd2c5
commit a496444b7e
9 changed files with 89 additions and 64 deletions

View File

@ -1,3 +1,4 @@
#include "Config.hpp"
#include "libslic3r.h" #include "libslic3r.h"
#include "GCode/ExtrusionProcessor.hpp" #include "GCode/ExtrusionProcessor.hpp"
#include "I18N.hpp" #include "I18N.hpp"
@ -2870,12 +2871,15 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
bool variable_speed = false; bool variable_speed = false;
std::vector<ProcessedPoint> new_points{}; std::vector<ProcessedPoint> new_points{};
if (this->m_config.enable_dynamic_overhang_speeds && !this->on_first_layer() && path.role().is_perimeter()) { if (this->m_config.enable_dynamic_overhang_speeds && !this->on_first_layer() && path.role().is_perimeter()) {
std::vector<std::pair<int, ConfigOptionFloatOrPercent>> overhangs_with_speeds{
{0, m_config.overhang_speed_0}, {20, m_config.overhang_speed_1}, {40, m_config.overhang_speed_2},
{60, m_config.overhang_speed_3}, {80, m_config.overhang_speed_4},
};
double external_perim_reference_speed = std::min(m_config.get_abs_value("external_perimeter_speed"), double external_perim_reference_speed = std::min(m_config.get_abs_value("external_perimeter_speed"),
std::min(EXTRUDER_CONFIG(filament_max_volumetric_speed) / path.mm3_per_mm, std::min(EXTRUDER_CONFIG(filament_max_volumetric_speed) / path.mm3_per_mm,
m_config.max_volumetric_speed.value / path.mm3_per_mm)); m_config.max_volumetric_speed.value / path.mm3_per_mm));
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, m_config.overhang_overlap_levels, new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhangs_with_speeds, external_perim_reference_speed,
m_config.dynamic_overhang_speeds, speed);
external_perim_reference_speed, speed);
variable_speed = std::any_of(new_points.begin(), new_points.end(), [speed](const ProcessedPoint &p) { return p.speed != speed; }); variable_speed = std::any_of(new_points.begin(), new_points.end(), [speed](const ProcessedPoint &p) { return p.speed != speed; });
} }

View File

@ -257,26 +257,25 @@ public:
next_layer_boundaries[object] = AABBTreeLines::LinesDistancer<Linef>{to_unscaled_linesf(layer->lslices)}; next_layer_boundaries[object] = AABBTreeLines::LinesDistancer<Linef>{to_unscaled_linesf(layer->lslices)};
} }
std::vector<ProcessedPoint> estimate_extrusion_quality(const ExtrusionPath &path, std::vector<ProcessedPoint> estimate_extrusion_quality(const ExtrusionPath &path,
const ConfigOptionPercents &overlaps, const std::vector<std::pair<int, ConfigOptionFloatOrPercent>> overhangs_w_speeds,
const ConfigOptionFloatsOrPercents &speeds, float ext_perimeter_speed,
float ext_perimeter_speed, float original_speed)
float original_speed)
{ {
size_t speed_sections_count = std::min(overlaps.values.size(), speeds.values.size()); float speed_base = ext_perimeter_speed > 0 ? ext_perimeter_speed : original_speed;
float speed_base = ext_perimeter_speed > 0 ? ext_perimeter_speed : original_speed;
std::vector<std::pair<float, float>> speed_sections; std::vector<std::pair<float, float>> speed_sections;
for (size_t i = 0; i < speed_sections_count; i++) { for (size_t i = 0; i < overhangs_w_speeds.size(); i++) {
float distance = path.width * (1.0 - (overlaps.get_at(i) / 100.0)); float distance = path.width * (1.0 - (overhangs_w_speeds[i].first / 100.0));
float speed = speeds.get_at(i).percent ? (speed_base * speeds.get_at(i).value / 100.0) : speeds.get_at(i).value; float speed = overhangs_w_speeds[i].second.percent ? (speed_base * overhangs_w_speeds[i].second.value / 100.0) :
overhangs_w_speeds[i].second.value;
speed_sections.push_back({distance, speed}); speed_sections.push_back({distance, speed});
} }
std::sort(speed_sections.begin(), speed_sections.end(), std::sort(speed_sections.begin(), speed_sections.end(), [](const std::pair<float, float> &a, const std::pair<float, float> &b) {
[](const std::pair<float, float> &a, const std::pair<float, float> &b) { if (a.first == b.first) {
if (a.first == b.first) { return a.second > b.second;
return a.second > b.second; }
} return a.first < b.first;
return a.first < b.first; }); });
std::pair<float, float> last_section{INFINITY, 0}; std::pair<float, float> last_section{INFINITY, 0};
for (auto &section : speed_sections) { for (auto &section : speed_sections) {

View File

@ -440,7 +440,7 @@ static std::vector<std::string> s_Preset_print_options {
"fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_dist", "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_dist",
"max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", "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", "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
"enable_dynamic_overhang_speeds", "dynamic_overhang_speeds", "overhang_overlap_levels", "enable_dynamic_overhang_speeds", "overhang_speed_0", "overhang_speed_1", "overhang_speed_2", "overhang_speed_3", "overhang_speed_4",
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed", "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_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration",
"external_perimeter_acceleration", "top_solid_infill_acceleration", "solid_infill_acceleration", "external_perimeter_acceleration", "top_solid_infill_acceleration", "solid_infill_acceleration",

View File

@ -534,36 +534,63 @@ void PrintConfigDef::init_fff_params()
def = this->add("enable_dynamic_overhang_speeds", coBool); def = this->add("enable_dynamic_overhang_speeds", coBool);
def->label = L("Enable dynamic overhang speeds"); def->label = L("Enable dynamic overhang speeds");
def->category = L("Speed"); def->category = L("Speed");
def->tooltip = L("This setting enables dynamic speed control on overhangs."); def->tooltip = L("This setting enables dynamic speed control on overhangs."
def->mode = comAdvanced; "Controls overhang levels, expressed as a percentage of overlap of the extrusion with the previous layer - "
def->set_default_value(new ConfigOptionBool(false));
def = this->add("overhang_overlap_levels", coPercents);
def->full_label = L("Overhang overlap levels");
def->category = L("Speed");
def->tooltip = L("Controls overhang levels, expressed as a percentage of overlap of the extrusion with the previous layer - "
"100% represents full overlap - no overhang is present, while 0% represents full overhang (floating extrusion). " "100% represents full overlap - no overhang is present, while 0% represents full overhang (floating extrusion). "
"Each overhang level then corresponds with the overhang speed below. Speeds for overhang levels in between are " "Each overhang level then corresponds with the overhang speed below. Speeds for overhang levels in between are "
"calculated via linear interpolation." "calculated via linear interpolation."
"If you set multiple different speeds for the same overhang level, only the largest speed is used. " "If you set multiple different speeds for the same overhang level, only the largest speed is used. "
); "This setting controls the speed on the overhang with the overlap value set above. "
def->sidetext = L("%");
def->min = 0;
def->max = 100;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPercents({60, 40, 20, 0}));
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 on the overhang with the overlap value set above. "
"The speed of the extrusion is calculated as a linear interpolation of the speeds for higher and lower overlap. " "The speed of the extrusion is calculated as a linear interpolation of the speeds for higher and lower overlap. "
"If set as percentage, the speed is calculated over the external perimeter speed." "If set as percentage, the speed is calculated over the external perimeter speed."
); );
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
def = this->add("overhang_speed_0", coFloatOrPercent);
def->full_label = L("speed for 0\% overlap (bridge)");
def->category = L("Speed");
def->tooltip = L("Controls the speed for the corresponding extrusion overlap value.");
def->sidetext = L("mm/s or %"); def->sidetext = L("mm/s or %");
def->min = 0; def->min = 0;
def->mode = comAdvanced; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatsOrPercents({{25, false}, {20, false}, {15, false}, {15, false}})); def->set_default_value(new ConfigOptionFloatOrPercent(15, false));
def = this->add("overhang_speed_1", coFloatOrPercent);
def->full_label = L("speed for 20\% overlap");
def->category = L("Speed");
def->tooltip = L("Controls the speed for the corresponding extrusion overlap value.");
def->sidetext = L("mm/s or %");
def->min = 0;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(20, false));
def = this->add("overhang_speed_2", coFloatOrPercent);
def->full_label = L("speed for 40\% overlap");
def->category = L("Speed");
def->tooltip = L("Controls the speed for the corresponding extrusion overlap value.");
def->sidetext = L("mm/s or %");
def->min = 0;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(25, false));
def = this->add("overhang_speed_3", coFloatOrPercent);
def->full_label = L("speed for 60\% overlap");
def->category = L("Speed");
def->tooltip = L("Controls the speed for the corresponding extrusion overlap value.");
def->sidetext = L("mm/s or %");
def->min = 0;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(25, false));
def = this->add("overhang_speed_4", coFloatOrPercent);
def->full_label = L("speed for 80\% overlap");
def->category = L("Speed");
def->tooltip = L("Controls the speed for the corresponding extrusion overlap value.");
def->sidetext = L("mm/s or %");
def->min = 0;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloatOrPercent(25, false));
def = this->add("brim_width", coFloat); def = this->add("brim_width", coFloat);
def->label = L("Brim width"); def->label = L("Brim width");

View File

@ -573,8 +573,11 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloatOrPercent, external_perimeter_extrusion_width)) ((ConfigOptionFloatOrPercent, external_perimeter_extrusion_width))
((ConfigOptionFloatOrPercent, external_perimeter_speed)) ((ConfigOptionFloatOrPercent, external_perimeter_speed))
((ConfigOptionBool, enable_dynamic_overhang_speeds)) ((ConfigOptionBool, enable_dynamic_overhang_speeds))
((ConfigOptionPercents, overhang_overlap_levels)) ((ConfigOptionFloatOrPercent, overhang_speed_0))
((ConfigOptionFloatsOrPercents, dynamic_overhang_speeds)) ((ConfigOptionFloatOrPercent, overhang_speed_1))
((ConfigOptionFloatOrPercent, overhang_speed_2))
((ConfigOptionFloatOrPercent, overhang_speed_3))
((ConfigOptionFloatOrPercent, overhang_speed_4))
((ConfigOptionBool, external_perimeters_first)) ((ConfigOptionBool, external_perimeters_first))
((ConfigOptionBool, extra_perimeters)) ((ConfigOptionBool, extra_perimeters))
((ConfigOptionBool, extra_perimeters_on_overhangs)) ((ConfigOptionBool, extra_perimeters_on_overhangs))

View File

@ -765,8 +765,11 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "support_material_interface_speed" || opt_key == "support_material_interface_speed"
|| opt_key == "bridge_speed" || opt_key == "bridge_speed"
|| opt_key == "enable_dynamic_overhang_speeds" || opt_key == "enable_dynamic_overhang_speeds"
|| opt_key == "overhang_overlap_levels" || opt_key == "overhang_speed_0"
|| opt_key == "dynamic_overhang_speeds" || opt_key == "overhang_speed_1"
|| opt_key == "overhang_speed_2"
|| opt_key == "overhang_speed_3"
|| opt_key == "overhang_speed_4"
|| opt_key == "external_perimeter_speed" || opt_key == "external_perimeter_speed"
|| opt_key == "infill_speed" || opt_key == "infill_speed"
|| opt_key == "perimeter_speed" || opt_key == "perimeter_speed"

View File

@ -221,12 +221,11 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
bool have_perimeters = config->opt_int("perimeters") > 0; bool have_perimeters = config->opt_int("perimeters") > 0;
for (auto el : { "extra_perimeters","extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "thin_walls", "overhangs", 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", "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_overlap_levels", "dynamic_overhang_speeds" }) "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "enable_dynamic_overhang_speeds"})
toggle_field(el, have_perimeters); toggle_field(el, have_perimeters);
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 5; i++) {
toggle_field("overhang_overlap_levels#" + std::to_string(i), config->opt_bool("enable_dynamic_overhang_speeds")); toggle_field("overhang_speed_" + 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<ConfigOptionPercent>("fill_density")->value > 0; bool have_infill = config->option<ConfigOptionPercent>("fill_density")->value > 0;

View File

@ -98,10 +98,6 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
suffix_local = " " + _(suffix); suffix_local = " " + _(suffix);
suffix = " " + suffix; suffix = " " + suffix;
} }
else if (gc.group == "Dynamic overhang speed" && id >= 0) {
suffix = " " + std::to_string(id+1);
suffix_local = suffix;
}
if (!label.IsEmpty()) if (!label.IsEmpty())
options.emplace_back(Option{ boost::nowide::widen(key), type, options.emplace_back(Option{ boost::nowide::widen(key), type,

View File

@ -1549,18 +1549,12 @@ void TabPrint::build()
optgroup->append_single_option_line("ironing_speed"); optgroup->append_single_option_line("ironing_speed");
optgroup = page->new_optgroup(L("Dynamic overhang speed")); optgroup = page->new_optgroup(L("Dynamic overhang speed"));
auto append_option_line = [](ConfigOptionsGroupShp optgroup, std::string opt_key) {
auto option = optgroup->get_option(opt_key, 0);
auto line = Line{option.opt.full_label, ""};
line.append_option(option);
line.append_option(optgroup->get_option(opt_key, 1));
line.append_option(optgroup->get_option(opt_key, 2));
line.append_option(optgroup->get_option(opt_key, 3));
optgroup->append_line(line);
};
optgroup->append_single_option_line("enable_dynamic_overhang_speeds"); optgroup->append_single_option_line("enable_dynamic_overhang_speeds");
append_option_line(optgroup,"overhang_overlap_levels"); optgroup->append_single_option_line("overhang_speed_0");
append_option_line(optgroup,"dynamic_overhang_speeds"); optgroup->append_single_option_line("overhang_speed_1");
optgroup->append_single_option_line("overhang_speed_2");
optgroup->append_single_option_line("overhang_speed_3");
optgroup->append_single_option_line("overhang_speed_4");
optgroup = page->new_optgroup(L("Speed for non-print moves")); optgroup = page->new_optgroup(L("Speed for non-print moves"));
optgroup->append_single_option_line("travel_speed"); optgroup->append_single_option_line("travel_speed");