New feature: Bridging angle override through a bridge_angle config

variable. When set to zero, the usual automatic bridge detection applies.
The bridging angle override may be set at the Infill->Advanced settings,
or through a modifier mesh.
This commit is contained in:
bubnikv 2017-07-31 16:23:52 +02:00
parent 75c72bc59b
commit 71f99423c5
7 changed files with 27 additions and 13 deletions

View file

@ -532,7 +532,7 @@ sub build {
seam_position external_perimeters_first seam_position external_perimeters_first
fill_density fill_pattern external_fill_pattern fill_density fill_pattern external_fill_pattern
infill_every_layers infill_only_where_needed 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 only_retract_when_crossing_perimeters infill_first
max_print_speed max_volumetric_speed max_print_speed max_volumetric_speed
max_volumetric_extrusion_rate_slope_positive max_volumetric_extrusion_rate_slope_negative 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('solid_infill_every_layers');
$optgroup->append_single_option_line('fill_angle'); $optgroup->append_single_option_line('fill_angle');
$optgroup->append_single_option_line('solid_infill_below_area'); $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('only_retract_when_crossing_perimeters');
$optgroup->append_single_option_line('infill_first'); $optgroup->append_single_option_line('infill_first');
} }
@ -977,7 +978,7 @@ sub _update {
solid_infill_speed); solid_infill_speed);
$self->get_field($_)->toggle($have_infill || $have_solid_infill) $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); $self->get_field('gap_fill_speed')->toggle($have_perimeters && $have_infill);

View file

@ -68,20 +68,20 @@ void BridgeDetector::initialize()
*/ */
} }
bool bool BridgeDetector::detect_angle(double bridge_direction_override)
BridgeDetector::detect_angle()
{ {
if (this->_edges.empty() || this->_anchor_regions.empty()) 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. // The bridging region is completely in the air, there are no anchors available at the layer below.
return false; return false;
std::vector<BridgeDirection> candidates; std::vector<BridgeDirection> candidates;
{ if (bridge_direction_override == 0.) {
std::vector<double> angles = bridge_direction_candidates(); std::vector<double> angles = bridge_direction_candidates();
candidates.reserve(angles.size()); candidates.reserve(angles.size());
for (size_t i = 0; i < angles.size(); ++ i) 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; /* 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 we'll use this one to clip our test lines and be sure that their endpoints

View file

@ -31,7 +31,8 @@ public:
BridgeDetector(ExPolygon _expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width); BridgeDetector(ExPolygon _expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width);
BridgeDetector(const ExPolygons &_expolygons, 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; Polygons coverage(double angle = -1) const;
void unsupported_edges(double angle, Polylines* unsupported) const; void unsupported_edges(double angle, Polylines* unsupported) const;
Polylines unsupported_edges(double angle = -1) const; Polylines unsupported_edges(double angle = -1) const;

View file

@ -1,6 +1,7 @@
#include "Layer.hpp" #include "Layer.hpp"
#include "BridgeDetector.hpp" #include "BridgeDetector.hpp"
#include "ClipperUtils.hpp" #include "ClipperUtils.hpp"
#include "Geometry.hpp"
#include "PerimeterGenerator.hpp" #include "PerimeterGenerator.hpp"
#include "Print.hpp" #include "Print.hpp"
#include "Surface.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::jtMiter, 1.5
#define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0. #define EXTERNAL_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0.
void void LayerRegion::process_external_surfaces(const Layer* lower_layer)
LayerRegion::process_external_surfaces(const Layer* lower_layer)
{ {
const Surfaces &surfaces = this->fill_surfaces.surfaces; const Surfaces &surfaces = this->fill_surfaces.surfaces;
const double margin = scale_(EXTERNAL_INFILL_MARGIN); const double margin = scale_(EXTERNAL_INFILL_MARGIN);
@ -260,7 +260,7 @@ LayerRegion::process_external_surfaces(const Layer* lower_layer)
#ifdef SLIC3R_DEBUG #ifdef SLIC3R_DEBUG
printf("Processing bridge at layer " PRINTF_ZU ":\n", this->layer()->id()); printf("Processing bridge at layer " PRINTF_ZU ":\n", this->layer()->id());
#endif #endif
if (bd.detect_angle()) { if (bd.detect_angle(Geometry::deg2rad(this->region()->config.bridge_angle))) {
bridges[idx_last].bridge_angle = bd.angle; bridges[idx_last].bridge_angle = bd.angle;
if (this->layer()->object()->config.support_material) { if (this->layer()->object()->config.support_material) {
polygons_append(this->bridged, bd.coverage()); polygons_append(this->bridged, bd.coverage());

View file

@ -65,6 +65,15 @@ PrintConfigDef::PrintConfigDef()
def->min = 0; def->min = 0;
def->default_value = new ConfigOptionFloat(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 = this->add("bridge_fan_speed", coInts);
def->label = "Bridges fan speed"; def->label = "Bridges fan speed";
def->tooltip = "This fan speed is enforced during all bridges and overhangs."; def->tooltip = "This fan speed is enforced during all bridges and overhangs.";

View file

@ -244,6 +244,7 @@ public:
class PrintRegionConfig : public virtual StaticPrintConfig class PrintRegionConfig : public virtual StaticPrintConfig
{ {
public: public:
ConfigOptionFloat bridge_angle;
ConfigOptionInt bottom_solid_layers; ConfigOptionInt bottom_solid_layers;
ConfigOptionFloat bridge_flow_ratio; ConfigOptionFloat bridge_flow_ratio;
ConfigOptionFloat bridge_speed; 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) { virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) {
UNUSED(create); UNUSED(create);
OPT_PTR(bridge_angle);
OPT_PTR(bottom_solid_layers); OPT_PTR(bottom_solid_layers);
OPT_PTR(bridge_flow_ratio); OPT_PTR(bridge_flow_ratio);
OPT_PTR(bridge_speed); OPT_PTR(bridge_speed);

View file

@ -195,7 +195,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "infill_extruder" || opt_key == "infill_extruder"
|| opt_key == "solid_infill_extruder" || opt_key == "solid_infill_extruder"
|| opt_key == "infill_extrusion_width" || opt_key == "infill_extrusion_width"
|| opt_key == "ensure_vertical_shell_thickness") { || opt_key == "ensure_vertical_shell_thickness"
|| opt_key == "bridge_angle") {
steps.emplace_back(posPrepareInfill); steps.emplace_back(posPrepareInfill);
} else if ( } else if (
opt_key == "external_fill_pattern" opt_key == "external_fill_pattern"