From 014441e9f0896c942e3dab3745ed51fad8f09ed3 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Wed, 10 Feb 2021 12:09:58 +0100 Subject: [PATCH] Squash merge of pull request by @jshuh Add setting to control when bridge infill is used #4374 Squashed commit of the following: commit 56e5c7756a683e80324521736215d0678748a8cb Merge: eaf6e0dca 33215bb75 Author: Vojtech Bubnik Date: Wed Feb 10 12:07:59 2021 +0100 Merge branch 'bridge_infill_threshold' of https://github.com/jschuh/PrusaSlicer into jschuh-bridge_infill_threshold commit 33215bb75fe6e20b1b089fb7dcde8e44ee882f13 Merge: 8b606130f fe4f1b15c Author: Justin Schuh Date: Tue Dec 8 16:55:09 2020 -0800 Merge branch 'master' into bridge_infill_threshold commit 8b606130f4699d60e4a915205082c76c4472455a Author: Justin Schuh Date: Tue Jun 9 20:01:15 2020 -0700 Add setting to control when bridge infill is used Bridge infill will be applied only if the average area of the voids between infill lines (computed from the infill density and infill extrusion width) is greater than the bridge_infill_threshold setting. --- src/libslic3r/Layer.hpp | 2 ++ src/libslic3r/LayerRegion.cpp | 11 +++++++++++ src/libslic3r/Preset.cpp | 2 +- src/libslic3r/Print.cpp | 1 + src/libslic3r/PrintConfig.cpp | 10 ++++++++++ src/libslic3r/PrintConfig.hpp | 2 ++ src/libslic3r/PrintObject.cpp | 13 ++++++++++--- src/slic3r/GUI/Tab.cpp | 1 + 8 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 9a3fe368d3..105bea2dff 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -65,6 +65,8 @@ public: void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces); void process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered); double infill_area_threshold() const; + // True if infill voids (computed from infill_density) are larger than bridge_infill_threshold. + bool needs_bridge_over_infill() const; // Trim surfaces by trimming polygons. Used by the elephant foot compensation at the 1st layer. void trim_surfaces(const Polygons &trimming_polygons); // Single elephant foot compensation step, used by the elephant foor compensation at the 1st layer. diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 2db3abf125..6816cb91eb 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -405,6 +405,17 @@ double LayerRegion::infill_area_threshold() const return ss*ss; } +bool LayerRegion::needs_bridge_over_infill() const +{ + auto region_config = region()->config(); + if (region_config.fill_density <= 0) + return true; + const double infill_extrusion_width = flow(frInfill).width; + // Compute the unsupported area assuming a grid, which is pragmatically good enough for all infill types. + const double bridging_area = pow(2.0 * 100.0 * infill_extrusion_width / region_config.fill_density - infill_extrusion_width, 2); + return bridging_area > region_config.bridge_infill_threshold; +} + void LayerRegion::trim_surfaces(const Polygons &trimming_polygons) { #ifndef NDEBUG diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index b7e966c9e7..a49f52dca5 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -410,7 +410,7 @@ const std::vector& Preset::print_options() "infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle", "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing", - "max_print_speed", "max_volumetric_speed", "avoid_crossing_perimeters_max_detour", + "max_print_speed", "max_volumetric_speed", "bridge_infill_threshold", "avoid_crossing_perimeters_max_detour", "fuzzy_skin_perimeter_mode", /* "fuzzy_skin_shape", */ "fuzzy_skin_thickness", "fuzzy_skin_point_dist", #ifdef HAS_PRESSURE_EQUALIZER "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index b96768904d..7b885116b0 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -74,6 +74,7 @@ bool Print::invalidate_state_by_config_options(const std::vectormode = comAdvanced; def->set_default_value(new ConfigOptionFloat(1)); + def = this->add("bridge_infill_threshold", coFloat); + def->label = L("Bridge infill threshold"); + def->tooltip = L("Forces bridge settings for the layer above infill where voids are larger than the specified area. " + "The infill void area is computed from the infill density and infill extrusion width. " + "Set to zero to force bridge settings for any layer above non-solid infill."); + def->sidetext = L("mm²"); + def->min = 0; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(25.)); + def = this->add("bridge_speed", coFloat); def->label = L("Bridges"); def->category = L("Speed"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 5189baab2d..6c931ac9c1 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -602,6 +602,7 @@ public: ConfigOptionFloat bottom_solid_min_thickness; ConfigOptionFloat bridge_flow_ratio; ConfigOptionFloat bridge_speed; + ConfigOptionFloat bridge_infill_threshold; ConfigOptionBool ensure_vertical_shell_thickness; ConfigOptionEnum top_fill_pattern; ConfigOptionEnum bottom_fill_pattern; @@ -654,6 +655,7 @@ protected: OPT_PTR(bottom_solid_layers); OPT_PTR(bottom_solid_min_thickness); OPT_PTR(bridge_flow_ratio); + OPT_PTR(bridge_infill_threshold); OPT_PTR(bridge_speed); OPT_PTR(ensure_vertical_shell_thickness); OPT_PTR(top_fill_pattern); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 233f693e3c..1d431400e4 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1472,9 +1472,16 @@ void PrintObject::bridge_over_infill() // iterate through regions and collect internal surfaces Polygons lower_internal; - for (LayerRegion *lower_layerm : lower_layer->m_regions) - lower_layerm->fill_surfaces.filter_by_type(stInternal, &lower_internal); - + for (LayerRegion* lower_layerm : lower_layer->m_regions) { + auto surfaces = lower_layerm->fill_surfaces.surfaces; + for (Surfaces::iterator surface = surfaces.begin(); surface != surfaces.end(); ++surface) { + if (surface->surface_type == stInternal && layerm->needs_bridge_over_infill()) { + Polygons pp = surface->expolygon; + lower_internal.insert(lower_internal.end(), pp.begin(), pp.end()); + } + } + } + // intersect such lower internal surfaces with the candidate solid surfaces to_bridge_pp = intersection(to_bridge_pp, lower_internal); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 6f371d1752..4ed25d3fc3 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1473,6 +1473,7 @@ void TabPrint::build() optgroup->append_single_option_line("fill_angle", category_path + "fill-angle"); optgroup->append_single_option_line("solid_infill_below_area", category_path + "solid-infill-threshold-area"); optgroup->append_single_option_line("bridge_angle"); + optgroup->append_single_option_line("bridge_infill_threshold"); optgroup->append_single_option_line("only_retract_when_crossing_perimeters"); optgroup->append_single_option_line("infill_first");