Fix of a crash when the Print Bed dialog is reopened after the bed shape
was defined with an STL. Fix of rendering on Windows, refresh on resize.
This commit is contained in:
parent
ef0d22be30
commit
e0b9865386
@ -5,8 +5,8 @@ use warnings;
|
||||
use List::Util qw(min max);
|
||||
use Slic3r::Geometry qw(PI X Y unscale deg2rad);
|
||||
use Slic3r::Geometry::Clipper qw(intersection_pl);
|
||||
use Wx qw(:misc :pen :brush :font wxTAB_TRAVERSAL);
|
||||
use Wx::Event qw(EVT_PAINT EVT_MOUSE_EVENTS);
|
||||
use Wx qw(:misc :pen :brush :font :systemsettings wxTAB_TRAVERSAL wxSOLID);
|
||||
use Wx::Event qw(EVT_PAINT EVT_ERASE_BACKGROUND EVT_MOUSE_EVENTS EVT_SIZE);
|
||||
use base qw(Wx::Panel Class::Accessor);
|
||||
|
||||
__PACKAGE__->mk_accessors(qw(bed_shape interactive pos _scale_factor _shift on_move));
|
||||
@ -15,19 +15,33 @@ sub new {
|
||||
my ($class, $parent, $bed_shape) = @_;
|
||||
|
||||
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, [250,-1], wxTAB_TRAVERSAL);
|
||||
$self->{user_drawn_background} = $^O ne 'darwin';
|
||||
$self->bed_shape($bed_shape // []);
|
||||
EVT_PAINT($self, \&_repaint);
|
||||
EVT_ERASE_BACKGROUND($self, sub {}) if $self->{user_drawn_background};
|
||||
EVT_MOUSE_EVENTS($self, \&_mouse_event);
|
||||
|
||||
EVT_SIZE($self, sub { $self->Refresh; });
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _repaint {
|
||||
my ($self) = @_;
|
||||
my ($self, $event) = @_;
|
||||
|
||||
my $dc = Wx::AutoBufferedPaintDC->new($self);
|
||||
my ($cw, $ch) = $self->GetSizeWH;
|
||||
return if $cw == 0; # when canvas is not rendered yet, size is 0,0
|
||||
|
||||
if ($self->{user_drawn_background}) {
|
||||
# On all systems the AutoBufferedPaintDC() achieves double buffering.
|
||||
# On MacOS the background is erased, on Windows the background is not erased
|
||||
# and on Linux/GTK the background is erased to gray color.
|
||||
# Fill DC with the background on Windows & Linux/GTK.
|
||||
my $color = Wx::SystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT);
|
||||
$dc->SetPen(Wx::Pen->new($color, 1, wxSOLID));
|
||||
$dc->SetBrush(Wx::Brush->new($color, wxSOLID));
|
||||
my $rect = $self->GetUpdateRegion()->GetBox();
|
||||
$dc->DrawRectangle($rect->GetLeft(), $rect->GetTop(), $rect->GetWidth(), $rect->GetHeight());
|
||||
}
|
||||
|
||||
# turn $cw and $ch from sizes to max coordinates
|
||||
$cw--;
|
||||
@ -39,11 +53,12 @@ sub _repaint {
|
||||
]);
|
||||
|
||||
# leave space for origin point
|
||||
$cbb->set_x_min($cbb->x_min + 2);
|
||||
$cbb->set_y_max($cbb->y_max - 2);
|
||||
$cbb->set_x_min($cbb->x_min + 4);
|
||||
$cbb->set_x_max($cbb->x_max - 4);
|
||||
$cbb->set_y_max($cbb->y_max - 4);
|
||||
|
||||
# leave space for origin label
|
||||
$cbb->set_y_max($cbb->y_max - 10);
|
||||
$cbb->set_y_max($cbb->y_max - 13);
|
||||
|
||||
# read new size
|
||||
($cw, $ch) = @{$cbb->size};
|
||||
|
@ -133,11 +133,14 @@ sub on_change {
|
||||
$self->{on_change} = $cb // sub {};
|
||||
}
|
||||
|
||||
# Called from the constructor.
|
||||
# Set the initial bed shape from a list of points.
|
||||
# Deduce the bed shape type (rect, circle, custom)
|
||||
# This routine shall be smart enough if the user messes up
|
||||
# with the list of points in the ini file directly.
|
||||
sub _set_shape {
|
||||
my ($self, $points) = @_;
|
||||
|
||||
$self->{bed_shape} = $points;
|
||||
|
||||
# is this a rectangle?
|
||||
if (@$points == 4) {
|
||||
my $polygon = Slic3r::Polygon->new_scale(@$points);
|
||||
@ -164,6 +167,7 @@ sub _set_shape {
|
||||
|
||||
# is this a circle?
|
||||
{
|
||||
# Analyze the array of points. Do they reside on a circle?
|
||||
my $polygon = Slic3r::Polygon->new_scale(@$points);
|
||||
my $center = $polygon->bounding_box->center;
|
||||
my @vertex_distances = map $center->distance_to($_), @$polygon;
|
||||
@ -178,10 +182,24 @@ sub _set_shape {
|
||||
}
|
||||
}
|
||||
|
||||
if (@$points < 3) {
|
||||
# Invalid polygon. Revert to default bed dimensions.
|
||||
$self->{shape_options_book}->SetSelection(SHAPE_RECTANGULAR);
|
||||
my $optgroup = $self->{optgroups}[SHAPE_RECTANGULAR];
|
||||
$optgroup->set_value('rect_size', [200, 200]);
|
||||
$optgroup->set_value('rect_origin', [0, 0]);
|
||||
$self->_update_shape;
|
||||
return;
|
||||
}
|
||||
|
||||
# This is a custom bed shape, use the polygon provided.
|
||||
$self->{shape_options_book}->SetSelection(SHAPE_CUSTOM);
|
||||
# Copy the polygon to the canvas, make a copy of the array.
|
||||
$self->{canvas}->bed_shape([@$points]);
|
||||
$self->_update_shape;
|
||||
}
|
||||
|
||||
# Update the bed shape from the dialog fields.
|
||||
sub _update_shape {
|
||||
my ($self) = @_;
|
||||
|
||||
@ -229,8 +247,11 @@ sub _update_shape {
|
||||
sub _update_preview {
|
||||
my ($self) = @_;
|
||||
$self->{canvas}->Refresh if $self->{canvas};
|
||||
$self->Refresh;
|
||||
}
|
||||
|
||||
# Called from the constructor.
|
||||
# Create a panel for a rectangular / circular / custom bed shape.
|
||||
sub _init_shape_options_page {
|
||||
my ($self, $title) = @_;
|
||||
|
||||
@ -252,6 +273,7 @@ sub _init_shape_options_page {
|
||||
return $optgroup;
|
||||
}
|
||||
|
||||
# Loads an stl file, projects it to the XY plane and calculates a polygon.
|
||||
sub _load_stl {
|
||||
my ($self) = @_;
|
||||
|
||||
@ -266,7 +288,7 @@ sub _load_stl {
|
||||
my $model = Slic3r::Model->read_from_file($input_file);
|
||||
my $mesh = $model->raw_mesh;
|
||||
my $expolygons = $mesh->horizontal_projection;
|
||||
|
||||
|
||||
if (@$expolygons == 0) {
|
||||
Slic3r::GUI::show_error($self, "The selected file contains no geometry.");
|
||||
return;
|
||||
@ -277,9 +299,11 @@ sub _load_stl {
|
||||
}
|
||||
|
||||
my $polygon = $expolygons->[0]->contour;
|
||||
$self->{canvas}->bed_shape([ map [ unscale($_->x), unscale($_->y) ], @$polygon ]); #))
|
||||
$self->{canvas}->bed_shape([ map [ unscale($_->x), unscale($_->y) ], @$polygon ]);
|
||||
$self->_update_preview();
|
||||
}
|
||||
|
||||
# Returns the resulting bed shape polygon. This value will be stored to the ini file.
|
||||
sub GetValue {
|
||||
my ($self) = @_;
|
||||
return $self->{canvas}->bed_shape;
|
||||
|
Loading…
Reference in New Issue
Block a user