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:
parent
478032ad28
commit
c86a4f3ac6
4 changed files with 96 additions and 9 deletions
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 ¶ms)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ¶ms);
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue