Просмотр исходного кода

Do not show shell for non-printable and out of printbed volumes in preview

enricoturri1966 1 год назад
Родитель
Сommit
200df9c02d

+ 6 - 3
src/slic3r/GUI/GCodeViewer.cpp

@@ -2255,9 +2255,12 @@ void GCodeViewer::load_shells(const Print& print)
         ++object_id;
     }
 
-    // remove modifiers
+    wxGetApp().plater()->get_current_canvas3D()->check_volumes_outside_state(m_shells.volumes);
+
+    // remove modifiers, non-printable and out-of-bed volumes
     while (true) {
-        GLVolumePtrs::iterator it = std::find_if(m_shells.volumes.volumes.begin(), m_shells.volumes.volumes.end(), [](GLVolume* volume) { return volume->is_modifier; });
+        GLVolumePtrs::iterator it = std::find_if(m_shells.volumes.volumes.begin(), m_shells.volumes.volumes.end(),
+            [](GLVolume* volume) { return volume->is_modifier || !volume->printable || volume->is_outside; });
         if (it != m_shells.volumes.volumes.end()) {
             delete *it;
             m_shells.volumes.volumes.erase(it);
@@ -3243,7 +3246,7 @@ void GCodeViewer::render_toolpaths()
 
 void GCodeViewer::render_shells()
 {
-    if (!m_shells.visible || m_shells.volumes.empty())
+    if (m_shells.volumes.empty() || (!m_shells.visible && !m_shells.force_visible))
         return;
 
     GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");

+ 2 - 2
src/slic3r/GUI/GCodeViewer.hpp

@@ -378,6 +378,7 @@ class GCodeViewer
     {
         GLVolumeCollection volumes;
         bool visible{ false };
+        bool force_visible{ false };
     };
 
     // helper to render center of gravity
@@ -849,8 +850,7 @@ public:
     bool is_legend_enabled() const { return m_legend_enabled; }
     void enable_legend(bool enable) { m_legend_enabled = enable; }
 
-    bool are_shells_visible() const { return m_shells.visible; }
-    void set_shells_visible(bool visible) { m_shells.visible = visible; }
+    void set_force_shells_visible(bool visible) { m_shells.force_visible = visible; }
 
     void export_toolpaths_to_obj(const char* filename) const;
 

+ 28 - 23
src/slic3r/GUI/GLCanvas3D.cpp

@@ -1442,11 +1442,16 @@ ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state(bool sele
 {
     ModelInstanceEPrintVolumeState state = ModelInstanceEPrintVolumeState::ModelInstancePVS_Inside;
     if (m_initialized && !m_volumes.empty())
-        check_volumes_outside_state(m_bed.build_volume(), &state, selection_only);
+        check_volumes_outside_state(const_cast<GLVolumeCollection&>(m_volumes), &state, selection_only);
     return state;
 }
 
-bool GLCanvas3D::check_volumes_outside_state(const Slic3r::BuildVolume& build_volume, ModelInstanceEPrintVolumeState* out_state, bool selection_only) const
+void GLCanvas3D::check_volumes_outside_state(GLVolumeCollection& volumes) const
+{
+    check_volumes_outside_state(volumes, nullptr, false);
+}
+
+bool GLCanvas3D::check_volumes_outside_state(GLVolumeCollection& volumes, ModelInstanceEPrintVolumeState* out_state, bool selection_only) const
 {
     auto                volume_below = [](GLVolume& volume) -> bool
     { return volume.object_idx() != -1 && volume.volume_idx() != -1 && volume.is_below_printbed(); };
@@ -1460,26 +1465,27 @@ bool GLCanvas3D::check_volumes_outside_state(const Slic3r::BuildVolume& build_vo
     auto                volume_convex_mesh = [this, volume_sinking](GLVolume& volume) -> const TriangleMesh&
     { return volume_sinking(volume) ? m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : *volume.convex_hull(); };
 
-    auto volumes_to_process_idxs = [this, selection_only]() {
-        std::vector<unsigned int> ret;
-        if (!selection_only || m_selection.is_empty()) {
-            ret = std::vector<unsigned int>(m_volumes.volumes.size());
-            std::iota(ret.begin(), ret.end(), 0);
-        }
-        else {
-            const GUI::Selection::IndicesList& selected_volume_idxs = m_selection.get_volume_idxs();
-            ret.assign(selected_volume_idxs.begin(), selected_volume_idxs.end());
-        }
-        return ret;
+    auto volumes_to_process_idxs = [this, &volumes, selection_only]() {
+      std::vector<unsigned int> ret;
+      if (!selection_only || m_selection.is_empty()) {
+          ret = std::vector<unsigned int>(volumes.volumes.size());
+          std::iota(ret.begin(), ret.end(), 0);
+      }
+      else {
+          const GUI::Selection::IndicesList& selected_volume_idxs = m_selection.get_volume_idxs();
+          ret.assign(selected_volume_idxs.begin(), selected_volume_idxs.end());
+      }
+      return ret;
     };
 
     ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside;
     bool contained_min_one = false;
 
-    const std::vector<unsigned int> volumes_idxs = volumes_to_process_idxs();
+    const Slic3r::BuildVolume& build_volume = m_bed.build_volume();
 
+    const std::vector<unsigned int> volumes_idxs = volumes_to_process_idxs();
     for (unsigned int vol_idx : volumes_idxs) {
-        GLVolume* volume = m_volumes.volumes[vol_idx];
+        GLVolume* volume = volumes.volumes[vol_idx];
         if (!volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (!volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) {
             BuildVolume::ObjectState state;
             if (volume_below(*volume))
@@ -1492,7 +1498,7 @@ bool GLCanvas3D::check_volumes_outside_state(const Slic3r::BuildVolume& build_vo
                     break;
                 case BuildVolume::Type::Circle:
                 case BuildVolume::Type::Convex:
-                    //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
+                //FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
                 case BuildVolume::Type::Custom:
                     state = build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast<float>(), volume_sinking(*volume));
                     break;
@@ -1514,9 +1520,9 @@ bool GLCanvas3D::check_volumes_outside_state(const Slic3r::BuildVolume& build_vo
         }
     }
 
-    for (unsigned int vol_idx = 0; vol_idx < m_volumes.volumes.size(); ++vol_idx) {
+    for (unsigned int vol_idx = 0; vol_idx < volumes.volumes.size(); ++vol_idx) {
         if (std::find(volumes_idxs.begin(), volumes_idxs.end(), vol_idx) == volumes_idxs.end()) {
-            if (!m_volumes.volumes[vol_idx]->is_outside) {
+            if (!volumes.volumes[vol_idx]->is_outside) {
                 contained_min_one = true;
                 break;
             }
@@ -2562,7 +2568,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
     // checks for geometry outside the print volume to render it accordingly
     if (!m_volumes.empty()) {
         ModelInstanceEPrintVolumeState state;
-        const bool contained_min_one = check_volumes_outside_state(m_bed.build_volume(), &state, !force_full_scene_refresh);
+        const bool contained_min_one = check_volumes_outside_state(m_volumes, &state, !force_full_scene_refresh);
         const bool partlyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Partly_Outside);
         const bool fullyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Fully_Outside);
 
@@ -2639,10 +2645,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
 
 void GLCanvas3D::load_gcode_shells()
 {
-    m_gcode_viewer_shells_visible = m_gcode_viewer.are_shells_visible();
     m_gcode_viewer.load_shells(*this->fff_print());
     m_gcode_viewer.update_shells_color_by_extruder(m_config);
-    m_gcode_viewer.set_shells_visible(true);
+    m_gcode_viewer.set_force_shells_visible(true);
 }
 
 void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector<std::string>& str_tool_colors)
@@ -2697,7 +2702,7 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, c
     for (const PrintObject* object : print->objects())
         _load_print_object_toolpaths(*object, build_volume, str_tool_colors, color_print_values);
 
-    m_gcode_viewer.set_shells_visible(m_gcode_viewer_shells_visible);
+    m_gcode_viewer.set_force_shells_visible(false);
     _set_warning_notification_if_needed(EWarning::ToolpathOutside);
 }
 
@@ -6036,7 +6041,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
         }
         }
         if (m_requires_check_outside_state) {
-            check_volumes_outside_state(build_volume, nullptr);
+            check_volumes_outside_state(m_volumes, nullptr);
             m_requires_check_outside_state = false;
         }
     }

+ 6 - 2
src/slic3r/GUI/GLCanvas3D.hpp

@@ -509,7 +509,6 @@ private:
     TriangleMesh m_wipe_tower_mesh;
 #endif // ENABLE_OPENGL_ES
     GCodeViewer m_gcode_viewer;
-    bool m_gcode_viewer_shells_visible{ true };
 
     RenderTimer m_render_timer;
 
@@ -712,10 +711,15 @@ public:
     const GLVolumeCollection& get_volumes() const { return m_volumes; }
     void reset_volumes();
     ModelInstanceEPrintVolumeState check_volumes_outside_state(bool selection_only = true) const;
+    // update the is_outside state of all the volumes contained in the given collection
+    void check_volumes_outside_state(GLVolumeCollection& volumes) const;
+
+private:
     // returns true if all the volumes are completely contained in the print volume
     // returns the containment state in the given out_state, if non-null
-    bool check_volumes_outside_state(const Slic3r::BuildVolume& build_volume, ModelInstanceEPrintVolumeState* out_state, bool selection_only = true) const;
+    bool check_volumes_outside_state(GLVolumeCollection& volumes, ModelInstanceEPrintVolumeState* out_state, bool selection_only = true) const;
 
+public:
     void init_gcode_viewer() { m_gcode_viewer.init(); }
     void reset_gcode_toolpaths() { m_gcode_viewer.reset(); }
     const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); }