From 20687bc27a5d2e4ee017baca81e81c04e06cf617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ach?= Date: Thu, 31 Oct 2024 17:08:29 +0100 Subject: [PATCH] Use slowdown above bridges --- src/libslic3r/ExtrusionRole.cpp | 1 + src/libslic3r/GCode.cpp | 11 +++++++++-- src/libslic3r/InfillAboveBridges.cpp | 5 ++++- src/libslic3r/InfillAboveBridges.hpp | 2 +- src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 10 ++++++++++ src/libslic3r/PrintConfig.hpp | 1 + src/libslic3r/PrintObject.cpp | 17 +++++++++++++++-- src/libslic3r/SupportSpotsGenerator.cpp | 1 + src/slic3r/GUI/ConfigManipulation.cpp | 2 +- src/slic3r/GUI/Tab.cpp | 1 + tests/fff_print/test_infill_above_bridges.cpp | 2 +- 12 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/ExtrusionRole.cpp b/src/libslic3r/ExtrusionRole.cpp index 09052e0e19..34fb888758 100644 --- a/src/libslic3r/ExtrusionRole.cpp +++ b/src/libslic3r/ExtrusionRole.cpp @@ -23,6 +23,7 @@ GCodeExtrusionRole extrusion_role_to_gcode_extrusion_role(ExtrusionRole role) } if (role == ExtrusionRole::InternalInfill) return GCodeExtrusionRole::InternalInfill; if (role == ExtrusionRole::SolidInfill) return GCodeExtrusionRole::SolidInfill; + if (role == ExtrusionRole::InfillOverBridge) return GCodeExtrusionRole::SolidInfill; if (role == ExtrusionRole::TopSolidInfill) return GCodeExtrusionRole::TopSolidInfill; if (role == ExtrusionRole::Ironing) return GCodeExtrusionRole::Ironing; if (role == ExtrusionRole::BridgeInfill) return GCodeExtrusionRole::BridgeInfill; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 7f576412db..970320568c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -704,7 +704,8 @@ namespace DoExport { if (region.config().get_abs_value("infill_speed") == 0 || region.config().get_abs_value("solid_infill_speed") == 0 || region.config().get_abs_value("top_solid_infill_speed") == 0 || - region.config().get_abs_value("bridge_speed") == 0) + region.config().get_abs_value("bridge_speed") == 0 || + region.config().get_abs_value("over_bridge_speed") == 0) { // Minimal volumetric flow should not be calculated over ironing extrusions. // Use following lambda instead of the built-it method. @@ -3388,7 +3389,13 @@ std::string GCodeGenerator::_extrude( } else if (path_attr.role == ExtrusionRole::SolidInfill) { speed = m_config.get_abs_value("solid_infill_speed"); } else if (path_attr.role == ExtrusionRole::InfillOverBridge) { - speed = 10; + const double solid_infill_speed = m_config.get_abs_value("solid_infill_speed"); + const double over_bridge_speed{m_config.get_abs_value("over_bridge_speed", solid_infill_speed)}; + if (over_bridge_speed > 0) { + speed = over_bridge_speed; + } else { + speed = solid_infill_speed; + } } else if (path_attr.role == ExtrusionRole::TopSolidInfill) { speed = m_config.get_abs_value("top_solid_infill_speed"); } else if (path_attr.role == ExtrusionRole::Ironing) { diff --git a/src/libslic3r/InfillAboveBridges.cpp b/src/libslic3r/InfillAboveBridges.cpp index dd3206215f..cb9787c66e 100644 --- a/src/libslic3r/InfillAboveBridges.cpp +++ b/src/libslic3r/InfillAboveBridges.cpp @@ -16,7 +16,7 @@ namespace Slic3r::PrepareInfill { } } - void separate_infill_above_bridges(const SurfaceRefs &surfaces) { + void separate_infill_above_bridges(const SurfaceRefs &surfaces, const double expand_offset) { if (surfaces.empty()) { return; } @@ -29,6 +29,9 @@ namespace Slic3r::PrepareInfill { bridges.push_back(bridge->expolygon); } } + if (expand_offset > 0) { + bridges = offset_ex(bridges, scale_(expand_offset)); + } mark_as_infill_above_bridge(bridges, layer); previous_layer = &layer; } diff --git a/src/libslic3r/InfillAboveBridges.hpp b/src/libslic3r/InfillAboveBridges.hpp index 2e2fc2c564..43b2037f90 100644 --- a/src/libslic3r/InfillAboveBridges.hpp +++ b/src/libslic3r/InfillAboveBridges.hpp @@ -10,7 +10,7 @@ namespace Slic3r::PrepareInfill { using SurfaceRefsByRegion = std::vector; using SurfaceRefs = std::vector; - void separate_infill_above_bridges(const SurfaceRefs &surfaces); + void separate_infill_above_bridges(const SurfaceRefs &surfaces, const double expand_offset); } #endif // slic3r_InfillAboveBridges_hpp_ diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index a54ac49bae..557b7767da 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -485,7 +485,7 @@ static std::vector s_Preset_print_options { "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed", "enable_dynamic_overhang_speeds", "overhang_speed_0", "overhang_speed_1", "overhang_speed_2", "overhang_speed_3", "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", "over_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", "travel_acceleration", "wipe_tower_acceleration", "bridge_acceleration", "first_layer_acceleration", "first_layer_acceleration_over_raft", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield", "min_skirt_length", "brim_width", "brim_separation", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 5acc2cf8d3..db517d6f8e 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -727,6 +727,16 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(60)); + def = this->add("over_bridge_speed", coFloatOrPercent); + def->label = L("Over bridges"); + def->category = L("Speed"); + def->tooltip = L("Speed for printing solid infill above bridges. Set to 0 to use solid infill speed. " + "If set as percentage, the speed is calculated over solid infill speed. "); + def->sidetext = L("mm/s or %"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); + def = this->add("enable_dynamic_overhang_speeds", coBool); def->label = L("Enable dynamic overhang speeds"); def->category = L("Speed"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index a7dfe1a460..8da9046f6a 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -693,6 +693,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, bridge_flow_ratio)) ((ConfigOptionFloat, bridge_speed)) ((ConfigOptionEnum, ensure_vertical_shell_thickness)) + ((ConfigOptionFloatOrPercent, over_bridge_speed)) ((ConfigOptionEnum, top_fill_pattern)) ((ConfigOptionEnum, bottom_fill_pattern)) ((ConfigOptionFloatOrPercent, external_perimeter_extrusion_width)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 9f8d404763..58f31e3e10 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -419,12 +419,13 @@ void PrintObject::prepare_infill() surfaces.emplace_back(); for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { LayerRegion *layerm = layer->m_regions[region_id]; - if (!layerm->fill_surfaces().empty()) { + if (!layerm->fill_surfaces().empty() && layerm->region().config().over_bridge_speed > 0) { surfaces.back().push_back(std::ref(layerm->m_fill_surfaces)); } } } - PrepareInfill::separate_infill_above_bridges(surfaces); + constexpr double infill_over_bridges_expand{1.0}; + PrepareInfill::separate_infill_above_bridges(surfaces, infill_over_bridges_expand); this->set_done(posPrepareInfill); } @@ -847,6 +848,18 @@ bool PrintObject::invalidate_state_by_config_options( steps.emplace_back(posInfill); } else if (opt_key == "fill_pattern") { steps.emplace_back(posPrepareInfill); + } else if (opt_key == "over_bridge_speed") { + const auto *old_speed = old_config.option(opt_key); + const auto *new_speed = new_config.option(opt_key); + if ( + old_speed == nullptr + || new_speed == nullptr + || old_speed->value == 0 + || new_speed->value == 0 + ) { + steps.emplace_back(posPrepareInfill); + } + invalidated |= m_print->invalidate_step(psGCodeExport); } else if (opt_key == "fill_density") { // One likely wants to reslice only when switching between zero infill to simulate boolean difference (subtracting volumes), // normal infill and 100% (solid) infill. diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index f735d77d31..3bd9e0adb4 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -278,6 +278,7 @@ float get_flow_width(const LayerRegion *region, ExtrusionRole role) if (role == ExtrusionRole::GapFill) return region->flow(FlowRole::frInfill).width(); if (role == ExtrusionRole::Perimeter) return region->flow(FlowRole::frPerimeter).width(); if (role == ExtrusionRole::SolidInfill) return region->flow(FlowRole::frSolidInfill).width(); + if (role == ExtrusionRole::InfillOverBridge) return region->flow(FlowRole::frSolidInfill).width(); if (role == ExtrusionRole::InternalInfill) return region->flow(FlowRole::frInfill).width(); if (role == ExtrusionRole::TopSolidInfill) return region->flow(FlowRole::frTopSolidInfill).width(); // default diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index ac6b29a2d5..70c187107c 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -317,7 +317,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) toggle_field(el, has_solid_infill); for (auto el : { "fill_angle", "bridge_angle", "infill_extrusion_width", - "infill_speed", "bridge_speed" }) + "infill_speed", "bridge_speed", "over_bridge_speed" }) toggle_field(el, have_infill || has_solid_infill); const bool has_ensure_vertical_shell_thickness = config->opt_enum("ensure_vertical_shell_thickness") != EnsureVerticalShellThickness::Disabled; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 2b1d1be57d..d6a890ae4d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1585,6 +1585,7 @@ void TabPrint::build() optgroup->append_single_option_line("support_material_speed"); optgroup->append_single_option_line("support_material_interface_speed"); optgroup->append_single_option_line("bridge_speed"); + optgroup->append_single_option_line("over_bridge_speed"); optgroup->append_single_option_line("gap_fill_speed"); optgroup->append_single_option_line("ironing_speed"); diff --git a/tests/fff_print/test_infill_above_bridges.cpp b/tests/fff_print/test_infill_above_bridges.cpp index c55c230125..dc0d72338c 100644 --- a/tests/fff_print/test_infill_above_bridges.cpp +++ b/tests/fff_print/test_infill_above_bridges.cpp @@ -61,7 +61,7 @@ TEST_CASE("Separate infill above bridges", "[PrepareInfill]") { draw_surfaces(layer_0, "layer_0.svg"); } - PrepareInfill::separate_infill_above_bridges({layer_0, layer_1}); + PrepareInfill::separate_infill_above_bridges({layer_0, layer_1}, 0); if constexpr (debug_files) { draw_surfaces(layer_1, "layer_1.svg");