Merge branch 'master' into avoid-crossing-perimeters
Conflicts: lib/Slic3r/GCode.pm lib/Slic3r/Print.pm
This commit is contained in:
commit
61b164b539
21 changed files with 123 additions and 65 deletions
3
Build.PL
3
Build.PL
|
@ -8,10 +8,11 @@ my $build = Module::Build->new(
|
|||
license => 'perl',
|
||||
requires => {
|
||||
'Boost::Geometry::Utils' => '0',
|
||||
'Encode::Locale' => '0',
|
||||
'File::Basename' => '0',
|
||||
'File::Spec' => '0',
|
||||
'Getopt::Long' => '0',
|
||||
'Math::Clipper' => '1.15',
|
||||
'Math::Clipper' => '1.17',
|
||||
'Math::ConvexHull::MonotoneChain' => '0.01',
|
||||
'Math::Geometry::Voronoi' => '1.3',
|
||||
'Math::PlanePath' => '53',
|
||||
|
|
|
@ -108,7 +108,7 @@ The author of the Silk icon set is Mark James.
|
|||
(default: 100,100)
|
||||
--z-offset Additional height in mm to add to vertical coordinates
|
||||
(+/-, default: 0)
|
||||
--gcode-flavor The type of G-code to generate (reprap/teacup/makerbot/mach3/no-extrusion,
|
||||
--gcode-flavor The type of G-code to generate (reprap/teacup/makerbot/sailfish/mach3/no-extrusion,
|
||||
default: reprap)
|
||||
--use-relative-e-distances Enable this to get relative E values
|
||||
--gcode-arcs Use G2/G3 commands for native arcs (experimental, not supported
|
||||
|
@ -275,7 +275,7 @@ The author of the Silk icon set is Mark James.
|
|||
(like 0.65) or a percentage over layer height (like 200%)
|
||||
--first-layer-extrusion-width
|
||||
Set a different extrusion width for first layer
|
||||
--perimeters-extrusion-width
|
||||
--perimeter-extrusion-width
|
||||
Set a different extrusion width for perimeters
|
||||
--infill-extrusion-width
|
||||
Set a different extrusion width for infill
|
||||
|
@ -286,7 +286,7 @@ The author of the Silk icon set is Mark James.
|
|||
Multiple extruder options:
|
||||
--extruder-offset Offset of each extruder, if firmware doesn't handle the displacement
|
||||
(can be specified multiple times, default: 0x0)
|
||||
--perimeters-extruder
|
||||
--perimeter-extruder
|
||||
Extruder to use for perimeters (1+, default: 1)
|
||||
--infill-extruder Extruder to use for infill (1+, default: 1)
|
||||
--support-material-extruder
|
||||
|
|
|
@ -7,7 +7,7 @@ use strict;
|
|||
use warnings;
|
||||
require v5.10;
|
||||
|
||||
our $VERSION = "0.9.8-dev";
|
||||
our $VERSION = "0.9.9-dev";
|
||||
|
||||
our $debug = 0;
|
||||
sub debugf {
|
||||
|
@ -27,7 +27,10 @@ warn "Running Slic3r under Perl >= 5.16 is not supported nor recommended\n"
|
|||
use FindBin;
|
||||
our $var = "$FindBin::Bin/var";
|
||||
|
||||
use Encode;
|
||||
use Encode::Locale;
|
||||
use Moo 0.091009;
|
||||
|
||||
use Slic3r::Config;
|
||||
use Slic3r::ExPolygon;
|
||||
use Slic3r::Extruder;
|
||||
|
@ -89,4 +92,9 @@ sub parallelize {
|
|||
}
|
||||
}
|
||||
|
||||
sub open {
|
||||
my ($fh, $mode, $filename) = @_;
|
||||
return CORE::open $$fh, $mode, encode('locale_fs', $filename);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -64,8 +64,8 @@ our $Options = {
|
|||
tooltip => 'Some G/M-code commands, including temperature control and others, are not universal. Set this option to your printer\'s firmware to get a compatible output. The "No extrusion" flavor prevents Slic3r from exporting any extrusion value at all.',
|
||||
cli => 'gcode-flavor=s',
|
||||
type => 'select',
|
||||
values => [qw(reprap teacup makerbot mach3 no-extrusion)],
|
||||
labels => ['RepRap (Marlin/Sprinter)', 'Teacup', 'MakerBot', 'Mach3/EMC', 'No extrusion'],
|
||||
values => [qw(reprap teacup makerbot sailfish mach3 no-extrusion)],
|
||||
labels => ['RepRap (Marlin/Sprinter)', 'Teacup', 'MakerBot', 'Sailfish', 'Mach3/EMC', 'No extrusion'],
|
||||
default => 'reprap',
|
||||
},
|
||||
'use_relative_e_distances' => {
|
||||
|
@ -158,7 +158,7 @@ our $Options = {
|
|||
sidetext => '°C',
|
||||
cli => 'temperature=i@',
|
||||
type => 'i',
|
||||
max => 300,
|
||||
max => 400,
|
||||
serialize => $serialize_comma,
|
||||
deserialize => sub { $_[0] ? [ split /,/, $_[0] ] : [0] },
|
||||
default => [200],
|
||||
|
@ -171,7 +171,7 @@ our $Options = {
|
|||
type => 'i',
|
||||
serialize => $serialize_comma,
|
||||
deserialize => sub { $_[0] ? [ split /,/, $_[0] ] : [0] },
|
||||
max => 300,
|
||||
max => 400,
|
||||
default => [200],
|
||||
},
|
||||
|
||||
|
@ -703,7 +703,7 @@ END
|
|||
type => 'f',
|
||||
serialize => $serialize_comma,
|
||||
deserialize => $deserialize_comma,
|
||||
default => [3],
|
||||
default => [10],
|
||||
},
|
||||
'retract_restart_extra_toolchange' => {
|
||||
label => 'Extra length on restart',
|
||||
|
@ -722,7 +722,7 @@ END
|
|||
tooltip => 'This flag enables all the cooling features.',
|
||||
cli => 'cooling!',
|
||||
type => 'bool',
|
||||
default => 0,
|
||||
default => 1,
|
||||
},
|
||||
'min_fan_speed' => {
|
||||
label => 'Min',
|
||||
|
@ -953,7 +953,7 @@ sub new_from_cli {
|
|||
if ($args{$opt_key}) {
|
||||
die "Invalid value for --${_}-gcode: file does not exist\n"
|
||||
if !-e $args{$opt_key};
|
||||
open my $fh, "<", $args{$opt_key}
|
||||
Slic3r::open(\my $fh, "<", $args{$opt_key})
|
||||
or die "Failed to open $args{$opt_key}\n";
|
||||
binmode $fh, ':utf8';
|
||||
$args{$opt_key} = do { local $/; <$fh> };
|
||||
|
@ -1031,6 +1031,17 @@ sub set {
|
|||
$value = 1;
|
||||
}
|
||||
|
||||
# For historical reasons, the world's full of configs having these very low values;
|
||||
# to avoid unexpected behavior we need to ignore them. Banning these two hard-coded
|
||||
# values is a dirty hack and will need to be removed sometime in the future, but it
|
||||
# will avoid lots of complaints for now.
|
||||
if ($opt_key eq 'perimeter_acceleration' && $value == '25') {
|
||||
$value = 0;
|
||||
}
|
||||
if ($opt_key eq 'infill_acceleration' && $value == '50') {
|
||||
$value = 0;
|
||||
}
|
||||
|
||||
if (!exists $Options->{$opt_key}) {
|
||||
my @keys = grep { $Options->{$_}{aliases} && grep $_ eq $opt_key, @{$Options->{$_}{aliases}} } keys %$Options;
|
||||
if (!@keys) {
|
||||
|
@ -1258,7 +1269,7 @@ sub write_ini {
|
|||
my $class = shift;
|
||||
my ($file, $ini) = @_;
|
||||
|
||||
open my $fh, '>', $file;
|
||||
Slic3r::open(\my $fh, '>', $file);
|
||||
binmode $fh, ':utf8';
|
||||
my $localtime = localtime;
|
||||
printf $fh "# generated by Slic3r $Slic3r::VERSION on %s\n", "$localtime";
|
||||
|
@ -1276,7 +1287,7 @@ sub read_ini {
|
|||
my ($file) = @_;
|
||||
|
||||
local $/ = "\n";
|
||||
open my $fh, '<', $file;
|
||||
Slic3r::open(\my $fh, '<', $file);
|
||||
binmode $fh, ':utf8';
|
||||
|
||||
my $ini = { _ => {} };
|
||||
|
|
|
@ -13,7 +13,7 @@ sub read_file {
|
|||
1;
|
||||
} or die "AMF parsing requires XML::SAX\n";
|
||||
|
||||
open my $fh, '<', $file or die "Failed to open $file\n";
|
||||
Slic3r::open(\my $fh, '<', $file) or die "Failed to open $file\n";
|
||||
|
||||
my $model = Slic3r::Model->new;
|
||||
XML::SAX::ParserFactory
|
||||
|
@ -30,7 +30,7 @@ sub write_file {
|
|||
|
||||
my %vertices_offset = ();
|
||||
|
||||
open my $fh, '>', $file;
|
||||
Slic3r::open(\my $fh, '>', $file);
|
||||
binmode $fh, ':utf8';
|
||||
printf $fh qq{<?xml version="1.0" encoding="UTF-8"?>\n};
|
||||
printf $fh qq{<amf unit="millimeter">\n};
|
||||
|
|
|
@ -5,7 +5,7 @@ sub read_file {
|
|||
my $self = shift;
|
||||
my ($file) = @_;
|
||||
|
||||
open my $fh, '<', $file or die "Failed to open $file\n";
|
||||
Slic3r::open(\my $fh, '<', $file) or die "Failed to open $file\n";
|
||||
my $vertices = [];
|
||||
my $facets = [];
|
||||
while (my $_ = <$fh>) {
|
||||
|
|
|
@ -7,7 +7,7 @@ sub read_file {
|
|||
my $self = shift;
|
||||
my ($file) = @_;
|
||||
|
||||
open my $fh, '<', $file or die "Failed to open $file\n";
|
||||
Slic3r::open(\my $fh, '<', $file) or die "Failed to open $file\n";
|
||||
|
||||
# let's detect whether file is ASCII or binary
|
||||
my $mode;
|
||||
|
@ -103,7 +103,7 @@ sub write_file {
|
|||
my $self = shift;
|
||||
my ($file, $model, %params) = @_;
|
||||
|
||||
open my $fh, '>', $file;
|
||||
Slic3r::open(\my $fh, '>', $file);
|
||||
|
||||
$params{binary}
|
||||
? _write_binary($fh, $model->mesh)
|
||||
|
|
|
@ -7,6 +7,7 @@ use Slic3r::Geometry qw(scale unscale scaled_epsilon points_coincide PI X Y B);
|
|||
use Slic3r::Geometry::Clipper qw(union_ex);
|
||||
|
||||
has 'multiple_extruders' => (is => 'ro', default => sub {0} );
|
||||
has 'layer_count' => (is => 'ro', required => 1 );
|
||||
has 'layer' => (is => 'rw');
|
||||
has 'move_z_callback' => (is => 'rw');
|
||||
has 'shift_x' => (is => 'rw', default => sub {0} );
|
||||
|
@ -80,6 +81,14 @@ sub change_layer {
|
|||
islands => union_ex([ map @$_, @{$layer->slices} ], undef, 1),
|
||||
));
|
||||
}
|
||||
|
||||
my $gcode = "";
|
||||
if ($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
|
||||
$gcode .= sprintf "M73 P%s%s\n",
|
||||
int(100 * ($layer->id / ($self->layer_count - 1))),
|
||||
($Slic3r::Config->gcode_comments ? ' ; update progress' : '');
|
||||
}
|
||||
return $gcode;
|
||||
}
|
||||
|
||||
# this method accepts Z in scaled coordinates
|
||||
|
@ -502,8 +511,18 @@ sub set_extruder {
|
|||
|
||||
# set the new extruder
|
||||
$self->extruder($extruder);
|
||||
$gcode .= sprintf "T%d%s\n", $extruder->id, ($Slic3r::Config->gcode_comments ? ' ; change extruder' : '');
|
||||
$gcode .= $self->reset_e;
|
||||
my $toolchange_gcode = sprintf "%s%d%s\n",
|
||||
($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/ ? 'M108 T' : 'T'),
|
||||
$extruder->id,
|
||||
($Slic3r::Config->gcode_comments ? ' ; change extruder' : '');
|
||||
|
||||
if ($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
|
||||
$gcode .= $self->reset_e;
|
||||
$gcode .= $toolchange_gcode;
|
||||
} else {
|
||||
$gcode .= $toolchange_gcode;
|
||||
$gcode .= $self->reset_e;
|
||||
}
|
||||
|
||||
return $gcode;
|
||||
}
|
||||
|
@ -517,11 +536,17 @@ sub set_fan {
|
|||
if ($speed == 0) {
|
||||
my $code = $Slic3r::Config->gcode_flavor eq 'teacup'
|
||||
? 'M106 S0'
|
||||
: 'M107';
|
||||
: $Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/
|
||||
? 'M127'
|
||||
: 'M107';
|
||||
return sprintf "$code%s\n", ($Slic3r::Config->gcode_comments ? ' ; disable fan' : '');
|
||||
} else {
|
||||
return sprintf "M106 %s%d%s\n", ($Slic3r::Config->gcode_flavor eq 'mach3' ? 'P' : 'S'),
|
||||
(255 * $speed / 100), ($Slic3r::Config->gcode_comments ? ' ; enable fan' : '');
|
||||
if ($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/) {
|
||||
return sprintf "M126%s\n", ($Slic3r::Config->gcode_comments ? ' ; enable fan' : '');
|
||||
} else {
|
||||
return sprintf "M106 %s%d%s\n", ($Slic3r::Config->gcode_flavor eq 'mach3' ? 'P' : 'S'),
|
||||
(255 * $speed / 100), ($Slic3r::Config->gcode_comments ? ' ; enable fan' : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
|
@ -531,14 +556,14 @@ sub set_temperature {
|
|||
my $self = shift;
|
||||
my ($temperature, $wait, $tool) = @_;
|
||||
|
||||
return "" if $wait && $Slic3r::Config->gcode_flavor eq 'makerbot';
|
||||
return "" if $wait && $Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/;
|
||||
|
||||
my ($code, $comment) = ($wait && $Slic3r::Config->gcode_flavor ne 'teacup')
|
||||
? ('M109', 'wait for temperature to be reached')
|
||||
: ('M104', 'set temperature');
|
||||
my $gcode = sprintf "$code %s%d %s; $comment\n",
|
||||
($Slic3r::Config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature,
|
||||
(defined $tool && $self->multiple_extruders) ? "T$tool " : "";
|
||||
(defined $tool && ($self->multiple_extruders || $Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/)) ? "T$tool " : "";
|
||||
|
||||
$gcode .= "M116 ; wait for temperature to be reached\n"
|
||||
if $Slic3r::Config->gcode_flavor eq 'teacup' && $wait;
|
||||
|
@ -551,8 +576,7 @@ sub set_bed_temperature {
|
|||
my ($temperature, $wait) = @_;
|
||||
|
||||
my ($code, $comment) = ($wait && $Slic3r::Config->gcode_flavor ne 'teacup')
|
||||
? (($Slic3r::Config->gcode_flavor eq 'makerbot' ? 'M109'
|
||||
: 'M190'), 'wait for bed temperature to be reached')
|
||||
? (($Slic3r::Config->gcode_flavor =~ /^(?:makerbot|sailfish)$/ ? 'M109' : 'M190'), 'wait for bed temperature to be reached')
|
||||
: ('M140', 'set bed temperature');
|
||||
my $gcode = sprintf "$code %s%d ; $comment\n",
|
||||
($Slic3r::Config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature;
|
||||
|
|
|
@ -413,8 +413,9 @@ sub notify {
|
|||
my $notifier = $serv->get_object('/org/freedesktop/Notifications',
|
||||
'org.freedesktop.Notifications');
|
||||
$notifier->Notify('Slic3r', 0, $self->{icon}, $title, $message, [], {}, -1);
|
||||
}
|
||||
};
|
||||
undef $Net::DBus::bus_session;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -47,12 +47,12 @@ sub new {
|
|||
'<html>' .
|
||||
'<body bgcolor="#ffffff" link="#808080">' .
|
||||
'<font color="#808080">' .
|
||||
'Copyright © 2011-2012 Alessandro Ranellucci. All rights reserved. ' .
|
||||
'Copyright © 2011-2013 Alessandro Ranellucci. All rights reserved. ' .
|
||||
'<a href="http://slic3r.org/">Slic3r</a> is licensed under the ' .
|
||||
'<a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License, version 3</a>.' .
|
||||
'<br /><br /><br />' .
|
||||
'Slic3r logo designed by Corey Daniels, <a href="http://www.famfamfam.com/lab/icons/silk/">Silk Icon Set</a> designed by Mark James. ' .
|
||||
'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess and numerous others.' .
|
||||
'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Mike Sheldrake and numerous others.' .
|
||||
'</font>' .
|
||||
'</body>' .
|
||||
'</html>';
|
||||
|
|
|
@ -62,7 +62,7 @@ sub new {
|
|||
Wx::ToolTip::Enable(1);
|
||||
$self->{htoolbar} = Wx::ToolBar->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL | wxTB_TEXT | wxBORDER_SIMPLE | wxTAB_TRAVERSAL);
|
||||
$self->{htoolbar}->AddTool(TB_MORE, "More", Wx::Bitmap->new("$Slic3r::var/add.png", wxBITMAP_TYPE_PNG), '');
|
||||
$self->{htoolbar}->AddTool(TB_LESS, "Less", Wx::Bitmap->new("$Slic3r::var/delete.png", wxBITMAP_TYPE_PNG), '');
|
||||
$self->{htoolbar}->AddTool(TB_LESS, "Fewer", Wx::Bitmap->new("$Slic3r::var/delete.png", wxBITMAP_TYPE_PNG), '');
|
||||
$self->{htoolbar}->AddSeparator;
|
||||
$self->{htoolbar}->AddTool(TB_45CCW, "45° ccw", Wx::Bitmap->new("$Slic3r::var/arrow_rotate_anticlockwise.png", wxBITMAP_TYPE_PNG), '');
|
||||
$self->{htoolbar}->AddTool(TB_45CW, "45° cw", Wx::Bitmap->new("$Slic3r::var/arrow_rotate_clockwise.png", wxBITMAP_TYPE_PNG), '');
|
||||
|
|
|
@ -18,7 +18,7 @@ use constant FILE_WILDCARDS => {
|
|||
obj => 'OBJ files (*.obj)|*.obj;*.OBJ',
|
||||
amf => 'AMF files (*.amf)|*.amf;*.AMF;*.xml;*.XML',
|
||||
ini => 'INI files *.ini|*.ini;*.INI',
|
||||
gcode => 'G-code files *.gcode|*.gcode;*.GCODE|G-code files *.g|*.g;*.G',
|
||||
gcode => 'G-code files (*.gcode, *.gco, *.g)|*.gcode;*.GCODE;*.gco;*.GCO;*.g;*.G',
|
||||
svg => 'SVG files *.svg|*.svg;*.SVG',
|
||||
};
|
||||
use constant MODEL_WILDCARD => join '|', @{&FILE_WILDCARDS}{qw(stl obj amf)};
|
||||
|
|
|
@ -8,7 +8,7 @@ our @EXPORT_OK = qw(safety_offset offset offset_ex
|
|||
diff_ex diff union_ex intersection_ex xor_ex PFT_EVENODD JT_MITER JT_ROUND
|
||||
JT_SQUARE is_counter_clockwise);
|
||||
|
||||
use Math::Clipper 1.15 qw(:cliptypes :polyfilltypes :jointypes is_counter_clockwise area);
|
||||
use Math::Clipper 1.17 qw(:cliptypes :polyfilltypes :jointypes is_counter_clockwise area);
|
||||
use Slic3r::Geometry qw(scale);
|
||||
our $clipper = Math::Clipper->new;
|
||||
|
||||
|
@ -21,7 +21,7 @@ sub offset {
|
|||
my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_;
|
||||
$scale ||= 100000;
|
||||
$joinType //= JT_MITER;
|
||||
$miterLimit //= 10;
|
||||
$miterLimit //= 3;
|
||||
|
||||
my $offsets = Math::Clipper::offset($polygons, $distance, $scale, $joinType, $miterLimit);
|
||||
return @$offsets;
|
||||
|
|
|
@ -252,7 +252,7 @@ sub make_perimeters {
|
|||
}
|
||||
|
||||
# fill gaps
|
||||
if ($Slic3r::Config->gap_fill_speed > 0) {
|
||||
if ($Slic3r::Config->gap_fill_speed > 0 && $Slic3r::Config->fill_density > 0) {
|
||||
my $filler = Slic3r::Fill::Rectilinear->new(layer_id => $self->layer->id);
|
||||
|
||||
my $w = $self->perimeter_flow->width;
|
||||
|
|
|
@ -242,11 +242,7 @@ sub object_copies {
|
|||
|
||||
sub layer_count {
|
||||
my $self = shift;
|
||||
my $count = 0;
|
||||
foreach my $object (@{$self->objects}) {
|
||||
$count = @{$object->layers} if @{$object->layers} > $count;
|
||||
}
|
||||
return $count;
|
||||
return max(map { scalar @{$_->layers} } @{$self->objects});
|
||||
}
|
||||
|
||||
sub regions_count {
|
||||
|
@ -472,7 +468,7 @@ sub export_svg {
|
|||
my $output_file = $self->expanded_output_filepath($params{output_file});
|
||||
$output_file =~ s/\.gcode$/.svg/i;
|
||||
|
||||
open my $fh, ">", $output_file or die "Failed to open $output_file for writing\n";
|
||||
Slic3r::open(\my $fh, ">", $output_file) or die "Failed to open $output_file for writing\n";
|
||||
print "Exporting to $output_file...";
|
||||
my $print_size = $self->size;
|
||||
print $fh sprintf <<"EOF", unscale($print_size->[X]), unscale($print_size->[Y]);
|
||||
|
@ -550,10 +546,10 @@ sub make_skirt {
|
|||
return unless $Slic3r::Config->skirts > 0;
|
||||
|
||||
# collect points from all layers contained in skirt height
|
||||
my $skirt_height = $Slic3r::Config->skirt_height;
|
||||
$skirt_height = $self->layer_count if $skirt_height > $self->layer_count;
|
||||
my @points = ();
|
||||
foreach my $obj_idx (0 .. $#{$self->objects}) {
|
||||
my $skirt_height = $Slic3r::Config->skirt_height;
|
||||
$skirt_height = $self->objects->[$obj_idx]->layer_count if $skirt_height > $self->objects->[$obj_idx]->layer_count;
|
||||
my @layers = map $self->objects->[$obj_idx]->layers->[$_], 0..($skirt_height-1);
|
||||
my @layer_points = (
|
||||
(map @$_, map @$_, map @{$_->slices}, @layers),
|
||||
|
@ -647,7 +643,7 @@ sub write_gcode {
|
|||
if (ref $file eq 'IO::Scalar') {
|
||||
$fh = $file;
|
||||
} else {
|
||||
open $fh, ">", $file
|
||||
Slic3r::open(\$fh, ">", $file)
|
||||
or die "Failed to open $file for writing\n";
|
||||
}
|
||||
|
||||
|
@ -675,7 +671,8 @@ sub write_gcode {
|
|||
|
||||
# set up our extruder object
|
||||
my $gcodegen = Slic3r::GCode->new(
|
||||
multiple_extruders => (@{$self->extruders} > 1),
|
||||
multiple_extruders => (@{$self->extruders} > 1),
|
||||
layer_count => $self->layer_count,
|
||||
);
|
||||
my $min_print_speed = 60 * $Slic3r::Config->min_print_speed;
|
||||
my $dec = $gcodegen->dec;
|
||||
|
@ -700,7 +697,7 @@ sub write_gcode {
|
|||
print $fh "G21 ; set units to millimeters\n";
|
||||
if ($Slic3r::Config->gcode_flavor =~ /^(?:reprap|teacup)$/) {
|
||||
printf $fh $gcodegen->reset_e;
|
||||
if ($Slic3r::Config->gcode_flavor =~ /^(?:reprap|makerbot)$/) {
|
||||
if ($Slic3r::Config->gcode_flavor =~ /^(?:reprap|makerbot|sailfish)$/) {
|
||||
if ($Slic3r::Config->use_relative_e_distances) {
|
||||
print $fh "M83 ; use relative distances for extrusion\n";
|
||||
} else {
|
||||
|
@ -753,7 +750,7 @@ sub write_gcode {
|
|||
}
|
||||
|
||||
# set new layer, but don't move Z as support material interfaces may need an intermediate one
|
||||
$gcodegen->change_layer($self->objects->[$object_copies->[0][0]]->layers->[$layer_id]);
|
||||
$gcode .= $gcodegen->change_layer($self->objects->[$object_copies->[0][0]]->layers->[$layer_id]);
|
||||
$gcodegen->elapsed_time(0);
|
||||
|
||||
# prepare callback to call as soon as a Z command is generated
|
||||
|
|
|
@ -445,8 +445,8 @@ sub combine_infill {
|
|||
my $area_threshold = $Slic3r::flow->scaled_spacing ** 2;
|
||||
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
# start from bottom, skip first layer
|
||||
for (my $i = 1; $i < $self->layer_count; $i++) {
|
||||
# start from top, skip lowest layer
|
||||
for (my $i = $self->layer_count - 1; $i > 0; $i--) {
|
||||
my $layerm = $self->layers->[$i]->regions->[$region_id];
|
||||
|
||||
# skip layer if no internal fill surfaces
|
||||
|
@ -506,6 +506,13 @@ sub combine_infill {
|
|||
{
|
||||
my @new_surfaces = ();
|
||||
push @new_surfaces, grep $_->surface_type != S_TYPE_INTERNAL, @{$lower_layerm->fill_surfaces};
|
||||
|
||||
# offset for the two different flow spacings
|
||||
$intersection = [ map $_->offset_ex(
|
||||
$lower_layerm->infill_flow->scaled_spacing / 2
|
||||
+ $layerm->infill_flow->scaled_spacing / 2
|
||||
), @$intersection];
|
||||
|
||||
foreach my $depth (1..$Slic3r::Config->infill_every_layers) {
|
||||
push @new_surfaces, map Slic3r::Surface->new
|
||||
(expolygon => $_, surface_type => S_TYPE_INTERNAL, depth_layers => $depth),
|
||||
|
@ -554,9 +561,14 @@ sub generate_support_material {
|
|||
my $layer = $self->layers->[$i];
|
||||
my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef;
|
||||
|
||||
my @current_layer_offsetted_slices = map $_->offset_ex($distance_from_object), @{$layer->slices};
|
||||
|
||||
# $queue[-1] contains the overhangs of the upper layer, regardless of any empty interface layers
|
||||
# $queue[0] contains the overhangs of the first upper layer above the empty interface layers
|
||||
$layers_interfaces{$i} = [@{ $queue[-1] || [] }];
|
||||
$layers_interfaces{$i} = diff_ex(
|
||||
[ map @$_, @{ $queue[-1] || [] } ],
|
||||
[ map @$_, @current_layer_offsetted_slices ],
|
||||
);
|
||||
|
||||
# step 1: generate support material in current layer (for upper layers)
|
||||
push @current_support_regions, @{ shift @queue } if @queue && $i < $#{$self->layers};
|
||||
|
@ -569,11 +581,11 @@ sub generate_support_material {
|
|||
$layers{$i} = diff_ex(
|
||||
[ map @$_, @current_support_regions ],
|
||||
[
|
||||
(map @$_, map $_->offset_ex($distance_from_object), @{$layer->slices}),
|
||||
(map @$_, @current_layer_offsetted_slices),
|
||||
(map @$_, @{ $layers_interfaces{$i} }),
|
||||
],
|
||||
);
|
||||
$_->simplify($flow->scaled_spacing * 2) for @{$layers{$i}};
|
||||
$_->simplify($flow->scaled_spacing) for @{$layers{$i}};
|
||||
|
||||
# step 2: get layer overhangs and put them into queue for adding support inside lower layers
|
||||
# we need an angle threshold for this
|
||||
|
@ -667,6 +679,7 @@ sub generate_support_material {
|
|||
items => [ keys %layers ],
|
||||
thread_cb => sub {
|
||||
my $q = shift;
|
||||
$Slic3r::Geometry::Clipper::clipper = Math::Clipper->new;
|
||||
my $result = {};
|
||||
while (defined (my $layer_id = $q->dequeue)) {
|
||||
$result->{$layer_id} = [ $process_layer->($layer_id) ];
|
||||
|
|
|
@ -130,7 +130,7 @@ sub output_lines {
|
|||
sub write_svg {
|
||||
my ($svg, $filename) = @_;
|
||||
|
||||
open my $fh, '>', $filename;
|
||||
Slic3r::open(\my $fh, '>', $filename);
|
||||
print $fh $svg->xmlify;
|
||||
close $fh;
|
||||
printf "SVG written to %s\n", $filename;
|
||||
|
|
|
@ -152,9 +152,9 @@ sub check_manifoldness {
|
|||
my ($first_bad_edge_id) =
|
||||
grep { @{ $self->edges_facets->[$_] } != 2 } 0..$#{$self->edges_facets};
|
||||
if (defined $first_bad_edge_id) {
|
||||
warn sprintf "Warning: The input file contains a hole near edge %f-%f (not manifold). "
|
||||
warn sprintf "Warning: The input file contains a hole near edge %f,%f,%f-%f,%f,%f (not manifold). "
|
||||
. "You might want to repair it and retry, or to check the resulting G-code before printing anyway.\n",
|
||||
@{$self->edges->[$first_bad_edge_id]};
|
||||
map @{$self->vertices->[$_]}, @{$self->edges->[$first_bad_edge_id]};
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -156,7 +156,7 @@ $j
|
|||
(default: $config->{print_center}->[0],$config->{print_center}->[1])
|
||||
--z-offset Additional height in mm to add to vertical coordinates
|
||||
(+/-, default: $config->{z_offset})
|
||||
--gcode-flavor The type of G-code to generate (reprap/teacup/makerbot/mach3/no-extrusion,
|
||||
--gcode-flavor The type of G-code to generate (reprap/teacup/makerbot/sailfish/mach3/no-extrusion,
|
||||
default: $config->{gcode_flavor})
|
||||
--use-relative-e-distances Enable this to get relative E values
|
||||
--gcode-arcs Use G2/G3 commands for native arcs (experimental, not supported
|
||||
|
@ -323,7 +323,7 @@ $j
|
|||
(like 0.65) or a percentage over layer height (like 200%)
|
||||
--first-layer-extrusion-width
|
||||
Set a different extrusion width for first layer
|
||||
--perimeters-extrusion-width
|
||||
--perimeter-extrusion-width
|
||||
Set a different extrusion width for perimeters
|
||||
--infill-extrusion-width
|
||||
Set a different extrusion width for infill
|
||||
|
@ -334,7 +334,7 @@ $j
|
|||
Multiple extruder options:
|
||||
--extruder-offset Offset of each extruder, if firmware doesn't handle the displacement
|
||||
(can be specified multiple times, default: 0x0)
|
||||
--perimeters-extruder
|
||||
--perimeter-extruder
|
||||
Extruder to use for perimeters (1+, default: 1)
|
||||
--infill-extruder Extruder to use for infill (1+, default: 1)
|
||||
--support-material-extruder
|
||||
|
|
|
@ -21,6 +21,7 @@ my $test = sub {
|
|||
my $tool = 0;
|
||||
my @toolchange_count = (); # track first usages so that we don't expect retract_length_toolchange when extruders are used for the first time
|
||||
my @retracted = (1); # ignore the first travel move from home to first point
|
||||
my @retracted_length = (0);
|
||||
my $lifted = 0;
|
||||
my $changed_tool = 0;
|
||||
my $wait_for_toolchange = 0;
|
||||
|
@ -52,21 +53,22 @@ my $test = sub {
|
|||
}
|
||||
}
|
||||
if ($info->{retracting}) {
|
||||
if (_eq(-$info->{dist_E}, $print->extruders->[$tool]->retract_length)) {
|
||||
$retracted[$tool] = 1;
|
||||
$retracted_length[$tool] += -$info->{dist_E};
|
||||
if (_eq($retracted_length[$tool], $print->extruders->[$tool]->retract_length)) {
|
||||
# okay
|
||||
} elsif (_eq(-$info->{dist_E}, $print->extruders->[$tool]->retract_length_toolchange)) {
|
||||
} elsif (_eq($retracted_length[$tool], $print->extruders->[$tool]->retract_length_toolchange)) {
|
||||
$wait_for_toolchange = 1;
|
||||
} else {
|
||||
fail 'retracted by the correct amount';
|
||||
}
|
||||
fail 'combining retraction and travel with G0'
|
||||
if $cmd ne 'G0' && $conf->g0 && ($info->{dist_Z} || $info->{dist_XY});
|
||||
$retracted[$tool] = 1;
|
||||
}
|
||||
if ($info->{extruding}) {
|
||||
fail 'only extruding while not lifted' if $lifted;
|
||||
if ($retracted[$tool]) {
|
||||
my $expected_amount = $print->extruders->[$tool]->retract_length + $print->extruders->[$tool]->retract_restart_extra;
|
||||
my $expected_amount = $retracted_length[$tool] + $print->extruders->[$tool]->retract_restart_extra;
|
||||
if ($changed_tool && $toolchange_count[$tool] > 1) {
|
||||
$expected_amount = $print->extruders->[$tool]->retract_length_toolchange + $print->extruders->[$tool]->retract_restart_extra_toolchange;
|
||||
$changed_tool = 0;
|
||||
|
@ -74,6 +76,7 @@ my $test = sub {
|
|||
fail 'unretracted by the correct amount'
|
||||
if !_eq($info->{dist_E}, $expected_amount);
|
||||
$retracted[$tool] = 0;
|
||||
$retracted_length[$tool] = 0;
|
||||
}
|
||||
}
|
||||
if ($info->{travel} && $info->{dist_XY} >= $print->extruders->[$tool]->retract_before_travel) {
|
||||
|
|
|
@ -22,7 +22,7 @@ _arguments -S \
|
|||
'*--nozzle-diameter[specify nozzle diameter]:nozzle diameter in mm' \
|
||||
'--print-center[specify print center coordinates]:print center coordinates in mm,mm' \
|
||||
'--z-offset[specify Z-axis offset]:Z-axis offset in mm' \
|
||||
'--gcode-flavor[specify the type of G-code to generate]:G-code flavor:(reprap teacup makerbot mach3 no-extrusion)' \
|
||||
'--gcode-flavor[specify the type of G-code to generate]:G-code flavor:(reprap teacup makerbot sailfish mach3 no-extrusion)' \
|
||||
'(--use-relative-e-distances --no-use-relative-e-distances)'--{no-,}use-relative-e-distances'[disable/enable relative E values]' \
|
||||
'--extrusion-axis[specify letter associated with the extrusion axis]:extrusion axis letter' \
|
||||
'(--gcode-arcs --no-gcode-arcs)'--{no-,}gcode-arcs'[disable/enable G2/G3 commands for native arcs]' \
|
||||
|
|
Loading…
Reference in a new issue