diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index d81498916..3a08cddf1 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -415,49 +415,73 @@ void SLAPrint::set_task(const TaskParams ¶ms) n_object_steps = (int)slaposCount; if (params.single_model_object.valid()) { + // Find the print object to be processed with priority. SLAPrintObject *print_object = nullptr; size_t idx_print_object = 0; - for (; idx_print_object < m_objects.size(); ++idx_print_object) + for (; idx_print_object < m_objects.size(); ++ idx_print_object) if (m_objects[idx_print_object]->model_object()->id() == params.single_model_object) { print_object = m_objects[idx_print_object]; break; } assert(print_object != nullptr); - bool shall_cancel = false; - for (int istep = 0; istep < n_object_steps; ++istep) - if (! print_object->m_stepmask[istep]) { - shall_cancel = true; + // Find out whether the priority print object is being currently processed. + bool running = false; + for (int istep = 0; istep < n_object_steps; ++ istep) { + if (! print_object->m_stepmask[istep]) + // Step was skipped, cancel. + break; + if (print_object->is_step_started_unguarded(SLAPrintObjectStep(istep))) { + // No step was skipped, and a wanted step is being processed. Don't cancel. + running = true; break; } - bool running = false; - if (!shall_cancel) { - for (int istep = 0; istep < n_object_steps; ++ istep) - if (print_object->is_step_started_unguarded(SLAPrintObjectStep(istep))) { - running = true; - break; - } } - if (!running) + if (! running) this->call_cancel_callback(); // Now the background process is either stopped, or it is inside one of the print object steps to be calculated anyway. if (params.single_model_instance_only) { // Suppress all the steps of other instances. for (SLAPrintObject *po : m_objects) - for (int istep = 0; istep < (int)slaposCount; ++istep) + for (int istep = 0; istep < (int)slaposCount; ++ istep) po->m_stepmask[istep] = false; - } - else if (!running) { + } else if (! running) { // Swap the print objects, so that the selected print_object is first in the row. // At this point the background processing must be stopped, so it is safe to shuffle print objects. if (idx_print_object != 0) std::swap(m_objects.front(), m_objects[idx_print_object]); } + // and set the steps for the current object. for (int istep = 0; istep < n_object_steps; ++ istep) print_object->m_stepmask[istep] = true; - for (int istep = n_object_steps; istep < (int)slaposCount; ++istep) + for (int istep = n_object_steps; istep < (int)slaposCount; ++ istep) print_object->m_stepmask[istep] = false; - } + } else { + // Slicing all objects. + bool running = false; + for (SLAPrintObject *print_object : m_objects) + for (int istep = 0; istep < n_object_steps; ++ istep) { + if (! print_object->m_stepmask[istep]) { + // Step may have been skipped. Restart. + goto loop_end; + } + if (print_object->is_step_started_unguarded(SLAPrintObjectStep(istep))) { + // This step is running, and the state cannot be changed due to the this->state_mutex() being locked. + // It is safe to manipulate m_stepmask of other SLAPrintObjects and SLAPrint now. + running = true; + goto loop_end; + } + } + loop_end: + if (! running) + this->call_cancel_callback(); + for (SLAPrintObject *po : m_objects) { + for (int istep = 0; istep < n_object_steps; ++ istep) + po->m_stepmask[istep] = true; + for (int istep = n_object_steps; istep < (int)slaposCount; ++ istep) + po->m_stepmask[istep] = false; + } + } if (params.to_object_step != -1 || params.to_print_step != -1) { // Limit the print steps. diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 28b3008fd..c368c4a07 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2142,6 +2142,8 @@ void Plater::priv::export_gcode(fs::path output_path, PrintHostJob upload_job) background_process.schedule_upload(std::move(upload_job)); } + // If the SLA processing of just a single object's supports is running, restart slicing for the whole object. + this->background_process.set_task(PrintBase::TaskParams()); this->restart_background_process(priv::UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT); } @@ -3068,6 +3070,8 @@ void Plater::reslice() unsigned int state = this->p->update_background_process(true); if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) this->p->view3D->reload_scene(false); + // If the SLA processing of just a single object's supports is running, restart slicing for the whole object. + this->p->background_process.set_task(PrintBase::TaskParams()); // Only restarts if the state is valid. this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART); }