diff --git a/src/libvgcode/src/ViewerImpl.cpp b/src/libvgcode/src/ViewerImpl.cpp index 41ef90531b..d4c535f028 100644 --- a/src/libvgcode/src/ViewerImpl.cpp +++ b/src/libvgcode/src/ViewerImpl.cpp @@ -893,6 +893,8 @@ void ViewerImpl::reset() m_enabled_options_count = 0; m_enabled_segments_reduced_count = 0; m_enabled_options_reduced_count = 0; + m_enabled_segments_reduced_tex_size = 0; + m_enabled_options_reduced_tex_size = 0; m_settings_used_for_ranges = std::nullopt; @@ -1278,18 +1280,20 @@ void ViewerImpl::update_enabled_entities() m_enabled_segments_reduced_count = enabled_segments_reduced.size(); m_enabled_options_reduced_count = enabled_options_reduced.size(); + m_enabled_segments_reduced_tex_size = enabled_segments_reduced.size() * sizeof(uint32_t); + m_enabled_options_reduced_tex_size = enabled_options_reduced.size() * sizeof(uint32_t); - if (build_reduced) { - assert(m_enabled_segments_reduced_buf_id > 0); - glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_reduced_buf_id)); - glsafe(glBufferData(GL_TEXTURE_BUFFER, enabled_segments_reduced.size() * sizeof(uint32_t), - enabled_segments_reduced.empty() ? nullptr : enabled_segments_reduced.data(), GL_STATIC_DRAW)); + // uploaded even when nothing was built, so that the last reduced set is released as soon as + // the preference is switched off + assert(m_enabled_segments_reduced_buf_id > 0); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_segments_reduced_buf_id)); + glsafe(glBufferData(GL_TEXTURE_BUFFER, m_enabled_segments_reduced_tex_size, + enabled_segments_reduced.empty() ? nullptr : enabled_segments_reduced.data(), GL_STATIC_DRAW)); - assert(m_enabled_options_reduced_buf_id > 0); - glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_options_reduced_buf_id)); - glsafe(glBufferData(GL_TEXTURE_BUFFER, enabled_options_reduced.size() * sizeof(uint32_t), - enabled_options_reduced.empty() ? nullptr : enabled_options_reduced.data(), GL_STATIC_DRAW)); - } + assert(m_enabled_options_reduced_buf_id > 0); + glsafe(glBindBuffer(GL_TEXTURE_BUFFER, m_enabled_options_reduced_buf_id)); + glsafe(glBufferData(GL_TEXTURE_BUFFER, m_enabled_options_reduced_tex_size, + enabled_options_reduced.empty() ? nullptr : enabled_options_reduced.data(), GL_STATIC_DRAW)); glsafe(glBindBuffer(GL_TEXTURE_BUFFER, 0)); #endif // ENABLE_OPENGL_ES @@ -1870,6 +1874,8 @@ size_t ViewerImpl::get_used_gpu_memory() const ret += m_colors_tex_size; ret += m_enabled_segments_tex_size; ret += m_enabled_options_tex_size; + ret += m_enabled_segments_reduced_tex_size; + ret += m_enabled_options_reduced_tex_size; #endif // ENABLE_OPENGL_ES return ret; } diff --git a/src/libvgcode/src/ViewerImpl.hpp b/src/libvgcode/src/ViewerImpl.hpp index cfc86e255a..6e8ac104fc 100644 --- a/src/libvgcode/src/ViewerImpl.hpp +++ b/src/libvgcode/src/ViewerImpl.hpp @@ -503,6 +503,8 @@ private: size_t m_colors_tex_size{ 0 }; size_t m_enabled_segments_tex_size{ 0 }; size_t m_enabled_options_tex_size{ 0 }; + size_t m_enabled_segments_reduced_tex_size{ 0 }; + size_t m_enabled_options_reduced_tex_size{ 0 }; // The set the next draw reads from: the reduced one while dragging, if one is built. bool use_reduced_set() const { return m_settings.reduced_detail && m_settings.reduced_detail_enabled; } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index efc956ff1a..2ead79da0f 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -354,6 +354,8 @@ public: void set_dim_previous_layers_brightness(float value) { m_viewer.set_dim_previous_layers_brightness(value); } float get_dim_previous_layers_brightness() const { return m_viewer.get_dim_previous_layers_brightness(); } + // whether the mouse is holding either slider's handle + bool is_slider_dragging() const { return m_layers_slider->is_dragging() || m_moves_slider->is_dragging(); } // while the user drags the camera or a slider, draw the solid model, if the preference asks for it void set_interacting(bool interacting); bool is_reduced_detail() const { return m_viewer.is_reduced_detail(); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b80120991a..0648e3359c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7726,13 +7726,20 @@ bool GLCanvas3D::_is_scene_cacheable() const return false; #endif - // The scene follows the cursor during a drag, under a gizmo that draws at the cursor, and while - // the cursor is on the layer height bar, where the object shader draws a band at its height. + // The scene follows the cursor while the user drags, under a gizmo that draws at the cursor, and + // while the cursor is on the layer height bar, where the object shader draws a band at its height. const GLGizmoBase* gizmo = m_gizmos.get_current(); const bool cursor_on_layers_bar = is_layers_editing_enabled() && m_layers_editing.bar_rect_contains(*this, (float)m_mouse.position.x(), (float)m_mouse.position.y()); - return !m_mouse.dragging && !m_gizmos.is_dragging() && !m_rectangle_selection.is_dragging() && - (gizmo == nullptr || !gizmo->render_follows_cursor()) && !cursor_on_layers_bar; + return !is_user_interacting() && (gizmo == nullptr || !gizmo->render_follows_cursor()) && !cursor_on_layers_bar; +} + +// Whether the user is holding something that moves the scene: the camera, the navigator, a gizmo, +// the rectangle selection or a preview slider. +bool GLCanvas3D::is_user_interacting() const +{ + return m_mouse.dragging || m_navigator_dragging || m_gizmos.is_dragging() || m_rectangle_selection.is_dragging() || + m_gcode_viewer.is_slider_dragging(); } bool GLCanvas3D::_is_frame_skipping_enabled() const @@ -8779,11 +8786,9 @@ void GLCanvas3D::_render_wireframe_overlay() // pass draws changed, since a frame that reuses the cached scene would hide the change. bool GLCanvas3D::_update_preview_interaction() { - IMSlider* layers_slider = m_gcode_viewer.get_layers_slider(); - IMSlider* moves_slider = m_gcode_viewer.get_moves_slider(); const auto now = std::chrono::steady_clock::now(); const bool settling = now < m_preview_interaction_until; - const bool dragging = m_mouse.dragging || m_navigator_dragging || layers_slider->is_dragging() || moves_slider->is_dragging(); + const bool dragging = is_user_interacting(); const bool was_reduced = m_gcode_viewer.is_reduced_detail(); m_gcode_viewer.set_interacting(dragging || settling); if (settling && !dragging && m_gcode_viewer.is_reduced_detail()) { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8f999cc11e..ba45543063 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -1219,6 +1219,8 @@ public: void msw_rescale() { m_gcode_viewer.invalidate_legend(); } void request_extra_frame() { m_extra_frame_requested = true; } + // whether the user is holding the camera, the navigator, a gizmo, the rectangle selection or a preview slider + bool is_user_interacting() const; // a wheel step is over before the next frame, so it holds the preview's solid model for a settle time void note_preview_interaction(); diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 6b67a718c6..2206abd452 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -1049,16 +1049,6 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too } } // ORCA: apply the preview dimming change immediately to the currently loaded preview - // apply the solid model preference immediately to the currently loaded preview - else if (param == "preview_solid_model_while_dragging") { - if (Plater* plater = wxGetApp().plater()) { - if (GLCanvas3D* canvas = plater->get_preview_canvas3D()) { - canvas->get_gcode_viewer().set_solid_model_while_dragging(app_config->get_bool(param)); - canvas->set_as_dirty(); - canvas->request_extra_frame(); - } - } - } else if (param == "preview_dim_previous_layers") { if (m_dim_previous_layers_brightness_input) m_dim_previous_layers_brightness_input->Enable(app_config->get_bool(param)); @@ -1070,6 +1060,16 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too } } } + // apply the solid model preference immediately to the currently loaded preview + else if (param == "preview_solid_model_while_dragging") { + if (Plater* plater = wxGetApp().plater()) { + if (GLCanvas3D* canvas = plater->get_preview_canvas3D()) { + canvas->get_gcode_viewer().set_solid_model_while_dragging(app_config->get_bool(param)); + canvas->set_as_dirty(); + canvas->request_extra_frame(); + } + } + } #ifdef __WXMSW__ if (param == "associate_3mf") { @@ -2032,8 +2032,8 @@ void PreferencesDialog::create_items() auto item_solid_model_while_dragging = create_item_checkbox( _L("Only render solid model when dragging"), _L("While dragging the camera or a preview slider, or zooming with the mouse wheel, draw the sliced objects and the prime tower as solid shapes " - "in their filament colours instead of toolpaths, so that large prints stay responsive. They are cut to the visible layer range, with its bottom " - "and top layers drawn as toolpaths. Supports are not shown. The toolpaths are restored as soon as you let go."), + "in their filament colors instead of toolpaths, so that large prints stay responsive. They are cut to the visible layer range, with its bottom " + "and top layers drawn as toolpaths. Supports are not shown, and negative volumes are not cut out. The toolpaths are restored as soon as you let go."), "preview_solid_model_while_dragging" ); g_sizer->Add(item_solid_model_while_dragging);