diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm
index a296b01a2..68de5518b 100644
--- a/lib/Slic3r/GUI/3DScene.pm
+++ b/lib/Slic3r/GUI/3DScene.pm
@@ -16,13 +16,13 @@ use strict;
 use warnings;
 
 use Wx qw(:timer :bitmap :icon :dialog);
-use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS EVT_TIMER);
+use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS EVT_CHAR EVT_TIMER);
 # must load OpenGL *before* Wx::GLCanvas
 use OpenGL qw(:glconstants :glfunctions :glufunctions :gluconstants);
 use base qw(Wx::GLCanvas Class::Accessor);
 use Math::Trig qw(asin tan);
 use List::Util qw(reduce min max first);
-use Slic3r::Geometry qw(X Y Z MIN MAX triangle_normal normalize deg2rad tan scale unscale scaled_epsilon);
+use Slic3r::Geometry qw(X Y normalize scale unscale scaled_epsilon);
 use Slic3r::Geometry::Clipper qw(offset_ex intersection_pl JT_ROUND);
 use Wx::GLCanvas qw(:all);
 use Slic3r::Geometry qw(PI);
@@ -168,6 +168,32 @@ sub new {
     });
     EVT_MOUSEWHEEL($self, \&mouse_wheel_event);
     EVT_MOUSE_EVENTS($self, \&mouse_event);
+#    EVT_KEY_DOWN($self, sub {
+    EVT_CHAR($self, sub {
+        my ($s, $event) = @_;
+        if ($event->HasModifiers) {
+            $event->Skip;
+        } else {
+            my $key = $event->GetKeyCode;
+            if ($key == ord('0')) {
+                $self->select_view('iso');
+            } elsif ($key == ord('1')) {
+                $self->select_view('top');
+            } elsif ($key == ord('2')) {
+                $self->select_view('bottom');
+            } elsif ($key == ord('3')) {
+                $self->select_view('front');
+            } elsif ($key == ord('4')) {
+                $self->select_view('rear');
+            } elsif ($key == ord('5')) {
+                $self->select_view('left');
+            } elsif ($key == ord('6')) {
+                $self->select_view('right');
+            } else {
+                $event->Skip;
+            }
+        }
+    });
     
     $self->{layer_height_edit_timer_id} = &Wx::NewId();
     $self->{layer_height_edit_timer} = Wx::Timer->new($self, $self->{layer_height_edit_timer_id});
diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm
index 74ae10749..f075b4b28 100644
--- a/lib/Slic3r/GUI/MainFrame.pm
+++ b/lib/Slic3r/GUI/MainFrame.pm
@@ -7,7 +7,7 @@ use utf8;
 
 use File::Basename qw(basename dirname);
 use List::Util qw(min);
-use Slic3r::Geometry qw(X Y Z);
+use Slic3r::Geometry qw(X Y);
 use Wx qw(:frame :bitmap :id :misc :notebook :panel :sizer :menu :dialog :filedialog
     :font :icon wxTheApp);
 use Wx::Event qw(EVT_CLOSE EVT_MENU EVT_NOTEBOOK_PAGE_CHANGED);
