Background processing: The milestone state machine was extended
with canceled / invalidated states.
Print / PrintObject infrastructure was extended with a cleanup()
callback, which may check for the new State::Canceled / State::Invalid
states of a particular milestone and turn it to State::Fresh
while releasing data of that particular milestone which is no more valid.
Also fixed a bug in 31fbfa56de
where the PrintObject shared data invalidation condition was flipped.
This commit is contained in:
parent
dac1e60153
commit
661463645b
6 changed files with 119 additions and 47 deletions
|
@ -740,7 +740,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
||||||
// Does the file exist? If so, we hope that it is still valid.
|
// Does the file exist? If so, we hope that it is still valid.
|
||||||
{
|
{
|
||||||
PrintStateBase::StateWithTimeStamp state = print->step_state_with_timestamp(psGCodeExport);
|
PrintStateBase::StateWithTimeStamp state = print->step_state_with_timestamp(psGCodeExport);
|
||||||
if (! state.enabled || (state.state == PrintStateBase::DONE && boost::filesystem::exists(boost::filesystem::path(path))))
|
if (! state.enabled || (state.is_done() && boost::filesystem::exists(boost::filesystem::path(path))))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -358,11 +358,15 @@ private:
|
||||||
// If ! m_slicing_params.valid, recalculate.
|
// If ! m_slicing_params.valid, recalculate.
|
||||||
void update_slicing_parameters();
|
void update_slicing_parameters();
|
||||||
|
|
||||||
|
// Called on main thread with stopped or paused background processing to let PrintObject release data for its milestones that were invalidated or canceled.
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders);
|
static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void make_perimeters();
|
void make_perimeters();
|
||||||
void prepare_infill();
|
void prepare_infill();
|
||||||
|
void clear_fills();
|
||||||
void infill();
|
void infill();
|
||||||
void ironing();
|
void ironing();
|
||||||
void generate_support_spots();
|
void generate_support_spots();
|
||||||
|
|
|
@ -1470,9 +1470,11 @@ void Print::cleanup()
|
||||||
for (auto it = all_objects.begin(); it != all_objects.end();) {
|
for (auto it = all_objects.begin(); it != all_objects.end();) {
|
||||||
PrintObjectRegions *shared_regions = (*it)->m_shared_regions;
|
PrintObjectRegions *shared_regions = (*it)->m_shared_regions;
|
||||||
auto it_begin = it;
|
auto it_begin = it;
|
||||||
for (++ it; it != all_objects.end() && shared_regions == (*it)->shared_regions(); ++ it);
|
for (; it != all_objects.end() && shared_regions == (*it)->shared_regions(); ++ it)
|
||||||
|
// Let the PrintObject clean up its data with invalidated milestones.
|
||||||
|
(*it)->cleanup();
|
||||||
auto this_objects = SpanOfConstPtrs<PrintObject>(const_cast<const PrintObject* const* const>(&(*it_begin)), it - it_begin);
|
auto this_objects = SpanOfConstPtrs<PrintObject>(const_cast<const PrintObject* const* const>(&(*it_begin)), it - it_begin);
|
||||||
if (Print::is_shared_print_object_step_valid_unguarded(this_objects, posSupportSpotsSearch))
|
if (! Print::is_shared_print_object_step_valid_unguarded(this_objects, posSupportSpotsSearch))
|
||||||
shared_regions->generated_support_points.reset();
|
shared_regions->generated_support_points.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,29 @@ public:
|
||||||
|
|
||||||
class PrintStateBase {
|
class PrintStateBase {
|
||||||
public:
|
public:
|
||||||
enum State {
|
enum class State {
|
||||||
INVALID,
|
// Fresh state, either the object is new or the data of that particular milestone was cleaned up.
|
||||||
STARTED,
|
// Fresh state may transit to Started.
|
||||||
DONE,
|
Fresh,
|
||||||
|
// Milestone was started and now it is being executed.
|
||||||
|
// Started state may transit to Canceled with invalid data or Done with valid data.
|
||||||
|
Started,
|
||||||
|
// Milestone was being executed, but now it is canceled and not yet cleaned up.
|
||||||
|
// Canceled state may transit to Fresh state if its invalid data is cleaned up
|
||||||
|
// or to Started state.
|
||||||
|
// Canceled and Invalidated states are of similar nature: Canceled step was Started but canceled,
|
||||||
|
// while Invalidated state was Done but invalidated.
|
||||||
|
Canceled,
|
||||||
|
// Milestone was finished successfully, it's data is now valid.
|
||||||
|
// Done state may transit to Invalidated state if its data is no more valid
|
||||||
|
// or to a Started state.
|
||||||
|
Done,
|
||||||
|
// Milestone was finished successfully (done), but now it is invalidated and it's data is no more valid.
|
||||||
|
// Invalidated state may transit to Fresh if its invalid data is cleaned up,
|
||||||
|
// or to state Started.
|
||||||
|
// Canceled and Invalidated states are of similar nature: Canceled step was Started but canceled,
|
||||||
|
// while Invalidated state was Done but invalidated.
|
||||||
|
Invalidated,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class WarningLevel {
|
enum class WarningLevel {
|
||||||
|
@ -39,9 +58,25 @@ public:
|
||||||
// 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
|
||||||
{
|
{
|
||||||
State state { INVALID };
|
State state { State::Fresh };
|
||||||
TimeStamp timestamp { 0 };
|
TimeStamp timestamp { 0 };
|
||||||
bool enabled { true };
|
bool enabled { true };
|
||||||
|
|
||||||
|
bool is_done() const { return state == State::Done; }
|
||||||
|
// The milestone may have some data available, but it is no more valid and it should be cleaned up to conserve memory.
|
||||||
|
bool is_dirty() const { return state == State::Canceled || state == State::Invalidated; }
|
||||||
|
|
||||||
|
// If the milestone is Started or Done, invalidate it:
|
||||||
|
// Turn Started to Canceled, turn Done to Invalidated.
|
||||||
|
// Update timestamp of this milestone.
|
||||||
|
bool try_invalidate() {
|
||||||
|
bool invalidated = this->state == State::Started || this->state == State::Done;
|
||||||
|
if (invalidated) {
|
||||||
|
this->state = this->state == State::Started ? State::Canceled : State::Invalidated;
|
||||||
|
this->timestamp = ++ g_last_timestamp;
|
||||||
|
}
|
||||||
|
return invalidated;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Warning
|
struct Warning
|
||||||
|
@ -93,11 +128,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_started(StepType step, std::mutex &mtx) const {
|
bool is_started(StepType step, std::mutex &mtx) const {
|
||||||
return this->state_with_timestamp(step, mtx).state == STARTED;
|
return this->state_with_timestamp(step, mtx).state == State::Started;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_done(StepType step, std::mutex &mtx) const {
|
bool is_done(StepType step, std::mutex &mtx) const {
|
||||||
return this->state_with_timestamp(step, mtx).state == DONE;
|
return this->state_with_timestamp(step, mtx).state == State::Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
StateWithTimeStamp state_with_timestamp_unguarded(StepType step) const {
|
StateWithTimeStamp state_with_timestamp_unguarded(StepType step) const {
|
||||||
|
@ -105,11 +140,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_started_unguarded(StepType step) const {
|
bool is_started_unguarded(StepType step) const {
|
||||||
return this->state_with_timestamp_unguarded(step).state == STARTED;
|
return this->state_with_timestamp_unguarded(step).state == State::Started;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_done_unguarded(StepType step) const {
|
bool is_done_unguarded(StepType step) const {
|
||||||
return this->state_with_timestamp_unguarded(step).state == DONE;
|
return this->state_with_timestamp_unguarded(step).state == State::Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_unguarded(StepType step, bool enable) {
|
void enable_unguarded(StepType step, bool enable) {
|
||||||
|
@ -146,12 +181,12 @@ public:
|
||||||
//
|
//
|
||||||
// assert(m_step_active == -1);
|
// assert(m_step_active == -1);
|
||||||
// for (int i = 0; i < int(COUNT); ++ i)
|
// for (int i = 0; i < int(COUNT); ++ i)
|
||||||
// assert(m_state[i].state != STARTED);
|
// assert(m_state[i].state != State::Started);
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
PrintStateBase::StateWithWarnings &state = m_state[step];
|
PrintStateBase::StateWithWarnings &state = m_state[step];
|
||||||
if (! state.enabled || state.state == DONE)
|
if (! state.enabled || state.state == State::Done)
|
||||||
return false;
|
return false;
|
||||||
state.state = STARTED;
|
state.state = State::Started;
|
||||||
state.timestamp = ++ g_last_timestamp;
|
state.timestamp = ++ g_last_timestamp;
|
||||||
state.mark_warnings_non_current();
|
state.mark_warnings_non_current();
|
||||||
m_step_active = static_cast<int>(step);
|
m_step_active = static_cast<int>(step);
|
||||||
|
@ -161,17 +196,17 @@ 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.
|
||||||
// Return value:
|
// Return value:
|
||||||
// Timestamp when this stepentered the DONE state.
|
// Timestamp when this step entered the Done state.
|
||||||
// bool indicates whether the UI has to update the slicing warnings of this step or not.
|
// bool indicates whether the UI has to update the slicing warnings of this step or not.
|
||||||
template<typename ThrowIfCanceled>
|
template<typename ThrowIfCanceled>
|
||||||
std::pair<TimeStamp, bool> set_done(StepType step, std::mutex &mtx, ThrowIfCanceled throw_if_canceled) {
|
std::pair<TimeStamp, bool> set_done(StepType step, std::mutex &mtx, ThrowIfCanceled throw_if_canceled) {
|
||||||
std::scoped_lock<std::mutex> lock(mtx);
|
std::scoped_lock<std::mutex> 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 == STARTED);
|
assert(m_state[step].state == State::Started);
|
||||||
assert(m_step_active == static_cast<int>(step));
|
assert(m_step_active == static_cast<int>(step));
|
||||||
PrintStateBase::StateWithWarnings &state = m_state[step];
|
PrintStateBase::StateWithWarnings &state = m_state[step];
|
||||||
state.state = DONE;
|
state.state = State::Done;
|
||||||
state.timestamp = ++ g_last_timestamp;
|
state.timestamp = ++ g_last_timestamp;
|
||||||
m_step_active = -1;
|
m_step_active = -1;
|
||||||
// Remove all non-current warnings.
|
// Remove all non-current warnings.
|
||||||
|
@ -190,16 +225,12 @@ public:
|
||||||
// processing by calling the cancel callback.
|
// processing by calling the cancel callback.
|
||||||
template<typename CancelationCallback>
|
template<typename CancelationCallback>
|
||||||
bool invalidate(StepType step, CancelationCallback cancel) {
|
bool invalidate(StepType step, CancelationCallback cancel) {
|
||||||
bool invalidated = m_state[step].state != INVALID;
|
if (PrintStateBase::StateWithWarnings &state = m_state[step]; state.try_invalidate()) {
|
||||||
if (invalidated) {
|
|
||||||
#if 0
|
#if 0
|
||||||
if (mtx.state != mtx.HELD) {
|
if (mtx.state != mtx.HELD) {
|
||||||
printf("Not held!\n");
|
printf("Not held!\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
PrintStateBase::StateWithWarnings &state = m_state[step];
|
|
||||||
state.state = INVALID;
|
|
||||||
state.timestamp = ++ g_last_timestamp;
|
|
||||||
// Raise the mutex, so that the following cancel() callback could cancel
|
// Raise the mutex, so that the following cancel() callback could cancel
|
||||||
// the background processing.
|
// the background processing.
|
||||||
// Internally the cancel() callback shall unlock the PrintBase::m_status_mutex to let
|
// Internally the cancel() callback shall unlock the PrintBase::m_status_mutex to let
|
||||||
|
@ -209,21 +240,17 @@ public:
|
||||||
// It is safe to modify it.
|
// It is safe to modify it.
|
||||||
state.mark_warnings_non_current();
|
state.mark_warnings_non_current();
|
||||||
m_step_active = -1;
|
m_step_active = -1;
|
||||||
}
|
return true;
|
||||||
return invalidated;
|
} else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename CancelationCallback, typename StepTypeIterator>
|
template<typename CancelationCallback, typename StepTypeIterator>
|
||||||
bool invalidate_multiple(StepTypeIterator step_begin, StepTypeIterator step_end, CancelationCallback cancel) {
|
bool invalidate_multiple(StepTypeIterator step_begin, StepTypeIterator step_end, CancelationCallback cancel) {
|
||||||
bool invalidated = false;
|
bool invalidated = false;
|
||||||
for (StepTypeIterator it = step_begin; it != step_end; ++ it) {
|
for (StepTypeIterator it = step_begin; it != step_end; ++ it)
|
||||||
StateWithTimeStamp &state = m_state[*it];
|
if (m_state[*it].try_invalidate())
|
||||||
if (state.state != INVALID) {
|
|
||||||
invalidated = true;
|
invalidated = true;
|
||||||
state.state = INVALID;
|
|
||||||
state.timestamp = ++ g_last_timestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalidated) {
|
if (invalidated) {
|
||||||
#if 0
|
#if 0
|
||||||
if (mtx.state != mtx.HELD) {
|
if (mtx.state != mtx.HELD) {
|
||||||
|
@ -251,14 +278,9 @@ public:
|
||||||
template<typename CancelationCallback>
|
template<typename CancelationCallback>
|
||||||
bool invalidate_all(CancelationCallback cancel) {
|
bool invalidate_all(CancelationCallback cancel) {
|
||||||
bool invalidated = false;
|
bool invalidated = false;
|
||||||
for (size_t i = 0; i < COUNT; ++ i) {
|
for (size_t i = 0; i < COUNT; ++ i)
|
||||||
StateWithTimeStamp &state = m_state[i];
|
if (m_state[i].try_invalidate())
|
||||||
if (state.state != INVALID) {
|
|
||||||
invalidated = true;
|
invalidated = true;
|
||||||
state.state = INVALID;
|
|
||||||
state.timestamp = ++ g_last_timestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalidated) {
|
if (invalidated) {
|
||||||
cancel();
|
cancel();
|
||||||
// Now the worker thread should be stopped, therefore it cannot write into the warnings field.
|
// Now the worker thread should be stopped, therefore it cannot write into the warnings field.
|
||||||
|
@ -270,6 +292,26 @@ public:
|
||||||
return invalidated;
|
return invalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the milestone is Canceled or Invalidated, return true and turn the state of the milestone to Fresh.
|
||||||
|
// The caller is responsible for releasing the data of the milestone that is no more valid.
|
||||||
|
bool query_reset_dirty_unguarded(StepType step) {
|
||||||
|
if (PrintStateBase::StateWithWarnings &state = m_state[step]; state.is_dirty()) {
|
||||||
|
state.state = State::Fresh;
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// To be called after the background thread was stopped by the user pressing the Cancel button,
|
||||||
|
// which in turn stops the background thread without adjusting state of the milestone being executed.
|
||||||
|
// This method fixes the state of the canceled milestone by setting it to a Canceled state.
|
||||||
|
void mark_canceled_unguarded() {
|
||||||
|
for (size_t i = 0; i < COUNT; ++ i) {
|
||||||
|
if (State &state = m_state[i].state; state == State::Started)
|
||||||
|
state = State::Canceled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update list of warnings of the current milestone with a new warning.
|
// Update list of warnings of the current milestone with a new warning.
|
||||||
// The warning may already exist in the list, marked as current or not current.
|
// The warning may already exist in the list, marked as current or not current.
|
||||||
// If it already exists, mark it as current.
|
// If it already exists, mark it as current.
|
||||||
|
@ -281,7 +323,7 @@ public:
|
||||||
std::scoped_lock<std::mutex> lock(mtx);
|
std::scoped_lock<std::mutex> lock(mtx);
|
||||||
assert(m_step_active != -1);
|
assert(m_step_active != -1);
|
||||||
StateWithWarnings &state = m_state[m_step_active];
|
StateWithWarnings &state = m_state[m_step_active];
|
||||||
assert(state.state == STARTED);
|
assert(state.state == State::Started);
|
||||||
std::pair<StepType, bool> retval(static_cast<StepType>(m_step_active), true);
|
std::pair<StepType, bool> retval(static_cast<StepType>(m_step_active), true);
|
||||||
// Does a warning of the same level and message or message_id exist already?
|
// Does a warning of the same level and message or message_id exist already?
|
||||||
auto it = (message_id == 0) ?
|
auto it = (message_id == 0) ?
|
||||||
|
@ -664,15 +706,19 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up after process() finished, either with success, error or if canceled.
|
// Clean up after process() finished, either with success, error or if canceled.
|
||||||
// The adjustments on the Print / PrintObject m_stepmask data due to set_task() are to be reverted here.
|
// The adjustments on the Print / PrintObject m_stepmask data due to set_task() are to be reverted here:
|
||||||
|
// Execution of all milestones is enabled in case some of them were suppressed for the last background execution.
|
||||||
|
// Also if the background processing was canceled, the current milestone that was just abandoned
|
||||||
|
// in Started state is to be reset to Canceled state.
|
||||||
template<typename PrintObject>
|
template<typename PrintObject>
|
||||||
void finalize_impl(std::vector<PrintObject*> &print_objects)
|
void finalize_impl(std::vector<PrintObject*> &print_objects)
|
||||||
{
|
{
|
||||||
// Grab the lock for the Print / PrintObject milestones.
|
// Grab the lock for the Print / PrintObject milestones.
|
||||||
std::scoped_lock<std::mutex> lock(this->state_mutex());
|
std::scoped_lock<std::mutex> lock(this->state_mutex());
|
||||||
for (auto *po : print_objects)
|
for (auto *po : print_objects)
|
||||||
po->enable_all_steps_unguarded(true);
|
po->finalize_impl();
|
||||||
m_state.enable_all_unguarded(true);
|
m_state.enable_all_unguarded(true);
|
||||||
|
m_state.mark_canceled_unguarded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -722,6 +768,11 @@ protected:
|
||||||
bool is_step_enabled_unguarded(PrintObjectStepEnum step) const { return m_state.is_enabled_unguarded(step); }
|
bool is_step_enabled_unguarded(PrintObjectStepEnum step) const { return m_state.is_enabled_unguarded(step); }
|
||||||
void enable_step_unguarded(PrintObjectStepEnum step, bool enable) { m_state.enable_unguarded(step, enable); }
|
void enable_step_unguarded(PrintObjectStepEnum step, bool enable) { m_state.enable_unguarded(step, enable); }
|
||||||
void enable_all_steps_unguarded(bool enable) { m_state.enable_all_unguarded(enable); }
|
void enable_all_steps_unguarded(bool enable) { m_state.enable_all_unguarded(enable); }
|
||||||
|
// See the comment at PrintBaseWithState::finalize_impl()
|
||||||
|
void finalize_impl() { m_state.enable_all_unguarded(true); m_state.mark_canceled_unguarded(); }
|
||||||
|
// If the milestone is Canceled or Invalidated, return true and turn the state of the milestone to Fresh.
|
||||||
|
// The caller is responsible for releasing the data of the milestone that is no more valid.
|
||||||
|
bool query_reset_dirty_step_unguarded(PrintObjectStepEnum step) { return m_state.query_reset_dirty_unguarded(step); }
|
||||||
|
|
||||||
// Add a slicing warning to the active PrintObject step and send a status notification.
|
// Add a slicing warning to the active PrintObject step and send a status notification.
|
||||||
// This method could be called multiple times between this->set_started() and this->set_done().
|
// This method could be called multiple times between this->set_started() and this->set_done().
|
||||||
|
|
|
@ -352,6 +352,12 @@ void PrintObject::prepare_infill()
|
||||||
this->set_done(posPrepareInfill);
|
this->set_done(posPrepareInfill);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintObject::clear_fills()
|
||||||
|
{
|
||||||
|
for (Layer *layer : m_layers)
|
||||||
|
layer->clear_fills();
|
||||||
|
}
|
||||||
|
|
||||||
void PrintObject::infill()
|
void PrintObject::infill()
|
||||||
{
|
{
|
||||||
// prerequisites
|
// prerequisites
|
||||||
|
@ -818,6 +824,15 @@ bool PrintObject::invalidate_all_steps()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called on main thread with stopped or paused background processing to let PrintObject release data for its milestones that were invalidated or canceled.
|
||||||
|
void PrintObject::cleanup()
|
||||||
|
{
|
||||||
|
if (this->query_reset_dirty_step_unguarded(posInfill))
|
||||||
|
this->clear_fills();
|
||||||
|
if (this->query_reset_dirty_step_unguarded(posSupportMaterial))
|
||||||
|
this->clear_support_layers();
|
||||||
|
}
|
||||||
|
|
||||||
// This function analyzes slices of a region (SurfaceCollection slices).
|
// This function analyzes slices of a region (SurfaceCollection slices).
|
||||||
// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface.
|
// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface.
|
||||||
// Initially all slices are of type stInternal.
|
// Initially all slices are of type stInternal.
|
||||||
|
|
|
@ -1867,11 +1867,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||||
SLASupportState state;
|
SLASupportState state;
|
||||||
for (size_t istep = 0; istep < sla_steps.size(); ++istep) {
|
for (size_t istep = 0; istep < sla_steps.size(); ++istep) {
|
||||||
state.step[istep] = print_object->step_state_with_timestamp(sla_steps[istep]);
|
state.step[istep] = print_object->step_state_with_timestamp(sla_steps[istep]);
|
||||||
if (state.step[istep].state == PrintStateBase::DONE) {
|
if (state.step[istep].is_done()) {
|
||||||
if (!print_object->has_mesh(sla_steps[istep]))
|
if (!print_object->has_mesh(sla_steps[istep]))
|
||||||
// Consider the DONE step without a valid mesh as invalid for the purpose
|
// Consider the Done step without a valid mesh as invalid for the purpose
|
||||||
// of mesh visualization.
|
// of mesh visualization.
|
||||||
state.step[istep].state = PrintStateBase::INVALID;
|
state.step[istep].state = PrintStateBase::State::Fresh;
|
||||||
else if (sla_steps[istep] != slaposDrillHoles)
|
else if (sla_steps[istep] != slaposDrillHoles)
|
||||||
for (const ModelInstance* model_instance : print_object->model_object()->instances)
|
for (const ModelInstance* model_instance : print_object->model_object()->instances)
|
||||||
// Only the instances, which are currently printable, will have the SLA support structures kept.
|
// Only the instances, which are currently printable, will have the SLA support structures kept.
|
||||||
|
@ -2038,7 +2038,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||||
if (! volume.offsets.empty() && state.step[istep].timestamp != volume.offsets.front()) {
|
if (! volume.offsets.empty() && state.step[istep].timestamp != volume.offsets.front()) {
|
||||||
// The backend either produced a new hollowed mesh, or it invalidated the one that the front end has seen.
|
// The backend either produced a new hollowed mesh, or it invalidated the one that the front end has seen.
|
||||||
volume.model.reset();
|
volume.model.reset();
|
||||||
if (state.step[istep].state == PrintStateBase::DONE) {
|
if (state.step[istep].is_done()) {
|
||||||
TriangleMesh mesh = print_object->get_mesh(slaposDrillHoles);
|
TriangleMesh mesh = print_object->get_mesh(slaposDrillHoles);
|
||||||
assert(! mesh.empty());
|
assert(! mesh.empty());
|
||||||
|
|
||||||
|
@ -2071,7 +2071,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||||
// of various concenrs (model vs. 3D print path).
|
// of various concenrs (model vs. 3D print path).
|
||||||
volume.offsets = { state.step[istep].timestamp };
|
volume.offsets = { state.step[istep].timestamp };
|
||||||
}
|
}
|
||||||
else if (state.step[istep].state == PrintStateBase::DONE) {
|
else if (state.step[istep].is_done()) {
|
||||||
// Check whether there is an existing auxiliary volume to be updated, or a new auxiliary volume to be created.
|
// Check whether there is an existing auxiliary volume to be updated, or a new auxiliary volume to be created.
|
||||||
ModelVolumeState key(state.step[istep].timestamp, instance.instance_id.id);
|
ModelVolumeState key(state.step[istep].timestamp, instance.instance_id.id);
|
||||||
auto it = std::lower_bound(aux_volume_state.begin(), aux_volume_state.end(), key, model_volume_state_lower);
|
auto it = std::lower_bound(aux_volume_state.begin(), aux_volume_state.end(), key, model_volume_state_lower);
|
||||||
|
|
Loading…
Add table
Reference in a new issue