diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index d04bc97fa..255afc631 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,7 +59,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER) -#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_2_3_0_ALPHA1) +#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 7426eafc9..71053819d 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -271,10 +271,29 @@ void GCodeViewer::set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, m_buffers[id].visible = visible; } +unsigned int GCodeViewer::get_options_visibility_flags() const +{ + auto set_flag = [](unsigned int flags, unsigned int flag, bool active) { + return active ? (flags | (1 << flag)) : flags; + }; + + unsigned int flags = 0; + flags = set_flag(flags, 0, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel)); + flags = set_flag(flags, 1, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Retract)); + flags = set_flag(flags, 2, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Unretract)); + flags = set_flag(flags, 3, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Tool_change)); + flags = set_flag(flags, 4, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Color_change)); + flags = set_flag(flags, 5, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Pause_Print)); + flags = set_flag(flags, 6, is_toolpath_move_type_visible(GCodeProcessor::EMoveType::Custom_GCode)); + flags = set_flag(flags, 7, m_shells.visible); + flags = set_flag(flags, 8, is_legend_enabled()); + return flags; +} + void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) { auto is_flag_set = [flags](unsigned int flag) { - return (flags& (1 << flag)) != 0; + return (flags & (1 << flag)) != 0; }; set_toolpath_move_type_visible(GCodeProcessor::EMoveType::Travel, is_flag_set(0)); @@ -752,7 +771,7 @@ void GCodeViewer::render_legend() const ImDrawList* draw_list = ImGui::GetWindowDrawList(); - auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label) { + auto add_item = [draw_list, &imgui](const std::array& color, const std::string& label, std::function callback = nullptr) { float icon_size = ImGui::GetTextLineHeight(); ImVec2 pos = ImGui::GetCursorPos(); draw_list->AddRect({ pos.x, pos.y }, { pos.x + icon_size, pos.y + icon_size }, ICON_BORDER_COLOR, 0.0f, 0); @@ -762,7 +781,13 @@ void GCodeViewer::render_legend() const // draw text ImGui::Dummy({ icon_size, icon_size }); ImGui::SameLine(); - imgui.text(label); + if (callback != nullptr) + { + if (ImGui::MenuItem(label.c_str())) + callback(); + } + else + imgui.text(label); }; auto add_range = [this, draw_list, &imgui, add_item](const Extrusions::Range& range, unsigned int decimals) { @@ -811,7 +836,15 @@ void GCodeViewer::render_legend() const if (!visible) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); - add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role))); + add_item(Extrusion_Role_Colors[static_cast(role)], I18N::translate_utf8(ExtrusionEntity::role_to_string(role)), [this, role]() { + if (role < erCount) + { + m_extrusions.role_visibility_flags = is_visible(role) ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->update_preview_bottom_toolbar(); + } + }); + if (!visible) ImGui::PopStyleVar(); } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index be239e20c..a8816f7a1 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -189,7 +189,7 @@ private: std::array m_layers_z_range; std::vector m_roles; std::vector m_extruder_ids; - Extrusions m_extrusions; + mutable Extrusions m_extrusions; Shells m_shells; EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; @@ -227,7 +227,9 @@ public: bool is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const; void set_toolpath_move_type_visible(GCodeProcessor::EMoveType type, bool visible); + unsigned int get_toolpath_role_visibility_flags() const { return m_extrusions.role_visibility_flags; } void set_toolpath_role_visibility_flags(unsigned int flags) { m_extrusions.role_visibility_flags = flags; } + unsigned int get_options_visibility_flags() const; void set_options_visibility_from_flags(unsigned int flags); void set_layers_z_range(const std::array& layers_z_range) { m_layers_z_range = layers_z_range; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 152658b13..bbe53c5cd 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -646,8 +646,11 @@ public: void ensure_on_bed(unsigned int object_idx); #if ENABLE_GCODE_VIEWER + GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); } const std::vector& get_layers_zs() const; + unsigned int get_gcode_options_visibility_flags() const { return m_gcode_viewer.get_options_visibility_flags(); } void set_gcode_options_visibility_from_flags(unsigned int flags); + unsigned int get_toolpath_role_visibility_flags() const { return m_gcode_viewer.get_toolpath_role_visibility_flags(); } void set_toolpath_role_visibility_flags(unsigned int flags); void set_toolpath_view_type(GCodeViewer::EViewType type); void set_toolpaths_z_range(const std::array& range); diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index a66396b27..ebdc51c6b 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -301,21 +301,33 @@ void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, cons } } -int combochecklist_get_flags(wxComboCtrl* comboCtrl) +unsigned int combochecklist_get_flags(wxComboCtrl* comboCtrl) { - int flags = 0; + unsigned int flags = 0; - wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup); - if (popup != nullptr) - { - for (unsigned int i = 0; i < popup->GetCount(); ++i) - { - if (popup->IsChecked(i)) - flags |= 1 << i; - } - } + wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup); + if (popup != nullptr) + { + for (unsigned int i = 0; i < popup->GetCount(); ++i) + { + if (popup->IsChecked(i)) + flags |= 1 << i; + } + } - return flags; + return flags; +} + +void combochecklist_set_flags(wxComboCtrl* comboCtrl, unsigned int flags) +{ + wxCheckListBoxComboPopup* popup = wxDynamicCast(comboCtrl->GetPopupControl(), wxCheckListBoxComboPopup); + if (popup != nullptr) + { + for (unsigned int i = 0; i < popup->GetCount(); ++i) + { + popup->Check(i, (flags & (1 << i)) != 0); + } + } } AppConfig* get_app_config() diff --git a/src/slic3r/GUI/GUI.hpp b/src/slic3r/GUI/GUI.hpp index 6690b2120..cf133971e 100644 --- a/src/slic3r/GUI/GUI.hpp +++ b/src/slic3r/GUI/GUI.hpp @@ -54,8 +54,12 @@ void warning_catcher(wxWindow* parent, const wxString& message); void create_combochecklist(wxComboCtrl* comboCtrl, const std::string& text, const std::string& items); // Returns the current state of the items listed in the wxCheckListBoxComboPopup contained in the given wxComboCtrl, -// encoded inside an int. -int combochecklist_get_flags(wxComboCtrl* comboCtrl); +// encoded inside an unsigned int. +unsigned int combochecklist_get_flags(wxComboCtrl* comboCtrl); + +// Sets the current state of the items listed in the wxCheckListBoxComboPopup contained in the given wxComboCtrl, +// with the flags encoded in the given unsigned int. +void combochecklist_set_flags(wxComboCtrl* comboCtrl, unsigned int flags); // wxString conversions: diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 3e0d5cd5a..e84d1a9d5 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -222,6 +222,9 @@ Preview::Preview( : m_canvas_widget(nullptr) , m_canvas(nullptr) , m_double_slider_sizer(nullptr) +#if ENABLE_GCODE_VIEWER + , m_bottom_toolbar_sizer(nullptr) +#endif // ENABLE_GCODE_VIEWER , m_label_view_type(nullptr) , m_choice_view_type(nullptr) , m_label_show(nullptr) @@ -256,7 +259,9 @@ Preview::Preview( if (init(parent, bed, camera, view_toolbar, model)) #endif // ENABLE_NON_STATIC_CANVAS_MANAGER { +#if !ENABLE_GCODE_VIEWER show_hide_ui_elements("none"); +#endif // !ENABLE_GCODE_VIEWER load_print(); } } @@ -358,15 +363,21 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0); +#if ENABLE_GCODE_VIEWER + m_bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); + m_bottom_toolbar_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); + m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); + m_bottom_toolbar_sizer->AddSpacer(10); + m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxEXPAND | wxALL, 5); +#else wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); bottom_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); bottom_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL, 5); bottom_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); -#if ENABLE_GCODE_VIEWER - bottom_sizer->Add(m_combochecklist_options, 0, wxEXPAND | wxALL, 5); -#else bottom_sizer->AddSpacer(20); bottom_sizer->Add(m_checkbox_travel, 0, wxEXPAND | wxALL, 5); bottom_sizer->AddSpacer(10); @@ -381,8 +392,12 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(top_sizer, 1, wxALL | wxEXPAND, 0); +#if ENABLE_GCODE_VIEWER + main_sizer->Add(m_bottom_toolbar_sizer, 0, wxALL | wxEXPAND, 0); + main_sizer->Hide(m_bottom_toolbar_sizer); +#else main_sizer->Add(bottom_sizer, 0, wxALL | wxEXPAND, 0); - +#endif // ENABLE_GCODE_VIEWER SetSizer(main_sizer); SetMinSize(GetSize()); GetSizer()->SetSizeHints(this); @@ -480,6 +495,9 @@ void Preview::load_print(bool keep_z_range) else if (tech == ptSLA) load_print_as_sla(); +#if ENABLE_GCODE_VIEWER + update_bottom_toolbar(); +#endif // ENABLE_GCODE_VIEWER Layout(); } @@ -581,6 +599,7 @@ void Preview::unbind_event_handlers() #endif // ENABLE_GCODE_VIEWER } +#if !ENABLE_GCODE_VIEWER void Preview::show_hide_ui_elements(const std::string& what) { bool enable = (what == "full"); @@ -615,6 +634,7 @@ void Preview::show_hide_ui_elements(const std::string& what) m_label_view_type->Show(visible); m_choice_view_type->Show(visible); } +#endif // !ENABLE_GCODE_VIEWER void Preview::reset_sliders(bool reset_all) { @@ -661,11 +681,11 @@ void Preview::on_choice_view_type(wxCommandEvent& evt) void Preview::on_combochecklist_features(wxCommandEvent& evt) { - int flags = Slic3r::GUI::combochecklist_get_flags(m_combochecklist_features); + unsigned int flags = Slic3r::GUI::combochecklist_get_flags(m_combochecklist_features); #if ENABLE_GCODE_VIEWER - m_canvas->set_toolpath_role_visibility_flags(static_cast(flags)); + m_canvas->set_toolpath_role_visibility_flags(flags); #else - m_gcode_preview_data->extrusion.role_flags = (unsigned int)flags; + m_gcode_preview_data->extrusion.role_flags = flags; #endif // ENABLE_GCODE_VIEWER refresh_print(); } @@ -673,7 +693,7 @@ void Preview::on_combochecklist_features(wxCommandEvent& evt) #if ENABLE_GCODE_VIEWER void Preview::on_combochecklist_options(wxCommandEvent& evt) { - m_canvas->set_gcode_options_visibility_from_flags(static_cast(Slic3r::GUI::combochecklist_get_flags(m_combochecklist_options))); + m_canvas->set_gcode_options_visibility_from_flags(Slic3r::GUI::combochecklist_get_flags(m_combochecklist_options)); refresh_print(); } #else @@ -730,6 +750,17 @@ void Preview::update_view_type(bool slice_completed) } } +#if ENABLE_GCODE_VIEWER +void Preview::update_bottom_toolbar() +{ + combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags()); + combochecklist_set_flags(m_combochecklist_options, m_canvas->get_gcode_options_visibility_flags()); + + m_bottom_toolbar_sizer->Show(m_combochecklist_features, m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType); + m_bottom_toolbar_sizer->Layout(); +} +#endif // ENABLE_GCODE_VIEWER + void Preview::create_double_slider() { m_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100); @@ -1039,7 +1070,8 @@ void Preview::load_print_as_fff(bool keep_z_range) #if ENABLE_GCODE_VIEWER m_canvas->load_gcode_preview(*m_gcode_result); m_canvas->refresh_gcode_preview(*m_gcode_result, colors); - show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); + GetSizer()->Show(m_bottom_toolbar_sizer); + GetSizer()->Layout(); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); #endif // ENABLE_GCODE_VIEWER @@ -1048,7 +1080,8 @@ void Preview::load_print_as_fff(bool keep_z_range) // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); #if ENABLE_GCODE_VIEWER - show_hide_ui_elements("none"); + GetSizer()->Hide(m_bottom_toolbar_sizer); + GetSizer()->Layout(); #endif // ENABLE_GCODE_VIEWER } #if ENABLE_GCODE_VIEWER @@ -1097,7 +1130,12 @@ void Preview::load_print_as_sla() if (IsShown()) { m_canvas->load_sla_preview(); +#if ENABLE_GCODE_VIEWER + GetSizer()->Hide(m_bottom_toolbar_sizer); + GetSizer()->Layout(); +#else show_hide_ui_elements("none"); +#endif // ENABLE_GCODE_VIEWER if (n_layers > 0) update_sliders(zs); @@ -1132,6 +1170,5 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) } } - } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index c4ad4eb79..a7db054bc 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -91,6 +91,9 @@ class Preview : public wxPanel wxGLCanvas* m_canvas_widget; GLCanvas3D* m_canvas; wxBoxSizer* m_double_slider_sizer; +#if ENABLE_GCODE_VIEWER + wxBoxSizer* m_bottom_toolbar_sizer; +#endif // ENABLE_GCODE_VIEWER wxStaticText* m_label_view_type; wxChoice* m_choice_view_type; wxStaticText* m_label_show; @@ -172,6 +175,10 @@ public: bool is_loaded() const { return m_loaded; } +#if ENABLE_GCODE_VIEWER + void update_bottom_toolbar(); +#endif // ENABLE_GCODE_VIEWER + private: #if ENABLE_NON_STATIC_CANVAS_MANAGER bool init(wxWindow* parent, Model* model); @@ -182,7 +189,9 @@ private: void bind_event_handlers(); void unbind_event_handlers(); +#if !ENABLE_GCODE_VIEWER void show_hide_ui_elements(const std::string& what); +#endif // !ENABLE_GCODE_VIEWER void reset_sliders(bool reset_all); void update_sliders(const std::vector& layers_z, bool keep_z_range = false); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b64f705dd..861e0e55f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1570,6 +1570,9 @@ struct Plater::priv #endif // ENABLE_NON_STATIC_CANVAS_MANAGER bool init_view_toolbar(); +#if ENABLE_GCODE_VIEWER + void update_preview_bottom_toolbar(); +#endif // ENABLE_GCODE_VIEWER void reset_all_gizmos(); void update_ui_from_settings(); @@ -3765,6 +3768,13 @@ bool Plater::priv::init_view_toolbar() return true; } +#if ENABLE_GCODE_VIEWER +void Plater::priv::update_preview_bottom_toolbar() +{ + preview->update_bottom_toolbar(); +} +#endif // ENABLE_GCODE_VIEWER + bool Plater::priv::can_set_instance_to_object() const { const int obj_idx = get_selected_object_idx(); @@ -5313,6 +5323,13 @@ GLToolbar& Plater::get_view_toolbar() } #endif // ENABLE_NON_STATIC_CANVAS_MANAGER +#if ENABLE_GCODE_VIEWER +void Plater::update_preview_bottom_toolbar() +{ + p->update_preview_bottom_toolbar(); +} +#endif // ENABLE_GCODE_VIEWER + const Mouse3DController& Plater::get_mouse3d_controller() const { return p->mouse3d_controller; diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 2ac4f23c1..f4ca22578 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -310,6 +310,10 @@ public: GLToolbar& get_view_toolbar(); #endif // ENABLE_NON_STATIC_CANVAS_MANAGER +#if ENABLE_GCODE_VIEWER + void update_preview_bottom_toolbar(); +#endif // ENABLE_GCODE_VIEWER + const Mouse3DController& get_mouse3d_controller() const; Mouse3DController& get_mouse3d_controller();