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

View file

@ -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<BridgeDirection> candidates;
{
if (bridge_direction_override == 0.) {
std::vector<double> 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

View file

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

View file

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

View file

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

View file

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

View file

@ -195,7 +195,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "infill_extruder"
|| opt_key == "solid_infill_extruder"
|| 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);
} else if (
opt_key == "external_fill_pattern"