Merge branch 'master' of https://github.com/prusa3d/Slic3r into et_multivolume_models

This commit is contained in:
Enrico Turri 2019-02-21 11:44:15 +01:00
commit bfdd702134
12 changed files with 203 additions and 37 deletions

View file

@ -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.

View file

@ -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,7 +243,24 @@ 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;
};
// After calling the apply() function, call set_task() to limit the task to be processed by process().
virtual void set_task(const TaskParams &params) {}
// Perform the calculation. This is the only method that is to be called at a worker thread.
virtual void process() = 0;
// Clean up after process() finished, either with success, error or if canceled.
// The adjustments on the Print / PrintObject data due to set_task() are to be reverted here.
virtual void finalize() {}
struct SlicingStatus {
SlicingStatus(int percent, const std::string &text, unsigned int flags = 0) : percent(percent), text(text), flags(flags) {}
@ -350,6 +375,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 +411,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.

View file

@ -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,80 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
return static_cast<ApplyStatus>(apply_status);
}
// After calling the apply() function, set_task() may be called to limit the task to be processed by process().
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 = int(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)
po->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 = n_object_steps; istep < (int)slaposCount; ++istep)
print_object->m_stepmask[istep] = false;
}
if (params.to_object_step != -1 || params.to_print_step != -1) {
// Limit the print steps.
size_t istep = (params.to_object_step != -1) ? 0 : size_t(params.to_print_step) + 1;
for (; istep < m_stepmask.size(); ++ istep)
m_stepmask[istep] = false;
}
}
// Clean up after process() finished, either with success, error or if canceled.
// The adjustments on the SLAPrint / SLAPrintObject data due to set_task() are to be reverted here.
void SLAPrint::finalize()
{
for (SLAPrintObject *po : m_objects)
for (int istep = 0; istep < (int)slaposCount; ++ istep)
po->m_stepmask[istep] = true;
for (int istep = 0; istep < (int)slapsCount; ++ istep)
m_stepmask[istep] = true;
}
namespace {
// Compile the argument for support creation from the static print config.
sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) {
@ -1035,7 +1109,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;
}

View file

@ -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,7 +195,9 @@ 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 &params) override;
void process() override;
void finalize() 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;
// Returns true if the last step was finished with success.