mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 09:17:52 -06:00
New feature: bridge density (#275)
Signed-off-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
parent
8244693b55
commit
fe9a2715e6
11 changed files with 32 additions and 13 deletions
|
@ -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.
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 ®ion = this->region();
|
||||
const PrintRegionConfig ®ion_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 {
|
||||
|
|
|
@ -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"
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue