mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	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
					
				
					 2 changed files with 50 additions and 11 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv