From 2f205dd77b8bc21d9c20f547be36639f68666aa0 Mon Sep 17 00:00:00 2001
From: Enrico Turri <enricoturri@seznam.cz>
Date: Fri, 22 Feb 2019 11:34:37 +0100
Subject: [PATCH 1/2] Fix of #1853 (Translation of volumes in side view)

---
 src/slic3r/GUI/GLCanvas3D.cpp | 39 +++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 599831d74..e0f66fb04 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -5088,11 +5088,42 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
 #endif // ENABLE_MOVE_MIN_THRESHOLD
             m_mouse.dragging = true;
 
-            // Get new position at the same Z of the initial click point.
-            float z0 = 0.0f;
-            float z1 = 1.0f;
+            Vec3d cur_pos = m_mouse.drag.start_position_3D;
             // we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag
-            Vec3d cur_pos = m_selection.contains_volume(m_hover_volume_id) ? Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D(2)) : m_mouse.drag.start_position_3D;
+            if (m_selection.contains_volume(m_hover_volume_id))
+            {
+                if (m_camera.get_theta() == 90.0f)
+                {
+                    // side view -> move selected volumes orthogonally to camera view direction
+                    Linef3 ray = mouse_ray(pos);
+                    Vec3d dir = ray.unit_vector();
+                    // finds the intersection of the mouse ray with the plane parallel to the camera viewport and passing throught the starting position
+                    // use ray-plane intersection see i.e. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection algebric form
+                    // in our case plane normal and ray direction are the same (orthogonal view)
+                    // when moving to perspective camera the negative z unit axis of the camera needs to be transformed in world space and used as plane normal
+                    Vec3d inters = ray.a + (m_mouse.drag.start_position_3D - ray.a).dot(dir) / dir.squaredNorm() * dir;
+                    // vector from the starting position to the found intersection
+                    Vec3d inters_vec = inters - m_mouse.drag.start_position_3D;
+
+                    // get the view matrix back from opengl
+                    GLfloat matrix[16];
+                    ::glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
+                    Vec3d camera_right((double)matrix[0], (double)matrix[4], (double)matrix[8]);
+
+                    // finds projection of the vector along the camera right axis
+                    double projection = inters_vec.dot(camera_right);
+
+                    cur_pos = m_mouse.drag.start_position_3D + projection * camera_right;
+                }
+                else
+                {
+                    // Generic view
+                    // Get new position at the same Z of the initial click point.
+                    float z0 = 0.0f;
+                    float z1 = 1.0f;
+                    cur_pos = Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D(2));
+                }
+            }
 
             m_regenerate_volumes = false;
             m_selection.translate(cur_pos - m_mouse.drag.start_position_3D);

From a398cbf24c153e5f78b30dde4a9137befd2980dc Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Tue, 26 Feb 2019 15:51:23 +0100
Subject: [PATCH 2/2] Fixed "color print" issues (SPE-836)

---
 src/slic3r/GUI/GUI_Preview.cpp  | 17 ++++++++++++++--
 src/slic3r/GUI/wxExtensions.cpp | 35 +++++++++++++++++++++------------
 src/slic3r/GUI/wxExtensions.hpp |  2 ++
 3 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp
index 25872fc1f..0dec0976d 100644
--- a/src/slic3r/GUI/GUI_Preview.cpp
+++ b/src/slic3r/GUI/GUI_Preview.cpp
@@ -637,12 +637,25 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool for
 
     const auto& config = wxGetApp().preset_bundle->project_config;
     const std::vector<double> &ticks_from_config = (config.option<ConfigOptionFloats>("colorprint_heights"))->values;
+
+    // Switch to the "Feature type" from the very beginning of a new object slicing after deleting of the old one
+    if (ticks_from_config.empty())
+    {
+        const int& type = m_choice_view_type->FindString(_(L("Feature type")));
+        if (m_choice_view_type->GetSelection() != type) {
+            m_choice_view_type->SetSelection(type);
+            if (0 <= type && type < int(GCodePreviewData::Extrusion::Num_View_Types))
+                m_gcode_preview_data->extrusion.view_type = GCodePreviewData::Extrusion::EViewType(type);
+            m_preferred_color_mode = "feature";
+            reload_print();
+        }
+    }
     m_slider->SetTicksValues(ticks_from_config);
 
     bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF);
     if (color_print_enable) {
-        const auto& config = wxGetApp().preset_bundle->full_config();
-        if (config.opt<ConfigOptionFloats>("nozzle_diameter")->values.size() > 1) 
+        const auto& cfg = wxGetApp().preset_bundle->full_config();
+        if (cfg.opt<ConfigOptionFloats>("nozzle_diameter")->values.size() > 1) 
             color_print_enable = false;
     }
     m_slider->EnableTickManipulation(color_print_enable);
diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp
index 7eb600a52..8afb54752 100644
--- a/src/slic3r/GUI/wxExtensions.cpp
+++ b/src/slic3r/GUI/wxExtensions.cpp
@@ -1432,9 +1432,11 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent,
     m_min_value(minValue), m_max_value(maxValue),
     m_style(style == wxSL_HORIZONTAL || style == wxSL_VERTICAL ? style: wxSL_HORIZONTAL)
 {
-#ifndef __WXOSX__ // SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX
-    SetDoubleBuffered(true);
+#ifdef __WXOSX__ 
+    is_osx = true;
 #endif //__WXOSX__
+    if (!is_osx)
+        SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX
 
     m_bmp_thumb_higher = wxBitmap(create_scaled_bitmap(style == wxSL_HORIZONTAL ? "right_half_circle.png"   : "up_half_circle.png"));
     m_bmp_thumb_lower  = wxBitmap(create_scaled_bitmap(style == wxSL_HORIZONTAL ? "left_half_circle.png"    : "down_half_circle.png"));
@@ -1480,6 +1482,10 @@ PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent,
 
     line_pens = { &DARK_GREY_PEN, &GREY_PEN, &LIGHT_GREY_PEN };
     segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN };
