Merge remote-tracking branch 'origin/vb_3dscene_partial_update' into tm_sla_supports_backend

This commit is contained in:
tamasmeszaros 2018-11-20 16:16:23 +01:00
commit 013e068d71
6 changed files with 100 additions and 50 deletions

View file

@ -126,8 +126,16 @@ private:
static bool is_end_of_line(char c) { return c == '\r' || c == '\n' || c == 0; } static bool is_end_of_line(char c) { return c == '\r' || c == '\n' || c == 0; }
static bool is_end_of_gcode_line(char c) { return c == ';' || is_end_of_line(c); } static bool is_end_of_gcode_line(char c) { return c == ';' || is_end_of_line(c); }
static bool is_end_of_word(char c) { return is_whitespace(c) || is_end_of_gcode_line(c); } static bool is_end_of_word(char c) { return is_whitespace(c) || is_end_of_gcode_line(c); }
static const char* skip_whitespaces(const char *c) { for (; is_whitespace(*c); ++ c); return c; } static const char* skip_whitespaces(const char *c) {
static const char* skip_word(const char *c) { for (; ! is_end_of_word(*c); ++ c); return c; } for (; is_whitespace(*c); ++ c)
; // silence -Wempty-body
return c;
}
static const char* skip_word(const char *c) {
for (; ! is_end_of_word(*c); ++ c)
; // silence -Wempty-body
return c;
}
GCodeConfig m_config; GCodeConfig m_config;
char m_extrusion_axis; char m_extrusion_axis;

View file

@ -15,9 +15,4 @@ std::function<void()> PrintObjectBase::cancel_callback(PrintBase *print)
return print->cancel_callback(); return print->cancel_callback();
} }
void PrintObjectBase::throw_if_canceled(PrintBase *print)
{
print->throw_if_canceled();
}
} // namespace Slic3r } // namespace Slic3r

View file

