diff --git a/lib/Slic3r/GUI/PresetEditor.pm b/lib/Slic3r/GUI/PresetEditor.pm index 759a71442..8df829342 100644 --- a/lib/Slic3r/GUI/PresetEditor.pm +++ b/lib/Slic3r/GUI/PresetEditor.pm @@ -472,7 +472,7 @@ sub options { extrusion_width first_layer_extrusion_width perimeter_extrusion_width external_perimeter_extrusion_width infill_extrusion_width solid_infill_extrusion_width top_infill_extrusion_width support_material_extrusion_width - infill_overlap bridge_flow_ratio + support_material_interface_extrusion_width infill_overlap bridge_flow_ratio xy_size_compensation resolution shortcuts compatible_printers print_settings_id ) @@ -685,7 +685,8 @@ sub build { for qw(extrusion_width first_layer_extrusion_width perimeter_extrusion_width external_perimeter_extrusion_width infill_extrusion_width solid_infill_extrusion_width - top_infill_extrusion_width support_material_extrusion_width); + top_infill_extrusion_width support_material_interface_extrusion_width + support_material_extrusion_width); } { my $optgroup = $page->new_optgroup('Overlap'); @@ -923,7 +924,8 @@ sub _update { for qw(support_material_threshold support_material_pattern support_material_spacing support_material_angle support_material_interface_layers dont_support_bridges - support_material_extrusion_width support_material_contact_distance); + support_material_extrusion_width support_material_interface_extrusion_width + support_material_contact_distance); $self->get_field($_)->toggle($have_support_material && $have_support_interface) for qw(support_material_interface_spacing support_material_interface_extruder diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 6eb9993aa..3bd01a1cd 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -670,11 +670,16 @@ sub support_material_flow { my $extruder = ($role == FLOW_ROLE_SUPPORT_MATERIAL) ? $self->config->support_material_extruder : $self->config->support_material_interface_extruder; + + my $width = $self->config->support_material_extrusion_width || $self->config->extrusion_width; + if ($role == FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE) { + $width = $self->config->support_material_interface_extrusion_width || $width; + } # we use a bogus layer_height because we use the same flow for all # support material layers return Slic3r::Flow->new_from_width( - width => $self->config->support_material_extrusion_width || $self->config->extrusion_width, + width => $width, role => $role, nozzle_diameter => $self->print->config->nozzle_diameter->[$extruder-1] // $self->print->config->nozzle_diameter->[0], layer_height => $self->config->layer_height, diff --git a/t/support.t b/t/support.t index 8d4655b3f..0a5a75337 100644 --- a/t/support.t +++ b/t/support.t @@ -1,4 +1,4 @@ -use Test::More tests => 28; +use Test::More tests => 29; use strict; use warnings; @@ -10,7 +10,7 @@ BEGIN { use List::Util qw(first); use Slic3r; -use Slic3r::Geometry qw(epsilon scale); +use Slic3r::Geometry qw(epsilon scale PI); use Slic3r::Geometry::Clipper qw(diff); use Slic3r::Test; @@ -114,7 +114,6 @@ use Slic3r::Test; my %first_object_layer_speeds = (); # F => 1 Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { my ($self, $cmd, $args, $info) = @_; - if ($info->{extruding} && $info->{dist_XY} > 0) { if ($layer_id <= $config->raft_layers) { # this is a raft layer or the first object layer @@ -141,6 +140,61 @@ use Slic3r::Test; 'bridge speed used in first object layer'; } +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('layer_height', 0.2); + $config->set('skirts', 0); + $config->set('raft_layers', 5); + $config->set('support_material_pattern', 'rectilinear'); + $config->set('support_material_extrusion_width', 0.4); + $config->set('support_material_interface_extrusion_width', 0.6); + $config->set('support_material_interface_layers', 2); + $config->set('first_layer_extrusion_width', '100%'); + $config->set('bridge_speed', 99); + $config->set('cooling', 0); # prevent speed alteration + $config->set('first_layer_speed', '100%'); # prevent speed alteration + $config->set('start_gcode', ''); # prevent any unexpected Z move + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + + my $layer_id = -1; + my $success = 1; + Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { + my ($self, $cmd, $args, $info) = @_; + if ($info->{extruding} && $info->{dist_XY} > 0) { + # this is a raft layer + if (($layer_id < $config->raft_layers) && ($layer_id > 0)) { + my $width; + my $support_layer_height = $config->nozzle_diameter->[0] * 0.75; + + # support layer + if ($config->raft_layers - $config->support_material_interface_layers > $layer_id) { + $width = $config->support_material_extrusion_width; + } + # interface layer + else { + $width = $config->support_material_interface_extrusion_width; + } + my $expected_E_per_mm3 = 4 / (($config->filament_diameter->[0]**2) * PI); + my $expected_mm3_per_mm = $width * $support_layer_height + ($support_layer_height**2) / 4.0 * (PI-4.0); + my $expected_e_per_mm = $expected_E_per_mm3 * $expected_mm3_per_mm; + + my $e_per_mm = ($info->{dist_E} / $info->{dist_XY});; + + my $diff = abs($e_per_mm - $expected_e_per_mm); + + if ($diff > 0.001) { + $success = 0; + } + } + } elsif ($cmd eq 'G1' && $info->{dist_Z} > 0) { + $layer_id++; + } + }); + + ok $success, + 'support material interface extrusion width is used for interfaces'; +} + { my $config = Slic3r::Config->new_from_defaults; $config->set('skirts', 0); diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 0056a8a20..c5dc67618 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -1430,6 +1430,18 @@ PrintConfigDef::PrintConfigDef() def->min = 1; def->default_value = new ConfigOptionInt(1); + def = this->add("support_material_interface_extrusion_width", coFloatOrPercent); + def->label = "Support material"; + def->gui_type = "f_enum_open"; + def->category = "Extrusion Width"; + def->tooltip = "Set this to a non-zero value to set a manual extrusion width for support material interface. If expressed as percentage (for example 90%) it will be computed over layer height."; + def->sidetext = "mm or %"; + def->cli = "support-material-interface-extrusion-width=s"; + def->min = 0; + def->enum_values.push_back("0"); + def->enum_labels.push_back("default"); + def->default_value = new ConfigOptionFloatOrPercent(0, false); + def = this->add("support_material_interface_layers", coInt); def->label = "Interface layers"; def->category = "Support material"; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 292b3eab5..abf9d9a7a 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -174,6 +174,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig ConfigOptionInt support_material_extruder; ConfigOptionFloatOrPercent support_material_extrusion_width; ConfigOptionInt support_material_interface_extruder; + ConfigOptionFloatOrPercent support_material_interface_extrusion_width; ConfigOptionInt support_material_interface_layers; ConfigOptionFloat support_material_interface_spacing; ConfigOptionFloatOrPercent support_material_interface_speed; @@ -210,6 +211,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig OPT_PTR(support_material_extruder); OPT_PTR(support_material_extrusion_width); OPT_PTR(support_material_interface_extruder); + OPT_PTR(support_material_interface_extrusion_width); OPT_PTR(support_material_interface_layers); OPT_PTR(support_material_interface_spacing); OPT_PTR(support_material_interface_speed); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 10b56c37f..b6848082b 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -244,6 +244,7 @@ PrintObject::invalidate_state_by_config(const PrintConfigBase &config) || opt_key == "support_material_extrusion_width" || opt_key == "support_material_interface_layers" || opt_key == "support_material_interface_extruder" + || opt_key == "support_material_interface_extrusion_width" || opt_key == "support_material_interface_spacing" || opt_key == "support_material_interface_speed" || opt_key == "support_material_buildplate_only"