2018-03-23 10:41:20 +00:00
|
|
|
#ifndef slic3r_GUI_BackgroundSlicingProcess_hpp_
|
|
|
|
#define slic3r_GUI_BackgroundSlicingProcess_hpp_
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <condition_variable>
|
|
|
|
#include <mutex>
|
|
|
|
#include <thread>
|
|
|
|
|
2018-11-20 14:01:32 +00:00
|
|
|
#include <wx/event.h>
|
|
|
|
|
2018-11-26 13:41:58 +00:00
|
|
|
#include "libslic3r/Print.hpp"
|
2018-12-11 09:33:11 +00:00
|
|
|
#include "slic3r/Utils/PrintHost.hpp"
|
2018-10-23 13:27:31 +00:00
|
|
|
|
2018-03-23 10:41:20 +00:00
|
|
|
namespace Slic3r {
|
|
|
|
|
|
|
|
class DynamicPrintConfig;
|
|
|
|
class GCodePreviewData;
|
2018-10-18 16:06:40 +00:00
|
|
|
class Model;
|
2018-11-08 19:18:40 +00:00
|
|
|
class SLAPrint;
|
2018-03-23 10:41:20 +00:00
|
|
|
|
2018-11-20 12:22:26 +00:00
|
|
|
class SlicingStatusEvent : public wxEvent
|
|
|
|
{
|
|
|
|
public:
|
2018-11-20 15:27:30 +00:00
|
|
|
SlicingStatusEvent(wxEventType eventType, int winid, const PrintBase::SlicingStatus &status) :
|
2018-11-20 12:22:26 +00:00
|
|
|
wxEvent(winid, eventType), status(std::move(status)) {}
|
|
|
|
virtual wxEvent *Clone() const { return new SlicingStatusEvent(*this); }
|
|
|
|
|
2018-11-20 15:27:30 +00:00
|
|
|
PrintBase::SlicingStatus status;
|
2018-11-20 12:22:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
wxDEFINE_EVENT(EVT_SLICING_UPDATE, SlicingStatusEvent);
|
|
|
|
|
2018-10-23 13:27:31 +00:00
|
|
|
// Print step IDs for keeping track of the print state.
|
|
|
|
enum BackgroundSlicingProcessStep {
|
|
|
|
bspsGCodeFinalize, bspsCount,
|
|
|
|
};
|
|
|
|
|
2018-03-23 10:41:20 +00:00
|
|
|
// Support for the GUI background processing (Slicing and G-code generation).
|
|
|
|
// As of now this class is not declared in Slic3r::GUI due to the Perl bindings limits.
|
|
|
|
class BackgroundSlicingProcess
|
|
|
|
{
|
|
|
|
public:
|
2018-09-14 07:28:00 +00:00
|
|
|
BackgroundSlicingProcess();
|
|
|
|
// Stop the background processing and finalize the bacgkround processing thread, remove temp files.
|
|
|
|
~BackgroundSlicingProcess();
|
2018-03-23 10:41:20 +00:00
|
|
|
|
2018-11-08 19:18:40 +00:00
|
|
|
void set_fff_print(Print *print) { m_fff_print = print; }
|
|
|
|
void set_sla_print(SLAPrint *print) { m_sla_print = print; }
|
2018-03-23 10:41:20 +00:00
|
|
|
void set_gcode_preview_data(GCodePreviewData *gpd) { m_gcode_preview_data = gpd; }
|
2018-03-23 15:00:00 +00:00
|
|
|
// The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished
|
|
|
|
// and the background processing will transition into G-code export.
|
|
|
|
// The wxCommandEvent is sent to the UI thread asynchronously without waiting for the event to be processed.
|
2018-11-20 12:22:26 +00:00
|
|
|
void set_slicing_completed_event(int event_id) { m_event_slicing_completed_id = event_id; }
|
2018-03-23 15:00:00 +00:00
|
|
|
// The following wxCommandEvent will be sent to the UI thread / Platter window, when the G-code export is finished.
|
|
|
|
// The wxCommandEvent is sent to the UI thread asynchronously without waiting for the event to be processed.
|
2018-03-23 10:41:20 +00:00
|
|
|
void set_finished_event(int event_id) { m_event_finished_id = event_id; }
|
|
|
|
|
2018-11-08 19:18:40 +00:00
|
|
|
// Activate either m_fff_print or m_sla_print.
|
2018-12-03 12:14:28 +00:00
|
|
|
// Return true if changed.
|
|
|
|
bool select_technology(PrinterTechnology tech);
|
2018-11-22 14:29:59 +00:00
|
|
|
|
|
|
|
// Get the currently active printer technology.
|
|
|
|
PrinterTechnology current_printer_technology() const;
|
|
|
|
// Get the current print. It is either m_fff_print or m_sla_print.
|
|
|
|
const PrintBase* current_print() const { return m_print; }
|
|
|
|
const Print* fff_print() const { return m_fff_print; }
|
|
|
|
const SLAPrint* sla_print() const { return m_sla_print; }
|
|
|
|
|
2018-03-23 10:41:20 +00:00
|
|
|
// Start the background processing. Returns false if the background processing was already running.
|
|
|
|
bool start();
|
|
|
|
// Cancel the background processing. Returns false if the background processing was not running.
|
|
|
|
// A stopped background processing may be restarted with start().
|
|
|
|
bool stop();
|
2018-11-08 13:23:17 +00:00
|
|
|
// Cancel the background processing and reset the print. Returns false if the background processing was not running.
|
|
|
|
// Useful when the Model or configuration is being changed drastically.
|
|
|
|
bool reset();
|
2018-03-23 10:41:20 +00:00
|
|
|
|
2018-10-18 16:06:40 +00:00
|
|
|
// Apply config over the print. Returns false, if the new config values caused any of the already
|
|
|
|
// processed steps to be invalidated, therefore the task will need to be restarted.
|
2018-10-23 20:53:43 +00:00
|
|
|
Print::ApplyStatus apply(const Model &model, const DynamicPrintConfig &config);
|
2019-02-21 10:40:56 +00:00
|
|
|
// After calling the apply() function, set_task() may be called to limit the task to be processed by process().
|
|
|
|
// This is useful for calculating SLA supports for a single object only.
|
|
|
|
void set_task(const PrintBase::TaskParams ¶ms);
|
2018-11-13 16:45:44 +00:00
|
|
|
// After calling apply, the empty() call will report whether there is anything to slice.
|
|
|
|
bool empty() const;
|
|
|
|
// Validate the print. Returns an empty string if valid, returns an error message if invalid.
|
|
|
|
// Call validate before calling start().
|
|
|
|
std::string validate();
|
|
|
|
|
2018-10-23 13:27:31 +00:00
|
|
|
// Set the export path of the G-code.
|
|
|
|
// Once the path is set, the G-code
|
|
|
|
void schedule_export(const std::string &path);
|
2018-12-11 09:33:11 +00:00
|
|
|
// Set print host upload job data to be enqueued to the PrintHostJobQueue
|
|
|
|
// after current print slicing is complete
|
|
|
|
void schedule_upload(Slic3r::PrintHostJob upload_job);
|
2018-10-23 13:27:31 +00:00
|
|
|
// Clear m_export_path.
|
|
|
|
void reset_export();
|
|
|
|
// Once the G-code export is scheduled, the apply() methods will do nothing.
|
|
|
|
bool is_export_scheduled() const { return ! m_export_path.empty(); }
|
2019-02-21 10:40:56 +00:00
|
|
|
bool is_upload_scheduled() const { return ! m_upload_job.empty(); }
|
2018-03-23 10:41:20 +00:00
|
|
|
|
|
|
|
enum State {
|
|
|
|
// m_thread is not running yet, or it did not reach the STATE_IDLE yet (it does not wait on the condition yet).
|
|
|
|
STATE_INITIAL = 0,
|
|
|
|
// m_thread is waiting for the task to execute.
|
|
|
|
STATE_IDLE,
|
|
|
|
STATE_STARTED,
|
|
|
|
// m_thread is executing a task.
|
|
|
|
STATE_RUNNING,
|
|
|
|
// m_thread finished executing a task, and it is waiting until the UI thread picks up the results.
|
|
|
|
STATE_FINISHED,
|
|
|
|
// m_thread finished executing a task, the task has been canceled by the UI thread, therefore the UI thread will not be notified.
|
|
|
|
STATE_CANCELED,
|
|
|
|
// m_thread exited the loop and it is going to finish. The UI thread should join on m_thread.
|
|
|
|
STATE_EXIT,
|
|
|
|
STATE_EXITED,
|
|
|
|
};
|
|
|
|
State state() const { return m_state; }
|
|
|
|
bool idle() const { return m_state == STATE_IDLE; }
|
|
|
|
bool running() const { return m_state == STATE_STARTED || m_state == STATE_RUNNING || m_state == STATE_FINISHED || m_state == STATE_CANCELED; }
|
2018-12-11 16:49:31 +00:00
|
|
|
// Returns true if the last step of the active print was finished with success.
|
|
|
|
// The "finished" flag is reset by the apply() method, if it changes the state of the print.
|
|
|
|
// This "finished" flag does not account for the final export of the output file (.gcode or zipped PNGs),
|
|
|
|
// and it does not account for the OctoPrint scheduling.
|
|
|
|
bool finished() const { return m_print->finished(); }
|
2018-03-23 10:41:20 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void thread_proc();
|
2018-11-06 10:54:36 +00:00
|
|
|
void thread_proc_safe();
|
2018-03-23 10:41:20 +00:00
|
|
|
void join_background_thread();
|
2018-10-30 08:27:31 +00:00
|
|
|
// To be called by Print::apply() through the Print::m_cancel_callback to stop the background
|
|
|
|
// processing before changing any data of running or finalized milestones.
|
|
|
|
// This function shall not trigger any UI update through the wxWidgets event.
|
|
|
|
void stop_internal();
|
2018-03-23 10:41:20 +00:00
|
|
|
|
2018-11-08 19:18:40 +00:00
|
|
|
// Helper to wrap the FFF slicing & G-code generation.
|
|
|
|
void process_fff();
|
|
|
|
|
2018-11-13 10:53:54 +00:00
|
|
|
// Temporary: for mimicking the fff file export behavior with the raster output
|
|
|
|
void process_sla();
|
|
|
|
|
2018-11-08 19:18:40 +00:00
|
|
|
// Currently active print. It is one of m_fff_print and m_sla_print.
|
|
|
|
PrintBase *m_print = nullptr;
|
|
|
|
// Non-owned pointers to Print instances.
|
|
|
|
Print *m_fff_print = nullptr;
|
|
|
|
SLAPrint *m_sla_print = nullptr;
|
2018-03-23 15:00:00 +00:00
|
|
|
// Data structure, to which the G-code export writes its annotations.
|
2018-03-23 10:41:20 +00:00
|
|
|
GCodePreviewData *m_gcode_preview_data = nullptr;
|
2018-10-23 13:27:31 +00:00
|
|
|
// Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID.
|
2018-09-14 07:28:00 +00:00
|
|
|
std::string m_temp_output_path;
|
2018-10-23 13:27:31 +00:00
|
|
|
// Output path provided by the user. The output path may be set even if the slicing is running,
|
|
|
|
// but once set, it cannot be re-set.
|
|
|
|
std::string m_export_path;
|
2018-12-11 09:33:11 +00:00
|
|
|
// Print host upload job to schedule after slicing is complete, used by schedule_upload(),
|
|
|
|
// empty by default (ie. no upload to schedule)
|
|
|
|
PrintHostJob m_upload_job;
|
2018-03-23 10:41:20 +00:00
|
|
|
// Thread, on which the background processing is executed. The thread will always be present
|
|
|
|
// and ready to execute the slicing process.
|
|
|
|
std::thread m_thread;
|
|
|
|
// Mutex and condition variable to synchronize m_thread with the UI thread.
|
|
|
|
std::mutex m_mutex;
|
|
|
|
std::condition_variable m_condition;
|
|
|
|
State m_state = STATE_INITIAL;
|
|
|
|
|
2018-10-23 13:27:31 +00:00
|
|
|
PrintState<BackgroundSlicingProcessStep, bspsCount> m_step_state;
|
|
|
|
mutable tbb::mutex m_step_state_mutex;
|
2018-11-16 17:28:50 +00:00
|
|
|
bool set_step_started(BackgroundSlicingProcessStep step);
|
2018-10-23 13:27:31 +00:00
|
|
|
void set_step_done(BackgroundSlicingProcessStep step);
|
2018-11-16 17:28:50 +00:00
|
|
|
bool is_step_done(BackgroundSlicingProcessStep step) const;
|
2018-10-23 13:27:31 +00:00
|
|
|
bool invalidate_step(BackgroundSlicingProcessStep step);
|
|
|
|
bool invalidate_all_steps();
|
2018-11-16 17:28:50 +00:00
|
|
|
// If the background processing stop was requested, throw CanceledException.
|
|
|
|
void throw_if_canceled() const { if (m_print->canceled()) throw CanceledException(); }
|
2018-12-20 15:35:54 +00:00
|
|
|
void prepare_upload();
|
2018-11-16 17:28:50 +00:00
|
|
|
|
2018-03-23 10:41:20 +00:00
|
|
|
// wxWidgets command ID to be sent to the platter to inform that the slicing is finished, and the G-code export will continue.
|
2018-11-20 12:22:26 +00:00
|
|
|
int m_event_slicing_completed_id = 0;
|
2018-03-23 10:41:20 +00:00
|
|
|
// wxWidgets command ID to be sent to the platter to inform that the task finished.
|
2018-11-20 12:22:26 +00:00
|
|
|
int m_event_finished_id = 0;
|
2018-03-23 10:41:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}; // namespace Slic3r
|
|
|
|
|
|
|
|
#endif /* slic3r_GUI_BackgroundSlicingProcess_hpp_ */
|