Partial update of 3D scene (GLVolumes derived from Model and from

the SLAPrintObject).
Updated PrintBase to generate a unique timestamp at each step invalidation.
This commit is contained in:
bubnikv 2018-11-16 18:28:50 +01:00
parent a468078df3
commit c9a4c6c73c
15 changed files with 670 additions and 373 deletions

View file

@ -1467,4 +1467,52 @@ Transform3d ModelInstance::get_matrix(bool dont_translate, bool dont_rotate, boo
}
#endif // !ENABLE_MODELVOLUME_TRANSFORM
#ifdef _DEBUG
// Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
void check_model_ids_validity(const Model &model)
{
std::set<ModelID> ids;
auto check = [&ids](ModelID id) {
assert(id.id > 0);
assert(ids.find(id) == ids.end());
ids.insert(id);
};
for (const ModelObject *model_object : model.objects) {
check(model_object->id());
for (const ModelVolume *model_volume : model_object->volumes)
check(model_volume->id());
for (const ModelInstance *model_instance : model_object->instances)
check(model_instance->id());
}
for (const auto mm : model.materials)
check(mm.second->id());
}
void check_model_ids_equal(const Model &model1, const Model &model2)
{
// Verify whether the IDs of model1 and model match.
assert(model1.objects.size() == model2.objects.size());
for (size_t idx_model = 0; idx_model < model2.objects.size(); ++ idx_model) {
const ModelObject &model_object1 = *model1.objects[idx_model];
const ModelObject &model_object2 = * model2.objects[idx_model];
assert(model_object1.id() == model_object2.id());
assert(model_object1.volumes.size() == model_object2.volumes.size());
assert(model_object1.instances.size() == model_object2.instances.size());
for (size_t i = 0; i < model_object1.volumes.size(); ++ i)
assert(model_object1.volumes[i]->id() == model_object2.volumes[i]->id());
for (size_t i = 0; i < model_object1.instances.size(); ++ i)
assert(model_object1.instances[i]->id() == model_object2.instances[i]->id());
}
assert(model1.materials.size() == model2.materials.size());
{
auto it1 = model1.materials.begin();
auto it2 = model2.materials.begin();
for (; it1 != model1.materials.end(); ++ it1, ++ it2) {
assert(it1->first == it2->first); // compare keys
assert(it1->second->id() == it2->second->id());
}
}
}
#endif /* _DEBUG */
}

View file

@ -652,6 +652,12 @@ private:
#undef MODELBASE_DERIVED_COPY_MOVE_CLONE
#undef MODELBASE_DERIVED_PRIVATE_COPY_MOVE
#ifdef _DEBUG
// Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
void check_model_ids_validity(const Model &model);
void check_model_ids_equal(const Model &model1, const Model &model2);
#endif /* _DEBUG */
}
#endif

View file

