diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index b4ac5455af..08b44ef1ef 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -532,7 +532,7 @@ sub build { seam_position external_perimeters_first fill_density fill_pattern external_fill_pattern infill_every_layers infill_only_where_needed - solid_infill_every_layers fill_angle solid_infill_below_area + solid_infill_every_layers fill_angle bridge_angle solid_infill_below_area only_retract_when_crossing_perimeters infill_first max_print_speed max_volumetric_speed max_volumetric_extrusion_rate_slope_positive max_volumetric_extrusion_rate_slope_negative @@ -622,6 +622,7 @@ sub build { $optgroup->append_single_option_line('solid_infill_every_layers'); $optgroup->append_single_option_line('fill_angle'); $optgroup->append_single_option_line('solid_infill_below_area'); + $optgroup->append_single_option_line('bridge_angle'); $optgroup->append_single_option_line('only_retract_when_crossing_perimeters'); $optgroup->append_single_option_line('infill_first'); } @@ -977,7 +978,7 @@ sub _update { solid_infill_speed); $self->get_field($_)->toggle($have_infill || $have_solid_infill) - for qw(fill_angle infill_extrusion_width infill_speed bridge_speed); + for qw(fill_angle bridge_angle infill_extrusion_width infill_speed bridge_speed); $self->get_field('gap_fill_speed')->toggle($have_perimeters && $have_infill); diff --git a/xs/src/libslic3r/BridgeDetector.cpp b/xs/src/libslic3r/BridgeDetector.cpp index 8ed38b7e91..a5272683f0 100644 --- a/xs/src/libslic3r/BridgeDetector.cpp +++ b/xs/src/libslic3r/BridgeDetector.cpp @@ -68,20 +68,20 @@ void BridgeDetector::initialize() */ } -bool -BridgeDetector::detect_angle() +bool BridgeDetector::detect_angle(double bridge_direction_override) { if (this->_edges.empty() || this->_anchor_regions.empty()) // The bridging region is completely in the air, there are no anchors available at the layer below. return false; std::vector candidates; - { + if (bridge_direction_override == 0.) { std::vector angles = bridge_direction_candidates(); candidates.reserve(angles.size()); for (size_t i = 0; i < angles.size(); ++ i) - candidates.push_back(BridgeDirection(angles[i])); - } + candidates.emplace_back(BridgeDirection(angles[i])); + } else + candidates.emplace_back(BridgeDirection(bridge_direction_override)); /* Outset the bridge expolygon by half the amount we used for detecting anchors; we'll use this one to clip our test lines and be sure that their endpoints diff --git a/xs/src/libslic3r/BridgeDetector.hpp b/xs/src/libslic3r/BridgeDetector.hpp index 8dc93336a8..5c55276bed 100644 --- a/xs/src/libslic3r/BridgeDetector.hpp +++ b/xs/src/libslic3r/BridgeDetector.hpp @@ -31,7 +31,8 @@ public: BridgeDetector(ExPolygon _expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width); BridgeDetector(const ExPolygons &_expolygons, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width); - bool detect_angle(); + // If bridge_direction_override != 0, then the angle is used instead of auto-detect. + bool detect_angle(double bridge_direction_override = 0.); Polygons coverage(double angle = -1) const; void unsupported_edges(double angle, Polylines* unsupported) const; Polylines unsupported_edges(double angle = -1) const; diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp index dc2783f9ad..16d27ab6f7 100644 --- a/xs/src/libslic3r/LayerRegion.cpp +++ b/xs/src/libslic3r/LayerRegion.cpp @@ -1,6 +1,7 @@ #include "Layer.hpp" #include "BridgeDetector.hpp" #include "ClipperUtils.hpp" +#include "Geometry.hpp" #include "PerimeterGenerator.hpp" #include "Print.hpp" #include "Surface.hpp" @@ -87,8 +88,7 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* //#define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtMiter, 1.5 #define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0. -void -LayerRegion::process_external_surfaces(const Layer* lower_layer) +void LayerRegion::process_external_surfaces(const Layer* lower_layer) { const Surfaces &surfaces = this->fill_surfaces.surfaces; const double margin = scale_(EXTERNAL_INFILL_MARGIN); @@ -260,7 +260,7 @@ LayerRegion::process_external_surfaces(const Layer* lower_layer) #ifdef SLIC3R_DEBUG printf("Processing bridge at layer " PRINTF_ZU ":\n", this->layer()->id()); #endif - if (bd.detect_angle()) { + if (bd.detect_angle(Geometry::deg2rad(this->region()->config.bridge_angle))) { bridges[idx_last].bridge_angle = bd.angle; if (this->layer()->object()->config.support_material) { polygons_append(this->bridged, bd.coverage()); diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 004286224d..f54be8e22d 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -65,6 +65,15 @@ PrintConfigDef::PrintConfigDef() def->min = 0; def->default_value = new ConfigOptionFloat(0); + def = this->add("bridge_angle", coFloat); + def->label = "Bridging angle"; + def->category = "Infill"; + def->tooltip = "Bridging angle override. If left to zero, the bridging angle will be calculated automatically. Otherwise the provided angle will be used for all bridges, use 180° for zero angle."; + def->sidetext = "°"; + def->cli = "bridge-angle=f"; + def->min = 0; + def->default_value = new ConfigOptionFloat(0.); + def = this->add("bridge_fan_speed", coInts); def->label = "Bridges fan speed"; def->tooltip = "This fan speed is enforced during all bridges and overhangs."; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index c292f03c04..fdfcc81066 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -243,7 +243,8 @@ public: // This object is mapped to Perl as Slic3r::Config::PrintRegion. class PrintRegionConfig : public virtual StaticPrintConfig { - public: +public: + ConfigOptionFloat bridge_angle; ConfigOptionInt bottom_solid_layers; ConfigOptionFloat bridge_flow_ratio; ConfigOptionFloat bridge_speed; @@ -285,6 +286,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { UNUSED(create); + OPT_PTR(bridge_angle); OPT_PTR(bottom_solid_layers); OPT_PTR(bridge_flow_ratio); OPT_PTR(bridge_speed); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 3999551c0d..26f6c50a0b 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -195,7 +195,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector