diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index f618ceed2e..ef51c6b872 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4747,6 +4747,22 @@ void GCodeViewer::render_legend(float& legend_height) return std::make_pair(it->second.first * koef, it->second.second); }; +#if ENABLE_NEW_GCODE_VIEWER + auto toggle_extrusion_role_visibility = [this](libvgcode::EGCodeExtrusionRole role) { + const libvgcode::Interval view_visible_range = m_viewer.get_view_visible_range(); + const libvgcode::Interval view_enabled_range = m_viewer.get_view_enabled_range(); + m_viewer.toggle_extrusion_role_visibility(role); + std::optional view_visible_range_min; + std::optional view_visible_range_max; + if (view_visible_range != view_enabled_range) { + view_visible_range_min = static_cast(view_visible_range[0]); + view_visible_range_max = static_cast(view_visible_range[1]); + } + wxGetApp().plater()->update_preview_moves_slider(view_visible_range_min, view_visible_range_max); + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + }; +#endif // ENABLE_NEW_GCODE_VIEWER + // data used to properly align items in columns when showing time std::array offsets = { 0.0f, 0.0f, 0.0f, 0.0f }; std::vector labels; @@ -4903,9 +4919,12 @@ void GCodeViewer::render_legend(float& legend_height) #if ENABLE_NEW_GCODE_VIEWER if (curr_view_type_i != new_view_type_i) { - m_viewer.set_view_type(static_cast(new_view_type_i)); + enable_view_type_cache_load(false); + set_view_type(static_cast(new_view_type_i)); + enable_view_type_cache_load(true); wxGetApp().plater()->set_keep_current_preview_type(true); - wxGetApp().plater()->refresh_print(); + wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); + wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); view_type_changed = true; } @@ -4960,19 +4979,7 @@ void GCodeViewer::render_legend(float& legend_height) append_item(EItemType::Rect, libvgcode::convert(m_viewer.get_extrusion_role_color(role)), labels[i], visible, times[i], percents[i], max_time_percent, offsets, used_filaments_m[i], used_filaments_g[i], - [this, role]() { - const libvgcode::Interval view_visible_range = m_viewer.get_view_visible_range(); - const libvgcode::Interval view_enabled_range = m_viewer.get_view_enabled_range(); - m_viewer.toggle_extrusion_role_visibility((libvgcode::EGCodeExtrusionRole)role); - std::optional view_visible_range_min; - std::optional view_visible_range_max; - if (view_visible_range != view_enabled_range) { - view_visible_range_min = static_cast(view_visible_range[0]); - view_visible_range_max = static_cast(view_visible_range[1]); - } - wxGetApp().plater()->update_preview_moves_slider(view_visible_range_min, view_visible_range_max); - wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); - } + [role, toggle_extrusion_role_visibility]() { toggle_extrusion_role_visibility(role); } ); #else max_time_percent = std::max(max_time_percent, time_mode.travel_time / time_mode.time); @@ -5430,12 +5437,12 @@ void GCodeViewer::render_legend(float& legend_height) ImGui::Separator(); if (imgui.button(btn_text, ImVec2(-1.0f, 0.0f), true)) { #if ENABLE_NEW_GCODE_VIEWER - m_viewer.toggle_extrusion_role_visibility((libvgcode::EGCodeExtrusionRole)GCodeExtrusionRole::Custom); + toggle_extrusion_role_visibility(libvgcode::EGCodeExtrusionRole::Custom); #else m_extrusions.role_visibility_flags = custom_visible ? m_extrusions.role_visibility_flags & ~(1 << int(GCodeExtrusionRole::Custom)) : m_extrusions.role_visibility_flags | (1 << int(GCodeExtrusionRole::Custom)); -#endif // ENABLE_NEW_GCODE_VIEWER wxGetApp().plater()->refresh_print(); +#endif // ENABLE_NEW_GCODE_VIEWER } } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 38826234a6..c76413ca53 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -866,6 +866,13 @@ private: #endif // ENABLE_COG_AND_TOOL_MARKERS bool m_legend_visible{ true }; bool m_legend_enabled{ true }; + struct ViewTypeCache + { + bool write{ false }; + bool load{ false }; + libvgcode::EViewType value{ libvgcode::EViewType::FeatureType }; + }; + ViewTypeCache m_view_type_cache; #else EViewType m_view_type{ EViewType::FeatureType }; bool m_legend_enabled{ true }; @@ -974,8 +981,18 @@ public: bool is_contained_in_bed() const { return m_contained_in_bed; } #if ENABLE_NEW_GCODE_VIEWER - void set_view_type(libvgcode::EViewType type) { m_viewer.set_view_type(type); } + void set_view_type(libvgcode::EViewType type) { + m_viewer.set_view_type((m_view_type_cache.load && m_view_type_cache.value != type) ? m_view_type_cache.value : type); + const libvgcode::EViewType view_type = get_view_type(); + if (m_view_type_cache.write && m_view_type_cache.value != view_type) + m_view_type_cache.value = view_type; + } + libvgcode::EViewType get_view_type() const { return m_viewer.get_view_type(); } + void enable_view_type_cache_load(bool enable) { m_view_type_cache.load = enable; } + void enable_view_type_cache_write(bool enable) { m_view_type_cache.write = enable; } + bool is_view_type_cache_load_enabled() const { return m_view_type_cache.load; } + bool is_view_type_cache_write_enabled() const { return m_view_type_cache.write; } #else EViewType get_view_type() const { return m_view_type; } void set_view_type(EViewType type) { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5452623391..5549f071b6 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2691,6 +2691,9 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, co { #if ENABLE_NEW_GCODE_VIEWER m_gcode_viewer.enable_legend(true); + m_gcode_viewer.enable_view_type_cache_write(true); + m_gcode_viewer.enable_view_type_cache_load(true); + m_gcode_viewer.set_view_type(m_gcode_viewer.get_view_type()); m_gcode_viewer.load_as_gcode(gcode_result, *this->fff_print(), str_tool_colors); m_gcode_layers_times_cache = m_gcode_viewer.get_layers_times(); #else @@ -2748,6 +2751,9 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c // send data to the viewer m_gcode_viewer.enable_legend(false); + m_gcode_viewer.enable_view_type_cache_write(false); + m_gcode_viewer.enable_view_type_cache_load(false); + m_gcode_viewer.set_view_type(libvgcode::EViewType::FeatureType); m_gcode_viewer.load_as_preview(std::move(data), str_tool_colors); #else const BuildVolume& build_volume = m_bed.build_volume(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index b6b21143d2..ee723eb83f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -874,6 +874,10 @@ public: #if ENABLE_NEW_GCODE_VIEWER void set_gcode_view_type(libvgcode::EViewType type) { return m_gcode_viewer.set_view_type(type); } libvgcode::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); } + void enable_gcode_view_type_cache_load(bool enable) { m_gcode_viewer.enable_view_type_cache_load(enable); } + void enable_gcode_view_type_cache_write(bool enable) { m_gcode_viewer.enable_view_type_cache_write(enable); } + bool is_gcode_view_type_cache_load_enabled() const { return m_gcode_viewer.is_view_type_cache_load_enabled(); } + bool is_gcode_view_type_cache_write_enabled() const { return m_gcode_viewer.is_view_type_cache_write_enabled(); } #else void refresh_gcode_preview_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last); void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); } diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 41e73654e8..2a43fc6bfb 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -305,6 +305,16 @@ void Preview::load_print(bool keep_z_range) Layout(); } +#if ENABLE_NEW_GCODE_VIEWER +void Preview::reload_print() +{ + if (!IsShown()) + return; + + m_loaded = false; + load_print(); +} +#else void Preview::reload_print(bool keep_volumes) { #ifdef __linux__ @@ -331,6 +341,7 @@ void Preview::reload_print(bool keep_volumes) load_print(); } +#endif // ENABLE_NEW_GCODE_VIEWER void Preview::refresh_print() { @@ -437,8 +448,12 @@ wxBoxSizer* Preview::create_layers_slider_sizer() m_schedule_background_process(); m_keep_current_preview_type = false; +#if ENABLE_NEW_GCODE_VIEWER + reload_print(); +#else reload_print(false); - }); +#endif // ENABLE_NEW_GCODE_VIEWER + }); return sizer; } @@ -850,18 +865,20 @@ void Preview::load_print_as_fff(bool keep_z_range) } #if ENABLE_NEW_GCODE_VIEWER - const libvgcode::EViewType gcode_view_type = m_canvas->get_gcode_view_type(); + libvgcode::EViewType gcode_view_type = m_canvas->get_gcode_view_type(); + const bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); + const bool is_pregcode_preview = !gcode_preview_data_valid && wxGetApp().is_editor(); #else GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); + const bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); #endif // ENABLE_NEW_GCODE_VIEWER - bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); // Collect colors per extruder. std::vector colors; std::vector color_print_values = {}; - // set color print values, if it si selected "ColorPrint" view type + // set color print values, if it is selected "ColorPrint" view type #if ENABLE_NEW_GCODE_VIEWER - if (gcode_view_type == libvgcode::EViewType::ColorPrint) { + if (gcode_view_type == libvgcode::EViewType::ColorPrint || is_pregcode_preview) { #else if (gcode_view_type == GCodeViewer::EViewType::ColorPrint) { #endif // ENABLE_NEW_GCODE_VIEWER @@ -891,6 +908,10 @@ void Preview::load_print_as_fff(bool keep_z_range) if (gcode_preview_data_valid) { // Load the real G-code preview. m_canvas->load_gcode_preview(*m_gcode_result, colors); +#if ENABLE_NEW_GCODE_VIEWER + // the view type may have been changed by the call m_canvas->load_gcode_preview() + gcode_view_type = m_canvas->get_gcode_view_type(); +#endif // ENABLE_NEW_GCODE_VIEWER m_left_sizer->Layout(); Refresh(); zs = m_canvas->get_gcode_layers_zs(); @@ -898,9 +919,18 @@ void Preview::load_print_as_fff(bool keep_z_range) m_left_sizer->Show(m_bottom_toolbar_panel); m_loaded = true; } +#if ENABLE_NEW_GCODE_VIEWER + else if (is_pregcode_preview) { +#else else if (wxGetApp().is_editor()) { +#endif // ENABLE_NEW_GCODE_VIEWER // Load the initial preview based on slices, not the final G-code. m_canvas->load_preview(colors, color_print_values); +#if ENABLE_NEW_GCODE_VIEWER + // the view type has been changed by the call m_canvas->load_gcode_preview() + if (gcode_view_type == libvgcode::EViewType::ColorPrint && !color_print_values.empty()) + m_canvas->set_gcode_view_type(gcode_view_type); +#endif // ENABLE_NEW_GCODE_VIEWER m_left_sizer->Hide(m_bottom_toolbar_panel); m_left_sizer->Layout(); Refresh(); @@ -917,10 +947,10 @@ void Preview::load_print_as_fff(bool keep_z_range) } if (!zs.empty() && !m_keep_current_preview_type) { - unsigned int number_extruders = wxGetApp().is_editor() ? + const unsigned int number_extruders = wxGetApp().is_editor() ? (unsigned int)print->extruders().size() : m_canvas->get_gcode_extruders_count(); - std::vector gcodes = wxGetApp().is_editor() ? + const std::vector gcodes = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_canvas->get_custom_gcode_per_print_z(); const bool contains_color_gcodes = std::any_of(std::begin(gcodes), std::end(gcodes), @@ -936,13 +966,20 @@ void Preview::load_print_as_fff(bool keep_z_range) #endif // ENABLE_NEW_GCODE_VIEWER if (choice != gcode_view_type) { #if ENABLE_NEW_GCODE_VIEWER + const bool gcode_view_type_cache_load = m_canvas->is_gcode_view_type_cache_load_enabled(); + if (gcode_view_type_cache_load) + m_canvas->enable_gcode_view_type_cache_load(false); m_canvas->set_gcode_view_type(choice); + if (gcode_view_type_cache_load) + m_canvas->enable_gcode_view_type_cache_load(true); #else m_canvas->set_gcode_view_preview_type(choice); #endif // ENABLE_NEW_GCODE_VIEWER if (wxGetApp().is_gcode_viewer()) m_keep_current_preview_type = true; +#if !ENABLE_NEW_GCODE_VIEWER refresh_print(); +#endif // !ENABLE_NEW_GCODE_VIEWER } } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index c2fc60e8bd..9974adfac6 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -89,11 +89,13 @@ class Preview : public wxPanel BackgroundSlicingProcess* m_process; GCodeProcessorResult* m_gcode_result; +#if !ENABLE_NEW_GCODE_VIEWER #ifdef __linux__ // We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955. // So we are applying a workaround here. bool m_volumes_cleanup_required { false }; #endif /* __linux__ */ +#endif // !ENABLE_NEW_GCODE_VIEWER // Calling this function object forces Plater::schedule_background_process. std::function m_schedule_background_process; @@ -138,7 +140,11 @@ public: void load_gcode_shells(); void load_print(bool keep_z_range = false); +#if ENABLE_NEW_GCODE_VIEWER + void reload_print(); +#else void reload_print(bool keep_volumes = false); +#endif // ENABLE_NEW_GCODE_VIEWER void refresh_print(); void msw_rescale(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e62801335a..22fe36d6e6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2707,7 +2707,11 @@ void Plater::priv::set_current_panel(wxPanel* panel) q->reslice(); } // keeps current gcode preview, if any +#if ENABLE_NEW_GCODE_VIEWER + preview->reload_print(); +#else preview->reload_print(true); +#endif // ENABLE_NEW_GCODE_VIEWER } preview->set_as_dirty(); @@ -4020,7 +4024,11 @@ void Plater::load_gcode(const wxString& filename) // cleanup view before to start loading/processing p->gcode_result.reset(); reset_gcode_toolpaths(); +#if ENABLE_NEW_GCODE_VIEWER + p->preview->reload_print(); +#else p->preview->reload_print(false); +#endif // ENABLE_NEW_GCODE_VIEWER p->get_current_canvas3D()->render(); wxBusyCursor wait; @@ -4041,7 +4049,11 @@ void Plater::load_gcode(const wxString& filename) // show results try { +#if ENABLE_NEW_GCODE_VIEWER + p->preview->reload_print(); +#else p->preview->reload_print(false); +#endif // ENABLE_NEW_GCODE_VIEWER } catch (const std::exception&) { @@ -4049,7 +4061,11 @@ void Plater::load_gcode(const wxString& filename) p->gcode_result.reset(); reset_gcode_toolpaths(); set_default_bed_shape(); +#if ENABLE_NEW_GCODE_VIEWER + p->preview->reload_print(); +#else p->preview->reload_print(false); +#endif // ENABLE_NEW_GCODE_VIEWER p->get_current_canvas3D()->render(); MessageDialog(this, _L("The selected file") + ":\n" + filename + "\n" + _L("does not contain valid gcode."), wxString(GCODEVIEWER_APP_NAME) + " - " + _L("Error while loading .gcode file"), wxOK | wxICON_WARNING | wxCENTRE).ShowModal(); @@ -5791,7 +5807,11 @@ void Plater::reslice() if (clean_gcode_toolpaths) reset_gcode_toolpaths(); +#if ENABLE_NEW_GCODE_VIEWER + p->preview->reload_print(); +#else p->preview->reload_print(!clean_gcode_toolpaths); +#endif // ENABLE_NEW_GCODE_VIEWER } void Plater::reslice_until_step_inner(int step, const ModelObject &object, bool postpone_error_messages)