diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 4314e4fa6..d9b8b3313 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -8,7 +8,7 @@ use Slic3r::ExtrusionPath ':roles'; use Slic3r::Flow ':roles'; use Slic3r::Geometry qw(epsilon scale scaled_epsilon PI rad2deg deg2rad convex_hull); use Slic3r::Geometry::Clipper qw(offset diff union union_ex intersection offset_ex offset2 - intersection_pl offset2_ex diff_pl); + intersection_pl offset2_ex diff_pl diff_ex); use Slic3r::Surface ':types'; has 'print_config' => (is => 'rw', required => 1); @@ -782,7 +782,7 @@ sub generate_toolpaths { my $base_flow = $_flow; # find centerline of the external loop/extrusions - my $to_infill = offset2_ex($base, +scaled_epsilon, -(scaled_epsilon + $_flow->scaled_width/2)); + my $to_infill = offset2($base, +scaled_epsilon, -(scaled_epsilon + $_flow->scaled_width/2)); my @paths = (); @@ -796,6 +796,15 @@ sub generate_toolpaths { # use the proper spacing for first layer as we don't need to align # its pattern to the other layers $filler->set_min_spacing($base_flow->spacing); + + # subtract brim so that it goes around the object fully (and support gets its own brim) + if ($self->print_config->brim_width > 0) { + my $d = +scale $self->print_config->brim_width*2; + $to_infill = diff_ex( + $to_infill, + offset($object->get_layer(0)->slices->polygons, $d), + ); + } } else { # draw a perimeter all around support infill # TODO: use brim ordering algorithm @@ -806,10 +815,10 @@ sub generate_toolpaths { mm3_per_mm => $mm3_per_mm, width => $_flow->width, height => $layer->height, - ), map @$_, @$to_infill; + ), @$to_infill; # TODO: use offset2_ex() - $to_infill = offset_ex([ map @$_, @$to_infill ], -$_flow->scaled_spacing); + $to_infill = offset_ex($to_infill, -$_flow->scaled_spacing); } my $mm3_per_mm = $base_flow->mm3_per_mm; diff --git a/xs/src/libslic3r/Fill/Fill.cpp b/xs/src/libslic3r/Fill/Fill.cpp index c88a32514..555081616 100644 --- a/xs/src/libslic3r/Fill/Fill.cpp +++ b/xs/src/libslic3r/Fill/Fill.cpp @@ -1,3 +1,6 @@ +#define DEBUG +#undef NDEBUG +#include #include #include diff --git a/xs/src/libslic3r/Flow.cpp b/xs/src/libslic3r/Flow.cpp index 6131534e7..a0cd62236 100644 --- a/xs/src/libslic3r/Flow.cpp +++ b/xs/src/libslic3r/Flow.cpp @@ -50,6 +50,11 @@ Flow::spacing() const { return this->width - OVERLAP_FACTOR * (this->width - min_flow_spacing); } +void +Flow::set_spacing(float spacing) { + this->width = Flow::_width_from_spacing(spacing, this->nozzle_diameter, this->height, this->bridge); +} + /* This method returns the centerline spacing between an extrusion using this flow and another one using another flow. this->spacing(other) shall return the same value as other.spacing(*this) */ diff --git a/xs/src/libslic3r/Flow.hpp b/xs/src/libslic3r/Flow.hpp index fdfcac695..8284cc6d6 100644 --- a/xs/src/libslic3r/Flow.hpp +++ b/xs/src/libslic3r/Flow.hpp @@ -30,6 +30,7 @@ class Flow : width(_w), height(_h), nozzle_diameter(_nd), bridge(_bridge) {}; float spacing() const; float spacing(const Flow &other) const; + void set_spacing(float spacing); double mm3_per_mm() const; coord_t scaled_width() const { return scale_(this->width); @@ -48,7 +49,6 @@ class Flow static float _bridge_width(float nozzle_diameter, float bridge_flow_ratio); static float _auto_width(FlowRole role, float nozzle_diameter, float height); static float _width_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge); - static float _spacing(float width, float nozzle_diameter, float height, float bridge_flow_ratio); }; } diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 36ce27a8a..118c73e96 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -163,6 +163,10 @@ Print::invalidate_state_by_config(const PrintConfigBase &config) || opt_key == "min_skirt_length" || opt_key == "ooze_prevention") { steps.insert(psSkirt); + } else if (opt_key == "brim_width") { + steps.insert(psBrim); + steps.insert(psSkirt); + osteps.insert(posSupportMaterial); } else if (opt_key == "brim_width" || opt_key == "interior_brim_width" || opt_key == "brim_connections_width") { @@ -759,13 +763,17 @@ Print::brim_flow() const extruders and take the one with, say, the smallest index. The same logic should be applied to the code that selects the extruder during G-code generation as well. */ - return Flow::new_from_config_width( + Flow flow = Flow::new_from_config_width( frPerimeter, width, this->config.nozzle_diameter.get_at(this->regions.front()->config.perimeter_extruder-1), this->skirt_first_layer_height(), 0 ); + + flow.set_spacing(unscale(Fill::adjust_solid_spacing(scale_(this->config.brim_width.value), scale_(flow.spacing())))); + + return flow; } Flow @@ -844,8 +852,8 @@ Print::_make_brim() // perimeters because here we're offsetting outwards) append_to(loops, offset2( islands, - flow.scaled_width() + flow.scaled_spacing() * (i - 1.0 + 0.5), - flow.scaled_spacing() * -1.0, + flow.scaled_width() + flow.scaled_spacing() * (i - 1.5 + 0.5), + flow.scaled_spacing() * -0.5, 100000, ClipperLib::jtSquare ));