From 9f3e7617d86cd5c53a161a606c113b1c2e2b658a Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Tue, 1 Sep 2020 20:08:59 +0200
Subject: [PATCH] Add Imgui popup for rotation gizmo under SLA

---
 src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 64 +++++++++++++++++++++++++
 src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 64 ++++++++++++++++++-------
 src/slic3r/GUI/ImGuiWrapper.cpp         |  4 +-
 3 files changed, 112 insertions(+), 20 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
index f3e565686..8365875d9 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
@@ -1,9 +1,15 @@
 // Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
 #include "GLGizmoRotate.hpp"
 #include "slic3r/GUI/GLCanvas3D.hpp"
+#include "slic3r/GUI/ImGuiWrapper.hpp"
 
 #include <GL/glew.h>
 
+#include "slic3r/GUI/GUI_App.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "libslic3r/PresetBundle.hpp"
+
+#include "libslic3r/SLA/Rotfinder.hpp"
 
 namespace Slic3r {
 namespace GUI {
@@ -194,6 +200,64 @@ void GLGizmoRotate::on_render_for_picking() const
     glsafe(::glPopMatrix());
 }
 
+GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper *   imgui,
+                                                    State &          state,
+                                                    const Alignment &alignment)
+    : m_imgui{imgui}
+{
+    imgui->begin(_L("Rotation"), ImGuiWindowFlags_NoMove |
+                                   ImGuiWindowFlags_AlwaysAutoResize |
+                                   ImGuiWindowFlags_NoCollapse);
+
+    // adjust window position to avoid overlap the view toolbar
+    float win_h = ImGui::GetWindowHeight();
+    float x = alignment.x, y = alignment.y;
+    y = std::min(y, alignment.bottom_limit - win_h);
+    ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always);
+
+    ImGui::SliderFloat(_L("Accuracy").c_str(), &state.accuracy, 0.01f, 1.f, "%.1f");
+
+    if (imgui->button(_L("Optimize orientation"))) {
+        std::cout << "Blip" << std::endl;
+    }
+
+    static const std::vector<std::string> options = {
+        _L("Least supports").ToStdString(),
+        _L("Suface quality").ToStdString()
+    };
+
+    if (imgui->combo(_L("Choose method"), options, state.method) ) {
+        std::cout << "method: " << state.method << std::endl;
+    }
+
+
+}
+
+GLGizmoRotate3D::RotoptimzeWindow::~RotoptimzeWindow()
+{
+    m_imgui->end();
+}
+
+void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limit)
+{
+    if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA)
+        return;
+
+//    m_rotoptimizewin_state.mobj = ;
+    RotoptimzeWindow popup{m_imgui, m_rotoptimizewin_state, {x, y, bottom_limit}};
+
+//    if ((last_h != win_h) || (last_y != y))
+//    {
+//        // ask canvas for another frame to render the window in the correct position
+//        m_parent.request_extra_frame();
+//        if (last_h != win_h)
+//            last_h = win_h;
+//        if (last_y != y)
+//            last_y = y;
+//    }
+
+}
+
 void GLGizmoRotate::render_circle() const
 {
     ::glBegin(GL_LINE_LOOP);
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp
index 7365a20c3..c547dfbc0 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp
@@ -52,12 +52,12 @@ public:
     std::string get_tooltip() const override;
 
 protected:
-    virtual bool on_init();
-    virtual std::string on_get_name() const { return ""; }
-    virtual void on_start_dragging();
-    virtual void on_update(const UpdateData& data);
-    virtual void on_render() const;
-    virtual void on_render_for_picking() const;
+    bool on_init() override;
+    std::string on_get_name() const override { return ""; }
+    void on_start_dragging() override;
+    void on_update(const UpdateData& data) override;
+    void on_render() const override;
+    void on_render_for_picking() const override;
 
 private:
     void render_circle() const;
@@ -94,46 +94,74 @@ public:
     }
 
 protected:
-    virtual bool on_init();
-    virtual std::string on_get_name() const;
-    virtual void on_set_state()
+    bool on_init() override;
+    std::string on_get_name() const override;
+    void on_set_state() override
     {
         for (GLGizmoRotate& g : m_gizmos)
             g.set_state(m_state);
     }
-    virtual void on_set_hover_id()
+    void on_set_hover_id() override
     {
         for (int i = 0; i < 3; ++i)
             m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
     }
-    virtual void on_enable_grabber(unsigned int id)
+    void on_enable_grabber(unsigned int id) override
     {
         if (id < 3)
             m_gizmos[id].enable_grabber(0);
     }
-    virtual void on_disable_grabber(unsigned int id)
+    void on_disable_grabber(unsigned int id) override
     {
         if (id < 3)
             m_gizmos[id].disable_grabber(0);
     }
-    virtual bool on_is_activable() const;
-    virtual void on_start_dragging();
-    virtual void on_stop_dragging();
-    virtual void on_update(const UpdateData& data)
+    bool on_is_activable() const override;
+    void on_start_dragging() override;
+    void on_stop_dragging() override;
+    void on_update(const UpdateData& data) override
     {
         for (GLGizmoRotate& g : m_gizmos)
         {
             g.update(data);
         }
     }
-    virtual void on_render() const;
-    virtual void on_render_for_picking() const
+    void on_render() const override;
+    void on_render_for_picking() const override
     {
         for (const GLGizmoRotate& g : m_gizmos)
         {
             g.render_for_picking();
         }
     }
+
+    void on_render_input_window(float x, float y, float bottom_limit) override;
+private:
+
+    class RotoptimzeWindow {
+        ImGuiWrapper *m_imgui = nullptr;
+
+    public:
+        struct State {
+            enum Metods { mMinSupportPoints, mLegacy };
+
+            float        accuracy = 1.f;
+            int          method   = mMinSupportPoints;
+            ModelObject *mobj     = nullptr;
+        };
+
+        struct Alignment { float x, y, bottom_limit; };
+
+        RotoptimzeWindow(ImGuiWrapper *imgui, State &settings, const Alignment &bottom_limit);
+        ~RotoptimzeWindow();
+
+        RotoptimzeWindow(const RotoptimzeWindow&) = delete;
+        RotoptimzeWindow(RotoptimzeWindow &&) = delete;
+        RotoptimzeWindow& operator=(const RotoptimzeWindow &) = delete;
+        RotoptimzeWindow& operator=(RotoptimzeWindow &&) = delete;
+    };
+
+    RotoptimzeWindow::State m_rotoptimizewin_state = {};
 };
 
 } // namespace GUI
diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp
index e839fdf9b..0fecc822d 100644
--- a/src/slic3r/GUI/ImGuiWrapper.cpp
+++ b/src/slic3r/GUI/ImGuiWrapper.cpp
@@ -425,10 +425,10 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector<std::string>&
     text(label);
     ImGui::SameLine();
 
-    int selection_out = -1;
+    int selection_out = selection;
     bool res = false;
 
-    const char *selection_str = selection < (int)options.size() ? options[selection].c_str() : "";
+    const char *selection_str = selection < int(options.size()) && selection >= 0 ? options[selection].c_str() : "";
     if (ImGui::BeginCombo("", selection_str)) {
         for (int i = 0; i < (int)options.size(); i++) {
             if (ImGui::Selectable(options[i].c_str(), i == selection)) {