mirror of
https://github.com/FULU-Foundation/OrcaSlicer-bambulab.git
synced 2026-07-12 12:34:23 +03:00
WIP: Background processing.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <wx/event.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
// Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx.
|
||||
#include "../../libslic3r/Print.hpp"
|
||||
@@ -11,12 +12,28 @@
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace GUI {
|
||||
extern wxPanel *g_wxPlater;
|
||||
};
|
||||
|
||||
BackgroundSlicingProcess::BackgroundSlicingProcess()
|
||||
{
|
||||
m_temp_output_path = wxStandardPaths::Get().GetTempDir().utf8_str().data();
|
||||
m_temp_output_path += (boost::format(".%1%.gcode") % get_current_pid()).str();
|
||||
}
|
||||
|
||||
BackgroundSlicingProcess::~BackgroundSlicingProcess()
|
||||
{
|
||||
this->stop();
|
||||
this->join_background_thread();
|
||||
boost::nowide::remove(m_temp_output_path.c_str());
|
||||
}
|
||||
|
||||
void BackgroundSlicingProcess::thread_proc()
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(m_mutex);
|
||||
@@ -41,7 +58,10 @@ void BackgroundSlicingProcess::thread_proc()
|
||||
m_print->process();
|
||||
if (! m_print->canceled()) {
|
||||
wxQueueEvent(GUI::g_wxPlater, new wxCommandEvent(m_event_sliced_id));
|
||||
m_print->export_gcode(m_output_path, m_gcode_preview_data);
|
||||
m_print->export_gcode(m_temp_output_path, m_gcode_preview_data);
|
||||
if (! m_print->canceled() && ! m_output_path.empty() &&
|
||||
copy_file(m_temp_output_path, m_output_path) != 0)
|
||||
throw std::runtime_error("Copying of the temporary G-code to the output G-code failed");
|
||||
}
|
||||
} catch (CanceledException &ex) {
|
||||
// Canceled, this is all right.
|
||||
@@ -111,8 +131,10 @@ bool BackgroundSlicingProcess::start()
|
||||
bool BackgroundSlicingProcess::stop()
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(m_mutex);
|
||||
if (m_state == STATE_INITIAL)
|
||||
if (m_state == STATE_INITIAL) {
|
||||
this->m_output_path.clear();
|
||||
return false;
|
||||
}
|
||||
assert(this->running());
|
||||
if (m_state == STATE_STARTED || m_state == STATE_RUNNING) {
|
||||
m_print->cancel();
|
||||
@@ -124,6 +146,7 @@ bool BackgroundSlicingProcess::stop()
|
||||
// In the "Finished" or "Canceled" state. Reset the state to "Idle".
|
||||
m_state = STATE_IDLE;
|
||||
}
|
||||
this->m_output_path.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ class Print;
|
||||
class BackgroundSlicingProcess
|
||||
{
|
||||
public:
|
||||
BackgroundSlicingProcess() {}
|
||||
// Stop the background processing and finalize the bacgkround processing thread.
|
||||
~BackgroundSlicingProcess() { this->stop(); this->join_background_thread(); }
|
||||
BackgroundSlicingProcess();
|
||||
// Stop the background processing and finalize the bacgkround processing thread, remove temp files.
|
||||
~BackgroundSlicingProcess();
|
||||
|
||||
void set_print(Print *print) { m_print = print; }
|
||||
void set_gcode_preview_data(GCodePreviewData *gpd) { m_gcode_preview_data = gpd; }
|
||||
@@ -31,6 +31,8 @@ public:
|
||||
// The wxCommandEvent is sent to the UI thread asynchronously without waiting for the event to be processed.
|
||||
void set_finished_event(int event_id) { m_event_finished_id = event_id; }
|
||||
|
||||
// Set the output path of the G-code.
|
||||
void set_output_path(const std::string &path) { m_output_path = path; }
|
||||
// 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.
|
||||
@@ -68,6 +70,7 @@ private:
|
||||
Print *m_print = nullptr;
|
||||
// Data structure, to which the G-code export writes its annotations.
|
||||
GCodePreviewData *m_gcode_preview_data = nullptr;
|
||||
std::string m_temp_output_path;
|
||||
std::string m_output_path;
|
||||
// Thread, on which the background processing is executed. The thread will always be present
|
||||
// and ready to execute the slicing process.
|
||||
|
||||
@@ -5208,9 +5208,9 @@ void GLCanvas3D::_load_shells()
|
||||
|
||||
// adds objects' volumes
|
||||
unsigned int object_id = 0;
|
||||
for (PrintObject* obj : m_print->objects())
|
||||
for (const PrintObject* obj : m_print->objects())
|
||||
{
|
||||
ModelObject* model_obj = obj->model_object();
|
||||
const ModelObject* model_obj = obj->model_object();
|
||||
|
||||
std::vector<int> instance_ids(model_obj->instances.size());
|
||||
for (int i = 0; i < (int)model_obj->instances.size(); ++i)
|
||||
|
||||
@@ -383,13 +383,10 @@ void update_after_moving()
|
||||
if (volume_id < 0)
|
||||
return;
|
||||
|
||||
Vec3d m = m_move_options;
|
||||
Vec3d l = m_last_coords;
|
||||
|
||||
auto d = Vec3d(m(0) - l(0), m(1) - l(1), m(2) - l(2));
|
||||
auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
|
||||
auto d = m_move_options - m_last_coords;
|
||||
auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
|
||||
volume->mesh.translate(d(0), d(1), d(2));
|
||||
m_last_coords = m;
|
||||
m_last_coords = m_move_options;
|
||||
|
||||
m_parts_changed = true;
|
||||
parts_changed(m_selected_object_id);
|
||||
|
||||
72
xs/src/slic3r/GUI/ProgressIndicator.hpp
Normal file
72
xs/src/slic3r/GUI/ProgressIndicator.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef IPROGRESSINDICATOR_HPP
|
||||
#define IPROGRESSINDICATOR_HPP
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
/**
|
||||
* @brief Generic progress indication interface.
|
||||
*/
|
||||
class ProgressIndicator {
|
||||
public:
|
||||
using CancelFn = std::function<void(void)>; // Cancel function signature.
|
||||
|
||||
private:
|
||||
float state_ = .0f, max_ = 1.f, step_;
|
||||
CancelFn cancelfunc_ = [](){};
|
||||
|
||||
public:
|
||||
|
||||
inline virtual ~ProgressIndicator() {}
|
||||
|
||||
/// Get the maximum of the progress range.
|
||||
float max() const { return max_; }
|
||||
|
||||
/// Get the current progress state
|
||||
float state() const { return state_; }
|
||||
|
||||
/// Set the maximum of the progress range
|
||||
virtual void max(float maxval) { max_ = maxval; }
|
||||
|
||||
/// Set the current state of the progress.
|
||||
virtual void state(float val) { state_ = val; }
|
||||
|
||||
/**
|
||||
* @brief Number of states int the progress. Can be used instead of giving a
|
||||
* maximum value.
|
||||
*/
|
||||
virtual void states(unsigned statenum) {
|
||||
step_ = max_ / statenum;
|
||||
}
|
||||
|
||||
/// Message shown on the next status update.
|
||||
virtual void message(const wxString&) = 0;
|
||||
|
||||
/// Title of the operation.
|
||||
virtual void title(const wxString&) = 0;
|
||||
|
||||
/// Formatted message for the next status update. Works just like sprintf.
|
||||
virtual void message_fmt(const wxString& fmt, ...);
|
||||
|
||||
/// Set up a cancel callback for the operation if feasible.
|
||||
virtual void on_cancel(CancelFn func = CancelFn()) { cancelfunc_ = func; }
|
||||
|
||||
/**
|
||||
* Explicitly shut down the progress indicator and call the associated
|
||||
* callback.
|
||||
*/
|
||||
virtual void cancel() { cancelfunc_(); }
|
||||
|
||||
/// Convenience function to call message and status update in one function.
|
||||
void update(float st, const wxString& msg) {
|
||||
message(msg); state(st);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // IPROGRESSINDICATOR_HPP
|
||||
Reference in New Issue
Block a user