From c3fec7b34934b44cef9334160d30cb02e36444f1 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Wed, 11 Jan 2023 14:47:40 +0100 Subject: [PATCH 1/3] WIP: Invalidating shared support spots in Print::apply() --- src/libslic3r/Print.hpp | 6 ++++++ src/libslic3r/PrintApply.cpp | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 4e8eaa63b..d254e4eef 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -609,6 +609,12 @@ private: // Return 4 wipe tower corners in the world coordinates (shifted and rotated), including the wipe tower brim. std::vector first_layer_wipe_tower_corners() const; + // Returns true if any of the print_objects has print_object_step valid. + // That means data shared by all print objects of the print_objects span may still use the shared data. + // Otherwise the shared data shall be released. + // Unguarded variant, thus it shall only be called from main thread with background processing stopped. + static bool is_shared_print_object_step_valid_unguarded(SpanOfConstPtrs print_objects, PrintObjectStep print_object_step); + PrintConfig m_config; PrintObjectConfig m_default_object_config; PrintRegionConfig m_default_region_config; diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 330ad533c..6beb1cae7 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1451,6 +1451,21 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ for (PrintObject *object : m_objects) object->update_slicing_parameters(); + if (apply_status == APPLY_STATUS_INVALIDATED) { + // Invalidate data of a single ModelObject shared by multiple PrintObjects. + // Find spans of PrintObjects sharing the same PrintObjectRegions. + std::vector all_objects(m_objects); + std::sort(all_objects.begin(), all_objects.end(), [](const PrintObject *l, const PrintObject *r){ return l->shared_regions() < r->shared_regions(); } ); + for (auto it = all_objects.begin(); it != all_objects.end();) { + PrintObjectRegions *shared_regions = (*it)->m_shared_regions; + auto it_begin = it; + for (++ it; it != all_objects.end() && shared_regions == (*it)->shared_regions(); ++ it); + auto this_objects = SpanOfConstPtrs(const_cast(&(*it_begin)), it - it_begin); + if (Print::is_shared_print_object_step_valid_unguarded(this_objects, posSupportSpotsSearch)) + shared_regions->generated_support_points.reset(); + } + } + #ifdef _DEBUG check_model_ids_equal(m_model, model); #endif /* _DEBUG */ @@ -1458,4 +1473,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ return static_cast(apply_status); } +bool Print::is_shared_print_object_step_valid_unguarded(SpanOfConstPtrs print_objects, PrintObjectStep print_object_step) +{ + return std::any_of(print_objects.begin(), print_objects.end(), [print_object_step](auto po){ return po->is_step_done_unguarded(print_object_step); }); +} + } // namespace Slic3r From 31fbfa56de70bf8093cea5fe56c73b0e6fa017c3 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Wed, 11 Jan 2023 16:01:37 +0100 Subject: [PATCH 2/3] Follow-up to c3fec7b34934b44cef9334160d30cb02e36444f1 WIP: Invalidating shared support spots in Print::apply() The background slicing background was modified to call Print::cleanup() any time any data of any print step or print object step could become invalid. Cleaning up such invalid data will reduce memory footprint. --- src/libslic3r/Print.hpp | 1 + src/libslic3r/PrintApply.cpp | 32 ++++++++++++--------- src/libslic3r/PrintBase.hpp | 4 +++ src/libslic3r/SLAPrint.hpp | 1 + src/slic3r/GUI/BackgroundSlicingProcess.cpp | 3 ++ 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index d254e4eef..2f5c4e96b 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -517,6 +517,7 @@ public: void set_task(const TaskParams ¶ms) override { PrintBaseWithState::set_task_impl(params, m_objects); } void process() override; void finalize() override { PrintBaseWithState::finalize_impl(m_objects); } + void cleanup() override; // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r). diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 6beb1cae7..5f95edefa 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1451,20 +1451,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ for (PrintObject *object : m_objects) object->update_slicing_parameters(); - if (apply_status == APPLY_STATUS_INVALIDATED) { - // Invalidate data of a single ModelObject shared by multiple PrintObjects. - // Find spans of PrintObjects sharing the same PrintObjectRegions. - std::vector all_objects(m_objects); - std::sort(all_objects.begin(), all_objects.end(), [](const PrintObject *l, const PrintObject *r){ return l->shared_regions() < r->shared_regions(); } ); - for (auto it = all_objects.begin(); it != all_objects.end();) { - PrintObjectRegions *shared_regions = (*it)->m_shared_regions; - auto it_begin = it; - for (++ it; it != all_objects.end() && shared_regions == (*it)->shared_regions(); ++ it); - auto this_objects = SpanOfConstPtrs(const_cast(&(*it_begin)), it - it_begin); - if (Print::is_shared_print_object_step_valid_unguarded(this_objects, posSupportSpotsSearch)) - shared_regions->generated_support_points.reset(); - } - } + if (apply_status == APPLY_STATUS_CHANGED || apply_status == APPLY_STATUS_INVALIDATED) + this->cleanup(); #ifdef _DEBUG check_model_ids_equal(m_model, model); @@ -1473,6 +1461,22 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ return static_cast(apply_status); } +void Print::cleanup() +{ + // Invalidate data of a single ModelObject shared by multiple PrintObjects. + // Find spans of PrintObjects sharing the same PrintObjectRegions. + std::vector all_objects(m_objects); + std::sort(all_objects.begin(), all_objects.end(), [](const PrintObject *l, const PrintObject *r){ return l->shared_regions() < r->shared_regions(); } ); + for (auto it = all_objects.begin(); it != all_objects.end();) { + PrintObjectRegions *shared_regions = (*it)->m_shared_regions; + auto it_begin = it; + for (++ it; it != all_objects.end() && shared_regions == (*it)->shared_regions(); ++ it); + auto this_objects = SpanOfConstPtrs(const_cast(&(*it_begin)), it - it_begin); + if (Print::is_shared_print_object_step_valid_unguarded(this_objects, posSupportSpotsSearch)) + shared_regions->generated_support_points.reset(); + } +} + bool Print::is_shared_print_object_step_valid_unguarded(SpanOfConstPtrs print_objects, PrintObjectStep print_object_step) { return std::any_of(print_objects.begin(), print_objects.end(), [print_object_step](auto po){ return po->is_step_done_unguarded(print_object_step); }); diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 13796abba..6aac560a3 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -408,6 +408,10 @@ public: // Clean up after process() finished, either with success, error or if canceled. // The adjustments on the Print / PrintObject data due to set_task() are to be reverted here. virtual void finalize() = 0; + // Clean up print step / print object step data after + // 1) some print step / print object step was invalidated inside PrintBase::apply() while holding the milestone mutex locked. + // 2) background thread finished being canceled. + virtual void cleanup() = 0; struct SlicingStatus { SlicingStatus(int percent, const std::string &text, unsigned int flags = 0) : percent(percent), text(text), flags(flags) {} diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 528d3c28b..2ebb7cc2f 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -412,6 +412,7 @@ public: void set_task(const TaskParams ¶ms) override { PrintBaseWithState::set_task_impl(params, m_objects); } void process() override; void finalize() override { PrintBaseWithState::finalize_impl(m_objects); } + void cleanup() override {} // Returns true if an object step is done on all objects and there's at least one object. bool is_step_done(SLAPrintObjectStep step) const; // Returns true if the last step was finished with success. diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 275fcdc98..678761924 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -251,6 +251,9 @@ void BackgroundSlicingProcess::thread_proc() (m_state == STATE_CANCELED) ? SlicingProcessCompletedEvent::Cancelled : exception ? SlicingProcessCompletedEvent::Error : SlicingProcessCompletedEvent::Finished, exception); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone()); + // Cancelled by the user, not internally, thus cleanup() was not called yet. + // Otherwise cleanup() is called from Print::apply() + m_print->cleanup(); } m_print->restart(); lck.unlock(); From bf6584995a80375b5065bc4519b95d108f65cef7 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 11 Jan 2023 16:03:16 +0100 Subject: [PATCH 3/3] MSW specific: Fixed disabling of filament comboboxes after load from 3mf --- src/slic3r/GUI/Plater.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b55f6299a..6e65371ed 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -983,20 +983,24 @@ Sidebar::Sidebar(Plater *parent) Sidebar::~Sidebar() {} -void Sidebar::init_filament_combo(PlaterPresetComboBox **combo, const int extr_idx) { +void Sidebar::init_filament_combo(PlaterPresetComboBox** combo, const int extr_idx) +{ *combo = new PlaterPresetComboBox(p->presets_panel, Slic3r::Preset::TYPE_FILAMENT); -// # copy icons from first choice -// $choice->SetItemBitmap($_, $choices->[0]->GetItemBitmap($_)) for 0..$#presets; - (*combo)->set_extruder_idx(extr_idx); +#ifdef __WXMSW__ + // When project is loading and progress dialog is processing + // In this case mainframe is marked as a disabled, that is why new created filament preset comboboxes are disabled + if (wxWindow* mf = wxGetApp().mainframe; mf && !mf->IsThisEnabled()) + mf->Enable(); +#endif //__WXMSW__ + auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL); combo_and_btn_sizer->Add(*combo, 1, wxEXPAND); combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, int(0.3*wxGetApp().em_unit())); - auto /***/sizer_filaments = this->p->sizer_filaments; - sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND | + this->p->sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND | #ifdef __WXGTK3__ wxRIGHT, int(0.5 * wxGetApp().em_unit())); #else