diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index c358cd9184..36ba68c45e 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -24,7 +24,9 @@ class Print; class PrintObject; class ModelObject; class GCode; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER enum class SlicingMode : uint32_t; // Print step IDs for keeping track of the print state. diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c22e504dff..8ce01a3530 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -55,6 +55,7 @@ // Enable G-Code viewer #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1) +#define ENABLE_GCODE_USE_WXWIDGETS_SLIDER (1 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index 91ebc1372c..22a99951ff 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -17,7 +17,9 @@ namespace Slic3r { class DynamicPrintConfig; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER class Model; class SLAPrint; class SL1Archive; diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 4732ff2613..021d73882e 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -20,7 +20,9 @@ #include #include #include +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #include +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #include #include @@ -408,22 +410,22 @@ void Control::render() // draw line draw_scroll_line(dc, lower_pos, higher_pos); - //draw color print ticks + // draw color print ticks draw_ticks(dc); // draw both sliders draw_thumbs(dc, lower_pos, higher_pos); - //draw lock/unlock + // draw lock/unlock draw_one_layer_icon(dc); - //draw revert bitmap (if it's shown) + // draw revert bitmap (if it's shown) draw_revert_icon(dc); - //draw cog bitmap (if it's shown) + // draw cog bitmap (if it's shown) draw_cog_icon(dc); - //draw mouse position + // draw mouse position draw_tick_on_mouse_position(dc); } @@ -535,10 +537,21 @@ wxString Control::get_label(int tick) const if (value >= m_values.size()) return "ErrVal"; - const wxString str = m_values.empty() ? - wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None) : - wxNumberFormatter::ToString(m_values[value], 2, wxNumberFormatter::Style_None); - return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value+1); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_draw_mode == dmSequentialGCodeView) + return wxString::Format("%d", static_cast(m_values[value])); + else { + const wxString str = m_values.empty() ? + wxString::Format("%.*f", 2, m_label_koef * value) : + wxString::Format("%.*f", 2, m_values[value]); + return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1); + } +#else + const wxString str = m_values.empty() ? + wxNumberFormatter::ToString(m_label_koef * value, 2, wxNumberFormatter::Style_None) : + wxNumberFormatter::ToString(m_values[value], 2, wxNumberFormatter::Style_None); + return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER } void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side/*=true*/) const @@ -779,6 +792,11 @@ void Control::draw_colored_band(wxDC& dc) void Control::draw_one_layer_icon(wxDC& dc) { +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_draw_mode == dmSequentialGCodeView) + return; +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + const wxBitmap& icon = m_is_one_layer ? m_focus == fiOneLayerIcon ? m_bmp_one_layer_lock_off.bmp() : m_bmp_one_layer_lock_on.bmp() : m_focus == fiOneLayerIcon ? m_bmp_one_layer_unlock_off.bmp() : m_bmp_one_layer_unlock_on.bmp(); @@ -1284,7 +1302,11 @@ void Control::OnWheel(wxMouseEvent& event) ssLower : ssHigher; } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + move_current_thumb((m_draw_mode == dmSequentialGCodeView) ? event.GetWheelRotation() < 0 : event.GetWheelRotation() > 0); +#else move_current_thumb(event.GetWheelRotation() > 0); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER } void Control::OnKeyDown(wxKeyEvent &event) @@ -1306,20 +1328,34 @@ void Control::OnKeyDown(wxKeyEvent &event) UseDefaultColors(false); else if (is_horizontal()) { - if (key == WXK_LEFT || key == WXK_RIGHT) - move_current_thumb(key == WXK_LEFT); - else if (key == WXK_UP || key == WXK_DOWN) { - m_selection = key == WXK_UP ? ssHigher : ssLower; - Refresh(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_is_focused) + { +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (key == WXK_LEFT || key == WXK_RIGHT) + move_current_thumb(key == WXK_LEFT); + else if (key == WXK_UP || key == WXK_DOWN) { + m_selection = key == WXK_UP ? ssHigher : ssLower; + Refresh(); + } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER } - } else { - if (key == WXK_LEFT || key == WXK_RIGHT) { - m_selection = key == WXK_LEFT ? ssHigher : ssLower; - Refresh(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_is_focused) + { +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (key == WXK_LEFT || key == WXK_RIGHT) { + m_selection = key == WXK_LEFT ? ssHigher : ssLower; + Refresh(); + } + else if (key == WXK_UP || key == WXK_DOWN) + move_current_thumb(key == WXK_UP); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER } - else if (key == WXK_UP || key == WXK_DOWN) - move_current_thumb(key == WXK_UP); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER } event.Skip(); // !Needed to have EVT_CHAR generated as well diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index 36bff17e94..a17fb2b6fa 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -73,6 +73,9 @@ enum DrawMode dmRegular, dmSlaPrint, dmSequentialFffPrint, +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + dmSequentialGCodeView, +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER }; using t_mode = CustomGCode::Mode; @@ -211,6 +214,9 @@ public: void SetTicksValues(const Slic3r::CustomGCode::Info &custom_gcode_per_print_z); void SetDrawMode(bool is_sla_print, bool is_sequential_print); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void SetDrawMode(DrawMode mode) { m_draw_mode = mode; } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER void SetManipulationMode(t_mode mode) { m_mode = mode; } t_mode GetManipulationMode() const { return m_mode; } @@ -223,7 +229,7 @@ public: bool is_higher_at_max() const { return m_higher_value == m_max_value; } bool is_full_span() const { return this->is_lower_at_min() && this->is_higher_at_max(); } - void OnPaint(wxPaintEvent& ) { render();} + void OnPaint(wxPaintEvent& ) { render(); } void OnLeftDown(wxMouseEvent& event); void OnMotion(wxMouseEvent& event); void OnLeftUp(wxMouseEvent& event); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index aa188cae3f..acf1da4c71 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -324,7 +324,9 @@ void GCodeViewer::render() const m_sequential_view.marker.render(); render_shells(); render_legend(); +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER render_sequential_bar(); +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS render_statistics(); #endif // ENABLE_GCODE_VIEWER_STATISTICS @@ -381,6 +383,16 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags) enable_legend(is_flag_set(9)); } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void GCodeViewer::set_layers_z_range(const std::array& layers_z_range) +{ + bool keep_sequential_current = layers_z_range[1] <= m_layers_z_range[1]; + m_layers_z_range = layers_z_range; + refresh_render_paths(keep_sequential_current); + wxGetApp().plater()->update_preview_horz_slider(); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + bool GCodeViewer::init_shaders() { unsigned char begin_id = buffer_id(GCodeProcessor::EMoveType::Retract); @@ -1147,6 +1159,7 @@ void GCodeViewer::render_legend() const ImGui::PopStyleVar(); } +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER void GCodeViewer::render_sequential_bar() const { static const float MARGIN = 125.0f; @@ -1231,6 +1244,7 @@ void GCodeViewer::render_sequential_bar() const imgui.end(); ImGui::PopStyleVar(); } +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS void GCodeViewer::render_statistics() const diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 6f3ca47dba..a4ac3358d2 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -149,6 +149,7 @@ class GCodeViewer void reset_ranges() { ranges.reset(); } }; +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER struct SequentialView { class Marker @@ -182,6 +183,7 @@ class GCodeViewer Vec3f current_position{ Vec3f::Zero() }; Marker marker; }; +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS struct Statistics @@ -229,6 +231,42 @@ class GCodeViewer #endif // ENABLE_GCODE_VIEWER_STATISTICS public: +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + struct SequentialView + { + class Marker + { + GL_Model m_model; + Transform3f m_world_transform; + std::array m_color{ 1.0f, 1.0f, 1.0f, 1.0f }; + bool m_visible{ false }; + Shader m_shader; + + public: + void init(); + + const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } + + void set_world_transform(const Transform3f& transform) { m_world_transform = transform; } + void set_color(const std::array& color) { m_color = color; } + + bool is_visible() const { return m_visible; } + void set_visible(bool visible) { m_visible = visible; } + + void render() const; + + private: + void init_shader(); + }; + + unsigned int first{ 0 }; + unsigned int last{ 0 }; + unsigned int current{ 0 }; + Vec3f current_position{ Vec3f::Zero() }; + Marker marker; + }; +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + enum class EViewType : unsigned char { FeatureType, @@ -284,6 +322,11 @@ public: const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; } const std::vector& get_layers_zs() const { return m_layers_zs; }; +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + const SequentialView& get_sequential_view() const { return m_sequential_view; } + void update_sequential_view_current(unsigned int low, unsigned int high) { m_sequential_view.current = high; refresh_render_paths(true); } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + EViewType get_view_type() const { return m_view_type; } void set_view_type(EViewType type) { if (type == EViewType::Count) @@ -298,12 +341,16 @@ public: 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); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void set_layers_z_range(const std::array& layers_z_range); +#else void set_layers_z_range(const std::array& layers_z_range) { bool keep_sequential_current = layers_z_range[1] <= m_layers_z_range[1]; m_layers_z_range = layers_z_range; refresh_render_paths(keep_sequential_current); } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER bool is_legend_enabled() const { return m_legend_enabled; } void enable_legend(bool enable) { m_legend_enabled = enable; } @@ -316,7 +363,9 @@ private: void render_toolpaths() const; void render_shells() const; void render_legend() const; +#if !ENABLE_GCODE_USE_WXWIDGETS_SLIDER void render_sequential_bar() const; +#endif // !ENABLE_GCODE_USE_WXWIDGETS_SLIDER #if ENABLE_GCODE_VIEWER_STATISTICS void render_statistics() const; #endif // ENABLE_GCODE_VIEWER_STATISTICS diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 3e7296e139..d4df60ad2a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -42,7 +42,9 @@ namespace Slic3r { class Bed3D; struct Camera; class BackgroundSlicingProcess; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER struct ThumbnailData; struct SlicingParameters; enum LayerHeightEditActionType : unsigned int; @@ -551,6 +553,10 @@ public: #if ENABLE_GCODE_VIEWER void reset_gcode_toolpaths() { m_gcode_viewer.reset(); } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); } + void update_gcode_sequential_view_current(unsigned int low, unsigned int high) { m_gcode_viewer.update_sequential_view_current(low, high); } +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index fc97796749..9547e0bf89 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -210,7 +210,9 @@ Preview::Preview( , m_number_extruders(1) , m_preferred_color_mode("feature") , m_loaded(false) +#if !ENABLE_GCODE_VIEWER , m_enabled(false) +#endif // !ENABLE_GCODE_VIEWER , m_schedule_background_process(schedule_background_process_func) #ifdef __linux__ , m_volumes_cleanup_required(false) @@ -245,8 +247,12 @@ bool Preview::init(wxWindow* parent, Model* model) m_canvas->enable_dynamic_background(true); m_canvas->enable_collapse_toolbar(true); +#if ENABLE_GCODE_VIEWER + m_double_slider_sizer = create_vert_slider_sizer(); +#else m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL); create_double_slider(); +#endif // ENABLE_GCODE_VIEWER m_label_view_type = new wxStaticText(this, wxID_ANY, _L("View")); @@ -315,15 +321,25 @@ bool Preview::init(wxWindow* parent, Model* model) top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + m_horz_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); + m_horz_slider->SetDrawMode(DoubleSlider::dmSequentialGCodeView); + m_horz_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_horz_slider_scroll_changed, this); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + #if ENABLE_GCODE_VIEWER m_bottom_toolbar_sizer = new wxBoxSizer(wxHORIZONTAL); m_bottom_toolbar_sizer->AddSpacer(10); - 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->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); + m_bottom_toolbar_sizer->Add(m_choice_view_type, 0, wxALIGN_CENTER_VERTICAL, 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_options, 0, wxEXPAND | wxALL, 5); - m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5); + m_bottom_toolbar_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_options, 0, wxALIGN_CENTER_VERTICAL, 5); + m_bottom_toolbar_sizer->Add(m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + m_bottom_toolbar_sizer->AddSpacer(10); + m_bottom_toolbar_sizer->Add(m_horz_slider, 1, wxALL | wxEXPAND, 5); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #else wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5); @@ -417,10 +433,12 @@ void Preview::set_number_extruders(unsigned int number_extruders) } } +#if !ENABLE_GCODE_VIEWER void Preview::set_enabled(bool enabled) { m_enabled = enabled; } +#endif // !ENABLE_GCODE_VIEWER void Preview::bed_shape_changed() { @@ -498,7 +516,14 @@ void Preview::refresh_print() void Preview::msw_rescale() { // rescale slider +#if ENABLE_GCODE_VIEWER + if (m_vert_slider != nullptr) m_vert_slider->msw_rescale(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + if (m_horz_slider != nullptr) m_horz_slider->msw_rescale(); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#else if (m_slider) m_slider->msw_rescale(); +#endif // ENABLE_GCODE_VIEWER // rescale warning legend on the canvas get_canvas3d()->msw_rescale(); @@ -509,14 +534,22 @@ void Preview::msw_rescale() void Preview::move_double_slider(wxKeyEvent& evt) { - if (m_slider) +#if ENABLE_GCODE_VIEWER + if (m_vert_slider != nullptr) m_vert_slider->OnKeyDown(evt); +#else + if (m_slider) m_slider->OnKeyDown(evt); +#endif // ENABLE_GCODE_VIEWER } void Preview::edit_double_slider(wxKeyEvent& evt) { - if (m_slider) +#if ENABLE_GCODE_VIEWER + if (m_vert_slider != nullptr) m_vert_slider->OnChar(evt); +#else + if (m_slider) m_slider->OnChar(evt); +#endif // ENABLE_GCODE_VIEWER } void Preview::bind_event_handlers() @@ -580,25 +613,35 @@ void Preview::show_hide_ui_elements(const std::string& what) } #endif // !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +void Preview::hide_vert_slider() +{ + m_double_slider_sizer->Hide((size_t)0); + Layout(); +} +#else void Preview::reset_sliders(bool reset_all) { m_enabled = false; -// reset_double_slider(); + // reset_double_slider(); if (reset_all) m_double_slider_sizer->Hide((size_t)0); else m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide(1); } +#endif // ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER void Preview::update_sliders(const std::vector& layers_z, bool keep_z_range) { m_enabled = true; - update_double_slider(layers_z, keep_z_range); + m_double_slider_sizer->Show((size_t)0); Layout(); } +#endif // !ENABLE_GCODE_VIEWER void Preview::on_size(wxSizeEvent& evt) { @@ -705,32 +748,68 @@ 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_bottom_toolbar_sizer->Show(m_combochecklist_features, !m_canvas->is_gcode_legend_enabled() || m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType); m_bottom_toolbar_sizer->Layout(); + Refresh(); } #endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +wxBoxSizer* Preview::create_vert_slider_sizer() +{ + wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); + m_vert_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100); + + m_vert_slider->SetDrawMode(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA, + wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects")); + + sizer->Add(m_vert_slider, 0, wxEXPAND, 0); + + // sizer, m_canvas_widget + m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_vert_slider_from_canvas, this); + m_canvas_widget->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event) { + if (event.GetKeyCode() == WXK_SHIFT) + m_vert_slider->UseDefaultColors(true); + event.Skip(); + }); + + m_vert_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_vert_slider_scroll_changed, this); + + Bind(DoubleSlider::wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { + Model& model = wxGetApp().plater()->model(); + model.custom_gcode_per_print_z = m_vert_slider->GetTicksValues(); + m_schedule_background_process(); + + update_view_type(false); + + reload_print(); + }); + + return sizer; +} +#else void Preview::create_double_slider() { m_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100); + bool sla_print_technology = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA; bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects"); m_slider->SetDrawMode(sla_print_technology, sequential_print); m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); + // sizer, m_canvas_widget m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this); m_canvas_widget->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event) { if (event.GetKeyCode() == WXK_SHIFT) m_slider->UseDefaultColors(true); event.Skip(); - }); + }); m_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_sliders_scroll_changed, this); - Bind(DoubleSlider::wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { Model& model = wxGetApp().plater()->model(); model.custom_gcode_per_print_z = m_slider->GetTicksValues(); @@ -739,8 +818,9 @@ void Preview::create_double_slider() update_view_type(false); reload_print(); - }); + }); } +#endif // ENABLE_GCODE_VIEWER // Find an index of a value in a sorted vector, which is in . // Returns -1 if there is no such member. @@ -769,8 +849,13 @@ static int find_close_layer_idx(const std::vector& zs, double &z, double return -1; } +#if ENABLE_GCODE_VIEWER +void Preview::check_vert_slider_values(std::vector& ticks_from_model, + const std::vector& layers_z) +#else void Preview::check_slider_values(std::vector& ticks_from_model, const std::vector& layers_z) +#endif // ENABLE_GCODE_VIEWER { // All ticks that would end up outside the slider range should be erased. // TODO: this should be placed into more appropriate part of code, @@ -787,12 +872,68 @@ void Preview::check_slider_values(std::vector& ticks_from_mod m_schedule_background_process(); } -void Preview::update_double_slider(const std::vector& layers_z, bool keep_z_range) +#if ENABLE_GCODE_VIEWER +void Preview::update_vert_slider(const std::vector& layers_z, bool keep_z_range) +{ + // Save the initial slider span. + double z_low = m_vert_slider->GetLowerValueD(); + double z_high = m_vert_slider->GetHigherValueD(); + bool was_empty = m_vert_slider->GetMaxValue() == 0; + + bool force_sliders_full_range = was_empty; + if (!keep_z_range) + { + bool span_changed = layers_z.empty() || std::abs(layers_z.back() - m_vert_slider->GetMaxValueD()) > DoubleSlider::epsilon()/*1e-6*/; + force_sliders_full_range |= span_changed; +} + bool snap_to_min = force_sliders_full_range || m_vert_slider->is_lower_at_min(); + bool snap_to_max = force_sliders_full_range || m_vert_slider->is_higher_at_max(); + + // Detect and set manipulation mode for double slider + update_vert_slider_mode(); + + CustomGCode::Info& ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; + check_vert_slider_values(ticks_info_from_model.gcodes, layers_z); + + m_vert_slider->SetSliderValues(layers_z); + assert(m_vert_slider->GetMinValue() == 0); + m_vert_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1); + + int idx_low = 0; + int idx_high = m_vert_slider->GetMaxValue(); + if (!layers_z.empty()) { + if (!snap_to_min) { + int idx_new = find_close_layer_idx(layers_z, z_low, DoubleSlider::epsilon()/*1e-6*/); + if (idx_new != -1) + idx_low = idx_new; + } + if (!snap_to_max) { + int idx_new = find_close_layer_idx(layers_z, z_high, DoubleSlider::epsilon()/*1e-6*/); + if (idx_new != -1) + idx_high = idx_new; + } + } + m_vert_slider->SetSelectionSpan(idx_low, idx_high); + + m_vert_slider->SetTicksValues(ticks_info_from_model); + + bool sla_print_technology = wxGetApp().plater()->printer_technology() == ptSLA; + bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects"); + m_vert_slider->SetDrawMode(sla_print_technology, sequential_print); + + m_vert_slider->SetExtruderColors(wxGetApp().plater()->get_extruder_colors_from_plater_config()); + + m_double_slider_sizer->Show((size_t)0); + Layout(); +} +#else +void Preview::update_double_slider(const std::vector & layers_z, bool keep_z_range) { // Save the initial slider span. double z_low = m_slider->GetLowerValueD(); double z_high = m_slider->GetHigherValueD(); bool was_empty = m_slider->GetMaxValue() == 0; + bool force_sliders_full_range = was_empty; if (!keep_z_range) { @@ -800,27 +941,27 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee force_sliders_full_range |= span_changed; } bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); - bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max(); + bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max(); // Detect and set manipulation mode for double slider update_double_slider_mode(); - CustomGCode::Info &ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; + CustomGCode::Info& ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; check_slider_values(ticks_info_from_model.gcodes, layers_z); m_slider->SetSliderValues(layers_z); assert(m_slider->GetMinValue() == 0); m_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1); - int idx_low = 0; + int idx_low = 0; int idx_high = m_slider->GetMaxValue(); - if (! layers_z.empty()) { - if (! snap_to_min) { + if (!layers_z.empty()) { + if (!snap_to_min) { int idx_new = find_close_layer_idx(layers_z, z_low, DoubleSlider::epsilon()/*1e-6*/); if (idx_new != -1) idx_low = idx_new; } - if (! snap_to_max) { + if (!snap_to_max) { int idx_new = find_close_layer_idx(layers_z, z_high, DoubleSlider::epsilon()/*1e-6*/); if (idx_new != -1) idx_high = idx_new; @@ -836,8 +977,13 @@ void Preview::update_double_slider(const std::vector& layers_z, bool kee m_slider->SetExtruderColors(wxGetApp().plater()->get_extruder_colors_from_plater_config()); } +#endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER +void Preview::update_vert_slider_mode() +#else void Preview::update_double_slider_mode() +#endif // ENABLE_GCODE_VIEWER { // true -> single-extruder printer profile OR // multi-extruder printer profile , but whole model is printed by only one extruder @@ -886,16 +1032,68 @@ void Preview::update_double_slider_mode() } } +#if ENABLE_GCODE_VIEWER + m_vert_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); +#else m_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); +#endif // ENABLE_GCODE_VIEWER } +#if ENABLE_GCODE_VIEWER +void Preview::reset_vert_slider() +{ + m_vert_slider->SetHigherValue(0); + m_vert_slider->SetLowerValue(0); +} +#else void Preview::reset_double_slider() { m_slider->SetHigherValue(0); m_slider->SetLowerValue(0); } +#endif // ENABLE_GCODE_VIEWER -void Preview::update_double_slider_from_canvas(wxKeyEvent& event) +#if ENABLE_GCODE_VIEWER +void Preview::update_vert_slider_from_canvas(wxKeyEvent& event) +{ + if (event.HasModifiers()) { + event.Skip(); + return; + } + + const auto key = event.GetKeyCode(); + + if (key == 'U' || key == 'D') { + const int new_pos = key == 'U' ? m_vert_slider->GetHigherValue() + 1 : m_vert_slider->GetHigherValue() - 1; + m_vert_slider->SetHigherValue(new_pos); + if (event.ShiftDown() || m_vert_slider->is_one_layer()) m_vert_slider->SetLowerValue(m_vert_slider->GetHigherValue()); + } + else if (key == 'S') + m_vert_slider->ChangeOneLayerLock(); + else if (key == WXK_SHIFT) + m_vert_slider->UseDefaultColors(false); + else + event.Skip(); +} + +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void Preview::update_horz_slider() +{ + const GCodeViewer::SequentialView& view = m_canvas->get_gcode_sequential_view(); + std::vector values(view.last - view.first + 1); + unsigned int count = 0; + for (unsigned int i = view.first; i <= view.last; ++i) + { + values[count++] = static_cast(i + 1); + } + + m_horz_slider->SetSliderValues(values); + m_horz_slider->SetMaxValue(view.last - view.first); + m_horz_slider->SetSelectionSpan(0, view.current); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#else +void Preview::update_double_slider_from_canvas(wxKeyEvent & event) { if (event.HasModifiers()) { event.Skip(); @@ -909,13 +1107,11 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent& event) m_slider->SetHigherValue(new_pos); if (event.ShiftDown() || m_slider->is_one_layer()) m_slider->SetLowerValue(m_slider->GetHigherValue()); } -#if !ENABLE_GCODE_VIEWER else if (key == 'L') { m_checkbox_legend->SetValue(!m_checkbox_legend->GetValue()); auto evt = wxCommandEvent(); on_checkbox_legend(evt); } -#endif // !ENABLE_GCODE_VIEWER else if (key == 'S') m_slider->ChangeOneLayerLock(); else if (key == WXK_SHIFT) @@ -923,6 +1119,7 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent& event) else event.Skip(); } +#endif // ENABLE_GCODE_VIEWER void Preview::load_print_as_fff(bool keep_z_range) { @@ -951,10 +1148,12 @@ void Preview::load_print_as_fff(bool keep_z_range) if (! has_layers) { +#if ENABLE_GCODE_VIEWER + hide_vert_slider(); +#else reset_sliders(true); -#if !ENABLE_GCODE_VIEWER m_canvas->reset_legend_texture(); -#endif // !ENABLE_GCODE_VIEWER +#endif // ENABLE_GCODE_VIEWER m_canvas_widget->Refresh(); return; } @@ -1046,10 +1245,18 @@ void Preview::load_print_as_fff(bool keep_z_range) #endif // !ENABLE_GCODE_VIEWER if (zs.empty()) { // all layers filtered out +#if ENABLE_GCODE_VIEWER + hide_vert_slider(); +#else reset_sliders(true); +#endif // ENABLE_GCODE_VIEWER m_canvas_widget->Refresh(); } else +#if ENABLE_GCODE_VIEWER + update_vert_slider(zs, keep_z_range); +#else update_sliders(zs, keep_z_range); +#endif // ENABLE_GCODE_VIEWER } } @@ -1077,7 +1284,11 @@ void Preview::load_print_as_sla() n_layers = (unsigned int)zs.size(); if (n_layers == 0) { +#if ENABLE_GCODE_VIEWER + hide_vert_slider(); +#else reset_sliders(true); +#endif // ENABLE_GCODE_VIEWER m_canvas_widget->Refresh(); } @@ -1092,13 +1303,21 @@ void Preview::load_print_as_sla() #endif // ENABLE_GCODE_VIEWER if (n_layers > 0) +#if ENABLE_GCODE_VIEWER + update_vert_slider(zs); +#else update_sliders(zs); +#endif // ENABLE_GCODE_VIEWER m_loaded = true; } } +#if ENABLE_GCODE_VIEWER +void Preview::on_vert_slider_scroll_changed(wxCommandEvent& event) +#else void Preview::on_sliders_scroll_changed(wxCommandEvent& event) +#endif // ENABLE_GCODE_VIEWER { if (IsShown()) { @@ -1106,7 +1325,7 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) if (tech == ptFFF) { #if ENABLE_GCODE_VIEWER - m_canvas->set_toolpaths_z_range({ m_slider->GetLowerValueD(), m_slider->GetHigherValueD() }); + m_canvas->set_toolpaths_z_range({ m_vert_slider->GetLowerValueD(), m_vert_slider->GetHigherValueD() }); m_canvas->set_as_dirty(); #else m_canvas->set_toolpaths_range(m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6); @@ -1116,13 +1335,27 @@ void Preview::on_sliders_scroll_changed(wxCommandEvent& event) } else if (tech == ptSLA) { +#if ENABLE_GCODE_VIEWER + m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_vert_slider->GetLowerValueD())); + m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_vert_slider->GetHigherValueD())); + m_canvas->set_use_clipping_planes(m_vert_slider->GetHigherValue() != 0); +#else m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD())); m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD())); m_canvas->set_use_clipping_planes(m_slider->GetHigherValue() != 0); +#endif // ENABLE_GCODE_VIEWER m_canvas->render(); } } } +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void Preview::on_horz_slider_scroll_changed(wxCommandEvent& event) +{ + m_canvas->update_gcode_sequential_view_current(static_cast(m_horz_slider->GetLowerValueD()), static_cast(m_horz_slider->GetHigherValueD())); + m_canvas->render(); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index a11a474ccf..4df48a153e 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -24,7 +24,9 @@ namespace Slic3r { class DynamicPrintConfig; class Print; class BackgroundSlicingProcess; +#if !ENABLE_GCODE_VIEWER class GCodePreviewData; +#endif // !ENABLE_GCODE_VIEWER class Model; namespace DoubleSlider { @@ -100,9 +102,10 @@ class Preview : public wxPanel DynamicPrintConfig* m_config; BackgroundSlicingProcess* m_process; - GCodePreviewData* m_gcode_preview_data; #if ENABLE_GCODE_VIEWER GCodeProcessor::Result* m_gcode_result; +#else + GCodePreviewData* m_gcode_preview_data; #endif // ENABLE_GCODE_VIEWER #ifdef __linux__ @@ -118,9 +121,18 @@ class Preview : public wxPanel std::string m_preferred_color_mode; bool m_loaded; +#if !ENABLE_GCODE_VIEWER bool m_enabled; +#endif // !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + DoubleSlider::Control* m_vert_slider{ nullptr }; +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + DoubleSlider::Control* m_horz_slider{ nullptr }; +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#else DoubleSlider::Control* m_slider {nullptr}; +#endif // ENABLE_GCODE_VIEWER public: #if ENABLE_GCODE_VIEWER @@ -138,7 +150,9 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, void set_as_dirty(); void set_number_extruders(unsigned int number_extruders); +#if !ENABLE_GCODE_VIEWER void set_enabled(bool enabled); +#endif // !ENABLE_GCODE_VIEWER void bed_shape_changed(); void select_view(const std::string& direction); void set_drop_target(wxDropTarget* target); @@ -157,6 +171,9 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, #if ENABLE_GCODE_VIEWER void update_bottom_toolbar(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_horz_slider(); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER private: @@ -165,12 +182,14 @@ private: void bind_event_handlers(); void unbind_event_handlers(); -#if !ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + void hide_vert_slider(); +#else 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); +#endif // ENABLE_GCODE_VIEWER void on_size(wxSizeEvent& evt); void on_choice_view_type(wxCommandEvent& evt); @@ -185,20 +204,39 @@ private: void on_checkbox_legend(wxCommandEvent& evt); #endif // ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER + // Create/Update/Reset double slider on 3dPreview + wxBoxSizer* create_vert_slider_sizer(); + void check_vert_slider_values(std::vector& ticks_from_model, + const std::vector& layers_z); + void reset_vert_slider(); + void update_vert_slider(const std::vector& layers_z, bool keep_z_range = false); + void update_vert_slider_mode(); + // update vertical DoubleSlider after keyDown in canvas + void update_vert_slider_from_canvas(wxKeyEvent& event); +#else // Create/Update/Reset double slider on 3dPreview void create_double_slider(); - void check_slider_values(std::vector &ticks_from_model, - const std::vector &layers_z); + void check_slider_values(std::vector& ticks_from_model, + const std::vector& layers_z); void reset_double_slider(); void update_double_slider(const std::vector& layers_z, bool keep_z_range = false); void update_double_slider_mode(); // update DoubleSlider after keyDown in canvas void update_double_slider_from_canvas(wxKeyEvent& event); +#endif // ENABLE_GCODE_VIEWER void load_print_as_fff(bool keep_z_range = false); void load_print_as_sla(); +#if ENABLE_GCODE_VIEWER + void on_vert_slider_scroll_changed(wxCommandEvent& event); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void on_horz_slider_scroll_changed(wxCommandEvent& event); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER +#else void on_sliders_scroll_changed(wxCommandEvent& event); +#endif // ENABLE_GCODE_VIEWER }; } // namespace GUI diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8d505f2b65..4243b6ee84 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1641,6 +1641,9 @@ struct Plater::priv bool init_view_toolbar(); #if ENABLE_GCODE_VIEWER void update_preview_bottom_toolbar(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_preview_horz_slider(); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER void reset_all_gizmos(); @@ -2591,8 +2594,10 @@ void Plater::priv::deselect_all() void Plater::priv::remove(size_t obj_idx) { +#if !ENABLE_GCODE_VIEWER // Prevent toolpaths preview from rendering while we modify the Print object preview->set_enabled(false); +#endif // !ENABLE_GCODE_VIEWER if (view3D->is_layers_editing_enabled()) view3D->enable_layers_editing(false); @@ -2622,8 +2627,10 @@ void Plater::priv::reset() set_project_filename(wxEmptyString); +#if !ENABLE_GCODE_VIEWER // Prevent toolpaths preview from rendering while we modify the Print object preview->set_enabled(false); +#endif // !ENABLE_GCODE_VIEWER if (view3D->is_layers_editing_enabled()) view3D->enable_layers_editing(false); @@ -3867,6 +3874,13 @@ void Plater::priv::update_preview_bottom_toolbar() { preview->update_bottom_toolbar(); } + +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void Plater::priv::update_preview_horz_slider() +{ + preview->update_horz_slider(); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER bool Plater::priv::can_set_instance_to_object() const @@ -5463,6 +5477,13 @@ void Plater::update_preview_bottom_toolbar() { p->update_preview_bottom_toolbar(); } + +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER +void Plater::update_preview_horz_slider() +{ + p->update_preview_horz_slider(); +} +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER const Mouse3DController& Plater::get_mouse3d_controller() const diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 7a08c04efe..82c8bbe076 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -320,6 +320,9 @@ public: #if ENABLE_GCODE_VIEWER void update_preview_bottom_toolbar(); +#if ENABLE_GCODE_USE_WXWIDGETS_SLIDER + void update_preview_horz_slider(); +#endif // ENABLE_GCODE_USE_WXWIDGETS_SLIDER #endif // ENABLE_GCODE_VIEWER const Mouse3DController& get_mouse3d_controller() const;