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:
parent
75c72bc59b
commit
71f99423c5
7 changed files with 27 additions and 13 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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.";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue