Feature/fix profile variants issus (#14084)

* add print variant validation

* fix one profile error

* fix more prifiles
This commit is contained in:
SoftFever
2026-06-07 17:46:53 +08:00
committed by GitHub
parent ff4147ede3
commit 10a1b17381
14 changed files with 47 additions and 11 deletions

View File

@@ -6,6 +6,7 @@
#include "libslic3r.h"
#include "I18N.hpp"
#include "Utils.hpp"
#include "LocalesUtils.hpp"
#include "Model.hpp"
#include "libslic3r_version.h"
@@ -2231,6 +2232,7 @@ std::pair<PresetsConfigSubstitutions, std::string> PresetBundle::load_system_pre
[&](const tbb::blocked_range<size_t>& range) {
for (size_t i = range.begin(); i < range.end(); ++i) {
auto bundle = std::make_unique<PresetBundle>();
bundle->set_is_validation_mode(validation_mode);
try {
auto result = bundle->load_vendor_configs_from_json(
dir.string(), other_vendors[i], PresetBundle::LoadSystem,
@@ -4982,6 +4984,39 @@ std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_vendor_configs_
reason = std::string("can not find printer_variant in vendor profile");
return reason;
}
// An instantiation printer profile's nozzle_diameter must match the numeric (diameter)
// prefix of its printer_variant: "0.4" -> {0.4}, "0.8HF" -> {0.8} (a trailing
// non-numeric suffix such as "HF"/"HS" distinguishes a hardware sub-variant and is
// ignored here), and for multi-nozzle printers "0.4+0.6" -> {0.4, 0.6}.
// Note: a variant may legitimately repeat across presets of the same model (e.g. speed
// modes, IDEX copy/mirror, or different control boards), so only the diameter is
// validated, not variant uniqueness. Validation-only so the app keeps loading existing
// profiles unchanged.
if (validation_mode && instantiation == "true") {
const auto *nd = config.option<ConfigOptionFloats>("nozzle_diameter");
std::set<double> nozzles, variant_nozzles;
if (nd != nullptr)
nozzles.insert(nd->values.begin(), nd->values.end());
std::vector<std::string> variant_tokens;
boost::algorithm::split(variant_tokens, printer_variant, boost::algorithm::is_any_of("+"));
bool variant_ok = true; // printer_variant is already guaranteed non-empty above
for (const std::string &tok : variant_tokens) {
size_t consumed = 0;
double d = string_to_double_decimal_point(tok, &consumed);
// Require a leading numeric diameter; a trailing suffix (e.g. "HF") is allowed.
if (consumed == 0) { variant_ok = false; break; }
variant_nozzles.insert(d);
}
if (!variant_ok || variant_nozzles != nozzles) {
++m_errors;
BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
preset_name << "\" has printer_variant \"" << printer_variant <<
"\" that does not match its nozzle_diameter \"" << (nd ? nd->serialize() : std::string()) << "\". "
"printer_variant must begin with the nozzle diameter, optionally followed by a non-numeric suffix "
"(e.g. \"0.4\", \"0.8HF\"); for multi-nozzle printers, join the per-nozzle diameters with \"+\" in "
"nozzle order (e.g. \"0.4+0.6\").";
}
}
}
const Preset *preset_existing = presets_collection->find_preset(preset_name, false);
if (preset_existing != nullptr) {