New --solid-infill-extruder option. Includes a refactoring of the strategy used to order layer extrusions according to their extruder and island; toolchanges and travel moves should be more optimized now. #618

This commit is contained in:
Alessandro Ranellucci 2014-12-17 00:34:00 +01:00
parent d9cffeca4a
commit e79aa2e81c
25 changed files with 186 additions and 95 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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,

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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";

View file

@ -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;

View file

@ -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"

View file

@ -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");
}

View file

@ -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]),

View file

@ -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);
@ -182,6 +182,13 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
is $config->get('perimeter_extruder'), 3, 'defined extruder is not overwritten by default extruder';
}
{
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);

View file

@ -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(); %};

View file

@ -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,