mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-13 02:41:16 +00:00
Merge remote-tracking branch 'upstream/main' into feedback
This commit is contained in:
@@ -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 + ": ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user