mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-11 09:51:06 +00:00
Merge upstream, including texture displacement and the instance lock
138 commits. The count is large because texture displacement merged with its whole branch history behind it, going back to July, alongside config and preset file locking across instances, a foundation for configurable printer agent connections, and a day of smaller fixes and CI work. Two conflicts, both the same shape: each side had appended to a sorted list and git could not choose an order. libslic3r's CMakeLists gained InstanceLock alongside our IMEXHelpers and IMEXZones, and the preset bundle loading test gained an include for ParallelResolve alongside ours for IMEXHelpers. Both sides kept, alphabetical. No logic conflicted. Verified: 740 targets build clean under -Werror, and the Release suite passes 1740 of 1740, up from 1665 -- the 75 new cases arrived with the merge and all pass. That mattered more than usual here, since preset loading and config locking are both areas the IMEX preset code touches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include "libslic3r.h"
|
||||
#include "I18N.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "InstanceLock.hpp"
|
||||
#include "LocalesUtils.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "TriangleSelector.hpp"
|
||||
@@ -1280,6 +1282,13 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(std::string user, For
|
||||
|
||||
const auto user_load_t0 = std::chrono::steady_clock::now();
|
||||
|
||||
// Reads one bundle's metadata under the lock, per file, so the lock is never
|
||||
// held when bundles.WriteLock() is taken afterwards.
|
||||
auto load_bundle_metadata = [read_only](const fs::path &metadata_file, BundleMetadata &metadata) {
|
||||
InstanceLock instance_lock(user_presets_lock_path(read_only));
|
||||
return metadata.load_from_json(metadata_file.string());
|
||||
};
|
||||
|
||||
// Load bundle metadata from _local directory first
|
||||
fs::path local_dir(folder / PRESET_LOCAL_DIR);
|
||||
if (fs::exists(local_dir)) {
|
||||
@@ -1293,7 +1302,7 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(std::string user, For
|
||||
if (!fs::exists(metadata_file)) continue;
|
||||
|
||||
BundleMetadata metadata;
|
||||
if (!metadata.load_from_json(metadata_file.string())) continue;
|
||||
if (!load_bundle_metadata(metadata_file, metadata)) continue;
|
||||
metadata.print_presets.clear();
|
||||
metadata.filament_presets.clear();
|
||||
metadata.printer_presets.clear();
|
||||
@@ -1328,7 +1337,7 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(std::string user, For
|
||||
if (!fs::exists(metadata_file)) continue;
|
||||
|
||||
BundleMetadata metadata;
|
||||
if (!metadata.load_from_json(metadata_file.string())) continue;
|
||||
if (!load_bundle_metadata(metadata_file, metadata)) continue;
|
||||
metadata.print_presets.clear();
|
||||
metadata.filament_presets.clear();
|
||||
metadata.printer_presets.clear();
|
||||
@@ -1662,10 +1671,12 @@ PresetsConfigSubstitutions PresetBundle::import_presets(std::vector<std::string>
|
||||
if (ec) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " create directory failed: " << ec.message();
|
||||
//create temp folder
|
||||
//std::string user_default_temp_dir = data_dir() + "/" + PRESET_USER_DIR + "/" + DEFAULT_USER_FOLDER_NAME + "/" + "temp";
|
||||
fs::path temp_folder(configs_folder / "temp");
|
||||
// Under cache/, per process and per import, so two instances importing
|
||||
// at once do not clear each other's extraction and no preset scan reads it.
|
||||
static std::atomic<unsigned> import_counter{0};
|
||||
fs::path temp_folder(fs::path(data_dir()) / "cache" / ("import." + std::to_string(get_current_pid()) + "." + std::to_string(import_counter++)));
|
||||
std::string user_default_temp_dir = temp_folder.make_preferred().string();
|
||||
if (fs::exists(temp_folder)) fs::remove_all(temp_folder);
|
||||
fs::create_directory(temp_folder, ec);
|
||||
fs::create_directories(temp_folder, ec);
|
||||
if (ec) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " create directory failed: " << ec.message();
|
||||
|
||||
file = boost::filesystem::path(file).make_preferred().string();
|
||||
@@ -1677,6 +1688,9 @@ PresetsConfigSubstitutions PresetBundle::import_presets(std::vector<std::string>
|
||||
status = mz_zip_reader_init_cfile(&zip_archive, zipFile, 0, MZ_ZIP_FLAG_CASE_SENSITIVE | MZ_ZIP_FLAG_IGNORE_PATH);
|
||||
if (MZ_FALSE == status) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Failed to initialize reader ZIP archive";
|
||||
if (zipFile != nullptr)
|
||||
std::fclose(zipFile);
|
||||
fs::remove_all(temp_folder, ec);
|
||||
return substitutions;
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Success to initialize reader ZIP archive";
|
||||
@@ -2284,10 +2298,9 @@ void PresetBundle::remove_user_presets_directory(const std::string preset_folder
|
||||
return;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" enter, delete directory : %1%") % dir_user_presets;
|
||||
fs::path folder(dir_user_presets);
|
||||
if (fs::exists(folder)) {
|
||||
fs::remove_all(folder);
|
||||
}
|
||||
boost::system::error_code ec;
|
||||
InstanceLock instance_lock(user_presets_lock_path());
|
||||
fs::remove_all(fs::path(dir_user_presets), ec);
|
||||
}
|
||||
|
||||
void PresetBundle::update_system_preset_setting_ids(std::map<std::string, std::map<std::string, std::string>>& system_presets)
|
||||
@@ -4460,8 +4473,17 @@ std::vector<Preset *> PresetBundle::get_filament_presets_for_machine(const std::
|
||||
return compatible;
|
||||
}
|
||||
|
||||
int PresetBundle::get_filament_variant_index(const DynamicPrintConfig &filament_config, const DynamicPrintConfig &printer_config,
|
||||
int extruder_id, NozzleVolumeType nozzle_volume_type)
|
||||
{
|
||||
const auto *extruder_types = printer_config.option<ConfigOptionEnumsGeneric>("extruder_type");
|
||||
const ExtruderType extruder_type = extruder_types && !extruder_types->empty() ? ExtruderType(extruder_types->get_at(extruder_id)) : etDirectDrive;
|
||||
return std::max(0, filament_config.get_index_for_extruder(1, "", extruder_type, nozzle_volume_type, "filament_extruder_variant"));
|
||||
}
|
||||
|
||||
bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_mas_tray(
|
||||
const std::string &printer_type, std::string& nozzle_diameter_str, std::string &setting_id, std::string &tag_uid, std::string &nozzle_temp_min, std::string &nozzle_temp_max, std::string& preset_setting_id)
|
||||
const std::string &printer_type, std::string& nozzle_diameter_str, std::string &setting_id, std::string &tag_uid, std::string &nozzle_temp_min, std::string &nozzle_temp_max, std::string& preset_setting_id,
|
||||
int extruder_id, NozzleVolumeType nozzle_volume_type)
|
||||
{
|
||||
bool is_equation = true;
|
||||
|
||||
@@ -4484,13 +4506,15 @@ bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_m
|
||||
// Compare only once
|
||||
if (!compared) {
|
||||
compared = true;
|
||||
const Preset *printer = printers.find_preset(printer_str);
|
||||
const int variant_index = printer ? get_filament_variant_index(preset->config, printer->config, extruder_id, nozzle_volume_type) : 0;
|
||||
bool min_temp_equation = false, max_temp_equation = false;
|
||||
int min_nozzle_temp = std::stoi(nozzle_temp_min);
|
||||
int max_nozzle_temp = std::stoi(nozzle_temp_max);
|
||||
ConfigOption *opt_min = const_cast<Preset *>(preset)->config.option("nozzle_temperature_range_low");
|
||||
if (opt_min) {
|
||||
ConfigOptionInts *opt_min_ints = dynamic_cast<ConfigOptionInts *>(opt_min);
|
||||
min_nozzle_temp = opt_min_ints->get_at(0);
|
||||
min_nozzle_temp = opt_min_ints->get_at(variant_index);
|
||||
if (std::to_string(min_nozzle_temp) == nozzle_temp_min)
|
||||
min_temp_equation = true;
|
||||
else {
|
||||
@@ -4501,7 +4525,7 @@ bool PresetBundle::check_filament_temp_equation_by_printer_type_and_nozzle_for_m
|
||||
ConfigOption *opt_max = const_cast<Preset *>(preset)->config.option("nozzle_temperature_range_high");
|
||||
if (opt_max) {
|
||||
ConfigOptionInts *opt_max_ints = dynamic_cast<ConfigOptionInts *>(opt_max);
|
||||
max_nozzle_temp = opt_max_ints->get_at(0);
|
||||
max_nozzle_temp = opt_max_ints->get_at(variant_index);
|
||||
if (std::to_string(max_nozzle_temp) == nozzle_temp_max)
|
||||
max_temp_equation = true;
|
||||
else {
|
||||
@@ -8210,9 +8234,13 @@ bool BundleMetadata::save_to_json(const std::string& path) const
|
||||
j["filament_presets"] = strip_prefix(this->filament_presets);
|
||||
j["printer_presets"] = strip_prefix(this->printer_presets);
|
||||
|
||||
boost::nowide::ofstream ofs(path);
|
||||
ofs << j.dump(4);
|
||||
return ofs.good();
|
||||
const std::string content = j.dump(4);
|
||||
InstanceLock instance_lock(user_presets_lock_path());
|
||||
if (const std::error_code ec = write_file_atomically(path, content)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to save bundle metadata to " << path << ": " << ec.message();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to save bundle metadata to " << path << ": " << e.what();
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user