Merge branch 'master' into wipe

This commit is contained in:
Alessandro Ranellucci 2013-03-26 16:28:01 +01:00
commit d2b451d9a1
13 changed files with 110 additions and 76 deletions

View file

@ -85,15 +85,7 @@ sub offset_ex {
sub safety_offset {
my $self = shift;
# we're offsetting contour and holes separately
# because Clipper doesn't return polygons in the same order as
# we feed them to it
return (ref $self)->new(
$self->contour->safety_offset,
@{ Slic3r::Geometry::Clipper::safety_offset([$self->holes]) },
);
return Slic3r::Geometry::Clipper::safety_offset_ex($self, @_);
}
sub noncollapsing_offset_ex {

View file

@ -13,7 +13,7 @@ has '_crossing_edges' => (is => 'rw', default => sub { {} }); # edge_idx => boo
use List::Util qw(first);
use Slic3r::Geometry qw(A B scale epsilon nearest_point);
use Slic3r::Geometry::Clipper qw(diff_ex JT_MITER);
use Slic3r::Geometry::Clipper qw(diff_ex offset JT_MITER);
# clearance (in mm) from the perimeters
has '_inner_margin' => (is => 'ro', default => sub { scale 0.5 });
@ -68,7 +68,8 @@ sub BUILD {
: [ $self->islands->[$i]->offset_ex(-$self->_inner_margin) ];
# offset the island outwards to make the boundaries for external movements
$self->_outer->[$i] = [ $self->islands->[$i]->contour->offset($self->_outer_margin) ];
$self->_outer->[$i] = [ offset([ $self->islands->[$i]->contour], $self->_outer_margin) ];
bless $_, 'Slic3r::Polygon' for @{ $self->_outer->[$i] };
# if internal motion is enabled, build a set of utility expolygons representing
# the outer boundaries (as contours) and the inner boundaries (as holes). whenever
@ -168,11 +169,17 @@ sub BUILD {
lines => \@lines,
points => [ values %{$self->_pointmap} ],
no_arrows => 1,
polygons => [ map @$_, @{$self->islands} ],
expolygons => $self->islands,
#red_polygons => [ map $_->holes, map @$_, @{$self->_inner} ],
#white_polygons => [ map @$_, @{$self->_outer} ],
);
printf "%d islands\n", scalar @{$self->islands};
eval "use Devel::Size";
print "MEMORY USAGE:\n";
printf " %-19s = %.1fMb\n", $_, Devel::Size::total_size($self->$_)/1024/1024
for qw(_inner _outer _contours_ex _pointmap _edges _crossing_edges islands last_crossings);
printf " %-19s = %.1fMb\n", 'self', Devel::Size::total_size($self)/1024/1024;
}
}

View file

@ -7,7 +7,7 @@ use File::Basename qw(basename dirname);
use List::Util qw(max sum first);
use Math::ConvexHull::MonotoneChain qw(convex_hull);
use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN MAX);
use Slic3r::Geometry::Clipper qw(JT_ROUND);
use Slic3r::Geometry::Clipper qw(offset JT_ROUND);
use threads::shared qw(shared_clone);
use Wx qw(:bitmap :brush :button :cursor :dialog :filedialog :font :keycode :icon :id :listctrl :misc :panel :pen :sizer :toolbar :window);
use Wx::Event qw(EVT_BUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_ACTIVATED EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL EVT_CHOICE);
@ -881,7 +881,7 @@ sub repaint {
# if sequential printing is enabled and we have more than one object
if ($parent->{config}->complete_objects && (map @{$_->instances}, @{$parent->{objects}}) > 1) {
my $convex_hull = Slic3r::Polygon->new(convex_hull([ map @{$_->contour}, @{$parent->{object_previews}->[-1][2]->expolygons} ]));
my $clearance = +($convex_hull->offset($parent->{config}->extruder_clearance_radius / 2 * $parent->{scaling_factor}, 1, JT_ROUND))[0];
my ($clearance) = offset([$convex_hull], $parent->{config}->extruder_clearance_radius / 2 * $parent->{scaling_factor}, 1, JT_ROUND);
$dc->SetPen($parent->{clearance_pen});
$dc->SetBrush($parent->{transparent_brush});
$dc->DrawPolygon($parent->_y($clearance), 0, 0);
@ -892,7 +892,7 @@ sub repaint {
# draw skirt
if (@{$parent->{object_previews}} && $parent->{config}->skirts) {
my $convex_hull = Slic3r::Polygon->new(convex_hull([ map @{$_->contour}, map @{$_->[2]->expolygons}, @{$parent->{object_previews}} ]));
$convex_hull = +($convex_hull->offset($parent->{config}->skirt_distance * $parent->{scaling_factor}, 1, JT_ROUND))[0];
($convex_hull) = offset([$convex_hull], $parent->{config}->skirt_distance * $parent->{scaling_factor}, 1, JT_ROUND);
$dc->SetPen($parent->{skirt_pen});
$dc->SetBrush($parent->{transparent_brush});
$dc->DrawPolygon($parent->_y($convex_hull), 0, 0) if $convex_hull;
@ -1052,8 +1052,8 @@ sub OnDropFiles {
# https://rt.perl.org/rt3/Public/Bug/Display.html?id=70602
@_ = ();
# only accept STL and AMF files
return 0 if grep !/\.(?:stl|amf(?:\.xml)?)$/i, @$filenames;
# only accept STL, OBJ and AMF files
return 0 if grep !/\.(?:stl|obj|amf(?:\.xml)?)$/i, @$filenames;
$self->{window}->load_file($_) for @$filenames;
}

View file

@ -98,7 +98,7 @@ sub new {
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
{
my $label = Wx::StaticText->new($self, -1, "You can use this section to override the default layer height for parts of this object.",
my $label = Wx::StaticText->new($self, -1, "You can use this section to override the default layer height for parts of this object. Set layer height to zero to skip portions of the input file.",
wxDefaultPosition, [-1, 25]);
$label->SetFont(Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
$sizer->Add($label, 0, wxEXPAND | wxALL, 10);
@ -162,7 +162,7 @@ sub CanClose {
Slic3r::GUI::show_error($self, "Invalid Z range $min-$max.");
return 0;
}
if ($height <= 0) {
if ($height < 0) {
Slic3r::GUI::show_error($self, "Invalid layer height $height.");
return 0;
}

View file

@ -172,11 +172,6 @@ sub build {
},
],
);
$self->append_optgroup(
title => 'Cooling',
options => [qw(cooling)],
);
}
package Slic3r::GUI::SimpleTab::Printer;

View file

@ -14,6 +14,7 @@ our $last_output_file;
our $last_config;
use constant FILE_WILDCARDS => {
known => 'Known files (*.stl, *.obj, *.amf, *.xml)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML',
stl => 'STL files (*.stl)|*.stl;*.STL',
obj => 'OBJ files (*.obj)|*.obj;*.OBJ',
amf => 'AMF files (*.amf)|*.amf;*.AMF;*.xml;*.XML',
@ -21,7 +22,7 @@ use constant FILE_WILDCARDS => {
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)};
use constant MODEL_WILDCARD => join '|', @{&FILE_WILDCARDS}{qw(known stl obj amf)};
sub new {
my $class = shift;

View file

@ -4,7 +4,7 @@ use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(safety_offset offset offset_ex collapse_ex
our @EXPORT_OK = qw(safety_offset safety_offset_ex offset offset_ex collapse_ex
diff_ex diff union_ex intersection_ex xor_ex PFT_EVENODD JT_MITER JT_ROUND
JT_SQUARE is_counter_clockwise);
@ -17,6 +17,11 @@ sub safety_offset {
return Math::Clipper::offset($polygons, $factor // (scale 1e-05), 100000, JT_MITER, 2);
}
sub safety_offset_ex {
# offset polygons and then apply holes to the right contours
return @{ union_ex([ safety_offset(@_) ]) };
}
sub offset {
my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_;
$scale ||= 100000;

View file

@ -290,7 +290,7 @@ sub make_perimeters {
)};
my $w = $self->perimeter_flow->width;
my @widths = (1.5 * $w, $w, 0.5 * $w); # worth trying 0.2 too?
my @widths = (1.5 * $w, $w, 0.4 * $w); # worth trying 0.2 too?
foreach my $width (@widths) {
my $flow = $self->perimeter_flow->clone(width => $width);
@ -462,7 +462,7 @@ sub prepare_fill_surfaces {
}
# turn too small internal regions into solid regions according to the user setting
{
if ($Slic3r::Config->fill_density > 0) {
my $min_area = scale scale $Slic3r::Config->solid_infill_below_area; # scaling an area requires two calls!
my @small = grep $_->surface_type == S_TYPE_INTERNAL && $_->expolygon->contour->area <= $min_area, @{$self->fill_surfaces};
$_->surface_type(S_TYPE_INTERNALSOLID) for @small;

View file

@ -95,16 +95,6 @@ sub area {
return Slic3r::Geometry::Clipper::area($self);
}
sub safety_offset {
my $self = shift;
return (ref $self)->new(Slic3r::Geometry::Clipper::safety_offset([$self])->[0]);
}
sub offset {
my $self = shift;
return map Slic3r::Polygon->new($_), Slic3r::Geometry::Clipper::offset([$self], @_);
}
sub grow {
my $self = shift;
return $self->split_at_first_point->grow(@_);
@ -152,7 +142,7 @@ sub is_printable {
# detect them and we would be discarding them.
my $p = $self->clone;
$p->make_counter_clockwise;
return $p->offset(-$width / 2) ? 1 : 0;
return Slic3r::Geometry::Clipper::offset([$p], -$width / 2) ? 1 : 0;
}
sub is_valid {

View file

@ -86,7 +86,10 @@ sub length {
sub grow {
my $self = shift;
return Slic3r::Polygon->new(@$self, CORE::reverse @$self[1..($#$self-1)])->offset(@_);
return Slic3r::Geometry::Clipper::offset(
[ Slic3r::Polygon->new(@$self, CORE::reverse @$self[1..($#$self-1)]) ],
@_,
);
}
sub nearest_point_to {

View file

@ -151,7 +151,7 @@ sub validate {
{
my @points = map [ @$_[X,Y] ], map @{$_->vertices}, @{$self->objects->[$obj_idx]->meshes};
my $convex_hull = Slic3r::Polygon->new(convex_hull(\@points));
$clearance = +($convex_hull->offset(scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND))[0];
($clearance) = offset([$convex_hull], scale $Slic3r::Config->extruder_clearance_radius / 2, 1, JT_ROUND);
}
for my $copy (@{$self->objects->[$obj_idx]->copies}) {
my $copy_clearance = $clearance->clone;
@ -693,7 +693,7 @@ sub write_gcode {
print $fh "; $_\n" foreach split /\R/, $Slic3r::Config->notes;
print $fh "\n" if $Slic3r::Config->notes;
for (qw(layer_height perimeters top_solid_layers bottom_solid_layers fill_density perimeter_speed infill_speed travel_speed scale)) {
for (qw(layer_height perimeters top_solid_layers bottom_solid_layers fill_density perimeter_speed infill_speed travel_speed)) {
printf $fh "; %s = %s\n", $_, $Slic3r::Config->$_;
}
for (qw(nozzle_diameter filament_diameter extrusion_multiplier)) {
@ -881,24 +881,24 @@ sub write_gcode {
if ($Slic3r::Config->avoid_crossing_perimeters) {
push @islands, map +{ perimeters => [], fills => [] }, @{$layer->slices};
PERIMETER: foreach my $perimeter (@{$layerm->perimeters}) {
$perimeter = $perimeter->unpack;
my $p = $perimeter->unpack;
for my $i (0 .. $#{$layer->slices}-1) {
if ($layer->slices->[$i]->contour->encloses_point($perimeter->first_point)) {
push @{ $islands[$i]{perimeters} }, $perimeter;
if ($layer->slices->[$i]->contour->encloses_point($p->first_point)) {
push @{ $islands[$i]{perimeters} }, $p;
next PERIMETER;
}
}
push @{ $islands[-1]{perimeters} }, $perimeter; # optimization
push @{ $islands[-1]{perimeters} }, $p; # optimization
}
FILL: foreach my $fill (@{$layerm->fills}) {
my $f = $fill->unpack;
for my $i (0 .. $#{$layer->slices}-1) {
$fill = $fill->unpack;
if ($layer->slices->[$i]->contour->encloses_point($fill->first_point)) {
push @{ $islands[$i]{fills} }, $fill;
if ($layer->slices->[$i]->contour->encloses_point($f->first_point)) {
push @{ $islands[$i]{fills} }, $f;
next FILL;
}
}
push @{ $islands[-1]{fills} }, $fill; # optimization
push @{ $islands[-1]{fills} }, $f; # optimization
}
} else {
push @islands, {
@ -927,9 +927,10 @@ sub write_gcode {
}
};
# give priority to infill if we were already using its extruder
# give priority to infill if we were already using its extruder and it wouldn't
# be good for perimeters
if ($Slic3r::Config->infill_first
|| ($gcodegen->multiple_extruders && $region->extruders->{infill} eq $gcodegen->extruder)) {
|| ($gcodegen->multiple_extruders && $region->extruders->{infill} eq $gcodegen->extruder) && $region->extruders->{infill} ne $region->extruders->{perimeter}) {
$extrude_fills->();
$extrude_perimeters->();
} else {

View file

@ -18,26 +18,50 @@ has 'layer_height_ranges' => (is => 'rw', default => sub { [] }); # [ z_min, z_m
sub BUILD {
my $self = shift;
# make layers
my $print_z = my $slice_z = my $raft_z = 0;
while (!@{$self->layers} || $self->layers->[-1]->slice_z < $self->size->[Z]) {
my $id = $#{$self->layers} + 1;
my $height = $Slic3r::Config->layer_height;
$height = $Slic3r::Config->get_value('first_layer_height') if $id == 0;
if (my $range = first { $_->[0] <= ($print_z + $_->[2]) && $_->[1] >= ($print_z + $_->[2]) } @{$self->layer_height_ranges}) {
$height = $range->[2];
}
# make layers taking custom heights into account
my $print_z = my $slice_z = my $height = 0;
# add raft layers
for my $id (0 .. $Slic3r::Config->raft_layers-1) {
$height = ($id == 0)
? $Slic3r::Config->get_value('first_layer_height')
: $Slic3r::Config->layer_height;
$print_z += $height;
if ($id < $Slic3r::Config->raft_layers) {
# this is a raft layer
$raft_z += $height;
$slice_z = -1;
} else {
$slice_z = $print_z - ($height/2) - $raft_z;
push @{$self->layers}, Slic3r::Layer->new(
object => $self,
id => $id,
height => $height,
print_z => scale $print_z,
slice_z => -1,
);
}
# loop until we have at least one layer and the max slice_z reaches the object height
my $max_z = unscale $self->size->[Z];
while (!@{$self->layers} || ($slice_z - $height) <= $max_z) {
my $id = $#{$self->layers} + 1;
# assign the default height to the layer according to the general settings
$height = ($id == 0)
? $Slic3r::Config->get_value('first_layer_height')
: $Slic3r::Config->layer_height;
# look for an applicable custom range
if (my $range = first { $_->[0] <= $slice_z && $_->[1] > $slice_z } @{$self->layer_height_ranges}) {
$height = $range->[2];
# if user set custom height to zero we should just skip the range and resume slicing over it
if ($height == 0) {
$slice_z += $range->[1] - $range->[0];
next;
}
}
$print_z += $height;
$slice_z += $height/2;
### Slic3r::debugf "Layer %d: height = %s; slice_z = %s; print_z = %s\n", $id, $height, $slice_z, $print_z;
push @{$self->layers}, Slic3r::Layer->new(
@ -47,6 +71,8 @@ sub BUILD {
print_z => scale $print_z,
slice_z => scale $slice_z,
);
$slice_z += $height/2; # add the other half layer
}
}
@ -131,9 +157,8 @@ sub slice {
# free memory
$self->meshes(undef);
# remove last layer if empty
# (we might have created it because of the $max_layer = ... + 1 code in TriangleMesh)
pop @{$self->layers} if !map @{$_->lines}, @{$self->layers->[-1]->regions};
# remove last layer(s) if empty
pop @{$self->layers} while !map @{$_->lines}, @{$self->layers->[-1]->regions};
foreach my $layer (@{ $self->layers }) {
# make sure all layers contain layer region objects for all regions
@ -806,7 +831,6 @@ sub generate_support_material {
[ map @$_, @current_layer_offsetted_slices ],
);
$layers_contact_areas{$i} = [
map $_->simplify($flow->scaled_spacing),
@{collapse_ex([ map @$_, @{$layers_contact_areas{$i}} ], $flow->scaled_width)},
];
@ -820,7 +844,6 @@ sub generate_support_material {
],
);
$layers_interfaces{$i} = [
map $_->simplify($flow->scaled_spacing),
@{collapse_ex([ map @$_, @{$layers_interfaces{$i}} ], $flow->scaled_width)},
];
@ -842,7 +865,6 @@ sub generate_support_material {
],
);
$layers{$i} = [
map $_->simplify($flow->scaled_spacing),
@{collapse_ex([ map @$_, @{$layers{$i}} ], $flow->scaled_width)},
];

View file

@ -95,4 +95,22 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
ok Slic3r::Test::gcode($print), 'successful hilbertcurve infill generation';
}
{
my $config = Slic3r::Config->new_from_defaults;
$config->set('skirts', 0);
$config->set('perimeters', 0);
$config->set('fill_density', 0);
$config->set('top_solid_layers', 0);
$config->set('bottom_solid_layers', 0);
$config->set('solid_infill_below_area', 20000000);
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
Slic3r::Test::GCodeReader->new(gcode => Slic3r::Test::gcode($print))->parse(sub {
my ($self, $cmd, $args, $info) = @_;
fail "solid_infill_below_area should be ignored when fill_density is 0"
if $info->{extruding};
});
}
__END__