diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index c0ed2e11..d5884c10 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -662,10 +662,9 @@ sub make_skirt { # skirt may be printed on several layers, having distinct layer heights, # but loops must be aligned so can't vary width/spacing # TODO: use each extruder's own flow - my $region0_config = $self->regions->[0]->config; my $first_layer_height = $self->objects->[0]->config->get_value('first_layer_height'); my $flow = Slic3r::Flow->new( - width => ($region0_config->first_layer_extrusion_width || $region0_config->perimeter_extrusion_width), + width => ($self->config->first_layer_extrusion_width || $self->regions->[0]->config->perimeter_extrusion_width), role => FLOW_ROLE_PERIMETER, nozzle_diameter => $self->config->nozzle_diameter->[0], layer_height => $first_layer_height, @@ -713,7 +712,7 @@ sub make_brim { # brim is only printed on first layer and uses support material extruder my $flow = Slic3r::Flow->new( - width => ($self->regions->[0]->config->first_layer_extrusion_width || $self->regions->[0]->config->perimeter_extrusion_width), + width => ($self->config->first_layer_extrusion_width || $self->regions->[0]->config->perimeter_extrusion_width), role => FLOW_ROLE_PERIMETER, nozzle_diameter => $self->config->nozzle_diameter->[ $self->objects->[0]->config->support_material_extruder-1 ], layer_height => $self->objects->[0]->config->get_abs_value('first_layer_height'), @@ -801,7 +800,7 @@ sub write_gcode { if $self->has_support_material; printf $fh "; first layer extrusion width = %.2fmm\n", $self->regions->[$region_id]->flow(FLOW_ROLE_PERIMETER, $layer_height, 0, 1)->width - if ($self->regions->[$region_id]->config->first_layer_extrusion_width ne '0'); + if $self->regions->[$region_id]->config->first_layer_extrusion_width; print $fh "\n"; } diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index bf4c2efb..84dc33b3 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -863,11 +863,20 @@ sub generate_support_material { return unless ($self->config->support_material || $self->config->raft_layers > 0) && $self->layer_count >= 2; + my $first_layer_flow = Slic3r::Flow->new( + width => ($self->config->first_layer_extrusion_width || $self->config->support_material_extrusion_width), + role => FLOW_ROLE_SUPPORT_MATERIAL, + nozzle_diameter => $self->print->config->nozzle_diameter->[ $self->config->support_material_extruder-1 ], + layer_height => $self->config->get_abs_value('first_layer_height'), + bridge_flow_ratio => 0, + ); + my $s = Slic3r::Print::SupportMaterial->new( - print_config => $self->print->config, - object_config => $self->config, - flow => $self->support_material_flow, - interface_flow => $self->support_material_flow(FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE), + print_config => $self->print->config, + object_config => $self->config, + first_layer_flow => $first_layer_flow, + flow => $self->support_material_flow, + interface_flow => $self->support_material_flow(FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE), ); $s->generate($self); } diff --git a/lib/Slic3r/Print/Region.pm b/lib/Slic3r/Print/Region.pm index ff05d5bc..c587f515 100644 --- a/lib/Slic3r/Print/Region.pm +++ b/lib/Slic3r/Print/Region.pm @@ -21,8 +21,8 @@ sub flow { if (!defined $config_width) { # get extrusion width from configuration # (might be an absolute value, or a percent value, or zero for auto) - if ($first_layer && $self->config->first_layer_extrusion_width ne '0') { - $config_width = $self->config->first_layer_extrusion_width; + if ($first_layer && $self->print->config->first_layer_extrusion_width) { + $config_width = $self->print->config->first_layer_extrusion_width; } elsif ($role == FLOW_ROLE_PERIMETER) { $config_width = $self->config->perimeter_extrusion_width; } elsif ($role == FLOW_ROLE_INFILL) { diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 0dae19e1..b6d793ee 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -9,9 +9,11 @@ use Slic3r::Geometry::Clipper qw(offset diff union union_ex intersection offset_ intersection_pl); use Slic3r::Surface ':types'; -has 'print_config' => (is => 'rw', required => 1); -has 'object_config' => (is => 'rw', required => 1); -has 'flow' => (is => 'rw', required => 1); +has 'print_config' => (is => 'rw', required => 1); +has 'object_config' => (is => 'rw', required => 1); +has 'flow' => (is => 'rw', required => 1); +has 'first_layer_flow' => (is => 'rw', required => 1); +has 'interface_flow' => (is => 'rw', required => 1); use constant DEBUG_CONTACT_ONLY => 0; @@ -385,11 +387,12 @@ sub clip_with_object { sub generate_toolpaths { my ($self, $object, $overhang, $contact, $interface, $base) = @_; - my $flow = $self->flow; + my $flow = $self->flow; + my $interface_flow = $self->interface_flow; # shape of contact area my $contact_loops = 1; - my $circle_radius = 1.5 * $flow->scaled_width; + my $circle_radius = 1.5 * $interface_flow->scaled_width; my $circle_distance = 3 * $circle_radius; my $circle = Slic3r::Polygon->new(map [ $circle_radius * cos $_, $circle_radius * sin $_ ], (5*PI/3, 4*PI/3, PI, 2*PI/3, PI/3, 0)); @@ -410,8 +413,8 @@ sub generate_toolpaths { ); my $interface_angle = $self->object_config->support_material_angle + 90; - my $interface_spacing = $self->object_config->support_material_interface_spacing + $flow->spacing; - my $interface_density = $interface_spacing == 0 ? 1 : $flow->spacing / $interface_spacing; + my $interface_spacing = $self->object_config->support_material_interface_spacing + $interface_flow->spacing; + my $interface_density = $interface_spacing == 0 ? 1 : $interface_flow->spacing / $interface_spacing; my $support_spacing = $self->object_config->support_material_spacing + $flow->spacing; my $support_density = $support_spacing == 0 ? 1 : $flow->spacing / $support_spacing; @@ -452,11 +455,11 @@ sub generate_toolpaths { my @loops0 = (); { # find centerline of the external loop of the contours - my @external_loops = @{offset($contact, -$flow->scaled_width/2)}; + my @external_loops = @{offset($contact, -$interface_flow->scaled_width/2)}; # only consider the loops facing the overhang { - my $overhang_with_margin = offset($overhang, +$flow->scaled_width/2); + my $overhang_with_margin = offset($overhang, +$interface_flow->scaled_width/2); @external_loops = grep { @{intersection_pl( [ $_->split_at_first_point ], @@ -476,8 +479,8 @@ sub generate_toolpaths { # make more loops my @loops = @loops0; for my $i (2..$contact_loops) { - my $d = ($i-1) * $flow->scaled_spacing; - push @loops, @{offset2(\@loops0, -$d -0.5*$flow->scaled_spacing, +0.5*$flow->scaled_spacing)}; + my $d = ($i-1) * $interface_flow->scaled_spacing; + push @loops, @{offset2(\@loops0, -$d -0.5*$interface_flow->scaled_spacing, +0.5*$interface_flow->scaled_spacing)}; } # clip such loops to the side oriented towards the object @@ -500,7 +503,7 @@ sub generate_toolpaths { @loops = map Slic3r::ExtrusionPath->new( polyline => $_, role => EXTR_ROLE_SUPPORTMATERIAL, - flow_spacing => $flow->spacing, + flow_spacing => $interface_flow->spacing, ), @loops; $layer->support_interface_fills->append(@loops); @@ -534,7 +537,7 @@ sub generate_toolpaths { my ($params, @p) = $fillers{interface}->fill_surface( Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL), density => $interface_density, - flow_spacing => $flow->spacing, + flow_spacing => $interface_flow->spacing, complete => 1, ); @@ -565,7 +568,7 @@ sub generate_toolpaths { $filler = $fillers{interface}; $filler->angle($self->object_config->support_material_angle + 90); $density = 0.5; - $flow_spacing = $object->print->first_layer_support_material_flow->spacing; + $flow_spacing = $self->first_layer_flow->spacing; } else { # draw a perimeter all around support infill # TODO: use brim ordering algorithm diff --git a/xs/src/Config.hpp b/xs/src/Config.hpp index 3af99a44..9306a18b 100644 --- a/xs/src/Config.hpp +++ b/xs/src/Config.hpp @@ -374,7 +374,7 @@ class ConfigOptionDef std::vector enum_labels; t_config_enum_values enum_keys_map; - ConfigOptionDef() : multiline(false), full_label(false), full_width(false), readonly(false), + ConfigOptionDef() : multiline(false), full_width(false), readonly(false), height(-1), width(-1), min(INT_MIN), max(INT_MAX) {}; }; diff --git a/xs/src/PrintConfig.hpp b/xs/src/PrintConfig.hpp index 8ac01f50..05380ab1 100644 --- a/xs/src/PrintConfig.hpp +++ b/xs/src/PrintConfig.hpp @@ -952,7 +952,6 @@ class PrintRegionConfig : public virtual StaticConfig ConfigOptionInt fill_angle; ConfigOptionFloat fill_density; ConfigOptionEnum fill_pattern; - ConfigOptionFloatOrPercent first_layer_extrusion_width; ConfigOptionInt infill_extruder; ConfigOptionFloatOrPercent infill_extrusion_width; ConfigOptionInt infill_every_layers; @@ -976,8 +975,6 @@ class PrintRegionConfig : public virtual StaticConfig this->fill_angle.value = 45; this->fill_density.value = 0.4; this->fill_pattern.value = ipHoneycomb; - this->first_layer_extrusion_width.value = 200; - this->first_layer_extrusion_width.percent = true; this->infill_extruder.value = 1; this->infill_extrusion_width.value = 0; this->infill_extrusion_width.percent = false; @@ -1003,7 +1000,6 @@ class PrintRegionConfig : public virtual StaticConfig if (opt_key == "fill_angle") return &this->fill_angle; if (opt_key == "fill_density") return &this->fill_density; if (opt_key == "fill_pattern") return &this->fill_pattern; - if (opt_key == "first_layer_extrusion_width") return &this->first_layer_extrusion_width; if (opt_key == "infill_extruder") return &this->infill_extruder; if (opt_key == "infill_extrusion_width") return &this->infill_extrusion_width; if (opt_key == "infill_every_layers") return &this->infill_every_layers; @@ -1052,6 +1048,7 @@ class PrintConfig : public virtual StaticConfig ConfigOptionFloats filament_diameter; ConfigOptionFloat first_layer_acceleration; ConfigOptionInt first_layer_bed_temperature; + ConfigOptionFloatOrPercent first_layer_extrusion_width; ConfigOptionFloatOrPercent first_layer_speed; ConfigOptionInts first_layer_temperature; ConfigOptionBool g0; @@ -1142,6 +1139,8 @@ class PrintConfig : public virtual StaticConfig this->filament_diameter.values[0] = 3; this->first_layer_acceleration.value = 0; this->first_layer_bed_temperature.value = 0; + this->first_layer_extrusion_width.value = 200; + this->first_layer_extrusion_width.percent = true; this->first_layer_speed.value = 30; this->first_layer_speed.percent = true; this->first_layer_temperature.values.resize(1); @@ -1242,6 +1241,7 @@ class PrintConfig : public virtual StaticConfig if (opt_key == "filament_diameter") return &this->filament_diameter; if (opt_key == "first_layer_acceleration") return &this->first_layer_acceleration; if (opt_key == "first_layer_bed_temperature") return &this->first_layer_bed_temperature; + if (opt_key == "first_layer_extrusion_width") return &this->first_layer_extrusion_width; if (opt_key == "first_layer_speed") return &this->first_layer_speed; if (opt_key == "first_layer_temperature") return &this->first_layer_temperature; if (opt_key == "g0") return &this->g0;