From c29493a41b3ae51b370caab9f80ce0b16bae19ef Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 26 Nov 2018 10:56:07 +0100 Subject: [PATCH] imgui: Refactor, use in cut gizmo --- resources/icons/overlay/cut_hover.png | Bin 2812 -> 3563 bytes resources/icons/overlay/cut_off.png | Bin 2769 -> 2319 bytes resources/icons/overlay/cut_on.png | Bin 2447 -> 5342 bytes src/libslic3r/Model.cpp | 77 +++++++++----- src/libslic3r/Model.hpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 30 ++++-- src/slic3r/GUI/GLCanvas3D.hpp | 10 +- src/slic3r/GUI/GLGizmo.cpp | 91 ++++++++++------ src/slic3r/GUI/GLGizmo.hpp | 30 ++++-- src/slic3r/GUI/GUI_App.cpp | 20 ++-- src/slic3r/GUI/GUI_App.hpp | 11 +- src/slic3r/GUI/ImGuiWrapper.cpp | 144 +++++++++++++++++--------- src/slic3r/GUI/ImGuiWrapper.hpp | 34 ++++-- src/slic3r/GUI/Plater.cpp | 21 +++- src/slic3r/GUI/Plater.hpp | 2 +- 15 files changed, 315 insertions(+), 157 deletions(-) diff --git a/resources/icons/overlay/cut_hover.png b/resources/icons/overlay/cut_hover.png index 99dc4cf8dbef9bf88bc6fa0a903705c400a815ed..a9758cfd951050c271c45383bbc95011677a8055 100644 GIT binary patch delta 3562 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 diff --git a/resources/icons/overlay/cut_off.png b/resources/icons/overlay/cut_off.png index cd4f130e1a3b37318c8cbdfc5714f3989ef67b74..f64179cf81f153a9f17846cd2105e9930059fd28 100644 GIT binary patch delta 2308 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 qr>9~@ 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 delta 2411 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 diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index c10e90bdb..871ac9497 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -981,19 +981,25 @@ template static void cut_reset_transform(T *thing) { thing->set_offset(offset); } -ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z) +ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower) { // Clone the object to duplicate instances, materials etc. - ModelObject* upper = ModelObject::new_clone(*this); - ModelObject* lower = ModelObject::new_clone(*this); - upper->set_model(nullptr); - lower->set_model(nullptr); - upper->sla_support_points.clear(); - lower->sla_support_points.clear(); - upper->clear_volumes(); - lower->clear_volumes(); - upper->input_file = ""; - lower->input_file = ""; + ModelObject* upper = keep_upper ? ModelObject::new_clone(*this) : nullptr; + ModelObject* lower = keep_lower ? ModelObject::new_clone(*this) : nullptr; + + if (keep_upper) { + upper->set_model(nullptr); + upper->sla_support_points.clear(); + upper->clear_volumes(); + upper->input_file = ""; + } + + if (keep_lower) { + lower->set_model(nullptr); + lower->sla_support_points.clear(); + lower->clear_volumes(); + lower->input_file = ""; + } const auto instance_matrix = instances[instance]->get_matrix(true); @@ -1008,14 +1014,18 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z) const auto bb = instance_bounding_box(instance, true); z -= bb.min(2); - for (auto *instance : upper->instances) { cut_reset_transform(instance); } - for (auto *instance : lower->instances) { cut_reset_transform(instance); } + if (keep_upper) { + for (auto *instance : upper->instances) { cut_reset_transform(instance); } + } + if (keep_lower) { + for (auto *instance : lower->instances) { cut_reset_transform(instance); } + } for (ModelVolume *volume : volumes) { if (! volume->is_model_part()) { // don't cut modifiers - upper->add_volume(*volume); - lower->add_volume(*volume); + if (keep_upper) { upper->add_volume(*volume); } + if (keep_lower) { lower->add_volume(*volume); } } else { TriangleMesh upper_mesh, lower_mesh; @@ -1026,18 +1036,22 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z) TriangleMeshSlicer tms(&volume->mesh); tms.cut(z, &upper_mesh, &lower_mesh); - upper_mesh.repair(); - lower_mesh.repair(); - upper_mesh.reset_repair_stats(); - lower_mesh.reset_repair_stats(); + if (keep_upper) { + upper_mesh.repair(); + upper_mesh.reset_repair_stats(); + } + if (keep_lower) { + lower_mesh.repair(); + lower_mesh.reset_repair_stats(); + } - if (upper_mesh.facets_count() > 0) { + if (keep_upper && upper_mesh.facets_count() > 0) { ModelVolume* vol = upper->add_volume(upper_mesh); vol->name = volume->name; vol->config = volume->config; vol->set_material(volume->material_id(), *volume->material()); } - if (lower_mesh.facets_count() > 0) { + if (keep_lower && lower_mesh.facets_count() > 0) { ModelVolume* vol = lower->add_volume(lower_mesh); vol->name = volume->name; vol->config = volume->config; @@ -1046,12 +1060,25 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z) } } - upper->invalidate_bounding_box(); - lower->invalidate_bounding_box(); + if (keep_lower && rotate_lower) { + for (auto *instance : lower->instances) { + Geometry::Transformation tr; + tr.set_offset(instance->get_offset()); + tr.set_rotation({Geometry::deg2rad(180.0), 0.0, 0.0}); + instance->set_transformation(tr); + } + } ModelObjectPtrs res; - if (upper->volumes.size() > 0) { res.push_back(upper); } - if (lower->volumes.size() > 0) { res.push_back(lower); } + + if (keep_upper && upper->volumes.size() > 0) { + upper->invalidate_bounding_box(); + res.push_back(upper); + } + if (keep_lower && lower->volumes.size() > 0) { + lower->invalidate_bounding_box(); + res.push_back(lower); + } return res; } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index c288010d0..8b8a0f59b 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -238,7 +238,7 @@ public: size_t materials_count() const; size_t facets_count() const; bool needed_repair() const; - ModelObjectPtrs cut(size_t instance, coordf_t z); + ModelObjectPtrs cut(size_t instance, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false); void split(ModelObjectPtrs* new_objects); void repair(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ee3951f02..d54ec650c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2893,7 +2893,7 @@ void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const GLCanvas3D: curr->render_for_picking(selection); } -void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas) const +void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas, const GLCanvas3D::Selection& selection) const { if (!m_enabled) return; @@ -2903,17 +2903,19 @@ void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas) const ::glPushMatrix(); ::glLoadIdentity(); - _render_overlay(canvas); + _render_overlay(canvas, selection); ::glPopMatrix(); } +#ifndef ENABLE_IMGUI void GLCanvas3D::Gizmos::create_external_gizmo_widgets(wxWindow *parent) { for (auto &entry : m_gizmos) { entry.second->create_external_gizmo_widgets(parent); } } +#endif // not ENABLE_IMGUI void GLCanvas3D::Gizmos::_reset() { @@ -2926,7 +2928,7 @@ void GLCanvas3D::Gizmos::_reset() m_gizmos.clear(); } -void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas) const +void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas, const GLCanvas3D::Selection& selection) const { if (m_gizmos.empty()) return; @@ -3326,7 +3328,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) , m_moving(false) , m_color_by("volume") , m_reload_delayed(false) +#ifndef ENABLE_IMGUI , m_external_gizmo_widgets_parent(nullptr) +#endif // not ENABLE_IMGUI { if (m_canvas != nullptr) { @@ -3434,10 +3438,12 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) return false; } +#ifndef ENABLE_IMGUI if (m_external_gizmo_widgets_parent != nullptr) { m_gizmos.create_external_gizmo_widgets(m_external_gizmo_widgets_parent); m_canvas->GetParent()->Layout(); } +#endif // not ENABLE_IMGUI } if (!_init_toolbar()) @@ -3753,7 +3759,7 @@ void GLCanvas3D::render() set_tooltip(""); #if ENABLE_IMGUI - wxGetApp().get_imgui().new_frame(); + wxGetApp().imgui()->new_frame(); #endif // ENABLE_IMGUI // picking pass @@ -3799,7 +3805,7 @@ void GLCanvas3D::render() _render_layer_editing_overlay(); #if ENABLE_IMGUI - wxGetApp().get_imgui().render(); + wxGetApp().imgui()->render(); #endif // ENABLE_IMGUI m_canvas->SwapBuffers(); @@ -4462,7 +4468,13 @@ void GLCanvas3D::on_timer(wxTimerEvent& evt) void GLCanvas3D::on_mouse(wxMouseEvent& evt) { #if ENABLE_IMGUI - wxGetApp().get_imgui().update_mouse_data(evt); + auto imgui = wxGetApp().imgui(); + if (imgui->update_mouse_data(evt)) { + render(); + if (imgui->want_any_input()) { + return; + } + } #endif // ENABLE_IMGUI Point pos(evt.GetX(), evt.GetY()); @@ -4957,10 +4969,12 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip) const } } +#ifndef ENABLE_IMGUI void GLCanvas3D::set_external_gizmo_widgets_parent(wxWindow *parent) { m_external_gizmo_widgets_parent = parent; } +#endif // not ENABLE_IMGUI void GLCanvas3D::do_move() { @@ -5323,7 +5337,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h) return; #if ENABLE_IMGUI - wxGetApp().get_imgui().set_display_size((float)w, (float)h); + wxGetApp().imgui()->set_display_size((float)w, (float)h); #endif // ENABLE_IMGUI // ensures that this canvas is current @@ -5796,7 +5810,7 @@ void GLCanvas3D::_render_current_gizmo() const void GLCanvas3D::_render_gizmos_overlay() const { - m_gizmos.render_overlay(*this); + m_gizmos.render_overlay(*this, m_selection); } void GLCanvas3D::_render_toolbar() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d98a0c8f0..3a6759393 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -636,14 +636,16 @@ private: void render_current_gizmo(const Selection& selection) const; void render_current_gizmo_for_picking_pass(const Selection& selection) const; - void render_overlay(const GLCanvas3D& canvas) const; + void render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; +#ifndef ENABLE_IMGUI void create_external_gizmo_widgets(wxWindow *parent); +#endif // not ENABLE_IMGUI private: void _reset(); - void _render_overlay(const GLCanvas3D& canvas) const; + void _render_overlay(const GLCanvas3D& canvas, const Selection& selection) const; void _render_current_gizmo(const Selection& selection) const; float _get_total_overlay_height() const; @@ -732,7 +734,9 @@ private: GCodePreviewVolumeIndex m_gcode_preview_volume_index; +#ifndef ENABLE_IMGUI wxWindow *m_external_gizmo_widgets_parent; +#endif // not ENABLE_IMGUI void post_event(wxEvent &&event); void viewport_changed(); @@ -852,7 +856,9 @@ public: void set_tooltip(const std::string& tooltip) const; +#ifndef ENABLE_IMGUI void set_external_gizmo_widgets_parent(wxWindow *parent); +#endif // not ENABLE_IMGUI void do_move(); void do_rotate(); diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 03acdcbdd..ed2a6f2d2 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -170,6 +170,7 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent) #endif // ENABLE_GIZMOS_SHORTCUT , m_hover_id(-1) , m_dragging(false) + , m_imgui(wxGetApp().imgui()) { ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 3 * sizeof(float)); ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 3 * sizeof(float)); @@ -273,7 +274,9 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const } } +#ifndef ENABLE_IMGUI void GLGizmoBase::create_external_gizmo_widgets(wxWindow *parent) {} +#endif // not ENABLE_IMGUI void GLGizmoBase::set_tooltip(const std::string& tooltip) const { @@ -687,16 +690,16 @@ void GLGizmoRotate3D::on_render(const GLCanvas3D::Selection& selection) const } #if ENABLE_IMGUI -void GLGizmoRotate3D::on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) const +void GLGizmoRotate3D::on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) { Vec3d rotation(Geometry::rad2deg(m_gizmos[0].get_angle()), Geometry::rad2deg(m_gizmos[1].get_angle()), Geometry::rad2deg(m_gizmos[2].get_angle())); - std::string label = _("Rotation (deg)"); + wxString label = _(L("Rotation (deg)")); - wxGetApp().get_imgui().set_next_window_pos(x, y, ImGuiCond_Always); - wxGetApp().get_imgui().set_next_window_bg_alpha(0.5f); - wxGetApp().get_imgui().begin(label, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - wxGetApp().get_imgui().input_vec3("", rotation, 100.0f, "%.2f"); - wxGetApp().get_imgui().end(); + m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); + m_imgui->set_next_window_bg_alpha(0.5f); + m_imgui->begin(label, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->input_vec3("", rotation, 100.0f, "%.2f"); + m_imgui->end(); } #endif // ENABLE_IMGUI @@ -987,17 +990,16 @@ void GLGizmoScale3D::on_render_for_picking(const GLCanvas3D::Selection& selectio } #if ENABLE_IMGUI -void GLGizmoScale3D::on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) const +void GLGizmoScale3D::on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) { bool single_instance = selection.is_single_full_instance(); - Vec3d scale = single_instance ? 100.0 * selection.get_volume(*selection.get_volume_idxs().begin())->get_scaling_factor() : 100.0 * m_scale; - std::string label = _("Scale (%)"); + wxString label = _(L("Scale (%)")); - wxGetApp().get_imgui().set_next_window_pos(x, y, ImGuiCond_Always); - wxGetApp().get_imgui().set_next_window_bg_alpha(0.5f); - wxGetApp().get_imgui().begin(label, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - wxGetApp().get_imgui().input_vec3("", scale, 100.0f, "%.2f"); - wxGetApp().get_imgui().end(); + m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); + m_imgui->set_next_window_bg_alpha(0.5f); + m_imgui->begin(label, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->input_vec3("", m_scale, 100.0f, "%.2f"); + m_imgui->end(); } #endif // ENABLE_IMGUI @@ -1215,26 +1217,20 @@ void GLGizmoMove3D::on_render_for_picking(const GLCanvas3D::Selection& selection } #if ENABLE_IMGUI -void GLGizmoMove3D::on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) const +void GLGizmoMove3D::on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) { bool show_position = selection.is_single_full_instance(); const Vec3d& position = selection.get_bounding_box().center(); Vec3d displacement = show_position ? position : m_displacement; - std::string label = show_position ? _("Position (mm)") : _("Displacement (mm)"); + wxString label = show_position ? _(L("Position (mm)")) : _(L("Displacement (mm)")); - wxGetApp().get_imgui().set_next_window_pos(x, y, ImGuiCond_Always); - wxGetApp().get_imgui().set_next_window_bg_alpha(0.5f); - wxGetApp().get_imgui().begin(label, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); - wxGetApp().get_imgui().input_vec3("", displacement, 100.0f, "%.2f"); + m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); + m_imgui->set_next_window_bg_alpha(0.5f); + m_imgui->begin(label, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + m_imgui->input_vec3("", displacement, 100.0f, "%.2f"); - if (ImGui::Button("Test")) - { - std::cout << "WOW" << std::endl; - } - - - wxGetApp().get_imgui().end(); + m_imgui->end(); } #endif // ENABLE_IMGUI @@ -1932,9 +1928,15 @@ const std::array GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0 }; GLGizmoCut::GLGizmoCut(GLCanvas3D& parent) : GLGizmoBase(parent) , m_cut_z(0.0) +#ifndef ENABLE_IMGUI , m_panel(nullptr) +#endif // not ENABLE_IMGUI + , m_keep_upper(true) + , m_keep_lower(true) + , m_rotate_lower(false) {} +#ifndef ENABLE_IMGUI void GLGizmoCut::create_external_gizmo_widgets(wxWindow *parent) { wxASSERT(m_panel == nullptr); @@ -1949,9 +1951,10 @@ void GLGizmoCut::create_external_gizmo_widgets(wxWindow *parent) m_panel->Hide(); m_panel->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { - perform_cut(); + perform_cut(m_parent.get_selection()); }, wxID_OK); } +#endif // not ENABLE_IMGUI bool GLGizmoCut::on_init() { @@ -1992,10 +1995,12 @@ void GLGizmoCut::on_set_state() m_cut_z = 0.0; } +#ifndef ENABLE_IMGUI // Display or hide the extra panel if (m_panel != nullptr) { m_panel->display(get_state() == On); } +#endif // not ENABLE_IMGUI } bool GLGizmoCut::on_is_activable(const GLCanvas3D::Selection& selection) const @@ -2080,16 +2085,38 @@ void GLGizmoCut::on_render_for_picking(const GLCanvas3D::Selection& selection) c render_grabbers_for_picking(selection.get_bounding_box()); } -void GLGizmoCut::perform_cut() +#if ENABLE_IMGUI +void GLGizmoCut::on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) { - const auto &selection = m_parent.get_selection(); + m_imgui->set_next_window_pos(x, y, ImGuiCond_Always); + m_imgui->set_next_window_bg_alpha(0.5f); + m_imgui->begin(_(L("Cut")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); + ImGui::PushItemWidth(100.0f); + bool _value_changed = ImGui::InputDouble("Z", &m_cut_z, 0.0f, 0.0f, "%.2f"); + + m_imgui->checkbox(_(L("Keep upper part")), m_keep_upper); + m_imgui->checkbox(_(L("Keep lower part")), m_keep_lower); + m_imgui->checkbox(_(L("Rotate lower part upwards")), m_rotate_lower); + + const bool cut_clicked = m_imgui->button(_(L("Perform cut"))); + + m_imgui->end(); + + if (cut_clicked) { + perform_cut(selection); + } +} +#endif // ENABLE_IMGUI + +void GLGizmoCut::perform_cut(const GLCanvas3D::Selection& selection) +{ const auto instance_idx = selection.get_instance_idx(); const auto object_idx = selection.get_object_idx(); wxCHECK_RET(instance_idx >= 0 && object_idx >= 0, "GLGizmoCut: Invalid object selection"); - wxGetApp().plater()->cut(object_idx, instance_idx, m_cut_z); + wxGetApp().plater()->cut(object_idx, instance_idx, m_cut_z, m_keep_upper, m_keep_lower, m_rotate_lower); } double GLGizmoCut::calc_projection(const Linef3& mouse_ray) const diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index 146c04771..64bd71876 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -23,6 +23,7 @@ class ModelObject; namespace GUI { class GLCanvas3D; +class ImGuiWrapper; class GLGizmoBase { @@ -88,6 +89,7 @@ protected: float m_drag_color[3]; float m_highlight_color[3]; mutable std::vector m_grabbers; + ImGuiWrapper* m_imgui; public: explicit GLGizmoBase(GLCanvas3D& parent); @@ -135,10 +137,12 @@ public: void render(const GLCanvas3D::Selection& selection) const { on_render(selection); } void render_for_picking(const GLCanvas3D::Selection& selection) const { on_render_for_picking(selection); } +#ifndef ENABLE_IMGUI virtual void create_external_gizmo_widgets(wxWindow *parent); +#endif // not ENABLE_IMGUI #if ENABLE_IMGUI - void render_input_window(float x, float y, const GLCanvas3D::Selection& selection) const { on_render_input_window(x, y, selection); } + void render_input_window(float x, float y, const GLCanvas3D::Selection& selection) { on_render_input_window(x, y, selection); } #endif // ENABLE_IMGUI protected: @@ -160,7 +164,7 @@ protected: virtual void on_render_for_picking(const GLCanvas3D::Selection& selection) const = 0; #if ENABLE_IMGUI - virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) const {} + virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) {} #endif // ENABLE_IMGUI float picking_color_component(unsigned int id) const; @@ -301,7 +305,7 @@ protected: } #if ENABLE_IMGUI - virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) const; + virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection); #endif // ENABLE_IMGUI }; @@ -341,7 +345,7 @@ protected: virtual void on_render_for_picking(const GLCanvas3D::Selection& selection) const; #if ENABLE_IMGUI - virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) const; + virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection); #endif // ENABLE_IMGUI private: @@ -385,7 +389,7 @@ protected: virtual void on_render_for_picking(const GLCanvas3D::Selection& selection) const; #if ENABLE_IMGUI - virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) const; + virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection); #endif // ENABLE_IMGUI private: @@ -494,7 +498,9 @@ protected: }; +#ifndef ENABLE_IMGUI class GLGizmoCutPanel; +#endif // not ENABLE_IMGUI class GLGizmoCut : public GLGizmoBase { @@ -507,12 +513,21 @@ class GLGizmoCut : public GLGizmoBase double m_max_z; Vec3d m_drag_pos; Vec3d m_drag_center; + bool m_keep_upper; + bool m_keep_lower; + bool m_rotate_lower; +#ifndef ENABLE_IMGUI GLGizmoCutPanel *m_panel; +#endif // not ENABLE_IMGUI public: explicit GLGizmoCut(GLCanvas3D& parent); +#ifndef ENABLE_IMGUI virtual void create_external_gizmo_widgets(wxWindow *parent); +#endif // not ENABLE_IMGUI +#ifndef ENABLE_IMGUI +#endif // not ENABLE_IMGUI protected: virtual bool on_init(); @@ -524,8 +539,11 @@ protected: virtual void on_render(const GLCanvas3D::Selection& selection) const; virtual void on_render_for_picking(const GLCanvas3D::Selection& selection) const; +#if ENABLE_IMGUI + virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection); +#endif // ENABLE_IMGUI private: - void perform_cut(); + void perform_cut(const GLCanvas3D::Selection& selection); double calc_projection(const Linef3& mouse_ray) const; }; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 923d19443..0299e27e5 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -32,9 +32,6 @@ #include #include #include "SysInfoDialog.hpp" -#if ENABLE_IMGUI -#include -#endif // ENABLE_IMGUI namespace Slic3r { namespace GUI { @@ -58,11 +55,16 @@ const wxString file_wildcards[FT_SIZE] = { static std::string libslic3r_translate_callback(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str().data(); } IMPLEMENT_APP(GUI_App) + +GUI_App::GUI_App() + : wxApp() + , m_imgui(new ImGuiWrapper()) +{} + bool GUI_App::OnInit() { #if ENABLE_IMGUI - if (!m_imgui.init()) - return false; + wxCHECK_MSG(m_imgui->init(), false, "Failed to initialize ImGui"); #endif // ENABLE_IMGUI SetAppName("Slic3rPE-alpha"); @@ -185,14 +187,6 @@ bool GUI_App::OnInit() return true; } -#if ENABLE_IMGUI -int GUI_App::OnExit() -{ - m_imgui.shutdown(); - return 0; -} -#endif // ENABLE_IMGUI - unsigned GUI_App::get_colour_approx_luma(const wxColour &colour) { double r = colour.Red(); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 451623e42..27c300257 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -1,6 +1,7 @@ #ifndef slic3r_GUI_App_hpp_ #define slic3r_GUI_App_hpp_ +#include #include #include "PrintConfig.hpp" #include "MainFrame.hpp" @@ -86,15 +87,13 @@ class GUI_App : public wxApp wxLocale* m_wxLocale{ nullptr }; #if ENABLE_IMGUI - ImGuiWrapper m_imgui; + std::unique_ptr m_imgui; #endif // ENABLE_IMGUI public: bool OnInit() override; -#if ENABLE_IMGUI - int OnExit() override; -#endif // ENABLE_IMGUI - GUI_App() : wxApp() {} + + GUI_App(); unsigned get_colour_approx_luma(const wxColour &colour); void init_label_colours(); @@ -162,7 +161,7 @@ public: std::vector tabs_list; #if ENABLE_IMGUI - ImGuiWrapper& get_imgui() { return m_imgui; } + ImGuiWrapper* imgui() { return m_imgui.get(); } #endif // ENABLE_IMGUI }; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 98baf1b36..aa8b58406 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1,13 +1,19 @@ -#include "../../libslic3r/libslic3r.h" #include "ImGuiWrapper.hpp" -#include "Utils.hpp" +#include +#include +#include + +#include #include +#include #include -#include +#include "libslic3r/libslic3r.h" +#include "GUI.hpp" +#include "Utils.hpp" namespace Slic3r { namespace GUI { @@ -26,9 +32,16 @@ ImGuiWrapper::ImGuiWrapper() , m_attrib_location_position(0) , m_attrib_location_uv(0) , m_attrib_location_color(0) + , m_mouse_buttons(0) { } +ImGuiWrapper::~ImGuiWrapper() +{ + destroy_device_objects(); + ImGui::DestroyContext(); +} + bool ImGuiWrapper::init() { // Store GLSL version string so we can refer to it later in case we recreate shaders. Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure. @@ -45,27 +58,21 @@ bool ImGuiWrapper::init() ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); - ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "\\fonts\\NotoSans-Regular.ttf").c_str(), 18.0f); - if (font == nullptr) - { + ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf").c_str(), 18.0f); + if (font == nullptr) { font = io.Fonts->AddFontDefault(); if (font == nullptr) return false; } - else + else { m_fonts.insert(FontsMap::value_type("Noto Sans Regular 18", font)); + } io.IniFilename = nullptr; return true; } -void ImGuiWrapper::shutdown() -{ - destroy_device_objects(); - ImGui::DestroyContext(); -} - void ImGuiWrapper::set_display_size(float w, float h) { ImGuiIO& io = ImGui::GetIO(); @@ -73,7 +80,7 @@ void ImGuiWrapper::set_display_size(float w, float h) io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f); } -void ImGuiWrapper::update_mouse_data(wxMouseEvent& evt) +bool ImGuiWrapper::update_mouse_data(wxMouseEvent& evt) { ImGuiIO& io = ImGui::GetIO(); io.MousePos = ImVec2((float)evt.GetX(), (float)evt.GetY()); @@ -81,10 +88,10 @@ void ImGuiWrapper::update_mouse_data(wxMouseEvent& evt) io.MouseDown[1] = evt.RightDown(); io.MouseDown[2] = evt.MiddleDown(); - if (io.MouseDown[0]) - { - int a = 0; - } + unsigned buttons = evt.LeftDown() | evt.RightDown() << 1 | evt.MiddleDown() << 2; + bool res = buttons != m_mouse_buttons; + m_mouse_buttons = buttons; + return res; } void ImGuiWrapper::new_frame() @@ -97,9 +104,6 @@ void ImGuiWrapper::new_frame() void ImGuiWrapper::render() { - ImGuiIO& io = ImGui::GetIO(); - - ImGui::Render(); render_draw_data(ImGui::GetDrawData()); } @@ -114,22 +118,33 @@ void ImGuiWrapper::set_next_window_bg_alpha(float alpha) ImGui::SetNextWindowBgAlpha(alpha); } -bool ImGuiWrapper::begin(const std::string& name, int flags) +bool ImGuiWrapper::begin(const std::string &name, int flags) { return ImGui::Begin(name.c_str(), nullptr, (ImGuiWindowFlags)flags); } +bool ImGuiWrapper::begin(const wxString &name, int flags) +{ + return begin(into_u8(name), flags); +} + void ImGuiWrapper::end() { ImGui::End(); } -bool ImGuiWrapper::input_double(const std::string& label, double& value, const std::string& format) +bool ImGuiWrapper::button(const wxString &label) { - return ImGui::InputDouble(label.c_str(), &value, 0.0f, 0.0f, format.c_str()); + auto label_utf8 = into_u8(label); + return ImGui::Button(label_utf8.c_str()); } -bool ImGuiWrapper::input_vec3(const std::string& label, Vec3d& value, float width, const std::string& format) +bool ImGuiWrapper::input_double(const std::string &label, const double &value, const std::string &format) +{ + return ImGui::InputDouble(label.c_str(), const_cast(&value), 0.0f, 0.0f, format.c_str()); +} + +bool ImGuiWrapper::input_vec3(const std::string &label, const Vec3d &value, float width, const std::string &format) { bool value_changed = false; @@ -140,7 +155,7 @@ bool ImGuiWrapper::input_vec3(const std::string& label, Vec3d& value, float widt std::string item_label = (i == 0) ? "X" : ((i == 1) ? "Y" : "Z"); ImGui::PushID(i); ImGui::PushItemWidth(width); - value_changed |= ImGui::InputDouble(item_label.c_str(), &value(i), 0.0f, 0.0f, format.c_str()); + value_changed |= ImGui::InputDouble(item_label.c_str(), const_cast(&value(i)), 0.0f, 0.0f, format.c_str()); ImGui::PopID(); } ImGui::EndGroup(); @@ -148,6 +163,33 @@ bool ImGuiWrapper::input_vec3(const std::string& label, Vec3d& value, float widt return value_changed; } +bool ImGuiWrapper::checkbox(const wxString &label, bool &value) +{ + auto label_utf8 = into_u8(label); + return ImGui::Checkbox(label_utf8.c_str(), &value); +} + +bool ImGuiWrapper::want_mouse() const +{ + return ImGui::GetIO().WantCaptureMouse; +} + +bool ImGuiWrapper::want_keyboard() const +{ + return ImGui::GetIO().WantCaptureKeyboard; +} + +bool ImGuiWrapper::want_text_input() const +{ + return ImGui::GetIO().WantTextInput; +} + +bool ImGuiWrapper::want_any_input() const +{ + const auto io = ImGui::GetIO(); + return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput; +} + void ImGuiWrapper::create_device_objects() { // Backup GL state @@ -289,19 +331,19 @@ void ImGuiWrapper::create_device_objects() m_vert_handle = glCreateShader(GL_VERTEX_SHADER); glShaderSource(m_vert_handle, 2, vertex_shader_with_version, nullptr); glCompileShader(m_vert_handle); - check_shader(m_vert_handle, "vertex shader"); + wxASSERT(check_shader(m_vert_handle, "vertex shader")); const GLchar* fragment_shader_with_version[2] = { m_glsl_version_string.c_str(), fragment_shader }; m_frag_handle = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(m_frag_handle, 2, fragment_shader_with_version, nullptr); glCompileShader(m_frag_handle); - check_shader(m_frag_handle, "fragment shader"); + wxASSERT(check_shader(m_frag_handle, "fragment shader")); m_shader_handle = glCreateProgram(); glAttachShader(m_shader_handle, m_vert_handle); glAttachShader(m_shader_handle, m_frag_handle); glLinkProgram(m_shader_handle); - check_program(m_shader_handle, "shader program"); + wxASSERT(check_program(m_shader_handle, "shader program")); m_attrib_location_tex = glGetUniformLocation(m_shader_handle, "Texture"); m_attrib_location_proj_mtx = glGetUniformLocation(m_shader_handle, "ProjMtx"); @@ -351,36 +393,40 @@ bool ImGuiWrapper::check_program(unsigned int handle, const char* desc) GLint status = 0, log_length = 0; glGetProgramiv(handle, GL_LINK_STATUS, &status); glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); - if ((GLboolean)status == GL_FALSE) - fprintf(stderr, "ERROR: ImGuiWrapper::check_program(): failed to link %s! (with GLSL '%s')\n", desc, m_glsl_version_string); - if (log_length > 0) - { - ImVector buf; - buf.resize((int)(log_length + 1)); - glGetProgramInfoLog(handle, log_length, NULL, (GLchar*)buf.begin()); - fprintf(stderr, "%s\n", buf.begin()); + + if (status == GL_FALSE) { + BOOST_LOG_TRIVIAL(error) << boost::format("ImGuiWrapper::check_program(): failed to link %1% (GLSL `%1%`)") % desc, m_glsl_version_string; } - return (GLboolean)status == GL_TRUE; + + if (log_length > 0) { + std::vector buf(log_length + 1, 0); + glGetProgramInfoLog(handle, log_length, nullptr, buf.data()); + BOOST_LOG_TRIVIAL(error) << boost::format("ImGuiWrapper::check_program(): error log:\n%1%\n") % buf.data(); + } + + return status == GL_TRUE; } -bool ImGuiWrapper::check_shader(unsigned int handle, const char* desc) +bool ImGuiWrapper::check_shader(unsigned int handle, const char *desc) { GLint status = 0, log_length = 0; glGetShaderiv(handle, GL_COMPILE_STATUS, &status); glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); - if ((GLboolean)status == GL_FALSE) - fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc); - if (log_length > 0) - { - ImVector buf; - buf.resize((int)(log_length + 1)); - glGetShaderInfoLog(handle, log_length, NULL, (GLchar*)buf.begin()); - fprintf(stderr, "%s\n", buf.begin()); + + if (status == GL_FALSE) { + BOOST_LOG_TRIVIAL(error) << boost::format("ImGuiWrapper::check_shader(): failed to compile %1%") % desc; } - return (GLboolean)status == GL_TRUE; + + if (log_length > 0) { + std::vector buf(log_length + 1, 0); + glGetProgramInfoLog(handle, log_length, nullptr, buf.data()); + BOOST_LOG_TRIVIAL(error) << boost::format("ImGuiWrapper::check_program(): error log:\n%1%\n") % buf.data(); + } + + return status == GL_TRUE; } -void ImGuiWrapper::render_draw_data(ImDrawData* draw_data) +void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index ce795d954..aae7391d4 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -4,9 +4,13 @@ #include #include +#include + +#include "libslic3r/Point.hpp" + +class wxString; class wxMouseEvent; -class ImFont; -class ImDrawData; + namespace Slic3r { namespace GUI { @@ -30,14 +34,16 @@ class ImGuiWrapper FontsMap m_fonts; unsigned int m_font_texture; + unsigned m_mouse_buttons; + public: ImGuiWrapper(); + ~ImGuiWrapper(); bool init(); - void shutdown(); void set_display_size(float w, float h); - void update_mouse_data(wxMouseEvent& evt); + bool update_mouse_data(wxMouseEvent &evt); void new_frame(); void render(); @@ -45,19 +51,25 @@ public: void set_next_window_pos(float x, float y, int flag); void set_next_window_bg_alpha(float alpha); - bool begin(const std::string& name, int flags = 0); + bool begin(const std::string &name, int flags = 0); + bool begin(const wxString &name, int flags = 0); void end(); - bool input_double(const std::string& label, double& value, const std::string& format = "%.3f"); - - bool input_vec3(const std::string& label, Vec3d& value, float width, const std::string& format = "%.3f"); + bool button(const wxString &label); + bool input_double(const std::string &label, const double &value, const std::string &format = "%.3f"); + bool input_vec3(const std::string &label, const Vec3d &value, float width, const std::string &format = "%.3f"); + bool checkbox(const wxString &label, bool &value); + bool want_mouse() const; + bool want_keyboard() const; + bool want_text_input() const; + bool want_any_input() const; private: void create_device_objects(); void create_fonts_texture(); - bool check_program(unsigned int handle, const char* desc); - bool check_shader(unsigned int handle, const char* desc); - void render_draw_data(ImDrawData* draw_data); + bool check_program(unsigned int handle, const char *desc); + bool check_shader(unsigned int handle, const char *desc); + void render_draw_data(ImDrawData *draw_data); void destroy_device_objects(); void destroy_fonts_texture(); }; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d4b4f1e1c..6edf345b5 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -913,7 +913,9 @@ struct Plater::priv // GUI elements wxNotebook *notebook; Sidebar *sidebar; +#ifndef ENABLE_IMGUI wxPanel *panel3d; +#endif // not ENABLE_IMGUI wxGLCanvas *canvas3Dwidget; // TODO: Use GLCanvas3D when we can GLCanvas3D *canvas3D; Preview *preview; @@ -1039,8 +1041,12 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) })) , notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM)) , sidebar(new Sidebar(q)) +#ifdef ENABLE_IMGUI + , canvas3Dwidget(GLCanvas3DManager::create_wxglcanvas(notebook)) +#else , panel3d(new wxPanel(notebook, wxID_ANY)) , canvas3Dwidget(GLCanvas3DManager::create_wxglcanvas(panel3d)) +#endif // ENABLE_IMGUI , canvas3D(nullptr) , delayed_scene_refresh(false) #if ENABLE_NEW_MENU_LAYOUT @@ -1068,6 +1074,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) this->canvas3D = _3DScene::get_canvas(this->canvas3Dwidget); this->canvas3D->allow_multisample(GLCanvas3DManager::can_multisample()); +#ifdef ENABLE_IMGUI + notebook->AddPage(canvas3Dwidget, _(L("3D"))); +#else auto *panel3dsizer = new wxBoxSizer(wxVERTICAL); panel3dsizer->Add(canvas3Dwidget, 1, wxEXPAND); auto *panel_gizmo_widgets = new wxPanel(panel3d, wxID_ANY); @@ -1076,9 +1085,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) panel3d->SetSizer(panel3dsizer); notebook->AddPage(panel3d, _(L("3D"))); - preview = new GUI::Preview(notebook, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); }); canvas3D->set_external_gizmo_widgets_parent(panel_gizmo_widgets); +#endif // ENABLE_IMGUI + + preview = new GUI::Preview(notebook, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); }); // XXX: If have OpenGL this->canvas3D->enable_picking(true); @@ -1921,7 +1932,11 @@ void Plater::priv::fix_through_netfabb(const int obj_idx) void Plater::priv::on_notebook_changed(wxBookCtrlEvent&) { const auto current_id = notebook->GetCurrentPage()->GetId(); +#ifdef ENABLE_IMGUI + if (current_id == canvas3Dwidget->GetId()) { +#else if (current_id == panel3d->GetId()) { +#endif // ENABLE_IMGUI if (this->canvas3D->is_reload_delayed()) { // Delayed loading of the 3D scene. if (this->printer_technology == ptSLA) { @@ -2454,14 +2469,14 @@ bool Plater::is_selection_empty() const return p->get_selection().is_empty(); } -void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z) +void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower) { wxCHECK_RET(obj_idx < p->model.objects.size(), "obj_idx out of bounds"); auto *object = p->model.objects[obj_idx]; wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds"); - const auto new_objects = object->cut(instance_idx, z); + const auto new_objects = object->cut(instance_idx, z, keep_upper, keep_lower, rotate_lower); remove(obj_idx); p->load_model_objects(new_objects); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 87d85cbb4..04b0523f8 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -139,7 +139,7 @@ public: void set_number_of_copies(/*size_t num*/); bool is_selection_empty() const; - void cut(size_t obj_idx, size_t instance_idx, coordf_t z); + void cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false); // Note: empty path means "use the default" void export_gcode(boost::filesystem::path output_path = boost::filesystem::path());