diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 87e78f11c..8ed70fde6 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -523,6 +523,9 @@ exit_for_rearrange_regions: invalidated = true; } + for (PrintObject *object : m_objects) + object->update_slicing_parameters(); + return invalidated; } @@ -1098,6 +1101,12 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co } } + // Update SlicingParameters for each object where the SlicingParameters is not valid. + // If it is not valid, then it is ensured that PrintObject.m_slicing_params is not in use + // (posSlicing and posSupportMaterial was invalidated). + for (PrintObject *object : m_objects) + object->update_slicing_parameters(); + #ifdef _DEBUG check_model_ids_equal(m_model, model); #endif /* _DEBUG */ @@ -1202,13 +1211,13 @@ std::string Print::validate() const break; } } - SlicingParameters slicing_params0 = m_objects.front()->slicing_parameters(); + const SlicingParameters &slicing_params0 = m_objects.front()->slicing_parameters(); size_t tallest_object_idx = 0; if (has_custom_layering) PrintObject::update_layer_height_profile(*m_objects.front()->model_object(), slicing_params0, layer_height_profiles.front()); for (size_t i = 1; i < m_objects.size(); ++ i) { - const PrintObject *object = m_objects[i]; - const SlicingParameters slicing_params = object->slicing_parameters(); + const PrintObject *object = m_objects[i]; + const SlicingParameters &slicing_params = object->slicing_parameters(); if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON || std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON) return L("The Wipe Tower is only supported for multiple objects if they have equal layer heigths"); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 2f85da96b..43fd52e18 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -131,7 +131,7 @@ public: // by the interactive layer height editor and by the printing process itself. // The slicing parameters are dependent on various configuration values // (layer height, first layer height, raft settings, print nozzle diameter etc). - SlicingParameters slicing_parameters() const; + const SlicingParameters& slicing_parameters() const { return m_slicing_params; } static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object); // returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions) @@ -161,7 +161,8 @@ protected: bool invalidate_all_steps(); // Invalidate steps based on a set of parameters changed. bool invalidate_state_by_config_options(const std::vector &opt_keys); - SlicingParameters slicing_parameters_internal() const; + // If ! m_slicing_params.valid, recalculate. + void update_slicing_parameters(); static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders); static PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_region_config, const ModelVolume &volume, size_t num_extruders); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 07fecdfc6..2349a7445 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -104,7 +104,6 @@ void PrintObject::slice() return; m_print->set_status(10, "Processing triangulated mesh"); std::vector layer_height_profile; - m_slicing_params = this->slicing_parameters_internal(); this->update_layer_height_profile(*this->model_object(), m_slicing_params, layer_height_profile); m_print->throw_if_canceled(); this->_slice(layer_height_profile); @@ -569,8 +568,11 @@ bool PrintObject::invalidate_step(PrintObjectStep step) } else if (step == posSlice) { invalidated |= this->invalidate_steps({ posPerimeters, posPrepareInfill, posInfill, posSupportMaterial }); invalidated |= m_print->invalidate_steps({ psSkirt, psBrim }); - } else if (step == posSupportMaterial) + this->m_slicing_params.valid = false; + } else if (step == posSupportMaterial) { invalidated |= m_print->invalidate_steps({ psSkirt, psBrim }); + this->m_slicing_params.valid = false; + } // Wipe tower depends on the ordering of extruders, which in turn depends on everything. // It also decides about what the wipe_into_infill / wipe_into_object features will do, @@ -1361,16 +1363,11 @@ PrintRegionConfig PrintObject::region_config_from_model_volume(const PrintRegion return config; } -SlicingParameters PrintObject::slicing_parameters_internal() const +void PrintObject::update_slicing_parameters() { - return SlicingParameters::create_from_config( - this->print()->config(), m_config, - unscale(this->size(2)), this->object_extruders()); -} - -SlicingParameters PrintObject::slicing_parameters() const -{ - return this->is_step_done(posSlice) ? m_slicing_params : this->slicing_parameters_internal(); + if (! m_slicing_params.valid) + m_slicing_params = SlicingParameters::create_from_config( + this->print()->config(), m_config, unscale(this->size(2)), this->object_extruders()); } SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index b3e314549..3a05e9d8a 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -149,6 +149,7 @@ SlicingParameters SlicingParameters::create_from_config( params.object_print_z_max += print_z; } + params.valid = true; return params; } diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index 094527850..fa5a12f9c 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -42,6 +42,8 @@ struct SlicingParameters // Height of the object to be printed. This value does not contain the raft height. coordf_t object_print_z_height() const { return object_print_z_max - object_print_z_min; } + bool valid; + // Number of raft layers. size_t base_raft_layers; // Number of interface layers including the contact layer. @@ -100,6 +102,8 @@ static_assert(IsTriviallyCopyable::value, "SlicingParameters // The two slicing parameters lead to the same layering as long as the variable layer thickness is not in action. inline bool equal_layering(const SlicingParameters &sp1, const SlicingParameters &sp2) { + assert(sp1.valid); + assert(sp2.valid); return sp1.base_raft_layers == sp2.base_raft_layers && sp1.interface_raft_layers == sp2.interface_raft_layers && sp1.base_raft_layer_height == sp2.base_raft_layer_height &&