mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Pan & zoom for toolpaths preview
This commit is contained in:
		
							parent
							
								
									97211f35e7
								
							
						
					
					
						commit
						80b169aa75
					
				
					 2 changed files with 128 additions and 22 deletions
				
			
		|  | @ -593,7 +593,7 @@ sub Resize { | |||
|         -$x/2, $x/2, -$y/2, $y/2, | ||||
|         -$depth, 2*$depth, | ||||
|     ); | ||||
|   | ||||
|      | ||||
|     glMatrixMode(GL_MODELVIEW); | ||||
| } | ||||
|   | ||||
|  |  | |||
|  | @ -84,6 +84,7 @@ sub reload_print { | |||
|     } | ||||
|      | ||||
|     $self->{canvas}->bb($self->print->total_bounding_box); | ||||
|     $self->{canvas}->Resize; | ||||
|      | ||||
|     my %z = ();  # z => 1 | ||||
|     foreach my $object (@{$self->{print}->objects}) { | ||||
|  | @ -119,11 +120,19 @@ use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS); | |||
| use OpenGL qw(:glconstants :glfunctions :glufunctions :gluconstants); | ||||
| use base qw(Wx::GLCanvas Class::Accessor); | ||||
| use Wx::GLCanvas qw(:all); | ||||
| use List::Util qw(min first); | ||||
| use Slic3r::Geometry qw(scale unscale epsilon); | ||||
| use List::Util qw(min max first); | ||||
| use Slic3r::Geometry qw(scale unscale epsilon X Y); | ||||
| use Slic3r::Print::State ':steps'; | ||||
| 
 | ||||
| __PACKAGE__->mk_accessors(qw(print z layers color init bb _dirty)); | ||||
| __PACKAGE__->mk_accessors(qw( | ||||
|     print z layers color init | ||||
|     bb | ||||
|     _camera_bb | ||||
|     _dirty | ||||
|     _zoom | ||||
|     _camera_target | ||||
|     _drag_start_xy | ||||
| )); | ||||
| 
 | ||||
