diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 0b9614fa21..e6006ef584 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -725,6 +725,11 @@ void ModelObject::clear_volumes() this->invalidate_bounding_box(); } +bool ModelObject::is_mm_painted() const +{ + return std::any_of(this->volumes.cbegin(), this->volumes.cend(), [](const ModelVolume *mv) { return mv->is_mm_painted(); }); +} + void ModelObject::sort_volumes(bool full_sort) { // sort volumes inside the object to order "Model Part, Negative Volume, Modifier, Support Blocker and Support Enforcer. " diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index fda500810b..11dcfa7757 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -285,6 +285,8 @@ public: void clear_volumes(); void sort_volumes(bool full_sort); bool is_multiparts() const { return volumes.size() > 1; } + // Checks if any of object volume is painted using the multi-material painting gizmo. + bool is_mm_painted() const; ModelInstance* add_instance(); ModelInstance* add_instance(const ModelInstance &instance); @@ -715,6 +717,8 @@ public: this->mmu_segmentation_facets.set_new_unique_id(); } + bool is_mm_painted() const { return !this->mmu_segmentation_facets.empty(); } + protected: friend class Print; friend class SLAPrint; diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index ba631c3ee5..1854800cc7 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -317,6 +317,8 @@ public: bool has_support() const { return m_config.support_material || m_config.support_material_enforce_layers > 0; } bool has_raft() const { return m_config.raft_layers > 0; } bool has_support_material() const { return this->has_support() || this->has_raft(); } + // Checks if the model object is painted using the multi-material painting gizmo. + bool is_mm_painted() const { return this->model_object()->is_mm_painted(); }; // returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions) std::vector object_extruders() const; diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 7aa39c8239..8ebe1eb101 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -509,13 +509,32 @@ bool PrintObject::invalidate_state_by_config_options( } else if ( opt_key == "perimeters" || opt_key == "extra_perimeters" - || opt_key == "gap_fill_enabled" - || opt_key == "gap_fill_speed" || opt_key == "first_layer_extrusion_width" || opt_key == "perimeter_extrusion_width" || opt_key == "infill_overlap" || opt_key == "external_perimeters_first") { steps.emplace_back(posPerimeters); + } else if ( + opt_key == "gap_fill_enabled" + || opt_key == "gap_fill_speed") { + // Return true if gap-fill speed has changed from zero value to non-zero or from non-zero value to zero. + auto is_gap_fill_changed_state_due_to_speed = [&opt_key, &old_config, &new_config]() -> bool { + if (opt_key == "gap_fill_speed") { + const auto *old_gap_fill_speed = old_config.option(opt_key); + const auto *new_gap_fill_speed = new_config.option(opt_key); + assert(old_gap_fill_speed && new_gap_fill_speed); + return (old_gap_fill_speed->value > 0.f && new_gap_fill_speed->value == 0.f) || + (old_gap_fill_speed->value == 0.f && new_gap_fill_speed->value > 0.f); + } + return false; + }; + + // Filtering of unprintable regions in multi-material segmentation depends on if gap-fill is enabled or not. + // So step posSlice is invalidated when gap-fill was enabled/disabled by option "gap_fill_enabled" or by + // changing "gap_fill_speed" to force recomputation of the multi-material segmentation. + if (this->is_mm_painted() && (opt_key == "gap_fill_enabled" || (opt_key == "gap_fill_speed" && is_gap_fill_changed_state_due_to_speed()))) + steps.emplace_back(posSlice); + steps.emplace_back(posPerimeters); } else if ( opt_key == "layer_height" || opt_key == "first_layer_height"