New feature: bridge density (#275)

Signed-off-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
SoftFever 2023-02-02 00:43:36 +08:00 committed by GitHub
parent 8244693b55
commit fe9a2715e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 32 additions and 13 deletions

View file

@ -185,7 +185,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
params.bridge = is_bridge || Fill::use_bridge_flow(params.pattern);
params.flow = params.bridge ?
//BBS: always enable thick bridge for internal bridge
layerm.bridging_flow(extrusion_role, (surface.is_bridge() && !surface.is_external()) || object_config.thick_bridges) :
layerm.bridging_flow(extrusion_role, (surface.is_bridge() && !surface.is_external()) || object_config.thick_bridges, surface.is_external() ? region_config.bridge_density.get_abs_value(1.0) : 1.0f) :
layerm.flow(extrusion_role, (surface.thickness == -1) ? layer.height : surface.thickness);
// Calculate flow spacing for infill pattern generation.

View file

@ -65,6 +65,7 @@ public:
float height() const { return m_height; }
// Spacing between the extrusion centerlines.
float spacing() const { return m_spacing; }
void set_spacing(float spacing) { m_spacing = spacing; }
coord_t scaled_spacing() const { return coord_t(scale_(m_spacing)); }
// Nozzle diameter.
float nozzle_diameter() const { return m_nozzle_diameter; }

View file

@ -68,7 +68,7 @@ public:
Flow flow(FlowRole role) const;
Flow flow(FlowRole role, double layer_height) const;
Flow bridging_flow(FlowRole role, bool thick_bridge = false) const;
Flow bridging_flow(FlowRole role, bool thick_bridge = false , float bridge_density = 1.0f) const;
void slices_to_fill_surfaces_clipped();
void prepare_fill_surfaces();

View file

@ -12,6 +12,7 @@
#include <map>
#include <boost/log/trivial.hpp>
#include <boost/algorithm/clamp.hpp>
namespace Slic3r {
@ -25,22 +26,27 @@ Flow LayerRegion::flow(FlowRole role, double layer_height) const
return m_region->flow(*m_layer->object(), role, layer_height, m_layer->id() == 0);
}
Flow LayerRegion::bridging_flow(FlowRole role, bool thick_bridge) const
Flow LayerRegion::bridging_flow(FlowRole role, bool thick_bridge, float bridge_density) const
{
const PrintRegion &region = this->region();
const PrintRegionConfig &region_config = region.config();
const PrintObject &print_object = *this->layer()->object();
Flow bridge_flow;
auto nozzle_diameter = float(print_object.print()->config().nozzle_diameter.get_at(region.extruder(role) - 1));
if (thick_bridge) {
// The old Slic3r way (different from all other slicers): Use rounded extrusions.
// Get the configured nozzle_diameter for the extruder associated to the flow role requested.
// Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right.
auto nozzle_diameter = float(print_object.print()->config().nozzle_diameter.get_at(region.extruder(role) - 1));
// Applies default bridge spacing.
return Flow::bridging_flow(float(sqrt(region_config.bridge_flow)) * nozzle_diameter, nozzle_diameter);
bridge_flow = Flow::bridging_flow(float(sqrt(region_config.bridge_flow)) * nozzle_diameter, nozzle_diameter);
} else {
// The same way as other slicers: Use normal extrusions. Apply bridge_flow while maintaining the original spacing.
return this->flow(role).with_flow_ratio(region_config.bridge_flow);
bridge_flow = this->flow(role).with_flow_ratio(region_config.bridge_flow);
}
bridge_density = boost::algorithm::clamp(bridge_density, 0.1f, 1.0f);
bridge_flow.set_spacing(bridge_flow.spacing() + bridge_flow.width() * ((1.0f / bridge_density) - 1.0f));
return bridge_flow;
}
// Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces.
@ -230,7 +236,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
// Grown by 3mm.
//BBS: eliminate too narrow area to avoid generating bridge on top layer when wall loop is 1
//Polygons polys = offset(bridges[i].expolygon, bridge_margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
Polygons polys = offset2({ bridges[i].expolygon }, -scale_(nozzle_diameter * 0.1), bridge_margin, EXTERNAL_SURFACES_OFFSET_PARAMETERS);
Polygons polys = offset2({ bridges[i].expolygon }, -scale_(nozzle_diameter * 0.1), bridge_margin + scale_((1.0 / this->region().config().bridge_density.get_abs_value(1.0) - 1.0)*nozzle_diameter/2.0), EXTERNAL_SURFACES_OFFSET_PARAMETERS);
if (idx_island == -1) {
BOOST_LOG_TRIVIAL(trace) << "Bridge did not fall into the source region!";
} else {

View file

@ -709,7 +709,7 @@ static std::vector<std::string> s_Preset_print_options {
"top_shell_layers", "top_shell_thickness", "bottom_shell_layers", "bottom_shell_thickness",
"ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall",
"seam_position", "wall_infill_order", "sparse_infill_density", "sparse_infill_pattern", "top_surface_pattern", "bottom_surface_pattern",
"infill_direction", "bridge_angle",
"infill_direction",
"minimum_sparse_infill_area", "reduce_infill_retraction",
"ironing_type", "ironing_flow", "ironing_speed", "ironing_spacing",
"max_travel_detour_distance",
@ -752,7 +752,7 @@ static std::vector<std::string> s_Preset_print_options {
"small_perimeter_speed", "small_perimeter_threshold","bridge_angle", "filter_out_gap_fill", "post_process", "travel_acceleration","inner_wall_acceleration",
"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk","travel_jerk",
"top_solid_infill_flow_ratio","bottom_solid_infill_flow_ratio","only_one_wall_first_layer",
"print_flow_ratio","seam_gap","role_based_wipe_speed","wipe_speed","accel_to_decel_enable", "accel_to_decel_factor", "wipe_on_loops"
"print_flow_ratio","seam_gap","role_based_wipe_speed","wipe_speed","accel_to_decel_enable", "accel_to_decel_factor", "wipe_on_loops", "bridge_density"
};

View file

@ -677,6 +677,16 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.));
def = this->add("bridge_density", coPercent);
def->label = L("Bridge density");
def->category = L("Strength");
def->tooltip = L("Density of external bridges. 100% means solid bridge. Default is 100%.");
def->sidetext = L("%");
def->min = 10;
def->max = 100;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPercent(100));
def = this->add("bridge_flow", coFloat);
def->label = L("Bridge flow");
def->category = L("Quality");

View file

@ -701,6 +701,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, bridge_angle))
((ConfigOptionFloat, bridge_flow))
((ConfigOptionFloat, bridge_speed))
((ConfigOptionPercent, bridge_density))
((ConfigOptionBool, ensure_vertical_shell_thickness))
((ConfigOptionEnum<InfillPattern>, top_surface_pattern))
((ConfigOptionFloat, top_solid_infill_flow_ratio))

View file

@ -828,7 +828,7 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "detect_thin_wall") {
steps.emplace_back(posPerimeters);
steps.emplace_back(posSupportMaterial);
} else if (opt_key == "bridge_flow") {
} else if (opt_key == "bridge_flow" || opt_key == "bridge_density") {
if (m_config.support_top_z_distance > 0.) {
// Only invalidate due to bridging if bridging is enabled.
// If later "support_top_z_distance" is modified, the complete PrintObject is invalidated anyway.

View file

@ -90,7 +90,7 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::OBJECT_C
std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::PART_CATEGORY_SETTINGS=
{
{ L("Quality"), {{"ironing_type", "",8},{"ironing_flow", "",9},{"ironing_spacing", "",10},{"bridge_flow", "",11}
{ L("Quality"), {{"ironing_type", "",8},{"ironing_flow", "",9},{"ironing_spacing", "",10},{"bridge_flow", "",11},{"bridge_density", "", 1}
}},
{ L("Strength"), {{"wall_loops", "",1},{"top_shell_layers", L("Top Solid Layers"),1},{"top_shell_thickness", L("Top Minimum Shell Thickness"),1},
{"bottom_shell_layers", L("Bottom Solid Layers"),1}, {"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"),1},

View file

@ -1868,9 +1868,10 @@ void TabPrint::build()
optgroup->append_single_option_line("wall_infill_order");
optgroup->append_single_option_line("print_flow_ratio");
optgroup->append_single_option_line("bridge_flow");
optgroup->append_single_option_line("bridge_density");
optgroup->append_single_option_line("thick_bridges");
optgroup->append_single_option_line("top_solid_infill_flow_ratio");
optgroup->append_single_option_line("bottom_solid_infill_flow_ratio");
optgroup->append_single_option_line("thick_bridges");
optgroup->append_single_option_line("only_one_wall_top");
optgroup->append_single_option_line("only_one_wall_first_layer");
optgroup->append_single_option_line("detect_overhang_wall");