| # make OpenGL::Array thread-safe | ||||
| { | ||||
|  | @ -136,6 +145,10 @@ sub new { | |||
|      | ||||
|     my $self = $class->SUPER::new($parent); | ||||
|     $self->print($print); | ||||
|     $self->_zoom(1); | ||||
|      | ||||
|     # 2D point in model space | ||||
|     $self->_camera_target(Slic3r::Pointf->new(0,0)); | ||||
|      | ||||
|     EVT_PAINT($self, sub { | ||||
|         my $dc = Wx::PaintDC->new($self); | ||||
|  | @ -145,13 +158,83 @@ sub new { | |||
|     EVT_IDLE($self, sub { | ||||
|         return unless $self->_dirty; | ||||
|         return if !$self->IsShownOnScreen; | ||||
|         $self->Resize( $self->GetSizeWH ); | ||||
|         $self->Resize; | ||||
|         $self->Refresh; | ||||
|     }); | ||||
|     EVT_MOUSEWHEEL($self, sub { | ||||
|         my ($self, $e) = @_; | ||||
|          | ||||
|         # Calculate the zoom delta and apply it to the current zoom factor | ||||
|         my $zoom = $e->GetWheelRotation() / $e->GetWheelDelta(); | ||||
|         $zoom = max(min($zoom, 4), -4); | ||||
|         $zoom /= 10; | ||||
|         $self->_zoom($self->_zoom / (1-$zoom)); | ||||
|         $self->_zoom(1) if $self->_zoom > 1; | ||||
|          | ||||
|         # In order to zoom around the mouse point we need to translate | ||||
|         # the camera target | ||||
|         my $size = Slic3r::Pointf->new($self->GetSizeWH); | ||||
|         my $pos = Slic3r::Pointf->new($e->GetX, $size->y - $e->GetY); #- | ||||
|         $self->_dirty(1); | ||||
|         $self->Resize; | ||||
|         $self->Refresh; | ||||
|     }); | ||||
|     EVT_MOUSE_EVENTS($self, \&mouse_event); | ||||
|      | ||||
|     return $self; | ||||
| } | ||||
| 
 | ||||
| sub mouse_event { | ||||
|     my ($self, $e) = @_; | ||||
|      | ||||
|     my $pos = Slic3r::Pointf->new($e->GetPositionXY); | ||||
|     if ($e->Entering && &Wx::wxMSW) { | ||||
|         # wxMSW needs focus in order to catch mouse wheel events | ||||
|         $self->SetFocus; | ||||
|     } elsif ($e->Dragging) { | ||||
|         if ($e->LeftIsDown || $e->MiddleIsDown || $e->RightIsDown) { | ||||
|             # if dragging, translate view | ||||
|              | ||||
|             if (defined $self->_drag_start_xy) { | ||||
|                 my $move = $self->_drag_start_xy->vector_to($pos);  # in pixels | ||||
|                  | ||||
|                 # get viewport and camera size in order to convert pixel to model units | ||||
|                 my ($x, $y) = $self->GetSizeWH; | ||||
|                 my $camera_bb_size = $self->_camera_bb->size; | ||||
|                  | ||||
|                 my @translate = ( | ||||
|                     -$move->x * $camera_bb_size->x / $x, | ||||
|                      $move->y * $camera_bb_size->y / $y,   # /** | ||||
|                 ); | ||||
|                  | ||||
|                 # keep camera_bb within total bb | ||||
|                 if ($self->_camera_bb->x_min < $self->bb->x_min) { | ||||
|                     $translate[X] += $self->bb->x_min - $self->_camera_bb->x_min; | ||||
|                 } | ||||
|                 if ($self->_camera_bb->y_min < $self->bb->y_min) { | ||||
|                     $translate[Y] += $self->bb->y_min - $self->_camera_bb->y_min; | ||||
|                 } | ||||
|                 if ($self->_camera_bb->x_max > $self->bb->x_max) { | ||||
|                     $translate[X] -= $self->_camera_bb->x_max - $self->bb->x_max; | ||||
|                 } | ||||
|                 if ($self->_camera_bb->y_max > $self->bb->y_max) { | ||||
|                     $translate[Y] -= $self->_camera_bb->y_max - $self->bb->y_max; | ||||
|                 } | ||||
|                  | ||||
|                 $self->_camera_target->translate(@translate); | ||||
|                  | ||||
|                 $self->Resize; | ||||
|                 $self->Refresh; | ||||
|             } | ||||
|             $self->_drag_start_xy($pos); | ||||
|         } | ||||
|     } elsif ($e->LeftUp || $e->MiddleUp || $e->RightUp) { | ||||
|         $self->_drag_start_xy(undef); | ||||
|     } else { | ||||
|         $e->Skip(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| sub set_z { | ||||
|     my ($self, $z) = @_; | ||||
|      | ||||
|  | @ -199,22 +282,6 @@ sub Render { | |||
|         return; | ||||
|     } | ||||
|      | ||||
|     glMatrixMode(GL_PROJECTION); | ||||
|     glLoadIdentity(); | ||||
|     my $bb = $self->bb; | ||||
|     my ($x1, $y1, $x2, $y2) = ($bb->x_min, $bb->y_min, $bb->x_max, $bb->y_max); | ||||
|     my ($x, $y) = $self->GetSizeWH; | ||||
|     if (($x2 - $x1)/($y2 - $y1) > $x/$y) { | ||||
|         # adjust Y | ||||
|         my $new_y = $y * ($x2 - $x1) / $x; | ||||
|         $y1 = ($y2 + $y1)/2 - $new_y/2; | ||||
|         $y2 = $y1 + $new_y; | ||||
|     } else { | ||||
|         my $new_x = $x * ($y2 - $y1) / $y; | ||||
|         $x1 = ($x2 + $x1)/2 - $new_x/2; | ||||
|         $x2 = $x1 + $new_x; | ||||
|     } | ||||
|     glOrtho($x1, $x2, $y1, $y2, 0, 1); | ||||
|     glDisable(GL_DEPTH_TEST); | ||||
|     glMatrixMode(GL_MODELVIEW); | ||||
|     glLoadIdentity(); | ||||
|  | @ -400,12 +467,51 @@ sub SetCurrent { | |||
| } | ||||
| 
 | ||||
| sub Resize { | ||||
|     my ($self, $x, $y) = @_; | ||||
|     my ($self) = @_; | ||||
|   | ||||
|     return unless $self->GetContext; | ||||
|     return unless $self->bb; | ||||
|     $self->_dirty(0); | ||||
|      | ||||
|     $self->SetCurrent($self->GetContext); | ||||
|     my ($x, $y) = $self->GetSizeWH; | ||||
|     glViewport(0, 0, $x, $y); | ||||
|      | ||||
|     glMatrixMode(GL_PROJECTION); | ||||
|     glLoadIdentity(); | ||||
|      | ||||
|     my $bb = $self->bb->clone; | ||||
|      | ||||
|     # center bounding box around origin before scaling it | ||||
|     my $bb_center = $bb->center; | ||||
|     $bb->translate(@{$bb_center->negative}); | ||||
|      | ||||
|     # scale bounding box according to zoom factor | ||||
|     $bb->scale($self->_zoom); | ||||
|      | ||||
|     # reposition bounding box around original center | ||||
|     $bb->translate(@{$bb_center}); | ||||
|      | ||||
|     # translate camera | ||||
|     $bb->translate(@{$self->_camera_target}); | ||||
|      | ||||
|     # save camera | ||||
|     $self->_camera_bb($bb); | ||||
|      | ||||
|     my ($x1, $y1, $x2, $y2) = ($bb->x_min, $bb->y_min, $bb->x_max, $bb->y_max); | ||||
|     if (($x2 - $x1)/($y2 - $y1) > $x/$y) { | ||||
|         # adjust Y | ||||
|         my $new_y = $y * ($x2 - $x1) / $x; | ||||
|         $y1 = ($y2 + $y1)/2 - $new_y/2; | ||||
|         $y2 = $y1 + $new_y; | ||||
|     } else { | ||||
|         my $new_x = $x * ($y2 - $y1) / $y; | ||||
|         $x1 = ($x2 + $x1)/2 - $new_x/2; | ||||
|         $x2 = $x1 + $new_x; | ||||
|     } | ||||
|     glOrtho($x1, $x2, $y1, $y2, 0, 1); | ||||
|      | ||||
|     glMatrixMode(GL_MODELVIEW); | ||||
| } | ||||
| 
 | ||||
| sub line { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci