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…
Reference in a new issue