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;
|
||||
tbb::mutex::scoped_lock lock(this->state_mutex());
|
||||
for (const PrintObject *object : m_objects)
|
||||
if (! object->m_state.is_done_unguarded(step))
|
||||
if (! object->is_step_done_unguarded(step))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -549,10 +549,14 @@ void Print::model_volume_list_update_supports(ModelObject &model_object_dst, con
|
|||
assert(! it->second); // not consumed yet
|
||||
it->second = true;
|
||||
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);
|
||||
if (model_volume_dst->is_support_modifier())
|
||||
model_volume_dst->set_transformation(model_volume_src->get_transformation());
|
||||
if (model_volume_dst->is_support_modifier()) {
|
||||
// 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()));
|
||||
} else {
|
||||
// The volume was not found in the old list. Create a new copy.
|
||||
|
|
|
@ -62,6 +62,10 @@ public:
|
|||
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 {
|
||||
return this->state_with_timestamp(step, mtx).state == DONE;
|
||||
}
|
||||
|
@ -70,6 +74,10 @@ public:
|
|||
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 {
|
||||
return this->state_with_timestamp_unguarded(step).state == DONE;
|
||||
}
|
||||
|
@ -235,6 +243,18 @@ public:
|
|||
virtual ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) = 0;
|
||||
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;
|
||||
|
||||
struct SlicingStatus {
|
||||
|
@ -350,6 +370,9 @@ protected:
|
|||
bool invalidate_all_steps()
|
||||
{ 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:
|
||||
PrintState<PrintStepEnum, COUNT> m_state;
|
||||
};
|
||||
|
@ -383,6 +406,9 @@ protected:
|
|||
bool invalidate_all_steps()
|
||||
{ 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:
|
||||
// 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.
|
||||
|
|
|
@ -51,7 +51,7 @@ const std::array<std::string, slaposCount> OBJ_STEP_LABELS =
|
|||
L("Slicing model"), // slaposObjectSlice,
|
||||
L("Generating support points"), // slaposSupportPoints,
|
||||
L("Generating support tree"), // slaposSupportTree,
|
||||
L("Generating base pool"), // slaposBasePool,
|
||||
L("Generating pad"), // slaposBasePool,
|
||||
L("Slicing supports"), // slaposSliceSupports,
|
||||
L("Slicing supports") // slaposIndexSlices,
|
||||
};
|
||||
|
@ -402,6 +402,61 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
|
|||
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 {
|
||||
// Compile the argument for support creation from the static print config.
|
||||
sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) {
|
||||
|
@ -1035,7 +1090,7 @@ bool SLAPrint::is_step_done(SLAPrintObjectStep step) const
|
|||
return false;
|
||||
tbb::mutex::scoped_lock lock(this->state_mutex());
|
||||
for (const SLAPrintObject *object : m_objects)
|
||||
if (! object->m_state.is_done_unguarded(step))
|
||||
if (! object->is_step_done_unguarded(step))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -139,6 +139,10 @@ protected:
|
|||
// Invalidate steps based on a set of parameters changed.
|
||||
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:
|
||||
// Object specific configuration, pulled from the configuration layer.
|
||||
SLAPrintObjectConfig m_config;
|
||||
|
@ -146,9 +150,6 @@ private:
|
|||
Transform3d m_trafo = Transform3d::Identity();
|
||||
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
|
||||
std::vector<ExPolygons> m_model_slices;
|
||||
|
||||
|
@ -194,6 +195,7 @@ public:
|
|||
void clear() override;
|
||||
bool empty() const override { return m_objects.empty(); }
|
||||
ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) override;
|
||||
void set_task(const TaskParams ¶ms);
|
||||
void process() override;
|
||||
// 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;
|
||||
|
|
Loading…
Reference in a new issue