From 2f2ae7552920fcfbec348b7e328c711569a7b0f5 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci <aar@cpan.org> Date: Sat, 13 Dec 2014 22:18:43 +0100 Subject: [PATCH] Some incomplete work for moving objects in 3D plater --- lib/Slic3r/GUI/PreviewCanvas.pm | 64 ++++++++++++++++++++++----------- utils/view-mesh.pl | 2 ++ xs/src/libslic3r/Point.cpp | 27 ++++++++++++++ xs/src/libslic3r/Point.hpp | 4 +++ xs/xsp/Point.xsp | 6 ++++ 5 files changed, 83 insertions(+), 20 deletions(-) diff --git a/lib/Slic3r/GUI/PreviewCanvas.pm b/lib/Slic3r/GUI/PreviewCanvas.pm index 25b5de93c..0e0d22c8f 100644 --- a/lib/Slic3r/GUI/PreviewCanvas.pm +++ b/lib/Slic3r/GUI/PreviewCanvas.pm @@ -15,6 +15,7 @@ use Wx::GLCanvas qw(:all); __PACKAGE__->mk_accessors( qw(quat dirty init mview_init object_bounding_box enable_picking + enable_moving on_select_object on_double_click on_right_click @@ -27,6 +28,8 @@ __PACKAGE__->mk_accessors( qw(quat dirty init mview_init bed_grid_lines origin _mouse_gl_pos + _drag_volume_idx + _drag_start_pos ) ); use constant TRACKBALLSIZE => 0.8; @@ -74,8 +77,8 @@ sub new { my $zoom = ($e->GetWheelRotation() / $e->GetWheelDelta() / 10); $zoom = $zoom > 0 ? (1.0 + $zoom) : 1 / (1.0 - $zoom); - my @pos3d = $self->mouse_to_3d($e->GetX(), $e->GetY()); - $self->ZoomTo($zoom, $pos3d[0], $pos3d[1]); + my $pos3d = $self->mouse_to_3d($e->GetX(), $e->GetY()); + $self->ZoomTo($zoom, $pos3d->x, $pos3d->y); #)) $self->Refresh; }); @@ -98,11 +101,28 @@ sub new { $self->on_select_object->($volume_idx) if $self->on_select_object; - if ($e->RightDown && $volume_idx != -1) { - # if right clicking on volume, propagate event through callback - $self->on_right_click->($e->GetPosition) - if $self->on_right_click; + if ($volume_idx != -1) { + if ($e->LeftDown && $self->enable_moving) { + $self->_drag_volume_idx($volume_idx); + $self->_drag_start_pos($self->mouse_to_3d(@$pos)); + } elsif ($e->RightDown) { + # if right clicking on volume, propagate event through callback + $self->on_right_click->($e->GetPosition) + if $self->on_right_click; + } } + } elsif ($e->Dragging && $e->LeftIsDown && defined($self->_drag_volume_idx)) { + # get volume being dragged + my $volume = $self->volumes->[$self->_drag_volume_idx]; + + # get new position and calculate the move vector + my $cur_pos = $self->mouse_to_3d(@$pos); + my $vector = $self->_drag_start_pos->vector_to($cur_pos); + + # apply new temporary volume origin and ignore Z + $volume->{origin}->set_x(-$vector->x); + $volume->{origin}->set_y(-$vector->y); #)) + $self->Refresh; } elsif ($e->Dragging) { my $volume_idx = first { $self->volumes->[$_]->{hover} } 0..$#{$self->volumes}; $volume_idx //= -1; @@ -113,12 +133,16 @@ sub new { } elsif ($e->RightIsDown && $volume_idx == -1) { # if dragging over blank area with right button, translate $self->handle_translation($e); - } elsif ($e->LeftIsDown && $volume_idx != -1) { - # if dragging volume, move it - # TODO } } elsif ($e->LeftUp || $e->RightUp) { $self->initpos(undef); + + if ($self->on_instance_moved && defined $self->_drag_volume_idx) { + my $volume = $self->volumes->[$self->_drag_volume_idx]; + $self->on_instance_moved($self->_drag_volume_idx, $volume->{instance_idx}); + } + $self->_drag_volume_idx(undef); + $self->_drag_start_pos(undef); } elsif ($e->Moving) { my $glpos = $pos->clone; $glpos->set_y($self->GetSize->GetHeight - $glpos->y); #)) @@ -227,7 +251,7 @@ sub load_object { instance_idx => $instance_idx, mesh => $mesh, color => $color, - z_min => $z_min, + origin => Slic3r::Pointf3->new(0,0,$z_min), }; push @volumes_idx, $#{$self->volumes}; @@ -264,7 +288,7 @@ sub SetCuttingPlane { my @verts = (); foreach my $volume (@{$self->volumes}) { foreach my $volume (@{$self->volumes}) { - my $expolygons = $volume->{mesh}->slice([ $z + $volume->{z_min} ])->[0]; + my $expolygons = $volume->{mesh}->slice([ $z + $volume->{origin}->z ])->[0]; $expolygons = offset_ex([ map @$_, @$expolygons ], scale 0.1); foreach my $line (map @{$_->lines}, map @$_, @$expolygons) { @@ -418,9 +442,9 @@ sub handle_translation { } else { my $new = $e->GetPosition(); my $orig = $self->initpos; - my @orig3d = $self->mouse_to_3d($orig->x, $orig->y); #)() - my @new3d = $self->mouse_to_3d($new->x, $new->y); #)() - glTranslatef($new3d[0] - $orig3d[0], $new3d[1] - $orig3d[1], 0); + my $orig3d = $self->mouse_to_3d($orig->x, $orig->y); #)() + my $new3d = $self->mouse_to_3d($new->x, $new->y); #)() + glTranslatef($new3d->x - $orig3d->x, $new3d->y - $orig3d->y, 0); #-- $self->initpos($new); $self->Refresh; } @@ -434,7 +458,7 @@ sub mouse_to_3d { my @proj = glGetDoublev_p(GL_PROJECTION_MATRIX); # 16 items my @projected = gluUnProject_p($x, $viewport[3] - $y, 1.0, @mview, @proj, @viewport); - return @projected; + return Slic3r::Pointf3->new(@projected); } sub ZoomTo { @@ -581,7 +605,7 @@ sub Render { if ($self->enable_picking) { glDisable(GL_LIGHTING); - $self->draw_mesh(1); + $self->draw_volumes(1); glFlush(); glFinish(); @@ -599,7 +623,7 @@ sub Render { glEnable(GL_LIGHTING); } # draw objects - $self->draw_mesh; + $self->draw_volumes; # draw ground and axes glDisable(GL_LIGHTING); @@ -679,7 +703,7 @@ sub Render { $self->SwapBuffers(); } -sub draw_mesh { +sub draw_volumes { my ($self, $fakecolor) = @_; glEnable(GL_BLEND); @@ -689,7 +713,7 @@ sub draw_mesh { foreach my $volume_idx (0..$#{$self->volumes}) { my $volume = $self->volumes->[$volume_idx]; - glTranslatef(0, 0, -$volume->{z_min}); + glTranslatef(@{$volume->{origin}->negative}); glVertexPointer_p(3, $volume->{verts}); @@ -709,7 +733,7 @@ sub draw_mesh { } glDrawArrays(GL_TRIANGLES, 0, $volume->{verts}->elements / 3); - glTranslatef(0, 0, +$volume->{z_min}); + glTranslatef(@{$volume->{origin}}); } glDisableClientState(GL_NORMAL_ARRAY); glDisable(GL_BLEND); diff --git a/utils/view-mesh.pl b/utils/view-mesh.pl index 61d6748f6..58f641a92 100644 --- a/utils/view-mesh.pl +++ b/utils/view-mesh.pl @@ -20,6 +20,7 @@ my %opt = (); my %options = ( 'help' => sub { usage() }, 'cut=f' => \$opt{cut}, + 'enable-moving' => \$opt{enable_moving}, ); GetOptions(%options) or usage(1); $ARGV[0] or usage(1); @@ -33,6 +34,7 @@ my %opt = (); my $app = Slic3r::ViewMesh->new; $app->{canvas}->enable_picking(1); + $app->{canvas}->enable_moving($opt{enable_moving}); $app->{canvas}->load_object($model->objects->[0]); $app->{canvas}->set_bounding_box($model->objects->[0]->bounding_box); $app->{canvas}->set_auto_bed_shape; diff --git a/xs/src/libslic3r/Point.cpp b/xs/src/libslic3r/Point.cpp index 5f3f1da01..63fe63cfb 100644 --- a/xs/src/libslic3r/Point.cpp +++ b/xs/src/libslic3r/Point.cpp @@ -218,6 +218,12 @@ Point::negative() const return Point(-this->x, -this->y); } +Vector +Point::vector_to(const Point &point) const +{ + return Vector(point.x - this->x, point.y - this->y); +} + Point operator+(const Point& point1, const Point& point2) { @@ -353,6 +359,27 @@ Pointf3::translate(double x, double y, double z) this->z += z; } +double +Pointf3::distance_to(const Pointf3 &point) const +{ + double dx = ((double)point.x - this->x); + double dy = ((double)point.y - this->y); + double dz = ((double)point.z - this->z); + return sqrt(dx*dx + dy*dy + dz*dz); +} + +Pointf3 +Pointf3::negative() const +{ + return Pointf3(-this->x, -this->y, -this->z); +} + +Vectorf3 +Pointf3::vector_to(const Pointf3 &point) const +{ + return Vectorf3(point.x - this->x, point.y - this->y, point.z - this->z); +} + #ifdef SLIC3RXS REGISTER_CLASS(Pointf3, "Pointf3"); #endif diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp index 271c9584e..6f4d317a4 100644 --- a/xs/src/libslic3r/Point.hpp +++ b/xs/src/libslic3r/Point.hpp @@ -53,6 +53,7 @@ class Point Point projection_onto(const MultiPoint &poly) const; Point projection_onto(const Line &line) const; Point negative() const; + Vector vector_to(const Point &point) const; #ifdef SLIC3RXS void from_SV(SV* point_sv); @@ -96,6 +97,9 @@ class Pointf3 : public Pointf void scale(double factor); void translate(const Vectorf3 &vector); void translate(double x, double y, double z); + double distance_to(const Pointf3 &point) const; + Pointf3 negative() const; + Vectorf3 vector_to(const Pointf3 &point) const; }; } diff --git a/xs/xsp/Point.xsp b/xs/xsp/Point.xsp index e02638a13..dbf2f9bac 100644 --- a/xs/xsp/Point.xsp +++ b/xs/xsp/Point.xsp @@ -121,4 +121,10 @@ Point::coincides_with(point_sv) void set_z(double val) %code{% THIS->z = val; %}; void translate(double x, double y, double z); + double distance_to(Pointf3* point) + %code{% RETVAL = THIS->distance_to(*point); %}; + Clone<Pointf3> negative() + %code{% RETVAL = THIS->negative(); %}; + Clone<Pointf3> vector_to(Pointf3* point) + %code{% RETVAL = THIS->vector_to(*point); %}; };