@ -27,7 +27,7 @@ template class PrintState<PrintObjectStep, posCount>;
void Print::clear()
{
tbb::mutex::scoped_lock lock(this->cancel_mutex());
tbb::mutex::scoped_lock lock(this->state_mutex());
// The following call should stop background processing if it is running.
this->invalidate_all_steps();
for (PrintObject *object : m_objects)
@ -43,7 +43,7 @@ void Print::reload_object(size_t /* idx */)
{
ModelObjectPtrs model_objects;
{
tbb::mutex::scoped_lock lock(this->cancel_mutex());
tbb::mutex::scoped_lock lock(this->state_mutex());
// The following call should stop background processing if it is running.
this->invalidate_all_steps();
/* TODO: this method should check whether the per-object config and per-material configs
@ -271,8 +271,9 @@ bool Print::is_step_done(PrintObjectStep step) const
{
if (m_objects.empty())
return false;
tbb::mutex::scoped_lock lock(this->state_mutex());
for (const PrintObject *object : m_objects)
if (!object->m_state.is_done(step))
if (! object->m_state.is_done_unguarded(step))
return false;
return true;
}
@ -374,7 +375,7 @@ static PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig
// and have explicit instance positions.
void Print::add_model_object(ModelObject* model_object, int idx)
{
tbb::mutex::scoped_lock lock(this->cancel_mutex());
tbb::mutex::scoped_lock lock(this->state_mutex());
// Initialize a new print object and store it at the given position.
PrintObject *object = new PrintObject(this, model_object);
if (idx != -1) {
@ -435,7 +436,7 @@ void Print::add_model_object(ModelObject* model_object, int idx)
bool Print::apply_config(DynamicPrintConfig config)
{
tbb::mutex::scoped_lock lock(this->cancel_mutex());
tbb::mutex::scoped_lock lock(this->state_mutex());
// we get a copy of the config object so we can modify it safely
config.normalize();
@ -734,54 +735,6 @@ static std::vector<PrintInstances> print_objects_from_model_object(const ModelOb
return std::vector<PrintInstances>(trafos.begin(), trafos.end());
}
#ifdef _DEBUG
// Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
static inline void check_model_ids_validity(const Model &model)
{
std::set<ModelID> ids;
auto check = [&ids](ModelID id) {
assert(id.id > 0);
assert(ids.find(id) == ids.end());
ids.insert(id);
};
for (const ModelObject *model_object : model.objects) {
check(model_object->id());
for (const ModelVolume *model_volume : model_object->volumes)
check(model_volume->id());
for (const ModelInstance *model_instance : model_object->instances)
check(model_instance->id());
}
for (const auto mm : model.materials)
check(mm.second->id());
}
static inline void check_model_ids_equal(const Model &model1, const Model &model2)
{
// Verify whether the IDs of model1 and model match.
assert(model1.objects.size() == model2.objects.size());
for (size_t idx_model = 0; idx_model < model2.objects.size(); ++ idx_model) {
const ModelObject &model_object1 = *model1.objects[idx_model];
const ModelObject &model_object2 = * model2.objects[idx_model];
assert(model_object1.id() == model_object2.id());
assert(model_object1.volumes.size() == model_object2.volumes.size());
assert(model_object1.instances.size() == model_object2.instances.size());
for (size_t i = 0; i < model_object1.volumes.size(); ++ i)
assert(model_object1.volumes[i]->id() == model_object2.volumes[i]->id());
for (size_t i = 0; i < model_object1.instances.size(); ++ i)
assert(model_object1.instances[i]->id() == model_object2.instances[i]->id());
}
assert(model1.materials.size() == model2.materials.size());
{
auto it1 = model1.materials.begin();
auto it2 = model2.materials.begin();
for (; it1 != model1.materials.end(); ++ it1, ++ it2) {
assert(it1->first == it2->first); // compare keys
assert(it1->second->id() == it2->second->id());
}
}
}
#endif /* _DEBUG */
Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &config_in)
{
#ifdef _DEBUG
@ -804,7 +757,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
update_apply_status(false);
// Grab the lock for the Print / PrintObject milestones.
tbb::mutex::scoped_lock lock(this->cancel_mutex());
tbb::mutex::scoped_lock lock(this->state_mutex());
// The following call may stop the background processing.
update_apply_status(this->invalidate_state_by_config_options(print_diff));
@ -1579,16 +1532,12 @@ void Print::process()
BOOST_LOG_TRIVIAL(info) << "Staring the slicing process.";
for (PrintObject *obj : m_objects)
obj->make_perimeters();
this->throw_if_canceled();
this->set_status(70, "Infilling layers");
for (PrintObject *obj : m_objects)
obj->infill();
this->throw_if_canceled();
for (PrintObject *obj : m_objects)
obj->generate_support_material();
this->throw_if_canceled();
if (! this->is_step_done(psSkirt)) {
this->set_started(psSkirt);
if (this->set_started(psSkirt)) {
m_skirt.clear();
if (this->has_skirt()) {
this->set_status(88, "Generating skirt");
@ -1596,9 +1545,7 @@ void Print::process()
}
this->set_done(psSkirt);
}
this->throw_if_canceled();
if (! this->is_step_done(psBrim)) {
this->set_started(psBrim);
if (this->set_started(psBrim)) {
m_brim.clear();
if (m_config.brim_width > 0) {
this->set_status(88, "Generating brim");
@ -1606,9 +1553,7 @@ void Print::process()
}
this->set_done(psBrim);
}
this->throw_if_canceled();
if (! this->is_step_done(psWipeTower)) {
this->set_started(psWipeTower);
if (this->set_started(psWipeTower)) {
m_wipe_tower_data.clear();
if (this->has_wipe_tower()) {
//this->set_status(95, "Generating wipe tower");
@ -1625,9 +1570,6 @@ void Print::process()
// It is up to the caller to show an error message.
void Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data)
{
// prerequisites
this->process();
// output everything to a G-code file
// The following call may die if the output_filename_format template substitution fails.
std::string path = this->output_filepath(path_template);

View file

@ -97,8 +97,6 @@ public:
Vec3crd size; // XYZ in scaled coordinates
const ModelObject* model_object() const { return m_model_object; }
ModelObject* model_object() { return m_model_object; }
const PrintObjectConfig& config() const { return m_config; }
const LayerPtrs& layers() const { return m_layers; }
const SupportLayerPtrs& support_layers() const { return m_support_layers; }
@ -197,7 +195,6 @@ private:
void combine_infill();
void _generate_support_material();
ModelObject *m_model_object;
PrintObjectConfig m_config;
// Translation in Z + Rotation + Scaling / Mirroring.
Transform3d m_trafo = Transform3d::Identity();
@ -381,7 +378,6 @@ private:
// Declared here to have access to Model / ModelObject / ModelInstance
static void model_volume_list_update_supports(ModelObject &model_object_dst, const ModelObject &model_object_src);
Model m_model;
PrintConfig m_config;
PrintObjectConfig m_default_object_config;
PrintRegionConfig m_default_region_config;

View file

@ -3,9 +3,11 @@
namespace Slic3r
{
tbb::mutex& PrintObjectBase::cancel_mutex(PrintBase *print)
size_t PrintStateBase::g_last_timestamp = 0;
tbb::mutex& PrintObjectBase::state_mutex(PrintBase *print)
{
return print->cancel_mutex();
return print->state_mutex();
}
std::function<void()> PrintObjectBase::cancel_callback(PrintBase *print)
@ -13,4 +15,9 @@ std::function<void()> PrintObjectBase::cancel_callback(PrintBase *print)
return print->cancel_callback();
}
void PrintObjectBase::throw_if_canceled(PrintBase *print)
{
print->throw_if_canceled();
}
} // namespace Slic3r

View file

@ -2,13 +2,11 @@
#define slic3r_PrintBase_hpp_
#include "libslic3r.h"
#include <atomic>
#include <set>
#include <vector>
#include <string>
#include <functional>
#include "tbb/atomic.h"
// tbb/mutex.h includes Windows, which in turn defines min/max macros. Convince Windows.h to not define these min/max macros.
#ifndef NOMINMAX
#define NOMINMAX
@ -25,68 +23,117 @@ public:
const char* what() const throw() { return "Background processing has been canceled"; }
};
// To be instantiated over PrintStep or PrintObjectStep enums.
template <class StepType, size_t COUNT>
class PrintState
{
class PrintStateBase {
public:
PrintState() { for (size_t i = 0; i < COUNT; ++ i) m_state[i].store(INVALID, std::memory_order_relaxed); }
enum State {
INVALID,
STARTED,
DONE,
};
// With full memory barrier.
bool is_done(StepType step) const { return m_state[step] == DONE; }
// A new unique timestamp is being assigned to the step every time the step changes its state.
struct StateWithTimeStamp
{
StateWithTimeStamp() : state(INVALID), timestamp(0) {}
State state;
size_t timestamp;
};
protected:
//FIXME last timestamp is shared between Print & SLAPrint,
// and if multiple Print or SLAPrint instances are executed in parallel, modification of g_last_timestamp
// is not synchronized!
static size_t g_last_timestamp;
};
// To be instantiated over PrintStep or PrintObjectStep enums.
template <class StepType, size_t COUNT>
class PrintState : public PrintStateBase
{
public:
PrintState() {}
StateWithTimeStamp state_with_timestamp(StepType step, tbb::mutex &mtx) const {
tbb::mutex::scoped_lock lock(mtx);
StateWithTimeStamp state = m_state[step];
return state;
}
bool is_done(StepType step, tbb::mutex &mtx) const {
return this->state_with_timestamp(step, mtx).state == DONE;
}
StateWithTimeStamp state_with_timestamp_unguarded(StepType step) const {
return m_state[step];
}
bool is_done_unguarded(StepType step) const {
return this->state_with_timestamp_unguarded(step).state == DONE;
}
// Set the step as started. Block on mutex while the Print / PrintObject / PrintRegion objects are being
// modified by the UI thread.
// This is necessary to block until the Print::apply_config() updates its state, which may
// influence the processing step being entered.
void set_started(StepType step, tbb::mutex &mtx) {
mtx.lock();
m_state[step].store(STARTED, std::memory_order_relaxed);
mtx.unlock();
template<typename ThrowIfCanceled>
bool set_started(StepType step, tbb::mutex &mtx, ThrowIfCanceled throw_if_canceled) {
tbb::mutex::scoped_lock lock(mtx);
// If canceled, throw before changing the step state.
throw_if_canceled();
if (m_state[step].state == DONE)
return false;
m_state[step].state = STARTED;
m_state[step].timestamp = ++ g_last_timestamp;
return true;
}
// Set the step as done. Block on mutex while the Print / PrintObject / PrintRegion objects are being
// modified by the UI thread.
void set_done(StepType step, tbb::mutex &mtx) {
mtx.lock();
m_state[step].store(DONE, std::memory_order_relaxed);
mtx.unlock();
template<typename ThrowIfCanceled>
void set_done(StepType step, tbb::mutex &mtx, ThrowIfCanceled throw_if_canceled) {
tbb::mutex::scoped_lock lock(mtx);
// If canceled, throw before changing the step state.
throw_if_canceled();
assert(m_state[step].state != DONE);
m_state[step].state = DONE;
m_state[step].timestamp = ++ g_last_timestamp;
}
// Make the step invalid.
// The provided mutex should be locked at this point, guarding access to m_state.
// PrintBase::m_state_mutex should be locked at this point, guarding access to m_state.
// In case the step has already been entered or finished, cancel the background
// processing by calling the cancel callback.
template<typename CancelationCallback>
bool invalidate(StepType step, tbb::mutex &mtx, CancelationCallback cancel) {
bool invalidated = m_state[step].load(std::memory_order_relaxed) != INVALID;
bool invalidate(StepType step, CancelationCallback cancel) {
bool invalidated = m_state[step].state != INVALID;
if (invalidated) {
#if 0
if (mtx.state != mtx.HELD) {
printf("Not held!\n");
}
#endif
m_state[step].state = INVALID;
m_state[step].timestamp = ++ g_last_timestamp;
// Raise the mutex, so that the following cancel() callback could cancel
// the background processing.
mtx.unlock();
// Internally the cancel() callback shall unlock the PrintBase::m_status_mutex to let
// the working thread to proceed.
cancel();
m_state[step] = INVALID;
mtx.lock();
}
return invalidated;
}
template<typename CancelationCallback, typename StepTypeIterator>
bool invalidate_multiple(StepTypeIterator step_begin, StepTypeIterator step_end, tbb::mutex &mtx, CancelationCallback cancel) {
bool invalidate_multiple(StepTypeIterator step_begin, StepTypeIterator step_end, CancelationCallback cancel) {
bool invalidated = false;
for (StepTypeIterator it = step_begin; ! invalidated && it != step_end; ++ it)
invalidated = m_state[*it].load(std::memory_order_relaxed) != INVALID;
for (StepTypeIterator it = step_begin; it != step_end; ++ it) {
StateWithTimeStamp &state = m_state[*it];
if (state.state != INVALID) {
invalidated = true;
state.state = INVALID;
state.timestamp = ++ g_last_timestamp;
}
}
if (invalidated) {
#if 0
if (mtx.state != mtx.HELD) {
@ -95,50 +142,56 @@ public:
#endif
// Raise the mutex, so that the following cancel() callback could cancel
// the background processing.
mtx.unlock();
// Internally the cancel() callback shall unlock the PrintBase::m_status_mutex to let
// the working thread to proceed.
cancel();
for (StepTypeIterator it = step_begin; it != step_end; ++ it)
m_state[*it] = INVALID;
mtx.lock();
}
return invalidated;
}
// Make all steps invalid.
// The provided mutex should be locked at this point, guarding access to m_state.
// PrintBase::m_state_mutex should be locked at this point, guarding access to m_state.
// In case any step has already been entered or finished, cancel the background
// processing by calling the cancel callback.
template<typename CancelationCallback>
bool invalidate_all(tbb::mutex &mtx, CancelationCallback cancel) {
bool invalidate_all(CancelationCallback cancel) {
bool invalidated = false;
for (size_t i = 0; i < COUNT; ++ i)
if (m_state[i].load(std::memory_order_relaxed) != INVALID) {
for (size_t i = 0; i < COUNT; ++ i) {
StateWithTimeStamp &state = m_state[i];
if (state.state != INVALID) {
invalidated = true;
break;
state.state = INVALID;
state.timestamp = ++ g_last_timestamp;
}
if (invalidated) {
mtx.unlock();
cancel();
for (size_t i = 0; i < COUNT; ++ i)
m_state[i].store(INVALID, std::memory_order_relaxed);
mtx.lock();
}
if (invalidated)
cancel();
return invalidated;
}
private:
std::atomic<State> m_state[COUNT];
StateWithTimeStamp m_state[COUNT];
};
class PrintBase;
class PrintObjectBase
{
public:
const ModelObject* model_object() const { return m_model_object; }
ModelObject* model_object() { return m_model_object; }
protected:
PrintObjectBase(ModelObject *model_object) : m_model_object(model_object) {}
virtual ~PrintObjectBase() {}
// Declared here to allow access from PrintBase through friendship.
static tbb::mutex& cancel_mutex(PrintBase *print);
static tbb::mutex& state_mutex(PrintBase *print);
static std::function<void()> cancel_callback(PrintBase *print);
// 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.
static void throw_if_canceled(PrintBase *print);
ModelObject *m_model_object;
};
/**
@ -179,6 +232,7 @@ public:
APPLY_STATUS_INVALIDATED,
};
virtual ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) = 0;
const Model& model() const { return m_model; }
virtual void process() = 0;
@ -220,8 +274,9 @@ public:
protected:
friend class PrintObjectBase;
friend class BackgroundSlicingProcess;
tbb::mutex& cancel_mutex() { return m_cancel_mutex; }
tbb::mutex& state_mutex() const { return m_state_mutex; }
std::function<void()> cancel_callback() { return m_cancel_callback; }
void call_cancell_callback() { m_cancel_callback(); }
@ -229,6 +284,8 @@ protected:
// To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.
void throw_if_canceled() const { if (m_cancel_status) throw CanceledException(); }
Model m_model;
private:
tbb::atomic<CancelStatus> m_cancel_status;
// Callback to be evoked regularly to update state of the UI thread.
@ -240,27 +297,28 @@ private:
// Mutex used for synchronization of the worker thread with the UI thread:
// The mutex will be used to guard the worker thread against entering a stage
// while the data influencing the stage is modified.
mutable tbb::mutex m_cancel_mutex;
mutable tbb::mutex m_state_mutex;
};
template<typename PrintStepEnum, const size_t COUNT>
class PrintBaseWithState : public PrintBase
{
public:
bool is_step_done(PrintStepEnum step) const { return m_state.is_done(step); }
bool is_step_done(PrintStepEnum step) const { return m_state.is_done(step, this->state_mutex()); }
PrintStateBase::StateWithTimeStamp step_state_with_timestamp(PrintStepEnum step) const { return m_state.state_with_timestamp(step, this->state_mutex()); }
protected:
void set_started(PrintStepEnum step) { m_state.set_started(step, this->cancel_mutex()); throw_if_canceled(); }
void set_done(PrintStepEnum step) { m_state.set_done(step, this->cancel_mutex()); throw_if_canceled(); }
bool set_started(PrintStepEnum step) { return m_state.set_started(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); }
void set_done(PrintStepEnum step) { m_state.set_done(step, this->state_mutex(), [this](){ this->throw_if_canceled(); }); }
bool invalidate_step(PrintStepEnum step)
{ return m_state.invalidate(step, this->cancel_mutex(), this->cancel_callback()); }
{ return m_state.invalidate(step, this->cancel_callback()); }
template<typename StepTypeIterator>
bool invalidate_steps(StepTypeIterator step_begin, StepTypeIterator step_end)
{ return m_state.invalidate_multiple(step_begin, step_end, this->cancel_mutex(), this->cancel_callback()); }
{ return m_state.invalidate_multiple(step_begin, step_end, this->cancel_callback()); }
bool invalidate_steps(std::initializer_list<PrintStepEnum> il)
{ return m_state.invalidate_multiple(il.begin(), il.end(), this->cancel_mutex(), this->cancel_callback()); }
{ return m_state.invalidate_multiple(il.begin(), il.end(), this->cancel_callback()); }
bool invalidate_all_steps()
{ return m_state.invalidate_all(this->cancel_mutex(), this->cancel_callback()); }
{ return m_state.invalidate_all(this->cancel_callback()); }
private:
PrintState<PrintStepEnum, COUNT> m_state;
@ -273,22 +331,27 @@ public:
PrintType* print() { return m_print; }
const PrintType* print() const { return m_print; }
bool is_step_done(PrintObjectStepEnum step) const { return m_state.is_done(step); }
typedef PrintState<PrintObjectStepEnum, COUNT> PrintObjectState;
bool is_step_done(PrintObjectStepEnum step) const { return m_state.is_done(step, PrintObjectBase::state_mutex(m_print)); }
PrintStateBase::StateWithTimeStamp step_state_with_timestamp(PrintObjectStepEnum step) const { return m_state.state_with_timestamp(step, PrintObjectBase::state_mutex(m_print)); }
protected:
PrintObjectBaseWithState(PrintType *print) : m_print(print) {}
PrintObjectBaseWithState(PrintType *print, ModelObject *model_object) : PrintObjectBase(model_object), m_print(print) {}
void set_started(PrintObjectStepEnum step) { m_state.set_started(step, PrintObjectBase::cancel_mutex(m_print)); }
void set_done(PrintObjectStepEnum step) { m_state.set_done(step, PrintObjectBase::cancel_mutex(m_print)); }
bool set_started(PrintObjectStepEnum step)
{ return m_state.set_started(step, PrintObjectBase::state_mutex(m_print), [this](){ PrintObjectBase::throw_if_canceled(this->m_print); }); }
void set_done(PrintObjectStepEnum step)
{ m_state.set_done(step, PrintObjectBase::state_mutex(m_print), [this](){ PrintObjectBase::throw_if_canceled(this->m_print); }); }
bool invalidate_step(PrintObjectStepEnum step)
{ return m_state.invalidate(step, PrintObjectBase::cancel_mutex(m_print), PrintObjectBase::cancel_callback(m_print)); }
{ return m_state.invalidate(step, PrintObjectBase::cancel_callback(m_print)); }
template<typename StepTypeIterator>
bool invalidate_steps(StepTypeIterator step_begin, StepTypeIterator step_end)
{ return m_state.invalidate_multiple(step_begin, step_end, PrintObjectBase::cancel_mutex(m_print), PrintObjectBase::cancel_callback(m_print)); }
{ return m_state.invalidate_multiple(step_begin, step_end, PrintObjectBase::cancel_callback(m_print)); }
bool invalidate_steps(std::initializer_list<PrintObjectStepEnum> il)
{ return m_state.invalidate_multiple(il.begin(), il.end(), PrintObjectBase::cancel_mutex(m_print), PrintObjectBase::cancel_callback(m_print)); }
bool invalidate_all_steps() { return m_state.invalidate_all(PrintObjectBase::cancel_mutex(m_print), PrintObjectBase::cancel_callback(m_print)); }
{ return m_state.invalidate_multiple(il.begin(), il.end(), PrintObjectBase::cancel_callback(m_print)); }
bool invalidate_all_steps()
{ return m_state.invalidate_all(PrintObjectBase::cancel_callback(m_print)); }
protected:
friend PrintType;

View file

@ -35,9 +35,8 @@
namespace Slic3r {
PrintObject::PrintObject(Print* print, ModelObject* model_object) :
PrintObjectBaseWithState(print),
PrintObjectBaseWithState(print, model_object),
typed_slices(false),
m_model_object(model_object),
size(Vec3crd::Zero()),
layer_height_profile_valid(false)
{
@ -103,9 +102,8 @@ bool PrintObject::set_copies(const Points &points)
// this should be idempotent
void PrintObject::slice()
{
if (this->is_step_done(posSlice))
if (! this->set_started(posSlice))
return;
this->set_started(posSlice);
m_print->set_status(10, "Processing triangulated mesh");
this->_slice();
m_print->throw_if_canceled();
@ -131,10 +129,9 @@ void PrintObject::make_perimeters()
// prerequisites
this->slice();
if (this->is_step_done(posPerimeters))
if (! this->set_started(posPerimeters))
return;
this->set_started(posPerimeters);
m_print->set_status(20, "Generating perimeters");
BOOST_LOG_TRIVIAL(info) << "Generating perimeters...";
@ -242,10 +239,9 @@ void PrintObject::make_perimeters()
void PrintObject::prepare_infill()
{
if (this->is_step_done(posPrepareInfill))
if (! this->set_started(posPrepareInfill))
return;
this->set_started(posPrepareInfill);
m_print->set_status(30, "Preparing infill");
// This will assign a type (top/bottom/internal) to $layerm->slices.
@ -361,8 +357,7 @@ void PrintObject::infill()
// prerequisites
this->prepare_infill();
if (! this->is_step_done(posInfill)) {
this->set_started(posInfill);
if (this->set_started(posInfill)) {
BOOST_LOG_TRIVIAL(debug) << "Filling layers in parallel - start";
tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_layers.size()),
@ -384,8 +379,7 @@ void PrintObject::infill()
void PrintObject::generate_support_material()
{
if (! this->is_step_done(posSupportMaterial)) {
this->set_started(posSupportMaterial);
if (this->set_started(posSupportMaterial)) {
this->clear_support_layers();
if ((m_config.support_material || m_config.raft_layers > 0) && m_layers.size() > 1) {
m_print->set_status(85, "Generating support material");
@ -1706,9 +1700,8 @@ void PrintObject::_simplify_slices(double distance)
void PrintObject::_make_perimeters()
{
if (this->is_step_done(posPerimeters))
if (! this->set_started(posPerimeters))
return;
this->set_started(posPerimeters);
BOOST_LOG_TRIVIAL(info) << "Generating perimeters...";

View file

@ -61,7 +61,7 @@ const std::array<std::string, slapsCount> PRINT_STEP_LABELS =
void SLAPrint::clear()
{
tbb::mutex::scoped_lock lock(this->cancel_mutex());
tbb::mutex::scoped_lock lock(this->state_mutex());
// The following call should stop background processing if it is running.
this->invalidate_all_steps();
@ -76,7 +76,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model,
// return APPLY_STATUS_UNCHANGED;
// Grab the lock for the Print / PrintObject milestones.
tbb::mutex::scoped_lock lock(this->cancel_mutex());
tbb::mutex::scoped_lock lock(this->state_mutex());
if(m_objects.empty() && model.objects.empty())
return APPLY_STATUS_UNCHANGED;
@ -409,11 +409,9 @@ void SLAPrint::process()
}
SLAPrintObject::SLAPrintObject(SLAPrint *print, ModelObject *model_object):
Inherited(print),
m_model_object(model_object),
Inherited(print, model_object),
m_stepmask(slaposCount, true)
{
}
SLAPrintObject::~SLAPrintObject() {}

View file

@ -35,8 +35,6 @@ private: // Prevents erroneous use by other classes.
using Inherited = _SLAPrintObjectBase;
public:
const ModelObject* model_object() const { return m_model_object; }
ModelObject* model_object() { return m_model_object; }
const Transform3d& trafo() const { return m_trafo; }
struct Instance {
@ -78,8 +76,6 @@ protected:
bool invalidate_step(SLAPrintObjectStep step);
private:
// Points to the instance owned by a Model stored at the parent SLAPrint instance.
ModelObject *m_model_object;
// Object specific configuration, pulled from the configuration layer.
SLAPrintObjectConfig m_config;
// Translation in Z + Rotation by Y and Z + Scaling / Mirroring.
@ -138,7 +134,6 @@ private:
using SLAPrinter = FilePrinter<FilePrinterFormat::SLA_PNGZIP>;
using SLAPrinterPtr = std::unique_ptr<SLAPrinter>;
Model m_model;
SLAPrinterConfig m_printer_config;
SLAMaterialConfig m_material_config;
PrintObjects m_objects;