+
+    wxPaintDC dc(this);
+    const wxFont& font = dc.GetFont();
+    m_font = is_osx ? font.Smaller().Smaller() : font.Smaller();
 }
 
 int PrusaDoubleSlider::GetActiveValue() const
@@ -1494,7 +1500,9 @@ wxSize PrusaDoubleSlider::DoGetBestSize() const
     const wxSize size = wxControl::DoGetBestSize();
     if (size.x > 1 && size.y > 1)
         return size;
-    const int new_size = is_horizontal() ? 6 * Slic3r::GUI::wxGetApp().em_unit() : 8 * Slic3r::GUI::wxGetApp().em_unit();
+    const int new_size = is_horizontal() ? 
+                         (is_osx ? 8 : 6) * Slic3r::GUI::wxGetApp().em_unit() :
+                         (is_osx ? 10 : 8) * Slic3r::GUI::wxGetApp().em_unit();
     return wxSize(new_size, new_size);
 }
 
@@ -1558,7 +1566,7 @@ void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const in
     wxCoord line_end_y = is_horizontal() ? height*0.5 - 1 : height - SLIDER_MARGIN + 1;
 
     wxCoord segm_beg_x = is_horizontal() ? lower_pos : width*0.5 - 1;
-    wxCoord segm_beg_y = is_horizontal() ? height*0.5 - 1 : lower_pos-1;
+    wxCoord segm_beg_y = is_horizontal() ? height*0.5 - 1 : lower_pos/*-1*/;
     wxCoord segm_end_x = is_horizontal() ? higher_pos : width*0.5 - 1;
     wxCoord segm_end_y = is_horizontal() ? height*0.5 - 1 : higher_pos-1;
 
@@ -1619,8 +1627,11 @@ std::vector<double> PrusaDoubleSlider::GetTicksValues() const
     std::vector<double> values;
 
     if (!m_values.empty())
-        for (auto tick : m_ticks)
+        for (auto tick : m_ticks) {
+            if (tick > m_values.size())
+                break;
             values.push_back(m_values[tick].second);
+        }
 
     return values;
 }
@@ -1673,9 +1684,7 @@ void PrusaDoubleSlider::render()
     draw_focus_rect();
 
     wxPaintDC dc(this);
-    wxFont font = dc.GetFont();
-    const wxFont smaller_font = font.Smaller();
-    dc.SetFont(smaller_font);
+    dc.SetFont(m_font);
 
     const wxCoord lower_pos = get_position_from_value(m_lower_value);
     const wxCoord higher_pos = get_position_from_value(m_higher_value);
@@ -1727,8 +1736,8 @@ void PrusaDoubleSlider::draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, c
     if (m_selection == selection) {
         //draw info line
         dc.SetPen(DARK_ORANGE_PEN);
-        const wxPoint pt_beg = is_horizontal() ? wxPoint(pos.x, pos.y - m_thumb_size.y) : wxPoint(pos.x - m_thumb_size.x, pos.y - 1);
-        const wxPoint pt_end = is_horizontal() ? wxPoint(pos.x, pos.y + m_thumb_size.y) : wxPoint(pos.x + m_thumb_size.x, pos.y - 1);
+        const wxPoint pt_beg = is_horizontal() ? wxPoint(pos.x, pos.y - m_thumb_size.y) : wxPoint(pos.x - m_thumb_size.x, pos.y/* - 1*/);
+        const wxPoint pt_end = is_horizontal() ? wxPoint(pos.x, pos.y + m_thumb_size.y) : wxPoint(pos.x + m_thumb_size.x, pos.y/* - 1*/);
         dc.DrawLine(pt_beg, pt_end);
 
         //draw action icon
@@ -1779,7 +1788,7 @@ void PrusaDoubleSlider::draw_thumb_item(wxDC& dc, const wxPoint& pos, const Sele
         }
         else {
             x_draw = pos.x - int(0.5*m_thumb_size.x);
-            y_draw = pos.y;
+            y_draw = pos.y+1;
         }
     }
     else{
@@ -1850,9 +1859,9 @@ void PrusaDoubleSlider::draw_ticks(wxDC& dc)
         const wxCoord pos = get_position_from_value(tick);
 
         is_horizontal() ?   dc.DrawLine(pos, mid-14, pos, mid-9) :
-                            dc.DrawLine(mid - 14, pos - 1, mid - 9, pos - 1);
+                            dc.DrawLine(mid - 14, pos/* - 1*/, mid - 9, pos/* - 1*/);
         is_horizontal() ?   dc.DrawLine(pos, mid+14, pos, mid+9) :
-                            dc.DrawLine(mid + 14, pos - 1, mid + 9, pos - 1);
+                            dc.DrawLine(mid + 14, pos/* - 1*/, mid + 9, pos/* - 1*/);
     }
 }
 
diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp
index 22884bff4..e0bd5d091 100644
--- a/src/slic3r/GUI/wxExtensions.hpp
+++ b/src/slic3r/GUI/wxExtensions.hpp
@@ -791,6 +791,8 @@ protected:
     double      get_double_value(const SelectedSlider& selection);
 
 private:
+    bool        is_osx { false };
+    wxFont      m_font;
     int         m_min_value;
     int         m_max_value;
     int         m_lower_value;