@@ -273,13 +273,16 @@ sub _init_menubar {
     # View menu
     if (!$self->{no_plater}) {
         $self->{viewMenu} = Wx::Menu->new;
-        $self->_append_menu_item($self->{viewMenu}, "Iso"    , 'Iso View'    , sub { $self->select_view('iso'    ); });
-        $self->_append_menu_item($self->{viewMenu}, "Top"    , 'Top View'    , sub { $self->select_view('top'    ); });
-        $self->_append_menu_item($self->{viewMenu}, "Bottom" , 'Bottom View' , sub { $self->select_view('bottom' ); });
-        $self->_append_menu_item($self->{viewMenu}, "Front"  , 'Front View'  , sub { $self->select_view('front'  ); });
-        $self->_append_menu_item($self->{viewMenu}, "Rear"   , 'Rear View'   , sub { $self->select_view('rear'   ); });
-        $self->_append_menu_item($self->{viewMenu}, "Left"   , 'Left View'   , sub { $self->select_view('left'   ); });
-        $self->_append_menu_item($self->{viewMenu}, "Right"  , 'Right View'  , sub { $self->select_view('right'  ); });
+        # \xA0 is a non-breaing space. It is entered here to spoil the automatic accelerators,
+        # as the simple numeric accelerators spoil all numeric data entry.
+        # The camera control accelerators are captured by 3DScene Perl module instead.
+        $self->_append_menu_item($self->{viewMenu}, "Iso\t\xA00"    , 'Iso View'    , sub { $self->select_view('iso'    ); });
+        $self->_append_menu_item($self->{viewMenu}, "Top\t\xA01"    , 'Top View'    , sub { $self->select_view('top'    ); });
+        $self->_append_menu_item($self->{viewMenu}, "Bottom\t\xA02" , 'Bottom View' , sub { $self->select_view('bottom' ); });
+        $self->_append_menu_item($self->{viewMenu}, "Front\t\xA03"  , 'Front View'  , sub { $self->select_view('front'  ); });
+        $self->_append_menu_item($self->{viewMenu}, "Rear\t\xA04"   , 'Rear View'   , sub { $self->select_view('rear'   ); });
+        $self->_append_menu_item($self->{viewMenu}, "Left\t\xA05"   , 'Left View'   , sub { $self->select_view('left'   ); });
+        $self->_append_menu_item($self->{viewMenu}, "Right\t\xA06"  , 'Right View'  , sub { $self->select_view('right'  ); });
     }
     
     # Help menu
diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm
index 5d6f8d23a..6e06687d4 100644
--- a/lib/Slic3r/GUI/Plater.pm
+++ b/lib/Slic3r/GUI/Plater.pm
@@ -7,7 +7,7 @@ use utf8;
 
 use File::Basename qw(basename dirname);
 use List::Util qw(sum first max);
-use Slic3r::Geometry qw(X Y Z MIN MAX scale unscale deg2rad rad2deg);
+use Slic3r::Geometry qw(X Y Z scale unscale deg2rad rad2deg);
 use LWP::UserAgent;
 use threads::shared qw(shared_clone);
 use Wx qw(:button :colour :cursor :dialog :filedialog :keycode :icon :font :id :listctrl :misc 
@@ -105,6 +105,12 @@ sub new {
         $self->{canvas3D}->set_on_select_object($on_select_object);
         $self->{canvas3D}->set_on_double_click($on_double_click);
         $self->{canvas3D}->set_on_right_click(sub { $on_right_click->($self->{canvas3D}, @_); });
+        $self->{canvas3D}->set_on_rotate_object_left(sub { $self->rotate(-45, Z, 'relative') });
+        $self->{canvas3D}->set_on_rotate_object_right(sub { $self->rotate( 45, Z, 'relative') });
+        $self->{canvas3D}->set_on_scale_object_uniformly(sub { $self->changescale(undef) });
+        $self->{canvas3D}->set_on_increase_objects(sub { $self->increase() });
+        $self->{canvas3D}->set_on_decrease_objects(sub { $self->decrease() });
+        $self->{canvas3D}->set_on_remove_object(sub { $self->remove() });
         $self->{canvas3D}->set_on_instances_moved($on_instances_moved);
         $self->{canvas3D}->set_on_wipe_tower_moved(sub {
             my ($new_pos_3f) = @_;
@@ -862,8 +868,9 @@ sub remove {
     $self->{preview3D}->enabled(0) if $self->{preview3D};
     
     # if no object index is supplied, remove the selected one
-    if (!defined $obj_idx) {
+    if (! defined $obj_idx) {
         ($obj_idx, undef) = $self->selected_object;
+        return if ! defined $obj_idx;
     }
     
     splice @{$self->{objects}}, $obj_idx, 1;
@@ -1121,12 +1128,12 @@ sub changescale {
         if ($tosize) {
             my $cursize = max(@$object_size);
             my $newsize = $self->_get_number_from_user('Enter the new max size for the selected object:', 'Scale', 'Invalid scaling value entered', $cursize, 1);
-            return if $newsize eq '';
+            return if ! defined($newsize) || $newsize eq '';
             $scale = $model_instance->scaling_factor * $newsize / $cursize * 100;
         } else {
             # max scale factor should be above 2540 to allow importing files exported in inches
             $scale = $self->_get_number_from_user('Enter the scale % for the selected object:', 'Scale', 'Invalid scaling value entered', $model_instance->scaling_factor*100, 1);
-            return if $scale eq '';
+            return if ! defined($scale) || $scale eq '';
         }
     
         $self->{list}->SetItem($obj_idx, 2, "$scale%");
@@ -2060,23 +2067,23 @@ sub object_menu {
     
     my $frame = $self->GetFrame;
     my $menu = Wx::Menu->new;
-    $frame->_append_menu_item($menu, "Delete\tCtrl+Del", 'Remove the selected object', sub {
+    $frame->_append_menu_item($menu, "Delete\t\xA0Del", 'Remove the selected object', sub {
         $self->remove;
     }, undef, 'brick_delete.png');
-    $frame->_append_menu_item($menu, "Increase copies\tCtrl++", 'Place one more copy of the selected object', sub {
+    $frame->_append_menu_item($menu, "Increase copies\t\xA0+", 'Place one more copy of the selected object', sub {
         $self->increase;
     }, undef, 'add.png');
-    $frame->_append_menu_item($menu, "Decrease copies\tCtrl+-", 'Remove one copy of the selected object', sub {
+    $frame->_append_menu_item($menu, "Decrease copies\t\xA0-", 'Remove one copy of the selected object', sub {
         $self->decrease;
     }, undef, 'delete.png');
     $frame->_append_menu_item($menu, "Set number of copies…", 'Change the number of copies of the selected object', sub {
         $self->set_number_of_copies;
     }, undef, 'textfield.png');
     $menu->AppendSeparator();
-    $frame->_append_menu_item($menu, "Rotate 45° clockwise", 'Rotate the selected object by 45° clockwise', sub {
+    $frame->_append_menu_item($menu, "Rotate 45° clockwise\t\xA0l", 'Rotate the selected object by 45° clockwise', sub {
         $self->rotate(-45, Z, 'relative');
     }, undef, 'arrow_rotate_clockwise.png');
-    $frame->_append_menu_item($menu, "Rotate 45° counter-clockwise", 'Rotate the selected object by 45° counter-clockwise', sub {
+    $frame->_append_menu_item($menu, "Rotate 45° counter-clockwise\t\xA0r", 'Rotate the selected object by 45° counter-clockwise', sub {
         $self->rotate(+45, Z, 'relative');
     }, undef, 'arrow_rotate_anticlockwise.png');
     
@@ -2109,7 +2116,7 @@ sub object_menu {
     my $scaleMenu = Wx::Menu->new;
     my $scaleMenuItem = $menu->AppendSubMenu($scaleMenu, "Scale", 'Scale the selected object along a single axis');
     $frame->_set_menu_item_icon($scaleMenuItem, 'arrow_out.png');
-    $frame->_append_menu_item($scaleMenu, "Uniformly…", 'Scale the selected object along the XYZ axes', sub {
+    $frame->_append_menu_item($scaleMenu, "Uniformly…\t\xA0s", 'Scale the selected object along the XYZ axes', sub {
         $self->changescale(undef);
     });
     $frame->_append_menu_item($scaleMenu, "Along X axis…", 'Scale the selected object along the X axis', sub {
@@ -2203,9 +2210,6 @@ sub OnDropFiles {
 package Slic3r::GUI::Plater::Object;
 use Moo;
 
-use List::Util qw(first);
-use Slic3r::Geometry qw(X Y Z MIN MAX deg2rad);
-
 has 'name'                  => (is => 'rw', required => 1);
 has 'thumbnail'             => (is => 'rw'); # ExPolygon::Collection in scaled model units with no transforms
 has 'transformed_thumbnail' => (is => 'rw');
diff --git a/lib/Slic3r/GUI/Plater/3D.pm b/lib/Slic3r/GUI/Plater/3D.pm
index 6fa46030a..503a3d159 100644
--- a/lib/Slic3r/GUI/Plater/3D.pm
+++ b/lib/Slic3r/GUI/Plater/3D.pm
@@ -4,12 +4,14 @@ use warnings;
 use utf8;
 
 use List::Util qw();
-use Slic3r::Geometry qw();
-use Slic3r::Geometry::Clipper qw();
-use Wx qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL);
-use Wx::Event qw();
+use Wx qw(:misc :pen :brush :sizer :font :cursor :keycode wxTAB_TRAVERSAL);
+use Wx::Event qw(EVT_KEY_DOWN EVT_CHAR);
 use base qw(Slic3r::GUI::3DScene Class::Accessor);
 
+__PACKAGE__->mk_accessors(qw(
+    on_rotate_object_left on_rotate_object_right on_scale_object_uniformly
+    on_remove_object on_increase_objects on_decrease_objects));
+
 sub new {
     my $class = shift;
     my ($parent, $objects, $model, $print, $config) = @_;
@@ -65,6 +67,42 @@ sub new {
         $self->{on_wipe_tower_moved}->($wipe_tower_moved)
             if $wipe_tower_moved && $self->{on_wipe_tower_moved};
     });
+
+    EVT_KEY_DOWN($self, sub {
+        my ($s, $event) = @_;
+        if ($event->HasModifiers) {
+            $event->Skip;
+        } else {
+            my $key = $event->GetKeyCode;
+            if ($key == WXK_DELETE) {
+                $self->on_remove_object->() if $self->on_remove_object;
+            } else {
+                $event->Skip;
+            }
+        }
+    });
+
+    EVT_CHAR($self, sub {
+        my ($s, $event) = @_;
+        if ($event->HasModifiers) {
+            $event->Skip;
+        } else {
+            my $key = $event->GetKeyCode;
+            if ($key == ord('l')) {
+                $self->on_rotate_object_left->() if $self->on_rotate_object_left;
+            } elsif ($key == ord('r')) {
+                $self->on_rotate_object_right->() if $self->on_rotate_object_right;
+            } elsif ($key == ord('s')) {
+                $self->on_scale_object_uniformly->() if $self->on_scale_object_uniformly;
+            } elsif ($key == ord('+')) {
+                $self->on_increase_objects->() if $self->on_increase_objects;
+            } elsif ($key == ord('-')) {
+                $self->on_decrease_objects->() if $self->on_decrease_objects;
+            } else {
+                $event->Skip;
+            }
+        }
+    });
     
     return $self;
 }
@@ -84,6 +122,36 @@ sub set_on_right_click {
     $self->on_right_click($cb);
 }
 
+sub set_on_rotate_object_left {
+    my ($self, $cb) = @_;
+    $self->on_rotate_object_left($cb);
+}
+
+sub set_on_rotate_object_right {
+    my ($self, $cb) = @_;
+    $self->on_rotate_object_right($cb);
+}
+
+sub set_on_scale_object_uniformly {
+    my ($self, $cb) = @_;
+    $self->on_scale_object_uniformly($cb);
+}
+
+sub set_on_increase_objects {
+    my ($self, $cb) = @_;
+    $self->on_increase_objects($cb);
+}
+
+sub set_on_decrease_objects {
+    my ($self, $cb) = @_;
+    $self->on_decrease_objects($cb);
+}
+
+sub set_on_remove_object {
+    my ($self, $cb) = @_;
+    $self->on_remove_object($cb);
+}
+
 sub set_on_instances_moved {
     my ($self, $cb) = @_;
     $self->{on_instances_moved} = $cb;