diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index 650dfe2e7..df9990822 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -1466,7 +1466,7 @@ public: m_cfg.head_back_radius_mm, w); - if(t <= w || (hp(Z) + nn(Z) * w) < m_result.ground_level) { + if(t <= w) { // Let's try to optimize this angle, there might be a // viable normal that doesn't collide with the model @@ -1509,7 +1509,7 @@ public: // save the verified and corrected normal m_support_nmls.row(fidx) = nn; - if(t > w && (hp(Z) + nn(Z) * w) > m_result.ground_level) { + if(t > w) { // mark the point for needing a head. m_iheads.emplace_back(fidx); } else if( polar >= 3*PI/4 ) { diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 0e8e717cc..83fa61fdd 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -571,7 +571,24 @@ void swapXY(ExPolygon& expoly) { for(auto& p : expoly.contour.points) std::swap(p(X), p(Y)); for(auto& h : expoly.holes) for(auto& p : h.points) std::swap(p(X), p(Y)); } +} +std::string SLAPrint::validate() const +{ + for(SLAPrintObject * po : m_objects) { + sla::SupportConfig cfg = make_support_cfg(po->config()); + + double pinhead_width = + 2 * cfg.head_front_radius_mm + + cfg.head_width_mm + + 2 * cfg.head_back_radius_mm - + cfg.head_penetration_mm; + + if(pinhead_width > cfg.object_elevation_mm) + return L("Elevetion is too low for object."); + } + + return ""; } std::vector<float> SLAPrint::calculate_heights(const BoundingBoxf3& bb3d, diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index eb927c769..c06e2fc77 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -240,6 +240,8 @@ public: const SLAPrintStatistics& print_statistics() const { return m_print_statistics; } + std::string validate() const override; + private: using SLAPrinter = FilePrinter<FilePrinterFormat::SLA_PNGZIP>; using SLAPrinterPtr = std::unique_ptr<SLAPrinter>; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 7eef82063..abfc067ff 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2022,6 +2022,8 @@ void ObjectList::update_selections_on_canvas() void ObjectList::select_item(const wxDataViewItem& item) { + if (! item.IsOk()) { return; } + m_prevent_list_events = true; UnselectAll(); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 2211e8d7d..9860f26b1 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -186,6 +186,7 @@ Preview::Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_t , m_loaded(false) , m_enabled(false) , m_schedule_background_process(schedule_background_process_func) + , m_volumes_cleanup_required(false) { if (init(parent, bed, camera, view_toolbar)) { @@ -363,18 +364,22 @@ void Preview::load_print() load_print_as_sla(); } -void Preview::reload_print(bool force, bool keep_volumes) +void Preview::reload_print(bool keep_volumes) { - if (!keep_volumes) + if (!IsShown()) + { + m_volumes_cleanup_required = !keep_volumes; + return; + } + + if (m_volumes_cleanup_required || !keep_volumes) { m_canvas->reset_volumes(); m_canvas->reset_legend_texture(); m_loaded = false; + m_volumes_cleanup_required = false; } - if (!IsShown() && !force) - return; - load_print(); } @@ -554,15 +559,14 @@ static int find_close_layer_idx(const std::vector<double>& zs, double &z, double return -1; } -void Preview::update_double_slider(const std::vector<double>& layers_z, bool force_sliders_full_range) +void Preview::update_double_slider(const std::vector<double>& layers_z) { // 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 span_changed = layers_z.empty() || std::abs(layers_z.back() - m_slider->GetMaxValueD()) > 1e-6; - force_sliders_full_range |= was_empty | span_changed; - bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); + bool force_sliders_full_range = was_empty; + 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(); std::vector<std::pair<int, double>> values; diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index bfb604c40..59f62ded1 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -86,6 +86,8 @@ class Preview : public wxPanel BackgroundSlicingProcess* m_process; GCodePreviewData* m_gcode_preview_data; + bool m_volumes_cleanup_required; + // Calling this function object forces Plater::schedule_background_process. std::function<void()> m_schedule_background_process; @@ -112,7 +114,7 @@ public: void set_drop_target(wxDropTarget* target); void load_print(); - void reload_print(bool force = false, bool keep_volumes = false); + void reload_print(bool keep_volumes = false); void refresh_print(); private: @@ -136,7 +138,7 @@ private: // Create/Update/Reset double slider on 3dPreview void create_double_slider(); - void update_double_slider(const std::vector<double>& layers_z, bool force_sliders_full_range = false); + void update_double_slider(const std::vector<double>& layers_z); void fill_slider_values(std::vector<std::pair<int, double>> &values, const std::vector<double> &layers_z); void reset_double_slider(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 601c2ddb6..56dc323b3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2388,7 +2388,7 @@ void Plater::priv::set_current_panel(wxPanel* panel) { this->q->reslice(); // keeps current gcode preview, if any - preview->reload_print(false, true); + preview->reload_print(true); preview->set_canvas_as_dirty(); view_toolbar.select_item("Preview"); }