Add support for circular bed
This commit is contained in:
parent
7cc0bce97d
commit
4d8ecccc5e
3 changed files with 60 additions and 14 deletions
|
@ -114,7 +114,7 @@ sub OnInit {
|
||||||
}
|
}
|
||||||
if (!defined $last_version || $last_version =~ /^(?:0|1\.[01])\./) {
|
if (!defined $last_version || $last_version =~ /^(?:0|1\.[01])\./) {
|
||||||
show_info($self->{mainframe}, "Hello! In this version a new Bed Shape option was "
|
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");
|
. "to Print Settings and click the \"Set\" button next to \"Bed Shape\".", "Bed Shape");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use utf8;
|
||||||
use List::Util qw(min max);
|
use List::Util qw(min max);
|
||||||
use Slic3r::Geometry qw(PI X Y unscale);
|
use Slic3r::Geometry qw(PI X Y unscale);
|
||||||
use Wx qw(:dialog :id :misc :sizer :choicebook wxTAB_TRAVERSAL);
|
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';
|
use base 'Wx::Dialog';
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
|
@ -40,10 +40,10 @@ sub GetValue {
|
||||||
|
|
||||||
package Slic3r::GUI::BedShapePanel;
|
package Slic3r::GUI::BedShapePanel;
|
||||||
|
|
||||||
use List::Util qw(min max);
|
use List::Util qw(min max sum first);
|
||||||
use Slic3r::Geometry qw(PI X Y unscale);
|
use Slic3r::Geometry qw(PI X Y unscale scaled_epsilon);
|
||||||
use Wx qw(:dialog :id :misc :sizer :choicebook wxTAB_TRAVERSAL);
|
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 base 'Wx::Panel';
|
||||||
|
|
||||||
use constant SHAPE_RECTANGULAR => 0;
|
use constant SHAPE_RECTANGULAR => 0;
|
||||||
|
@ -83,6 +83,20 @@ sub new {
|
||||||
default => 'corner',
|
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
|
# right pane with preview canvas
|
||||||
my $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);
|
$self->{shape_options_book}->SetSelection(SHAPE_CUSTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +190,18 @@ sub _update_shape {
|
||||||
[$x1,$y1],
|
[$x1,$y1],
|
||||||
[$x0,$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}->();
|
$self->{on_change}->();
|
||||||
|
@ -176,18 +217,21 @@ sub _update_preview {
|
||||||
sub _init_shape_options_page {
|
sub _init_shape_options_page {
|
||||||
my ($self, $title, $options) = @_;
|
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});
|
my $panel = Wx::Panel->new($self->{shape_options_book});
|
||||||
push @{$self->{optgroups}}, my $optgroup = Slic3r::GUI::OptionsGroup->new(
|
push @{$self->{optgroups}}, my $optgroup = Slic3r::GUI::OptionsGroup->new(
|
||||||
parent => $panel,
|
parent => $panel,
|
||||||
title => 'Settings',
|
title => 'Settings',
|
||||||
options => $options,
|
options => $options,
|
||||||
on_change => sub {
|
on_change => $on_change,
|
||||||
my ($opt_key, $value) = @_;
|
|
||||||
$self->{"_$opt_key"} = $value;
|
|
||||||
$self->_update_shape;
|
|
||||||
},
|
|
||||||
label_width => 100,
|
label_width => 100,
|
||||||
);
|
);
|
||||||
|
$on_change->($_->{opt_key}, $_->{default}) for @$options; # populate with defaults
|
||||||
$panel->SetSizerAndFit($optgroup->sizer);
|
$panel->SetSizerAndFit($optgroup->sizer);
|
||||||
$self->{shape_options_book}->AddPage($panel, $title);
|
$self->{shape_options_book}->AddPage($panel, $title);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use utf8;
|
||||||
|
|
||||||
use List::Util qw(min max first);
|
use List::Util qw(min max first);
|
||||||
use Slic3r::Geometry qw(X Y scale unscale convex_hull);
|
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 qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL);
|
||||||
use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT EVT_SIZE);
|
use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT EVT_SIZE);
|
||||||
use base 'Wx::Panel';
|
use base 'Wx::Panel';
|
||||||
|
@ -261,13 +261,15 @@ sub update_bed_size {
|
||||||
# cache bed contours and grid
|
# cache bed contours and grid
|
||||||
{
|
{
|
||||||
my $step = scale 10; # 1cm 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) {
|
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) {
|
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 ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue