Merge remote-tracking branch 'upstream/main' into feedback

This commit is contained in:
Clifford Garwood
2026-05-17 20:21:23 -04:00
175 changed files with 37042 additions and 10898 deletions
+72 -36
View File
@@ -27,6 +27,8 @@
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <miniz/miniz.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_for.h>
// Mark string for localization and translate.
#define L(s) Slic3r::I18N::translate(s)
@@ -2188,48 +2190,82 @@ std::pair<PresetsConfigSubstitutions, std::string> PresetBundle::load_system_pre
vendor_name.erase(vendor_name.size() - 5);
vendor_names.push_back(vendor_name);
}
// Move ORCA_FILAMENT_LIBRARY to the beginning of the list
for (size_t i = 0; i < vendor_names.size(); ++ i) {
if (vendor_names[i] == ORCA_FILAMENT_LIBRARY) {
std::swap(vendor_names[0], vendor_names[i]);
break;
}
// Separate ORCA_FILAMENT_LIBRARY from other vendors. It must be loaded
// first because other vendors' filaments may inherit from it via the
// `base_bundle` lookup in parse_subfile. The remaining vendors are
// independent (no cross-vendor inheritance) and can be loaded in parallel.
std::string orca_lib_vendor;
std::vector<std::string> other_vendors;
other_vendors.reserve(vendor_names.size());
for (auto& vn : vendor_names) {
if (vn == ORCA_FILAMENT_LIBRARY)
orca_lib_vendor = vn;
else if (!(validation_mode && !vendor_to_validate.empty() && vn != vendor_to_validate))
other_vendors.push_back(vn);
}
for (auto &vendor_name : vendor_names)
{
if (validation_mode && !vendor_to_validate.empty() && vendor_name != vendor_to_validate && vendor_name != ORCA_FILAMENT_LIBRARY)
continue;
// Step 1: Load ORCA_FILAMENT_LIBRARY into `this` synchronously.
if (!orca_lib_vendor.empty()) {
try {
// Load the config bundle, flatten it.
if (first) {
// Reset this PresetBundle and load the first vendor config.
append(substitutions, this->load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadSystem, compatibility_rule).first);
first = false;
} else {
// Load the other vendor configs, merge them with this PresetBundle.
// Report duplicate profiles.
PresetBundle other;
append(substitutions, other.load_vendor_configs_from_json(dir.string(), vendor_name, PresetBundle::LoadSystem, compatibility_rule, this).first);
std::vector<std::string> duplicates = this->merge_presets(std::move(other));
if (!duplicates.empty()) {
errors_cummulative += "Found duplicated settings in vendor " + vendor_name + "'s json file lists: ";
for (size_t i = 0; i < duplicates.size(); ++i) {
if (i > 0)
errors_cummulative += ", ";
errors_cummulative += duplicates[i];
++m_errors;
BOOST_LOG_TRIVIAL(error) << "Found duplicated preset: " + duplicates[i] + " in vendor: " + vendor_name + ": ";
}
}
}
append(substitutions, this->load_vendor_configs_from_json(dir.string(), orca_lib_vendor, PresetBundle::LoadSystem, compatibility_rule).first);
first = false;
} catch (const std::runtime_error &err) {
if (validation_mode)
throw err;
else {
errors_cummulative += err.what();
errors_cummulative += "\n";
errors_cummulative += err.what();
errors_cummulative += "\n";
}
}
// Step 2: Load remaining vendors in parallel. Each gets its own
// PresetBundle and uses `this` (which contains ORCA_FILAMENT_LIBRARY)
// as the base_bundle for cross-bundle inheritance lookups.
std::vector<std::unique_ptr<PresetBundle>> parallel_bundles(other_vendors.size());
std::vector<PresetsConfigSubstitutions> parallel_substitutions(other_vendors.size());
std::vector<std::string> parallel_errors(other_vendors.size());
tbb::parallel_for(tbb::blocked_range<size_t>(0, other_vendors.size()),
[&](const tbb::blocked_range<size_t>& range) {
for (size_t i = range.begin(); i < range.end(); ++i) {
auto bundle = std::make_unique<PresetBundle>();
try {
auto result = bundle->load_vendor_configs_from_json(
dir.string(), other_vendors[i], PresetBundle::LoadSystem,
compatibility_rule, this);
parallel_substitutions[i] = std::move(result.first);
parallel_bundles[i] = std::move(bundle);
} catch (const std::runtime_error &err) {
parallel_errors[i] = err.what();
}
}
});
// Step 3: Sequentially merge the parallel-loaded bundles into `this`.
// The merge order is the original vendor order so any duplicate-warning
// output stays stable across runs.
for (size_t i = 0; i < other_vendors.size(); ++i) {
if (!parallel_errors[i].empty()) {
if (validation_mode)
throw std::runtime_error(parallel_errors[i]);
errors_cummulative += parallel_errors[i];
errors_cummulative += "\n";
continue;
}
if (!parallel_bundles[i])
continue;
const std::string& vendor_name = other_vendors[i];
append(substitutions, std::move(parallel_substitutions[i]));
std::vector<std::string> duplicates = this->merge_presets(std::move(*parallel_bundles[i]));
first = false;
if (!duplicates.empty()) {
errors_cummulative += "Found duplicated settings in vendor " + vendor_name + "'s json file lists: ";
for (size_t j = 0; j < duplicates.size(); ++j) {
if (j > 0)
errors_cummulative += ", ";
errors_cummulative += duplicates[j];
++m_errors;
BOOST_LOG_TRIVIAL(error) << "Found duplicated preset: " + duplicates[j] + " in vendor: " + vendor_name + ": ";
}
}
}