diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index d254e4eefb..2f5c4e96bd 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 6beb1cae7d..5f95edefa1 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 13796abbad..6aac560a32 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 528d3c28b8..2ebb7cc2fd 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 275fcdc986..678761924c 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();