mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-11-01 05:01:10 -06:00
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:
parent
d9cffeca4a
commit
e79aa2e81c
25 changed files with 186 additions and 95 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(); %};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue