Fix of "Change of object type support blocker to enforcer does nothing (and vice versa) (#1818)"

WIP: Limited background processing for SLA supports.
This commit is contained in:
bubnikv 2019-02-21 08:44:07 +01:00
parent 478032ad28
commit c86a4f3ac6
4 changed files with 96 additions and 9 deletions

View file

@ -280,7 +280,7 @@ bool Print::is_step_done(PrintObjectStep step) const
return false; return false;
tbb::mutex::scoped_lock lock(this->state_mutex()); tbb::mutex::scoped_lock lock(this->state_mutex());
for (const PrintObject *object : m_objects) for (const PrintObject *object : m_objects)
if (! object->m_state.is_done_unguarded(step)) if (! object->is_step_done_unguarded(step))
return false; return false;
return true; return true;
} }
@ -549,10 +549,14 @@ void Print::model_volume_list_update_supports(ModelObject &model_object_dst, con
assert(! it->second); // not consumed yet assert(! it->second); // not consumed yet
it->second = true; it->second = true;
ModelVolume *model_volume_dst = const_cast<ModelVolume*>(it->first); ModelVolume *model_volume_dst = const_cast<ModelVolume*>(it->first);
assert(model_volume_dst->type() == model_volume_src->type()); // For support modifiers, the type may have been switched from blocker to enforcer and vice versa.
assert((model_volume_dst->is_support_modifier() && model_volume_src->is_support_modifier()) || model_volume_dst->type() == model_volume_src->type());
model_object_dst.volumes.emplace_back(model_volume_dst); model_object_dst.volumes.emplace_back(model_volume_dst);
if (model_volume_dst->is_support_modifier()) if (model_volume_dst->is_support_modifier()) {
model_volume_dst->set_transformation(model_volume_src->get_transformation()); // For support modifiers, the type may have been switched from blocker to enforcer and vice versa.
model_volume_dst->set_type(model_volume_src->type());
model_volume_dst->set_transformation(model_volume_src->get_transformation());
}
assert(model_volume_dst->get_matrix().isApprox(model_volume_src->get_matrix())); assert(model_volume_dst->get_matrix().isApprox(model_volume_src->get_matrix()));
} else { } else {
// The volume was not found in the old list. Create a new copy. // The volume was not found in the old list. Create a new copy.

View file

@ -62,6 +62,10 @@ public:
return state; return state;
} }
bool is_started(StepType step, tbb::mutex &mtx) const {
return this->state_with_timestamp(step, mtx).state == STARTED;
}
bool is_done(StepType step, tbb::mutex &mtx) const { bool is_done(StepType step, tbb::mutex &mtx) const {
return this->state_with_timestamp(step, mtx).state == DONE; return this->state_with_timestamp(step, mtx).state == DONE;
} }
@ -70,6 +74,10 @@ public:
return m_state[step]; return m_state[step];
} }
bool is_started_unguarded(StepType step) const {
return this->state_with_timestamp_unguarded(step).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 == DONE;
} }
@ -235,6 +243,18 @@ public:
virtual ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) = 0; virtual ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) = 0;
const Model& model() const { return m_model; } const Model& model() const { return m_model; }
struct TaskParams {
TaskParams() : single_model_object(0), single_model_instance_only(false), to_object_step(-1), to_print_step(-1) {}
// If non-empty, limit the processing to this ModelObject.
ModelID single_model_object;
// If set, only process single_model_object. Otherwise process everything, but single_model_object first.
bool single_model_instance_only;
// If non-negative, stop processing at the successive object step.
int to_object_step;
// If non-negative, stop processing at the successive print step.
int to_print_step;
};
virtual void process() = 0; virtual void process() = 0;
struct SlicingStatus { struct SlicingStatus {
@ -350,6 +370,9 @@ protected:
bool invalidate_all_steps() bool invalidate_all_steps()
{ return m_state.invalidate_all(this->cancel_callback()); } { return m_state.invalidate_all(this->cancel_callback()); }
bool is_step_started_unguarded(PrintStepEnum step) const { return m_state.is_started_unguarded(step); }
bool is_step_done_unguarded(PrintStepEnum step) const { return m_state.is_done_unguarded(step); }
private: private:
PrintState<PrintStepEnum, COUNT> m_state; PrintState<PrintStepEnum, COUNT> m_state;
}; };
@ -383,6 +406,9 @@ protected:
bool invalidate_all_steps() bool invalidate_all_steps()
{ return m_state.invalidate_all(PrintObjectBase::cancel_callback(m_print)); } { return m_state.invalidate_all(PrintObjectBase::cancel_callback(m_print)); }
bool is_step_started_unguarded(PrintObjectStepEnum step) const { return m_state.is_started_unguarded(step); }
bool is_step_done_unguarded(PrintObjectStepEnum step) const { return m_state.is_done_unguarded(step); }
protected: protected:
// If the background processing stop was requested, throw CanceledException. // 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. // To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.

View file

@ -51,7 +51,7 @@ const std::array<std::string, slaposCount> OBJ_STEP_LABELS =
L("Slicing model"), // slaposObjectSlice, L("Slicing model"), // slaposObjectSlice,
L("Generating support points"), // slaposSupportPoints, L("Generating support points"), // slaposSupportPoints,
L("Generating support tree"), // slaposSupportTree, L("Generating support tree"), // slaposSupportTree,
L("Generating base pool"), // slaposBasePool, L("Generating pad"), // slaposBasePool,
L("Slicing supports"), // slaposSliceSupports, L("Slicing supports"), // slaposSliceSupports,
L("Slicing supports") // slaposIndexSlices, L("Slicing supports") // slaposIndexSlices,
}; };
@ -402,6 +402,61 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
return static_cast<ApplyStatus>(apply_status); return static_cast<ApplyStatus>(apply_status);
} }
void SLAPrint::set_task(const TaskParams &params)
{
// Grab the lock for the Print / PrintObject milestones.
tbb::mutex::scoped_lock lock(this->state_mutex());
int n_object_steps = params.to_object_step + 1;
if (n_object_steps = 0)
n_object_steps = (int)slaposCount;
if (params.single_model_object.valid()) {
SLAPrintObject *print_object = nullptr;
size_t idx_print_object = 0;
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;
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)
this->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)
print_object->m_stepmask[istep] = false;
}
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]);
}
for (int istep = 0; istep < n_object_steps; ++ istep)
print_object->m_stepmask[istep] = true;
for (int istep = 0; istep < (int)slaposCount; ++ istep)
print_object->m_stepmask[istep] = false;
}
}
namespace { namespace {
// Compile the argument for support creation from the static print config. // Compile the argument for support creation from the static print config.
sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) { sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) {
@ -1035,7 +1090,7 @@ bool SLAPrint::is_step_done(SLAPrintObjectStep step) const
return false; return false;
tbb::mutex::scoped_lock lock(this->state_mutex()); tbb::mutex::scoped_lock lock(this->state_mutex());
for (const SLAPrintObject *object : m_objects) for (const SLAPrintObject *object : m_objects)
if (! object->m_state.is_done_unguarded(step)) if (! object->is_step_done_unguarded(step))
return false; return false;
return true; return true;
} }

View file

@ -139,6 +139,10 @@ protected:
// Invalidate steps based on a set of parameters changed. // Invalidate steps based on a set of parameters changed.
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys); bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
// Which steps have to be performed. Implicitly: all
// to be accessible from SLAPrint
std::vector<bool> m_stepmask;
private: private:
// Object specific configuration, pulled from the configuration layer. // Object specific configuration, pulled from the configuration layer.
SLAPrintObjectConfig m_config; SLAPrintObjectConfig m_config;
@ -146,9 +150,6 @@ private:
Transform3d m_trafo = Transform3d::Identity(); Transform3d m_trafo = Transform3d::Identity();
std::vector<Instance> m_instances; std::vector<Instance> m_instances;
// Which steps have to be performed. Implicitly: all
std::vector<bool> m_stepmask;
// Individual 2d slice polygons from lower z to higher z levels // Individual 2d slice polygons from lower z to higher z levels
std::vector<ExPolygons> m_model_slices; std::vector<ExPolygons> m_model_slices;
@ -194,6 +195,7 @@ public:
void clear() override; void clear() override;
bool empty() const override { return m_objects.empty(); } bool empty() const override { return m_objects.empty(); }
ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) override; ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) override;
void set_task(const TaskParams &params);
void process() override; void process() override;
// Returns true if an object step is done on all objects and there's at least one object. // Returns true if an object step is done on all objects and there's at least one object.
bool is_step_done(SLAPrintObjectStep step) const; bool is_step_done(SLAPrintObjectStep step) const;