diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 343197948..d40ea5fb6 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -469,14 +469,15 @@ void ConfigBase::apply_only(const ConfigBase &other, const t_config_option_keys } // this will *ignore* options not present in both configs -t_config_option_keys ConfigBase::diff(const ConfigBase &other) const +t_config_option_keys ConfigBase::diff(const ConfigBase &other, bool even_phony /*=true*/) const { t_config_option_keys diff; for (const t_config_option_key &opt_key : this->keys()) { const ConfigOption *this_opt = this->option(opt_key); const ConfigOption *other_opt = other.option(opt_key); //dirty if both exist, they aren't both phony and value is different - if (this_opt != nullptr && other_opt != nullptr && !(this_opt->is_phony() && other_opt->is_phony()) + if (this_opt != nullptr && other_opt != nullptr + && (even_phony || !(this_opt->is_phony() && other_opt->is_phony())) && ((*this_opt != *other_opt) || (this_opt->is_phony() != other_opt->is_phony()))) diff.emplace_back(opt_key); } diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 058bebeb6..f7cb5536c 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1886,7 +1886,7 @@ public: // or this ConfigBase is of a StaticConfig type and it does not support some of the keys, and ignore_nonexistent is not set. void apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false); bool equals(const ConfigBase &other) const { return this->keys().size() == other.keys().size() && this->diff(other).empty(); } - t_config_option_keys diff(const ConfigBase &other) const; + t_config_option_keys diff(const ConfigBase &other, bool even_phony = true) const; t_config_option_keys equal(const ConfigBase &other) const; std::string opt_serialize(const t_config_option_key &opt_key) const; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 83a34835f..00d48462f 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1391,14 +1391,15 @@ void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys& } // Use deep_diff to correct return of changed options, considering individual options for each extruder. -inline t_config_option_keys deep_diff(const ConfigBase &config_this, const ConfigBase &config_other) +inline t_config_option_keys deep_diff(const ConfigBase &config_this, const ConfigBase &config_other, bool ignore_phony) { t_config_option_keys diff; for (const t_config_option_key &opt_key : config_this.keys()) { const ConfigOption *this_opt = config_this.option(opt_key); const ConfigOption *other_opt = config_other.option(opt_key); //dirty if both exist, they aren't both phony and value is different - if (this_opt != nullptr && other_opt != nullptr && !(this_opt->is_phony() && other_opt->is_phony()) + if (this_opt != nullptr && other_opt != nullptr + && (ignore_phony || !(this_opt->is_phony() && other_opt->is_phony())) && ((*this_opt != *other_opt) || (this_opt->is_phony() != other_opt->is_phony()))) { if (opt_key == "bed_shape" || opt_key == "compatible_prints" || opt_key == "compatible_printers") { @@ -1425,13 +1426,13 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi return diff; } -std::vector PresetCollection::dirty_options(const Preset *edited, const Preset *reference, const bool deep_compare /*= false*/) +std::vector PresetCollection::dirty_options(const Preset *edited, const Preset *reference, const bool deep_compare /*= false*/, const bool ignore_phony) { std::vector changed; if (edited != nullptr && reference != nullptr) { changed = deep_compare ? - deep_diff(edited->config, reference->config) : - reference->config.diff(edited->config); + deep_diff(edited->config, reference->config, ignore_phony) : + reference->config.diff(edited->config, ignore_phony); // The "compatible_printers" option key is handled differently from the others: // It is not mandatory. If the key is missing, it means it is compatible with any printer. // If the key exists and it is empty, it means it is compatible with no printer. diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index ec57f45c2..415831a5a 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -444,8 +444,9 @@ public: // Compare the content of get_selected_preset() with get_edited_preset() configs, return true if they differ. bool current_is_dirty() const { return ! this->current_dirty_options().empty(); } // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ. + // Note that it won't take into account phony settings. Because current_dirty_options() is only used to see if the preset need to be saved. std::vector current_dirty_options(const bool deep_compare = false) const - { return dirty_options(&this->get_edited_preset(), &this->get_selected_preset(), deep_compare); } + { return dirty_options(&this->get_edited_preset(), &this->get_selected_preset(), deep_compare, false); } // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ. std::vector current_different_from_parent_options(const bool deep_compare = false) const { return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), deep_compare); } @@ -518,7 +519,7 @@ private: size_t update_compatible_internal(const PresetWithVendorProfile &active_printer, const PresetWithVendorProfile *active_print, PresetSelectCompatibleType unselect_if_incompatible); - static std::vector dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type = false); + static std::vector dirty_options(const Preset *edited, const Preset *reference, const bool deep_compare = false, const bool ignore_phony = true); // Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER. Preset::Type m_type; diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 6acaf5e86..fafb3347a 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -685,6 +685,7 @@ namespace Slic3r { || opt_key == "overhangs_width" || opt_key == "overhangs_reverse" || opt_key == "overhangs_reverse_threshold" + || opt_key == "perimeter_extrusion_spacing" || opt_key == "perimeter_extrusion_width" || opt_key == "infill_overlap" || opt_key == "thin_perimeters" @@ -695,6 +696,8 @@ namespace Slic3r { || opt_key == "external_perimeters_first" || opt_key == "external_perimeters_hole" || opt_key == "external_perimeters_nothole" + || opt_key == "external_perimeter_extrusion_spacing" + || opt_key == "external_perimeter_extrusion_width" || opt_key == "external_perimeters_vase" || opt_key == "perimeter_loop" || opt_key == "perimeter_loop_seam") { @@ -763,6 +766,7 @@ namespace Slic3r { || opt_key == "fill_density" || opt_key == "interface_shells" || opt_key == "infill_extruder" + || opt_key == "infill_extrusion_spacing" || opt_key == "infill_extrusion_width" || opt_key == "infill_every_layers" || opt_key == "infill_dense" @@ -793,6 +797,7 @@ namespace Slic3r { || opt_key == "infill_connection_solid" || opt_key == "infill_connection_top" || opt_key == "infill_connection_bottom" + || opt_key == "top_infill_extrusion_spacing" || opt_key == "top_infill_extrusion_width") { steps.emplace_back(posInfill); } else if ( @@ -804,6 +809,7 @@ namespace Slic3r { || opt_key == "no_perimeter_unsupported_algo" || opt_key == "perimeters" || opt_key == "perimeter_overlap" + || opt_key == "solid_infill_extrusion_spacing" || opt_key == "solid_infill_extrusion_width") { steps.emplace_back(posPerimeters); steps.emplace_back(posPrepareInfill); @@ -813,6 +819,7 @@ namespace Slic3r { steps.emplace_back(posPerimeters); steps.emplace_back(posSupportMaterial); } else if (opt_key == "bridge_flow_ratio" + || opt_key == "first_layer_extrusion_spacing" || opt_key == "first_layer_extrusion_width") { //if (m_config.support_material_contact_distance > 0.) { // Only invalidate due to bridging if bridging is enabled.