Add support for circular bed

This commit is contained in:
Alessandro Ranellucci 2014-06-16 23:36:31 +02:00
parent 7cc0bce97d
commit 4d8ecccc5e
3 changed files with 60 additions and 14 deletions

View file

@ -114,7 +114,7 @@ sub OnInit {
}
if (!defined $last_version || $last_version =~ /^(?:0|1\.[01])\./) {
show_info($self->{mainframe}, "Hello! In this version a new Bed Shape option was "
. "added. If the bed placement in the plater preview screen looks wrong, go "
. "added. If the bed coordinates in the plater preview screen look wrong, go "
. "to Print Settings and click the \"Set\" button next to \"Bed Shape\".", "Bed Shape");
}
}

View file

@ -6,7 +6,7 @@ use utf8;
use List::Util qw(min max);
use Slic3r::Geometry qw(PI X Y unscale);
use Wx qw(:dialog :id :misc :sizer :choicebook wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_CLOSE EVT_BUTTON EVT_CHOICE);
use Wx::Event qw(EVT_CLOSE);
use base 'Wx::Dialog';
sub new {
@ -40,10 +40,10 @@ sub GetValue {
package Slic3r::GUI::BedShapePanel;
use List::Util qw(min max);
use Slic3r::Geometry qw(PI X Y unscale);
use List::Util qw(min max sum first);
use Slic3r::Geometry qw(PI X Y unscale scaled_epsilon);
use Wx qw(:dialog :id :misc :sizer :choicebook wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_CLOSE EVT_BUTTON EVT_CHOICE);
use Wx::Event qw(EVT_CLOSE EVT_CHOICEBOOK_PAGE_CHANGED);
use base 'Wx::Panel';
use constant SHAPE_RECTANGULAR => 0;
@ -83,6 +83,20 @@ sub new {
default => 'corner',
},
]);
$self->_init_shape_options_page('Circular', [
{
opt_key => 'diameter',
type => 'f',
label => 'Diameter',
tooltip => 'Diameter of the print bed. It is assumed that origin (0,0) is located in the center.',
sidetext => 'mm',
default => 200,
},
]);
EVT_CHOICEBOOK_PAGE_CHANGED($self, -1, sub {
$self->_update_shape;
});
# right pane with preview canvas
my $canvas;
@ -137,6 +151,21 @@ sub _set_shape {
}
}
# is this a circle?
{
my $polygon = Slic3r::Polygon->new_scale(@$points);
my $center = $polygon->bounding_box->center;
my @vertex_distances = map $center->distance_to($_), @$polygon;
my $avg_dist = sum(@vertex_distances)/@vertex_distances;
if (!defined first { abs($_ - $avg_dist) > scaled_epsilon } @vertex_distances) {
# all vertices are equidistant to center
$self->{shape_options_book}->SetSelection(SHAPE_CIRCULAR);
my $optgroup = $self->{optgroups}[SHAPE_CIRCULAR];
$optgroup->set_value('diameter', sprintf("%.0f", unscale($avg_dist*2)));
return;
}
}
$self->{shape_options_book}->SetSelection(SHAPE_CUSTOM);
}
@ -161,6 +190,18 @@ sub _update_shape {
[$x1,$y1],
[$x0,$y1],
];
} elsif ($page_idx == SHAPE_CIRCULAR) {
return if grep !defined($self->{"_$_"}), qw(diameter); # not loaded yet
my $r = $self->{_diameter}/2;
my $twopi = 2*PI;
my $edges = 60;
my $polygon = Slic3r::Polygon->new_scale(
map [ $r * cos $_, $r * sin $_ ],
map { $twopi/$edges*$_ } 1..$edges
);
$self->{bed_shape} = [
map [ unscale($_->x), unscale($_->y) ], @$polygon #))
];
}
$self->{on_change}->();
@ -176,18 +217,21 @@ sub _update_preview {
sub _init_shape_options_page {
my ($self, $title, $options) = @_;
my $on_change = sub {
my ($opt_key, $value) = @_;
$self->{"_$opt_key"} = $value;
$self->_update_shape;
};
my $panel = Wx::Panel->new($self->{shape_options_book});
push @{$self->{optgroups}}, my $optgroup = Slic3r::GUI::OptionsGroup->new(
parent => $panel,
title => 'Settings',
options => $options,
on_change => sub {
my ($opt_key, $value) = @_;
$self->{"_$opt_key"} = $value;
$self->_update_shape;
},
on_change => $on_change,
label_width => 100,
);
$on_change->($_->{opt_key}, $_->{default}) for @$options; # populate with defaults
$panel->SetSizerAndFit($optgroup->sizer);
$self->{shape_options_book}->AddPage($panel, $title);
}

View file

@ -5,7 +5,7 @@ use utf8;
use List::Util qw(min max first);
use Slic3r::Geometry qw(X Y scale unscale convex_hull);
use Slic3r::Geometry::Clipper qw(offset JT_ROUND);
use Slic3r::Geometry::Clipper qw(offset JT_ROUND intersection_pl);
use Wx qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT EVT_SIZE);
use base 'Wx::Panel';
@ -261,13 +261,15 @@ sub update_bed_size {
# cache bed contours and grid
{
my $step = scale 10; # 1cm grid
$self->{grid} = my $grid = []; # arrayref of lines
my @polylines = ();
for (my $x = $bb->x_min + $step; $x < $bb->x_max; $x += $step) {
push @$grid, $self->scaled_points_to_pixel([[$x, $bb->y_min], [$x, $bb->y_max]], 1);
push @polylines, Slic3r::Polyline->new([$x, $bb->y_min], [$x, $bb->y_max]);
}
for (my $y = $bb->y_min + $step; $y < $bb->y_max; $y += $step) {
push @$grid, $self->scaled_points_to_pixel([[$bb->x_min, $y], [$bb->x_max, $y]], 1);
push @polylines, Slic3r::Polyline->new([$bb->x_min, $y], [$bb->x_max, $y]);
}
@polylines = @{intersection_pl(\@polylines, [$polygon])};
$self->{grid} = [ map $self->scaled_points_to_pixel(\@$_, 1), @polylines ];
}
}