@ -31,12 +31,14 @@ public:
DONE, DONE,
}; };
typedef size_t TimeStamp;
// A new unique timestamp is being assigned to the step every time the step changes its state. // A new unique timestamp is being assigned to the step every time the step changes its state.
struct StateWithTimeStamp struct StateWithTimeStamp
{ {
StateWithTimeStamp() : state(INVALID), timestamp(0) {} StateWithTimeStamp() : state(INVALID), timestamp(0) {}
State state; State state;
size_t timestamp; TimeStamp timestamp;
}; };
protected: protected:
@ -90,13 +92,14 @@ public:
// Set the step as done. Block on mutex while the Print / PrintObject / PrintRegion objects are being // Set the step as done. Block on mutex while the Print / PrintObject / PrintRegion objects are being
// modified by the UI thread. // modified by the UI thread.
template<typename ThrowIfCanceled> template<typename ThrowIfCanceled>
void set_done(StepType step, tbb::mutex &mtx, ThrowIfCanceled throw_if_canceled) { TimeStamp set_done(StepType step, tbb::mutex &mtx, ThrowIfCanceled throw_if_canceled) {
tbb::mutex::scoped_lock lock(mtx); tbb::mutex::scoped_lock lock(mtx);
// If canceled, throw before changing the step state. // If canceled, throw before changing the step state.
throw_if_canceled(); throw_if_canceled();
assert(m_state[step].state != DONE); assert(m_state[step].state != DONE);
m_state[step].state = DONE; m_state[step].state = DONE;
m_state[step].timestamp = ++ g_last_timestamp; m_state[step].timestamp = ++ g_last_timestamp;
return m_state[step].timestamp;
} }
// Make the step invalid. // Make the step invalid.
@ -187,9 +190,6 @@ protected:
// Declared here to allow access from PrintBase through friendship. // Declared here to allow access from PrintBase through friendship.
static tbb::mutex& state_mutex(PrintBase *print); static tbb::mutex& state_mutex(PrintBase *print);
static std::function<void()> cancel_callback(PrintBase *print); static std::function<void()> cancel_callback(PrintBase *print);
// If the background processing stop was requested, throw CanceledException.
// To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.
static void throw_if_canceled(PrintBase *print);
ModelObject *m_model_object; ModelObject *m_model_object;
}; };
@ -236,16 +236,27 @@ public:
virtual void process() = 0; virtual void process() = 0;
typedef std::function<void(int, const std::string&)> status_callback_type; struct Status {
Status(int percent, const std::string &text, unsigned int flags = 0) : percent(percent), text(text), flags(flags) {}
int percent;
std::string text;
// Bitmap of flags.
enum FlagBits {
RELOAD_SCENE = 1,
};
// Bitmap of FlagBits
unsigned int flags;
};
typedef std::function<void(const Status&)> status_callback_type;
// Default status console print out in the form of percent => message. // Default status console print out in the form of percent => message.
void set_status_default() { m_status_callback = nullptr; } void set_status_default() { m_status_callback = nullptr; }
// No status output or callback whatsoever, useful mostly for automatic tests. // No status output or callback whatsoever, useful mostly for automatic tests.
void set_status_silent() { m_status_callback = [](int, const std::string&){}; } void set_status_silent() { m_status_callback = [](const Status&){}; }
// Register a custom status callback. // Register a custom status callback.
void set_status_callback(status_callback_type cb) { m_status_callback = cb; } void set_status_callback(status_callback_type cb) { m_status_callback = cb; }
// Calls a registered callback to update the status, or print out the default message. // Calls a registered callback to update the status, or print out the default message.
void set_status(int percent, const std::string &message) { void set_status(int percent, const std::string &message, unsigned int flags = 0) {
if (m_status_callback) m_status_callback(percent, message); if (m_status_callback) m_status_callback(Status(percent, message, flags));
else printf("%d => %s\n", percent, message.c_str()); else printf("%d => %s\n", percent, message.c_str());
} }
@ -309,7 +320,7 @@ public:
protected: protected:
bool set_started(PrintStepEnum step) { return m_state.set_started(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); } bool set_started(PrintStepEnum step) { return m_state.set_started(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); }
void set_done(PrintStepEnum step) { m_state.set_done(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); } PrintStateBase::TimeStamp set_done(PrintStepEnum step) { return m_state.set_done(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); }
bool invalidate_step(PrintStepEnum step) bool invalidate_step(PrintStepEnum step)
{ return m_state.invalidate(step, this->cancel_callback()); } { return m_state.invalidate(step, this->cancel_callback()); }
template<typename StepTypeIterator> template<typename StepTypeIterator>
@ -339,9 +350,9 @@ protected:
PrintObjectBaseWithState(PrintType *print, ModelObject *model_object) : PrintObjectBase(model_object), m_print(print) {} PrintObjectBaseWithState(PrintType *print, ModelObject *model_object) : PrintObjectBase(model_object), m_print(print) {}
bool set_started(PrintObjectStepEnum step) bool set_started(PrintObjectStepEnum step)
{ return m_state.set_started(step, PrintObjectBase::state_mutex(m_print), [this](){ PrintObjectBase::throw_if_canceled(this->m_print); }); } { return m_state.set_started(step, PrintObjectBase::state_mutex(m_print), [this](){ this->throw_if_canceled(); }); }
void set_done(PrintObjectStepEnum step) PrintStateBase::TimeStamp set_done(PrintObjectStepEnum step)
{ m_state.set_done(step, PrintObjectBase::state_mutex(m_print), [this](){ PrintObjectBase::throw_if_canceled(this->m_print); }); } { return m_state.set_done(step, PrintObjectBase::state_mutex(m_print), [this](){ this->throw_if_canceled(); }); }
bool invalidate_step(PrintObjectStepEnum step) bool invalidate_step(PrintObjectStepEnum step)
{ return m_state.invalidate(step, PrintObjectBase::cancel_callback(m_print)); } { return m_state.invalidate(step, PrintObjectBase::cancel_callback(m_print)); }
@ -354,6 +365,10 @@ protected:
{ return m_state.invalidate_all(PrintObjectBase::cancel_callback(m_print)); } { return m_state.invalidate_all(PrintObjectBase::cancel_callback(m_print)); }
protected: protected:
// If the background processing stop was requested, throw CanceledException.
// To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.
void throw_if_canceled() { if (m_print->canceled()) throw CanceledException(); }
friend PrintType; friend PrintType;
PrintType *m_print; PrintType *m_print;

View file

