diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm
index b12f84a94..afe79330d 100644
--- a/lib/Slic3r/GUI/3DScene.pm
+++ b/lib/Slic3r/GUI/3DScene.pm
@@ -761,41 +761,40 @@ sub set_viewport_from_scene {
 # zoom to volumes.
 sub select_view {
     my ($self, $direction) = @_;
-    my $dirvec;
-    if (ref($direction)) {
-        $dirvec = $direction;
-    } else {
-        if ($direction eq 'iso') {
-            $dirvec = VIEW_DEFAULT;
-        } elsif ($direction eq 'left') {
-            $dirvec = VIEW_LEFT;
-        } elsif ($direction eq 'right') {
-            $dirvec = VIEW_RIGHT;
-        } elsif ($direction eq 'top') {
-            $dirvec = VIEW_TOP;
-        } elsif ($direction eq 'bottom') {
-            $dirvec = VIEW_BOTTOM;
-        } elsif ($direction eq 'front') {
-            $dirvec = VIEW_FRONT;
-        } elsif ($direction eq 'rear') {
-            $dirvec = VIEW_REAR;
-        }
-    }
-    my $bb = $self->volumes_bounding_box;
-    if (! $bb->empty) {
 #==============================================================================================================================
-        Slic3r::GUI::_3DScene::set_camera_phi($self, $dirvec->[0]);
-        Slic3r::GUI::_3DScene::set_camera_theta($self, $dirvec->[1]);
-        
+    Slic3r::GUI::_3DScene::select_view($self, $direction);
+
+#    my $dirvec;
+#    if (ref($direction)) {
+#        $dirvec = $direction;
+#    } else {
+#        if ($direction eq 'iso') {
+#            $dirvec = VIEW_DEFAULT;
+#        } elsif ($direction eq 'left') {
+#            $dirvec = VIEW_LEFT;
+#        } elsif ($direction eq 'right') {
+#            $dirvec = VIEW_RIGHT;
+#        } elsif ($direction eq 'top') {
+#            $dirvec = VIEW_TOP;
+#        } elsif ($direction eq 'bottom') {
+#            $dirvec = VIEW_BOTTOM;
+#        } elsif ($direction eq 'front') {
+#            $dirvec = VIEW_FRONT;
+#        } elsif ($direction eq 'rear') {
+#            $dirvec = VIEW_REAR;
+#        }
+#    }
+#    my $bb = $self->volumes_bounding_box;
+#    if (! $bb->empty) {
 #        $self->_sphi($dirvec->[0]);
 #        $self->_stheta($dirvec->[1]);
 #        # Avoid gimball lock.
 #        $self->_stheta(GIMBALL_LOCK_THETA_MAX) if $self->_stheta > GIMBALL_LOCK_THETA_MAX;
 #        $self->_stheta(0) if $self->_stheta < 0;
+#        $self->on_viewport_changed->() if $self->on_viewport_changed;
+#        $self->Refresh;
+#    }
 #==============================================================================================================================
-        $self->on_viewport_changed->() if $self->on_viewport_changed;
-        $self->Refresh;
-    }
 }
 
 sub get_zoom_to_bounding_box_factor {
diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp
index c6effb0a9..ed2b7f8b8 100644
--- a/xs/src/slic3r/GUI/3DScene.cpp
+++ b/xs/src/slic3r/GUI/3DScene.cpp
@@ -1878,6 +1878,11 @@ void _3DScene::zoom_to_volumes(wxGLCanvas* canvas)
     s_canvas_mgr.zoom_to_volumes(canvas);
 }
 
+void _3DScene::select_view(wxGLCanvas* canvas, const std::string& direction)
+{
+    s_canvas_mgr.select_view(canvas, direction);
+}
+
 void _3DScene::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback)
 {
     s_canvas_mgr.register_on_viewport_changed_callback(canvas, callback);
diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp
index 5c603028d..5010d9c2c 100644
--- a/xs/src/slic3r/GUI/3DScene.hpp
+++ b/xs/src/slic3r/GUI/3DScene.hpp
@@ -582,6 +582,7 @@ public:
 
     static void zoom_to_bed(wxGLCanvas* canvas);
     static void zoom_to_volumes(wxGLCanvas* canvas);
+    static void select_view(wxGLCanvas* canvas, const std::string& direction);
 
     static void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
 
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp
index 487ffbc75..940a5b79c 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp
@@ -9,6 +9,15 @@
 static const bool TURNTABLE_MODE = true;
 static const float GIMBALL_LOCK_THETA_MAX = 180.0f;
 
+// phi / theta angles to orient the camera.
+static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f };
+static const float VIEW_LEFT[2] = { 90.0f, 90.0f };
+static const float VIEW_RIGHT[2] = { -90.0f, 90.0f };
+static const float VIEW_TOP[2] = { 0.0f, 0.0f };
+static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f };
+static const float VIEW_FRONT[2] = { 0.0f, 90.0f };
+static const float VIEW_REAR[2] = { 180.0f, 90.0f };
+
 namespace Slic3r {
 namespace GUI {
 
@@ -368,6 +377,37 @@ void GLCanvas3D::zoom_to_volumes()
     m_apply_zoom_to_volumes_filter = false;
 }
 
+void GLCanvas3D::select_view(const std::string& direction)
+{
+    const float* dir_vec = nullptr;
+
+    if (direction == "iso")
+        dir_vec = VIEW_DEFAULT;
+    else if (direction == "left")
+        dir_vec = VIEW_LEFT;
+    else if (direction == "right")
+        dir_vec = VIEW_RIGHT;
+    else if (direction == "top")
+        dir_vec = VIEW_TOP;
+    else if (direction == "bottom")
+        dir_vec = VIEW_BOTTOM;
+    else if (direction == "front")
+        dir_vec = VIEW_FRONT;
+    else if (direction == "rear")
+        dir_vec = VIEW_REAR;
+
+    if ((dir_vec != nullptr) && !empty(volumes_bounding_box()))
+    {
+        m_camera.set_phi(dir_vec[0]);
+        m_camera.set_theta(dir_vec[1]);
+
+        m_on_viewport_changed_callback.call();
+        
+        if (m_canvas != nullptr)
+            m_canvas->Refresh();
+    }
+}
+
 void GLCanvas3D::register_on_viewport_changed_callback(void* callback)
 {
     if (callback != nullptr)
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp
index d32421542..7568dec39 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp
@@ -138,6 +138,7 @@ public:
 
     void zoom_to_bed();
     void zoom_to_volumes();
+    void select_view(const std::string& direction);
 
     void register_on_viewport_changed_callback(void* callback);
 
diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp
index 9bde6210d..f5b76fe60 100644
--- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp
+++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp
@@ -328,6 +328,13 @@ void GLCanvas3DManager::zoom_to_volumes(wxGLCanvas* canvas)
         it->second->zoom_to_volumes();
 }
 
+void GLCanvas3DManager::select_view(wxGLCanvas* canvas, const std::string& direction)
+{
+    CanvasesMap::iterator it = _get_canvas(canvas);
+    if (it != m_canvases.end())
+        it->second->select_view(direction);
+}
+
 void GLCanvas3DManager::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback)
 {
     CanvasesMap::iterator it = _get_canvas(canvas);
diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp
index 4edf97dd6..c1ce8048c 100644
--- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp
+++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp
@@ -92,6 +92,7 @@ public:
 
     void zoom_to_bed(wxGLCanvas* canvas);
     void zoom_to_volumes(wxGLCanvas* canvas);
+    void select_view(wxGLCanvas* canvas, const std::string& direction);
 
     void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
 
diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp
index ee1a94cc8..7211cc513 100644
--- a/xs/xsp/GUI_3DScene.xsp
+++ b/xs/xsp/GUI_3DScene.xsp
@@ -387,6 +387,13 @@ zoom_to_volumes(canvas)
     CODE:
         _3DScene::zoom_to_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
     
+void
+select_view(canvas, direction)
+        SV          *canvas;
+        std::string direction;
+    CODE:
+        _3DScene::select_view((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), direction);
+    
 void
 register_on_viewport_changed_callback(canvas, callback)
         SV *canvas;