Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--lib/Slic3r/Fill.pm36
-rw-r--r--lib/Slic3r/GCode.pm4
-rw-r--r--lib/Slic3r/GUI/Tab.pm4
-rw-r--r--lib/Slic3r/Layer/Region.pm4
-rw-r--r--lib/Slic3r/Print/GCode.pm142
-rw-r--r--lib/Slic3r/Print/Object.pm5
-rw-r--r--lib/Slic3r/Print/SupportMaterial.pm2
-rwxr-xr-xslic3r.pl1
-rw-r--r--t/fill.t2
-rw-r--r--xs/lib/Slic3r/XS.pm4
-rw-r--r--xs/src/libslic3r/ExtrusionEntity.cpp13
-rw-r--r--xs/src/libslic3r/ExtrusionEntity.hpp3
-rw-r--r--xs/src/libslic3r/ExtrusionEntityCollection.cpp3
-rw-r--r--xs/src/libslic3r/ExtrusionEntityCollection.hpp2
-rw-r--r--xs/src/libslic3r/Layer.hpp2
-rw-r--r--xs/src/libslic3r/Print.cpp1
-rw-r--r--xs/src/libslic3r/PrintConfig.cpp7
-rw-r--r--xs/src/libslic3r/PrintConfig.hpp7
-rw-r--r--xs/src/libslic3r/PrintObject.cpp1
-rw-r--r--xs/src/libslic3r/PrintRegion.cpp4
-rw-r--r--xs/t/12_extrusionpathcollection.t7
-rw-r--r--xs/t/15_config.t9
-rw-r--r--xs/xsp/ExtrusionEntityCollection.xsp2
-rw-r--r--xs/xsp/ExtrusionPath.xsp3
25 files changed, 180 insertions, 89 deletions
diff --git a/README.md b/README.md
index 4e35d5572..fe8c267d6 100644
--- a/README.md
+++ b/README.md
@@ -353,6 +353,7 @@ The author of the Silk icon set is Mark James.
--perimeter-extruder
Extruder to use for perimeters (1+, default: 1)
--infill-extruder Extruder to use for infill (1+, default: 1)
+ --solid-infill-extruder Extruder to use for solid infill (1+, default: 1)
--support-material-extruder
Extruder to use for support material (1+, default: 1)
--support-material-interface-extruder
diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm
index 82c2ec6cc..4547a846b 100644
--- a/lib/Slic3r/Fill.pm
+++ b/lib/Slic3r/Fill.pm
@@ -225,28 +225,32 @@ sub make_fill {
my $mm3_per_mm = $flow->mm3_per_mm;
# save into layer
- push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new;
- $collection->no_sort($params->{no_sort});
+ {
+ my $role = $is_bridge ? EXTR_ROLE_BRIDGE
+ : $is_solid ? (($surface->surface_type == S_TYPE_TOP) ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL)
+ : EXTR_ROLE_FILL;
+
+ my $extrusion_height = $is_bridge ? $flow->width : $h;
+
+ push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new($role);
+ $collection->no_sort($params->{no_sort});
+ $collection->append(
+ map Slic3r::ExtrusionPath->new(
+ polyline => $_,
+ role => $role,
+ mm3_per_mm => $mm3_per_mm,
+ width => $flow->width,
+ height => $extrusion_height,
+ ), @polylines,
+ );
+ }
- $collection->append(
- map Slic3r::ExtrusionPath->new(
- polyline => $_,
- role => ($is_bridge
- ? EXTR_ROLE_BRIDGE
- : $is_solid
- ? (($surface->surface_type == S_TYPE_TOP) ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL)
- : EXTR_ROLE_FILL),
- mm3_per_mm => $mm3_per_mm,
- width => $flow->width,
- height => ($is_bridge ? $flow->width : $h),
- ), @polylines,
- );
push @fills_ordering_points, $polylines[0]->first_point;
}
# add thin fill regions
foreach my $thin_fill (@{$layerm->thin_fills}) {
- push @fills, Slic3r::ExtrusionPath::Collection->new($thin_fill);
+ push @fills, Slic3r::ExtrusionPath::Collection->new($thin_fill->role, $thin_fill);
push @fills_ordering_points, $thin_fill->first_point;
}
diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm
index 662d95a86..9dc4e29bd 100644
--- a/lib/Slic3r/GCode.pm
+++ b/lib/Slic3r/GCode.pm
@@ -256,10 +256,10 @@ sub _extrude_path {
$acceleration = $self->config->first_layer_acceleration;
} elsif ($self->config->perimeter_acceleration && $path->is_perimeter) {
$acceleration = $self->config->perimeter_acceleration;
- } elsif ($self->config->infill_acceleration && $path->is_fill) {
- $acceleration = $self->config->infill_acceleration;
} elsif ($self->config->bridge_acceleration && $path->is_bridge) {
$acceleration = $self->config->bridge_acceleration;
+ } elsif ($self->config->infill_acceleration && $path->is_infill) {
+ $acceleration = $self->config->infill_acceleration;
} else {
$acceleration = $self->config->default_acceleration;
}
diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm
index ecb476fd5..ad589e2b5 100644
--- a/lib/Slic3r/GUI/Tab.pm
+++ b/lib/Slic3r/GUI/Tab.pm
@@ -454,7 +454,8 @@ sub build {
complete_objects extruder_clearance_radius extruder_clearance_height
gcode_comments output_filename_format
post_process
- perimeter_extruder infill_extruder support_material_extruder support_material_interface_extruder
+ perimeter_extruder infill_extruder solid_infill_extruder
+ support_material_extruder support_material_interface_extruder
ooze_prevention standby_temperature_delta
interface_shells
extrusion_width first_layer_extrusion_width perimeter_extrusion_width
@@ -648,6 +649,7 @@ sub build {
my $optgroup = $page->new_optgroup('Extruders');
$optgroup->append_single_option_line('perimeter_extruder');
$optgroup->append_single_option_line('infill_extruder');
+ $optgroup->append_single_option_line('solid_infill_extruder');
$optgroup->append_single_option_line('support_material_extruder');
$optgroup->append_single_option_line('support_material_interface_extruder');
}
diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm
index fbc665df3..bc09f77ca 100644
--- a/lib/Slic3r/Layer/Region.pm
+++ b/lib/Slic3r/Layer/Region.pm
@@ -246,7 +246,7 @@ sub make_perimeters {
my ($polynodes, $depth, $is_contour) = @_;
# convert all polynodes to ExtrusionLoop objects
- my $collection = Slic3r::ExtrusionPath::Collection->new;
+ my $collection = Slic3r::ExtrusionPath::Collection->new(EXTR_ROLE_PERIMETER); # temporary collection
my @children = ();
foreach my $polynode (@$polynodes) {
my $polygon = ($polynode->{outer} // $polynode->{hole})->clone;
@@ -303,7 +303,7 @@ sub make_perimeters {
# (clone because the collection gets DESTROY'ed)
# We allow polyline reversal because Clipper may have randomly
# reversed polylines during clipping.
- my $collection = Slic3r::ExtrusionPath::Collection->new(@paths);
+ my $collection = Slic3r::ExtrusionPath::Collection->new(EXTR_ROLE_PERIMETER, @paths); # temporary collection
@paths = map $_->clone, @{$collection->chained_path(0)};
} else {
push @paths, Slic3r::ExtrusionPath->new(
diff --git a/lib/Slic3r/Print/GCode.pm b/lib/Slic3r/Print/GCode.pm
index ca572fc72..7417c48ec 100644
--- a/lib/Slic3r/Print/GCode.pm
+++ b/lib/Slic3r/Print/GCode.pm
@@ -380,54 +380,87 @@ sub process_layer {
}
}
- # tweak region ordering to save toolchanges
- my @region_ids = 0 .. ($self->print->region_count-1);
- if ($self->_gcodegen->writer->multiple_extruders) {
- my $last_extruder_id = $self->_gcodegen->writer->extruder->id;
- my $best_region_id = first { $self->print->regions->[$_]->config->perimeter_extruder-1 == $last_extruder_id } @region_ids;
- @region_ids = ($best_region_id, grep $_ != $best_region_id, @region_ids) if $best_region_id;
- }
+ # We now define a strategy for building perimeters and fills. The separation
+ # between regions doesn't matter in terms of printing order, as we follow
+ # another logic instead:
+ # - we group all extrusions by extruder so that we minimize toolchanges
+ # - we start from the last used extruder
+ # - for each extruder, we group extrusions by island
+ # - for each island, we extrude perimeters first, unless user set the infill_first
+ # option
+
+ # group extrusions by extruder and then by island
+ my %by_extruder = (); # extruder_id => [ { perimeters => \@perimeters, infill => \@infill } ]
- foreach my $region_id (@region_ids) {
+ foreach my $region_id (0..($self->print->region_count-1)) {
my $layerm = $layer->regions->[$region_id] or next;
- my $region = $self->print->regions->[$region_id];
- $self->_gcodegen->config->apply_region_config($region->config);
-
- # group extrusions by island
- my @perimeters_by_island = map [], 0..$#{$layer->slices}; # slice idx => @perimeters
- my @infill_by_island = map [], 0..$#{$layer->slices}; # slice idx => @fills
-
- # NOTE: we assume $layer->slices was already ordered with chained_path()!
+ my $region = $self->print->get_region($region_id);
- PERIMETER: foreach my $perimeter (@{$layerm->perimeters}) {
- for my $i (0 .. $#{$layer->slices}-1) {
- if ($layer->slices->[$i]->contour->contains_point($perimeter->first_point)) {
- push @{ $perimeters_by_island[$i] }, $perimeter;
- next PERIMETER;
+ # process perimeters
+ {
+ my $extruder_id = $region->config->perimeter_extruder-1;
+ foreach my $perimeter (@{$layerm->perimeters}) {
+ # init by_extruder item only if we actually use the extruder
+ $by_extruder{$extruder_id} //= [];
+
+ # $perimeter is an ExtrusionLoop or ExtrusionPath object
+ for my $i (0 .. $#{$layer->slices}) {
+ if ($i == $#{$layer->slices}
+ || $layer->slices->[$i]->contour->contains_point($perimeter->first_point)) {
+ $by_extruder{$extruder_id}[$i] //= { perimeters => {} };
+ $by_extruder{$extruder_id}[$i]{perimeters}{$region_id} //= [];
+ push @{ $by_extruder{$extruder_id}[$i]{perimeters}{$region_id} }, $perimeter;
+ last;
+ }
}
}
- push @{ $perimeters_by_island[-1] }, $perimeter; # optimization
}
- FILL: foreach my $fill (@{$layerm->fills}) {
- for my $i (0 .. $#{$layer->slices}-1) {
- if ($layer->slices->[$i]->contour->contains_point($fill->first_point)) {
- push @{ $infill_by_island[$i] }, $fill;
- next FILL;
+
+ # process infill
+ {
+ foreach my $fill (@{$layerm->fills}) {
+ # init by_extruder item only if we actually use the extruder
+ my $extruder_id = $fill->[0]->is_solid_infill
+ ? $region->config->solid_infill_extruder-1
+ : $region->config->infill_extruder-1;
+
+ $by_extruder{$extruder_id} //= [];
+
+ # $fill is an ExtrusionPath::Collection object
+ for my $i (0 .. $#{$layer->slices}) {
+ if ($i == $#{$layer->slices}
+ || $layer->slices->[$i]->contour->contains_point($fill->first_point)) {
+ $by_extruder{$extruder_id}[$i] //= { infill => {} };
+ $by_extruder{$extruder_id}[$i]{infill}{$region_id} //= [];
+ push @{ $by_extruder{$extruder_id}[$i]{infill}{$region_id} }, $fill;
+ last;
+ }
}
}
- push @{ $infill_by_island[-1] }, $fill; # optimization
}
-
- for my $i (0 .. $#{$layer->slices}) {
- # give priority to infill if we were already using its extruder and it wouldn't
- # be good for perimeters
- if ($self->print->config->infill_first
- || ($self->_gcodegen->writer->multiple_extruders && $region->config->infill_extruder-1 == $self->_gcodegen->writer->extruder->id && $region->config->infill_extruder != $region->config->perimeter_extruder)) {
- $gcode .= $self->_extrude_infill($infill_by_island[$i], $region);
- $gcode .= $self->_extrude_perimeters($perimeters_by_island[$i], $region);
+ }
+
+ # tweak extruder ordering to save toolchanges
+ my @extruders = sort keys %by_extruder;
+ if (@extruders > 1) {
+ my $last_extruder_id = $self->_gcodegen->writer->extruder->id;
+ if (exists $by_extruder{$last_extruder_id}) {
+ @extruders = (
+ $last_extruder_id,
+ grep $_ != $last_extruder_id, @extruders,
+ );
+ }
+ }
+
+ foreach my $extruder_id (@extruders) {
+ $gcode .= $self->_gcodegen->set_extruder($extruder_id);
+ foreach my $island (@{ $by_extruder{$extruder_id} }) {
+ if ($self->print->config->infill_first) {
+ $gcode .= $self->_extrude_infill($island->{infill} // {});
+ $gcode .= $self->_extrude_perimeters($island->{perimeters} // {});
} else {
- $gcode .= $self->_extrude_perimeters($perimeters_by_island[$i], $region);
- $gcode .= $self->_extrude_infill($infill_by_island[$i], $region);
+ $gcode .= $self->_extrude_perimeters($island->{perimeters} // {});
+ $gcode .= $self->_extrude_infill($island->{infill} // {});
}
}
}
@@ -452,31 +485,30 @@ sub process_layer {
}
sub _extrude_perimeters {
- my $self = shift;
- my ($island_perimeters, $region) = @_;
-
- return "" if !@$island_perimeters;
+ my ($self, $entities_by_region) = @_;
my $gcode = "";
- $gcode .= $self->_gcodegen->set_extruder($region->config->perimeter_extruder-1);
- $gcode .= $self->_gcodegen->extrude($_, 'perimeter') for @$island_perimeters;
+ foreach my $region_id (sort keys %$entities_by_region) {
+ $self->_gcodegen->config->apply_region_config($self->print->get_region($region_id)->config);
+ $gcode .= $self->_gcodegen->extrude($_, 'perimeter')
+ for @{ $entities_by_region->{$region_id} };
+ }
return $gcode;
}
sub _extrude_infill {
- my $self = shift;
- my ($island_fills, $region) = @_;
-
- return "" if !@$island_fills;
+ my ($self, $entities_by_region) = @_;
my $gcode = "";
- $gcode .= $self->_gcodegen->set_extruder($region->config->infill_extruder-1);
- for my $fill (@$island_fills) {
- if ($fill->isa('Slic3r::ExtrusionPath::Collection')) {
- $gcode .= $self->_gcodegen->extrude($_, 'fill')
- for @{$fill->chained_path_from($self->_gcodegen->last_pos, 0)};
- } else {
- $gcode .= $self->_gcodegen->extrude($fill, 'fill') ;
+ foreach my $region_id (sort keys %$entities_by_region) {
+ $self->_gcodegen->config->apply_region_config($self->print->get_region($region_id)->config);
+ for my $fill (@{ $entities_by_region->{$region_id} }) {
+ if ($fill->isa('Slic3r::ExtrusionPath::Collection')) {
+ $gcode .= $self->_gcodegen->extrude($_, 'infill')
+ for @{$fill->chained_path_from($self->_gcodegen->last_pos, 0)};
+ } else {
+ $gcode .= $self->_gcodegen->extrude($fill, 'infill') ;
+ }
}
}
return $gcode;
diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm
index 166f18792..be819fefb 100644
--- a/lib/Slic3r/Print/Object.pm
+++ b/lib/Slic3r/Print/Object.pm
@@ -1004,7 +1004,10 @@ sub combine_infill {
next unless $every > 1 && $region->config->fill_density > 0;
# limit the number of combined layers to the maximum height allowed by this regions' nozzle
- my $nozzle_diameter = $self->print->config->get_at('nozzle_diameter', $region->config->infill_extruder-1);
+ my $nozzle_diameter = min(
+ $self->print->config->get_at('nozzle_diameter', $region->config->infill_extruder-1),
+ $self->print->config->get_at('nozzle_diameter', $region->config->solid_infill_extruder-1),
+ );
# define the combinations
my %combine = (); # layer_idx => number of additional combined lower layers
diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm
index 01df21a55..5771fcc66 100644
--- a/lib/Slic3r/Print/SupportMaterial.pm
+++ b/lib/Slic3r/Print/SupportMaterial.pm
@@ -262,7 +262,7 @@ sub contact_area {
{
# get the average nozzle diameter used on this layer
my @nozzle_diameters = map $self->print_config->get_at('nozzle_diameter', $_),
- map { $_->config->perimeter_extruder-1, $_->config->infill_extruder-1 }
+ map { $_->config->perimeter_extruder-1, $_->config->infill_extruder-1, $_->config->solid_infill_extruder-1 }
@{$layer->regions};
my $nozzle_diameter = sum(@nozzle_diameters)/@nozzle_diameters;
diff --git a/slic3r.pl b/slic3r.pl
index 70e109215..3568f92e3 100755
--- a/slic3r.pl
+++ b/slic3r.pl
@@ -505,6 +505,7 @@ $j
--perimeter-extruder
Extruder to use for perimeters (1+, default: $config->{perimeter_extruder})
--infill-extruder Extruder to use for infill (1+, default: $config->{infill_extruder})
+ --solid-infill-extruder Extruder to use for solid infill (1+, default: $config->{solid_infill_extruder})
--support-material-extruder
Extruder to use for support material (1+, default: $config->{support_material_extruder})
--support-material-interface-extruder
diff --git a/t/fill.t b/t/fill.t
index 24370b660..15f693a66 100644
--- a/t/fill.t
+++ b/t/fill.t
@@ -146,6 +146,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
{
my $collection = Slic3r::ExtrusionPath::Collection->new(
+ EXTR_ROLE_PERIMETER,
map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1),
Slic3r::Polyline->new([0,15], [0,18], [0,20]),
Slic3r::Polyline->new([0,10], [0,8], [0,5]),
@@ -158,6 +159,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
{
my $collection = Slic3r::ExtrusionPath::Collection->new(
+ EXTR_ROLE_PERIMETER,
map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1),
Slic3r::Polyline->new([15,0], [10,0], [4,0]),
Slic3r::Polyline->new([10,5], [15,5], [20,5]),
diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm
index 9ac0b35e9..08bb625cb 100644
--- a/xs/lib/Slic3r/XS.pm
+++ b/xs/lib/Slic3r/XS.pm
@@ -64,9 +64,9 @@ use overload
'fallback' => 1;
sub new {
- my ($class, @paths) = @_;
+ my ($class, $type, @paths) = @_;
- my $self = $class->_new;
+ my $self = $class->_new($type);
$self->append(@paths);
return $self;
}
diff --git a/xs/src/libslic3r/ExtrusionEntity.cpp b/xs/src/libslic3r/ExtrusionEntity.cpp
index 1bc5b4b24..7901317a3 100644
--- a/xs/src/libslic3r/ExtrusionEntity.cpp
+++ b/xs/src/libslic3r/ExtrusionEntity.cpp
@@ -76,9 +76,18 @@ ExtrusionPath::is_perimeter() const
}
bool
-ExtrusionPath::is_fill() const
+ExtrusionPath::is_infill() const
{
- return this->role == erInternalInfill
+ return this->role == erBridgeInfill
+ || this->role == erInternalInfill
+ || this->role == erSolidInfill
+ || this->role == erTopSolidInfill;
+}
+
+bool
+ExtrusionPath::is_solid_infill() const
+{
+ return this->role == erBridgeInfill
|| this->role == erSolidInfill
|| this->role == erTopSolidInfill;
}
diff --git a/xs/src/libslic3r/ExtrusionEntity.hpp b/xs/src/libslic3r/ExtrusionEntity.hpp
index aad36cb3d..da7658b76 100644
--- a/xs/src/libslic3r/ExtrusionEntity.hpp
+++ b/xs/src/libslic3r/ExtrusionEntity.hpp
@@ -64,7 +64,8 @@ class ExtrusionPath : public ExtrusionEntity
void simplify(double tolerance);
double length() const;
bool is_perimeter() const;
- bool is_fill() const;
+ bool is_infill() const;
+ bool is_solid_infill() const;
bool is_bridge() const;
std::string gcode(Extruder* extruder, double e, double F,
double xofs, double yofs, std::string extrusion_axis,
diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.cpp b/xs/src/libslic3r/ExtrusionEntityCollection.cpp
index a958e53cf..89748bc86 100644
--- a/xs/src/libslic3r/ExtrusionEntityCollection.cpp
+++ b/xs/src/libslic3r/ExtrusionEntityCollection.cpp
@@ -5,7 +5,7 @@
namespace Slic3r {
ExtrusionEntityCollection::ExtrusionEntityCollection(const ExtrusionEntityCollection& collection)
- : no_sort(collection.no_sort), orig_indices(collection.orig_indices)
+ : no_sort(collection.no_sort), role(collection.role), orig_indices(collection.orig_indices)
{
this->entities.reserve(collection.entities.size());
for (ExtrusionEntitiesPtr::const_iterator it = collection.entities.begin(); it != collection.entities.end(); ++it)
@@ -23,6 +23,7 @@ void
ExtrusionEntityCollection::swap (ExtrusionEntityCollection &c)
{
std::swap(this->entities, c.entities);
+ std::swap(this->role, c.role);
std::swap(this->orig_indices, c.orig_indices);
std::swap(this->no_sort, c.no_sort);
}
diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.hpp b/xs/src/libslic3r/ExtrusionEntityCollection.hpp
index bc660611b..a72563f47 100644
--- a/xs/src/libslic3r/ExtrusionEntityCollection.hpp
+++ b/xs/src/libslic3r/ExtrusionEntityCollection.hpp
@@ -13,7 +13,9 @@ class ExtrusionEntityCollection : public ExtrusionEntity
ExtrusionEntitiesPtr entities;
std::vector<size_t> orig_indices; // handy for XS
bool no_sort;
+ ExtrusionRole role;
ExtrusionEntityCollection(): no_sort(false) {};
+ ExtrusionEntityCollection(ExtrusionRole _role): no_sort(false), role(_role) {};
ExtrusionEntityCollection(const ExtrusionEntityCollection &collection);
ExtrusionEntityCollection& operator= (const ExtrusionEntityCollection &other);
void swap (ExtrusionEntityCollection &c);
diff --git a/xs/src/libslic3r/Layer.hpp b/xs/src/libslic3r/Layer.hpp
index ff8cca1d9..115a728e0 100644
--- a/xs/src/libslic3r/Layer.hpp
+++ b/xs/src/libslic3r/Layer.hpp
@@ -46,9 +46,11 @@ class LayerRegion
PolylineCollection unsupported_bridge_edges;
// ordered collection of extrusion paths/loops to build all perimeters
+ // (this collection contains both ExtrusionPath and ExtrusionLoop objects)
ExtrusionEntityCollection perimeters;
// ordered collection of extrusion paths to fill surfaces
+ // (this collection contains only ExtrusionEntityCollection objects)
ExtrusionEntityCollection fills;
Flow flow(FlowRole role, bool bridge = false, double width = -1) const;
diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp
index 6edd32609..9d834c605 100644
--- a/xs/src/libslic3r/Print.cpp
+++ b/xs/src/libslic3r/Print.cpp
@@ -301,6 +301,7 @@ Print::extruders() const
FOREACH_REGION(this, region) {
extruders.insert((*region)->config.perimeter_extruder - 1);
extruders.insert((*region)->config.infill_extruder - 1);
+ extruders.insert((*region)->config.solid_infill_extruder - 1);
}
FOREACH_OBJECT(this, object) {
extruders.insert((*object)->config.support_material_extruder - 1);
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index 8e9720b76..649c941e9 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -694,6 +694,13 @@ PrintConfigDef::build_def() {
Options["solid_infill_below_area"].cli = "solid-infill-below-area=f";
Options["solid_infill_below_area"].min = 0;
+ Options["solid_infill_extruder"].type = coInt;
+ Options["solid_infill_extruder"].label = "Solid infill extruder";
+ Options["solid_infill_extruder"].category = "Extruders";
+ Options["solid_infill_extruder"].tooltip = "The extruder to use when printing solid infill.";
+ Options["solid_infill_extruder"].cli = "solid-infill-extruder=i";
+ Options["solid_infill_extruder"].min = 1;
+
Options["solid_infill_every_layers"].type = coInt;
Options["solid_infill_every_layers"].label = "Solid infill every";
Options["solid_infill_every_layers"].category = "Infill";
diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp
index 447948a26..48235c7d1 100644
--- a/xs/src/libslic3r/PrintConfig.hpp
+++ b/xs/src/libslic3r/PrintConfig.hpp
@@ -93,6 +93,10 @@ class DynamicPrintConfig : public DynamicConfig
this->option("support_material_interface_extruder", true)->setInt(extruder);
}
}
+
+ if (!this->has("solid_infill_extruder") && this->has("infill_extruder"))
+ this->option("solid_infill_extruder", true)->setInt(this->option("infill_extruder")->getInt());
+
if (this->has("spiral_vase") && this->opt<ConfigOptionBool>("spiral_vase", true)->value) {
{
// this should be actually done only on the spiral layers instead of all
@@ -225,6 +229,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig
ConfigOptionInt perimeters;
ConfigOptionFloatOrPercent small_perimeter_speed;
ConfigOptionFloat solid_infill_below_area;
+ ConfigOptionInt solid_infill_extruder;
ConfigOptionFloatOrPercent solid_infill_extrusion_width;
ConfigOptionInt solid_infill_every_layers;
ConfigOptionFloatOrPercent solid_infill_speed;
@@ -259,6 +264,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig
this->perimeter_extrusion_width.percent = false;
this->perimeter_speed.value = 30;
this->perimeters.value = 3;
+ this->solid_infill_extruder.value = 1;
this->small_perimeter_speed.value = 30;
this->small_perimeter_speed.percent = false;
this->solid_infill_below_area.value = 70;
@@ -299,6 +305,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig
if (opt_key == "perimeters") return &this->perimeters;
if (opt_key == "small_perimeter_speed") return &this->small_perimeter_speed;
if (opt_key == "solid_infill_below_area") return &this->solid_infill_below_area;
+ if (opt_key == "solid_infill_extruder") return &this->solid_infill_extruder;
if (opt_key == "solid_infill_extrusion_width") return &this->solid_infill_extrusion_width;
if (opt_key == "solid_infill_every_layers") return &this->solid_infill_every_layers;
if (opt_key == "solid_infill_speed") return &this->solid_infill_speed;
diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp
index 0da9d589b..da7e25a48 100644
--- a/xs/src/libslic3r/PrintObject.cpp
+++ b/xs/src/libslic3r/PrintObject.cpp
@@ -255,6 +255,7 @@ PrintObject::invalidate_state_by_config_options(const std::vector<t_config_optio
|| *opt_key == "top_solid_layers"
|| *opt_key == "solid_infill_below_area"
|| *opt_key == "infill_extruder"
+ || *opt_key == "solid_infill_extruder"
|| *opt_key == "infill_extrusion_width") {
steps.insert(posPrepareInfill);
} else if (*opt_key == "external_fill_pattern"
diff --git a/xs/src/libslic3r/PrintRegion.cpp b/xs/src/libslic3r/PrintRegion.cpp
index 4a84de15a..e5b9092e4 100644
--- a/xs/src/libslic3r/PrintRegion.cpp
+++ b/xs/src/libslic3r/PrintRegion.cpp
@@ -53,8 +53,10 @@ PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool first_la
size_t extruder; // 1-based
if (role == frPerimeter || role == frExternalPerimeter) {
extruder = this->config.perimeter_extruder;
- } else if (role == frInfill || role == frSolidInfill || role == frTopSolidInfill) {
+ } else if (role == frInfill) {
extruder = this->config.infill_extruder;
+ } else if (role == frSolidInfill || role == frTopSolidInfill) {
+ extruder = this->config.solid_infill_extruder;
} else {
CONFESS("Unknown role $role");
}
diff --git a/xs/t/12_extrusionpathcollection.t b/xs/t/12_extrusionpathcollection.t
index 6933f965a..7349ca941 100644
--- a/xs/t/12_extrusionpathcollection.t
+++ b/xs/t/12_extrusionpathcollection.t
@@ -26,7 +26,10 @@ my $loop = Slic3r::ExtrusionLoop->new_from_paths(
),
);
-my $collection = Slic3r::ExtrusionPath::Collection->new($path);
+my $collection = Slic3r::ExtrusionPath::Collection->new(
+ Slic3r::ExtrusionPath::EXTR_ROLE_FILL,
+ $path,
+);
isa_ok $collection, 'Slic3r::ExtrusionPath::Collection', 'collection object with items in constructor';
ok !$collection->no_sort, 'no_sort is false by default';
@@ -55,6 +58,7 @@ is scalar(@{$collection->[1]}), 1, 'appended collection was duplicated';
{
my $collection = Slic3r::ExtrusionPath::Collection->new(
+ Slic3r::ExtrusionPath::EXTR_ROLE_FILL,
map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1),
Slic3r::Polyline->new([0,15], [0,18], [0,20]),
Slic3r::Polyline->new([0,10], [0,8], [0,5]),
@@ -71,6 +75,7 @@ is scalar(@{$collection->[1]}), 1, 'appended collection was duplicated';
{
my $collection = Slic3r::ExtrusionPath::Collection->new(
+ Slic3r::ExtrusionPath::EXTR_ROLE_FILL,
map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1),
Slic3r::Polyline->new([15,0], [10,0], [4,0]),
Slic3r::Polyline->new([10,5], [15,5], [20,5]),
diff --git a/xs/t/15_config.t b/xs/t/15_config.t
index cd4dc2654..e051d9a86 100644
--- a/xs/t/15_config.t
+++ b/xs/t/15_config.t
@@ -4,7 +4,7 @@ use strict;
use warnings;
use Slic3r::XS;
-use Test::More tests => 107;
+use Test::More tests => 108;
foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
$config->set('layer_height', 0.3);
@@ -184,6 +184,13 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
{
my $config = Slic3r::Config->new;
+ $config->set('infill_extruder', 2);
+ $config->normalize;
+ is $config->get('solid_infill_extruder'), 2, 'undefined solid infill extruder is populated with infill extruder';
+}
+
+{
+ my $config = Slic3r::Config->new;
$config->set('spiral_vase', 1);
$config->set('retract_layer_change', [1,0]);
$config->normalize;
diff --git a/xs/xsp/ExtrusionEntityCollection.xsp b/xs/xsp/ExtrusionEntityCollection.xsp
index fa1d26eed..290bcea50 100644
--- a/xs/xsp/ExtrusionEntityCollection.xsp
+++ b/xs/xsp/ExtrusionEntityCollection.xsp
@@ -6,7 +6,7 @@
%}
%name{Slic3r::ExtrusionPath::Collection} class ExtrusionEntityCollection {
- %name{_new} ExtrusionEntityCollection();
+ %name{_new} ExtrusionEntityCollection(ExtrusionRole role);
void reverse();
void clear()
%code{% THIS->entities.clear(); %};
diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp
index d3a48ac24..4fbaea2d6 100644
--- a/xs/xsp/ExtrusionPath.xsp
+++ b/xs/xsp/ExtrusionPath.xsp
@@ -23,7 +23,8 @@
void simplify(double tolerance);
double length();
bool is_perimeter();
- bool is_fill();
+ bool is_infill();
+ bool is_solid_infill();
bool is_bridge();
std::string gcode(Extruder* extruder, double e, double F,
double xofs, double yofs, std::string extrusion_axis,