@ -2,7 +2,6 @@
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include <wx/app.h> #include <wx/app.h>
#include <wx/event.h>
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
@ -60,7 +59,7 @@ void BackgroundSlicingProcess::process_fff()
{ {
assert(m_print == m_fff_print); assert(m_print == m_fff_print);
m_print->process(); m_print->process();
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_sliced_id)); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id));
m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data);
if (this->set_step_started(bspsGCodeFinalize)) { if (this->set_step_started(bspsGCodeFinalize)) {
if (! m_export_path.empty()) { if (! m_export_path.empty()) {

View file

@ -6,6 +6,8 @@
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <wx/event.h>
#include "Print.hpp" #include "Print.hpp"
namespace Slic3r { namespace Slic3r {
@ -15,6 +17,18 @@ class GCodePreviewData;
class Model; class Model;
class SLAPrint; class SLAPrint;
class SlicingStatusEvent : public wxEvent
{
public:
SlicingStatusEvent(wxEventType eventType, int winid, const PrintBase::Status &status) :
wxEvent(winid, eventType), status(std::move(status)) {}
virtual wxEvent *Clone() const { return new SlicingStatusEvent(*this); }
PrintBase::Status status;
};
wxDEFINE_EVENT(EVT_SLICING_UPDATE, SlicingStatusEvent);
// Print step IDs for keeping track of the print state. // Print step IDs for keeping track of the print state.
enum BackgroundSlicingProcessStep { enum BackgroundSlicingProcessStep {
bspsGCodeFinalize, bspsCount, bspsGCodeFinalize, bspsCount,
@ -35,7 +49,7 @@ public:
// The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished // 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. // 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. // The wxCommandEvent is sent to the UI thread asynchronously without waiting for the event to be processed.
void set_sliced_event(int event_id) { m_event_sliced_id = event_id; } void set_slicing_completed_event(int event_id) { m_event_slicing_completed_id = event_id; }
// The following wxCommandEvent will be sent to the UI thread / Platter window, when the G-code export is finished. // 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. // 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; } void set_finished_event(int event_id) { m_event_finished_id = event_id; }
@ -133,11 +147,10 @@ private:
// If the background processing stop was requested, throw CanceledException. // If the background processing stop was requested, throw CanceledException.
void throw_if_canceled() const { if (m_print->canceled()) throw CanceledException(); } void throw_if_canceled() const { if (m_print->canceled()) throw CanceledException(); }
// wxWidgets command ID to be sent to the platter to inform that the slicing is finished, and the G-code export will continue. // wxWidgets command ID to be sent to the platter to inform that the slicing is finished, and the G-code export will continue.
int m_event_sliced_id = 0; int m_event_slicing_completed_id = 0;
// wxWidgets command ID to be sent to the platter to inform that the task finished. // wxWidgets command ID to be sent to the platter to inform that the task finished.
int m_event_finished_id = 0; int m_event_finished_id = 0;
}; };
}; // namespace Slic3r }; // namespace Slic3r

View file

@ -65,8 +65,7 @@ using Slic3r::Preset;
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
wxDEFINE_EVENT(EVT_SLICING_UPDATE, SlicingStatusEvent);
wxDEFINE_EVENT(EVT_PROGRESS_BAR, wxCommandEvent);
wxDEFINE_EVENT(EVT_SLICING_COMPLETED, wxCommandEvent); wxDEFINE_EVENT(EVT_SLICING_COMPLETED, wxCommandEvent);
wxDEFINE_EVENT(EVT_PROCESS_COMPLETED, wxCommandEvent); wxDEFINE_EVENT(EVT_PROCESS_COMPLETED, wxCommandEvent);
@ -958,8 +957,8 @@ struct Plater::priv
void on_notebook_changed(wxBookCtrlEvent&); void on_notebook_changed(wxBookCtrlEvent&);
void on_select_preset(wxCommandEvent&); void on_select_preset(wxCommandEvent&);
void on_progress_event(wxCommandEvent&); void on_slicing_update(SlicingStatusEvent&);
void on_update_print_preview(wxCommandEvent&); void on_slicing_completed(wxCommandEvent&);
void on_process_completed(wxCommandEvent&); void on_process_completed(wxCommandEvent&);
void on_layer_editing_toggled(bool enable); void on_layer_editing_toggled(bool enable);
@ -1017,21 +1016,18 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
background_process.set_fff_print(&print); background_process.set_fff_print(&print);
background_process.set_sla_print(&sla_print); background_process.set_sla_print(&sla_print);
background_process.set_gcode_preview_data(&gcode_preview_data); background_process.set_gcode_preview_data(&gcode_preview_data);
background_process.set_sliced_event(EVT_SLICING_COMPLETED); background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED);
background_process.set_finished_event(EVT_PROCESS_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED);
// Default printer technology for default config. // Default printer technology for default config.
background_process.select_technology(this->printer_technology); background_process.select_technology(this->printer_technology);
// Register progress callback from the Print class to the Platter. // Register progress callback from the Print class to the Platter.
auto statuscb = [this](int percent, const std::string &message) { auto statuscb = [this](const Slic3r::PrintBase::Status &status) {
wxCommandEvent event(EVT_PROGRESS_BAR); wxQueueEvent(this->q, new Slic3r::SlicingStatusEvent(EVT_SLICING_UPDATE, 0, status));
event.SetInt(percent);
event.SetString(message);
wxQueueEvent(this->q, event.Clone());
}; };
print.set_status_callback(statuscb); print.set_status_callback(statuscb);
sla_print.set_status_callback(statuscb); sla_print.set_status_callback(statuscb);
this->q->Bind(EVT_PROGRESS_BAR, &priv::on_progress_event, this); this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this);
_3DScene::add_canvas(canvas3D); _3DScene::add_canvas(canvas3D);
_3DScene::allow_multisample(canvas3D, GLCanvas3DManager::can_multisample()); _3DScene::allow_multisample(canvas3D, GLCanvas3DManager::can_multisample());
@ -1115,7 +1111,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// Preview events: // Preview events:
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this);
q->Bind(EVT_SLICING_COMPLETED, &priv::on_update_print_preview, this); q->Bind(EVT_SLICING_COMPLETED, &priv::on_slicing_completed, this);
q->Bind(EVT_PROCESS_COMPLETED, &priv::on_process_completed, this); q->Bind(EVT_PROCESS_COMPLETED, &priv::on_process_completed, this);
// Drop target: // Drop target:
@ -1883,21 +1879,43 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
wxGetApp().plater()->on_config_change(wxGetApp().preset_bundle->full_config()); wxGetApp().plater()->on_config_change(wxGetApp().preset_bundle->full_config());
} }
void Plater::priv::on_progress_event(wxCommandEvent &evt) void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
{ {
this->statusbar()->set_progress(evt.GetInt()); this->statusbar()->set_progress(evt.status.percent);
this->statusbar()->set_status_text(evt.GetString() + wxString::FromUTF8("")); this->statusbar()->set_status_text(_(L(evt.status.text)) + wxString::FromUTF8(""));
if (evt.status.flags & PrintBase::Status::RELOAD_SCENE) {
switch (this->printer_technology) {
case ptFFF:
if (this->preview != nullptr)
this->preview->reload_print();
break;
case ptSLA:
// Refresh the scene lazily by updating only SLA meshes.
//FIXME update SLAPrint?
_3DScene::reload_scene(canvas3D, true);
break;
}
}
} }
void Plater::priv::on_update_print_preview(wxCommandEvent &) void Plater::priv::on_slicing_completed(wxCommandEvent &)
{ {
if (this->preview != nullptr) switch (this->printer_technology) {
this->preview->reload_print(); case ptFFF:
// in case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: if (this->preview != nullptr)
// auto selections = collect_selections(); this->preview->reload_print();
// _3DScene::set_objects_selections(canvas3D, selections); // in case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth:
// if (canvas3D) // auto selections = collect_selections();
// _3DScene::reload_scene(canvas3D, true); // _3DScene::set_objects_selections(canvas3D, selections);
// if (canvas3D)
// _3DScene::reload_scene(canvas3D, true);
break;
case ptSLA:
// Refresh the scene lazily by updating only SLA meshes.
//FIXME update SLAPrint?
_3DScene::reload_scene(canvas3D, true);
break;
}
} }
void Plater::priv::on_process_completed(wxCommandEvent &evt) void Plater::priv::on_process_completed(wxCommandEvent &evt)
@ -2544,6 +2562,8 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
if (opt_key == "printer_technology") { if (opt_key == "printer_technology") {
p->printer_technology = config.opt_enum<PrinterTechnology>(opt_key); p->printer_technology = config.opt_enum<PrinterTechnology>(opt_key);
p->background_process.select_technology(this->printer_technology()); p->background_process.select_technology(this->printer_technology());
//FIXME for SLA synchronize
//p->background_process.apply(Model)!
} }
else if (opt_key == "bed_shape") { else if (opt_key == "bed_shape") {
if (p->canvas3D) _3DScene::set_bed_shape(p->canvas3D, p->config->option<ConfigOptionPoints>(opt_key)->values); if (p->canvas3D) _3DScene::set_bed_shape(p->canvas3D, p->config->option<ConfigOptionPoints>(opt_key)->values);