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 <bubnikv@gmail.com>
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 <jschuh@users.noreply.github.com>
Date:   Tue Dec 8 16:55:09 2020 -0800

    Merge branch 'master' into bridge_infill_threshold

commit 8b606130f4699d60e4a915205082c76c4472455a
Author: Justin Schuh <jschuh@users.noreply.github.com>
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.
This commit is contained in:
Vojtech Bubnik 2021-02-10 12:09:58 +01:00
parent eaf6e0dca7
commit 014441e9f0
8 changed files with 38 additions and 4 deletions

View File

@ -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.

View File

@ -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<double>(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

View File

@ -410,7 +410,7 @@ const std::vector<std::string>& 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",

View File

@ -74,6 +74,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"before_layer_gcode",
"between_objects_gcode",
"bridge_acceleration",
"bridge_infill_threshold",
"bridge_fan_speed",
"colorprint_heights",
"cooling",

View File

@ -286,6 +286,16 @@ void PrintConfigDef::init_fff_params()
def->mode = 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");

View File

@ -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<InfillPattern> top_fill_pattern;
ConfigOptionEnum<InfillPattern> 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);

View File

@ -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);
}

View File

@ -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");