Files
OrcaSlicer/src/libslic3r/PresetBundle.hpp
T
SoftFever e5aa9a8cfc Speed up profile loading with per-vendor preset caches
Each vendor's system presets are serialized into a <vendor>.opc cache
that the app loads instead of parsing the profile JSONs, falling back
to the parse whenever no cache covers what is installed. Shipped builds
carry the caches instead of the raw profiles, installing and updating
treat a vendor's cache as its installation, and the setup wizard loads
through the same path. Per-platform scripts and CI generate the caches
at build time; tests and a design doc cover the format and its
validation.
2026-07-29 21:56:17 +08:00

667 lines
35 KiB
C++

#ifndef slic3r_PresetBundle_hpp_
#define slic3r_PresetBundle_hpp_
#include "Preset.hpp"
#include "AppConfig.hpp"
#include "enum_bitmask.hpp"
#include <memory>
#include <set>
#include <shared_mutex>
#include <unordered_map>
#include <optional>
#include <array>
#include <boost/filesystem/path.hpp>
#include <unordered_set>
#define DEFAULT_USER_FOLDER_NAME "default"
#define BUNDLE_STRUCTURE_JSON_NAME "bundle_structure.json"
#define VALIDATE_PRESETS_SUCCESS 0
#define VALIDATE_PRESETS_PRINTER_NOT_FOUND 1
#define VALIDATE_PRESETS_FILAMENTS_NOT_FOUND 2
#define VALIDATE_PRESETS_MODIFIED_GCODES 3
// define an enum class of vendor type
enum class VendorType {
Unknown = 0,
Klipper,
Marlin,
Marlin_BBL,
Klipper_Qidi
};
namespace Slic3r {
struct AMSMapInfo
{
/*for new ams mapping*/ // from struct FilamentInfo
std::string ams_id{""};
std::string slot_id{""};
};
struct AMSComboInfo
{
std::vector<std::string> ams_filament_colors;
std::vector<std::vector<std::string>> ams_multi_color_filment;
std::vector<std::string> ams_filament_presets;
std::vector<std::string> ams_names;
void clear() {
ams_filament_colors.clear();
ams_multi_color_filment.clear();
ams_filament_presets.clear();
ams_names.clear();
}
bool empty() {
return ams_names.empty();
}
};
struct MergeFilamentInfo {
std::vector<std::vector<int>> merges;
bool is_empty() { return merges.empty();}
};
struct FilamentBaseInfo
{
std::string filament_name;
std::string filament_id;
std::string filament_type;
std::string vendor;
int nozzle_temp_range_low{ 220 };
int nozzle_temp_range_high{ 220 };
int temperature_vitrification = INT_MAX;
bool is_support{ false };
bool is_system{ true };
int filament_printable = 3;
// filament_extruder_compatibility packs one compatibility level per extruder into a single
// 32-bit int, 3 bits per extruder (up to 10 extruders). Levels: 0 = printable, 1 = error,
// 2 = critical warning, 3 = warning (4-7 reserved). extruder_id is 0-based.
int get_extruder_compatibility(int extruder_id) const {
constexpr int bits_per_extruder = 3;
constexpr int extruder_mask = (1 << bits_per_extruder) - 1; // 0x7
constexpr int max_extruder_count = 32 / bits_per_extruder; // 10
if (extruder_id < 0 || extruder_id >= max_extruder_count)
return 0;
return (m_filament_extruder_compatibility >> (bits_per_extruder * extruder_id)) & extruder_mask;
}
void set_filament_extruder_compatibility(int value) { m_filament_extruder_compatibility = value; }
int get_filament_extruder_compatibility() const { return m_filament_extruder_compatibility; }
private:
int m_filament_extruder_compatibility = 0;
};
enum BundleType{
Default = 0,
Local,
Subscribed,
};
// Orca: Bundle metadata structure for imported preset bundles
struct BundleMetadata
{
std::string id; // Bundle ID: UUID (OrcaCloud) or name+timestamp (external)
std::string name; // Display name
std::string version; // Bundle version
std::string description;
std::string author;
long long imported_time{0};
long long updated_time{0};
BundleType bundle_type{Default};
std::string path;
// Cached preset names by type (populated on load)
std::vector<std::string> print_presets;
std::vector<std::string> filament_presets;
std::vector<std::string> printer_presets;
// Runtime-only flags
bool is_subscribed{false};
bool update_available{false};
bool not_found{false};
bool unauthorized{false};
bool load_from_json(const std::string& path);
bool save_to_json(const std::string& path) const;
};
struct PresetBundleMetadata
{
// To make sure write locks take precedent, pausereads needs to be true for when Orca needs to read or manipulate the container
// We only need to explicitly pause reads when entering a region in Orca which we deem necessary to quickly acquire write locks.
std::unordered_map<std::string, BundleMetadata> m_bundles;
std::shared_mutex RWMtx;
std::atomic<bool> pauseReads{false};
void PauseRead()
{
pauseReads.store(true);
}
void UnpauseRead()
{
pauseReads.store(false);
}
void ReadLock()
{
RWMtx.lock_shared();
}
void ReadUnlock()
{
RWMtx.unlock_shared();
}
void WriteLock()
{
RWMtx.lock();
}
void WriteUnlock()
{
RWMtx.unlock();
}
};
// Bundle of Print + Filament + Printer presets.
class PresetBundle
{
public:
// ---- Per-vendor preset cache --------------------------------------------
// One cache file per vendor (plus the Orca filament library), stamped with
// the vendor's own profile version rather than a directory scan.
// The cache is not something a caller loads from: a vendor is loaded with
// load_vendor_configs_from_json, which comes from the cache whenever one covers
// it. What is public here is what the cache's own tests drive directly.
// Save this bundle's slice belonging to one vendor (vendor_name at
// vendor_version), built against the given filament library version.
bool save_vendor_cache(const std::string& cache_path, const std::string& vendor_name,
const std::string& vendor_version, const std::string& lib_version) const;
// Expected version meaning "no profile sits beside this cache", so nothing can
// be newer than it and only its own integrity decides whether it is used. Not
// the same as an empty version, which means a profile is there but unreadable.
static constexpr const char* CACHE_ANY_VERSION = "*";
// Load a validated per-vendor cache into this bundle. Rejects (returns
// false) unless the cache version, schema fingerprint and vendor name match
// and the cache was built from a vendor profile and filament library at
// least as new as the expected ones. Profiles without a version (empty
// string) are never served from cache.
bool load_vendor_cache(const std::string& cache_path, const std::string& expected_vendor_name,
const std::string& expected_vendor_version, const std::string& expected_lib_version);
// Read the profile version a cache was stamped with, without deserializing its
// presets. Empty if the file is unreadable, not a cache this build understands,
// or not this vendor's. This is how an installed vendor's version is known when
// only its cache is installed.
static std::string peek_vendor_cache_version(const std::string& cache_path, const std::string& expected_vendor_name);
// Enable writing a per-vendor cache after a JSON parse (off by default). Only
// for bundles whose parses are complete — load_system_presets_from_json loads
// the filament library first and every other vendor against it, so its parses
// qualify; a wizard's one-off parse of a single vendor does not.
void set_generate_vendor_caches(bool enable) { m_generate_vendor_caches = enable; }
static DynamicPrintConfig construct_full_config(Preset &in_printer_preset,
Preset &in_print_preset,
const DynamicPrintConfig &project_config,
std::vector<Preset> &in_filament_presets,
bool apply_extruder,
std::optional<std::vector<int>> filament_maps_new,
std::optional<std::vector<int>> filament_volume_maps_new = std::nullopt);
// ORCA: utility function to find the vendor for a given preset name
static std::string find_preset_vendor(const std::string& preset_name, Preset::Type type);
PresetBundle();
PresetBundle(const PresetBundle &rhs);
PresetBundle& operator=(const PresetBundle &rhs);
// Remove all the presets but the "-- default --".
// Optionally remove all the files referenced by the presets from the user profile directory.
void reset(bool delete_files);
void setup_directories();
void copy_files(const std::string& from);
struct PresetPreferences {
std::string printer_model_id;// name of a preferred printer model
std::string printer_variant; // name of a preferred printer variant
std::string filament; // name of a preferred filament preset
std::string sla_material; // name of a preferred sla_material preset
};
// Load ini files of all types (print, filament, printer) from Slic3r::data_dir() / presets.
// Load selections (current print, current filaments, current printer) from config.ini
// select preferred presets, if any exist
PresetsConfigSubstitutions load_presets(AppConfig &config, ForwardCompatibilitySubstitutionRule rule,
const PresetPreferences& preferred_selection = PresetPreferences());
// Load selections (current print, current filaments, current printer) from config.ini
// This is done just once on application start up.
//BBS: change it to public
void load_selections(AppConfig &config, const PresetPreferences& preferred_selection = PresetPreferences());
// BBS Load user presets
PresetsConfigSubstitutions load_user_presets(std::string user, ForwardCompatibilitySubstitutionRule rule);
PresetsConfigSubstitutions load_user_presets(AppConfig &config, std::map<std::string, std::map<std::string, std::string>>& my_presets, ForwardCompatibilitySubstitutionRule rule);
// Orca: Import subscribed bundle presets (load and save to disk in one operation), handles one bundle at a time
PresetsConfigSubstitutions update_subscribed_presets(AppConfig& config,
const std::map<std::string, std::map<std::string, std::string>>& bundle_presets,
const BundleMetadata& remote_metadata,
ForwardCompatibilitySubstitutionRule rule);
PresetsConfigSubstitutions import_presets(std::vector<std::string>& files,
std::function<int(std::string const&)> override_confirm,
ForwardCompatibilitySubstitutionRule rule,
AppConfig& config);
bool import_json_presets(PresetsConfigSubstitutions& substitutions,
std::string& file,
std::function<int(std::string const&)> override_confirm,
ForwardCompatibilitySubstitutionRule rule,
int& overwrite,
std::vector<std::string>& result,
const std::string& bundle_dir = "");
void save_user_presets(AppConfig& config, std::map<std::string, std::string>& need_to_delete_list);
void check_and_fix_user_presets_syncinfo(const std::string& user_id);
void remove_users_preset(AppConfig &config, std::map<std::string, std::map<std::string, std::string>> * my_presets = nullptr);
void update_user_presets_directory(const std::string preset_folder);
void remove_user_presets_directory(const std::string preset_folder);
void update_system_preset_setting_ids(std::map<std::string, std::map<std::string, std::string>>& system_presets);
// Apply vendor configuration changes (Core library version, no GUI dependencies)
// This function installs vendors from resources and loads them into the preset bundle
//
// Parameters:
// new_vendors: Map of vendor names to their enabled printer models and variants
// new_filaments: Map of filament names to their settings
// app_config: Pointer to AppConfig to update with new vendor/filament selections
// preferred_printer_model: Optional preferred printer model to select
// preferred_printer_variant: Optional preferred printer variant to select
// preferred_filament: Optional preferred filament to select
//
// Returns: true if successful, false otherwise
bool apply_vendor_config(
const std::map<std::string, std::map<std::string, std::set<std::string>>>& new_vendors,
const std::map<std::string, std::string>& new_filaments,
AppConfig* app_config,
bool overwrite = true,
const std::string& preferred_printer_model = std::string(),
const std::string& preferred_printer_variant = std::string(),
const std::string& preferred_filament = std::string());
//BBS: add API to get previous machine
int validate_presets(const std::string &file_name, DynamicPrintConfig& config, std::set<std::string>& different_gcodes);
//BBS: add function to generate differed preset for save
//the pointer should be freed by the caller
Preset* get_preset_differed_for_save(Preset& preset);
int get_differed_values_to_update(Preset& preset, std::map<std::string, std::string>& key_values);
//BBS: get vendor's current version
Semver get_vendor_profile_version(std::string vendor_name);
std::optional<FilamentBaseInfo> get_filament_by_filament_id(const std::string& filament_id, const std::string& printer_name = std::string()) const;
// Orca: get vendor type
VendorType get_current_vendor_type();
// Vendor related handy functions
bool is_bbl_vendor() { return get_current_vendor_type() == VendorType::Marlin_BBL; }
// Whether using bbl network for print upload
bool use_bbl_network();
// Whether using bbl's device tab
bool use_bbl_device_tab();
bool backup_user_folder() const;
//BBS: project embedded preset logic
PresetsConfigSubstitutions load_project_embedded_presets(std::vector<Preset*> project_presets, ForwardCompatibilitySubstitutionRule substitution_rule);
std::vector<Preset*> get_current_project_embedded_presets();
void reset_project_embedded_presets();
//BBS: find printer model
std::string get_texture_for_printer_model(std::string model_name);
std::string get_stl_model_for_printer_model(std::string model_name);
std::string get_hotend_model_for_printer_model(std::string model_name);
// Export selections (current print, current filaments, current printer) into config.ini
void export_selections(AppConfig &config);
// BBS
void set_num_filaments(unsigned int n, std::vector<std::string> new_colors);
void set_num_filaments(unsigned int n, std::string new_col = "");
void update_num_filaments(unsigned int to_del_flament_id);
void get_ams_cobox_infos(AMSComboInfo &combox_info);
unsigned int sync_ams_list(std::vector<std::pair<DynamicPrintConfig *,std::string>> &unknowns, bool use_map, std::map<int, AMSMapInfo> &maps, bool enable_append, MergeFilamentInfo &merge_info, bool color_only = false);
//BBS: check whether this is the only edited filament
bool is_the_only_edited_filament(unsigned int filament_index);
void reset_default_nozzle_volume_type();
std::vector<int> get_used_tpu_filaments(const std::vector<int> &used_filaments);
// Orca: update selected filament and print
void update_selections(AppConfig &config);
void set_calibrate_printer(std::string name);
void set_is_validation_mode(bool mode) { validation_mode = mode; }
void set_vendor_to_validate(std::string vendor) { vendor_to_validate = vendor; }
std::vector<std::vector<DynamicPrintConfig>> get_extruder_filament_info() const;
std::set<std::string> get_printer_names_by_printer_type_and_nozzle(const std::string &printer_type, std::string nozzle_diameter_str, bool system_only = true);
bool 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);
Preset * get_similar_printer_preset(std::string printer_model, std::string printer_variant);
PresetCollection prints;
PresetCollection sla_prints;
PresetCollection filaments;
PresetCollection sla_materials;
PresetCollection& materials(PrinterTechnology pt) { return pt == ptFFF ? this->filaments : this->sla_materials; }
const PresetCollection& materials(PrinterTechnology pt) const { return pt == ptFFF ? this->filaments : this->sla_materials; }
PrinterPresetCollection printers;
PhysicalPrinterCollection physical_printers;
// Filament preset names for a multi-extruder or multi-material print.
// extruders.size() should be the same as printers.get_edited_preset().config.nozzle_diameter.size()
std::vector<std::string> filament_presets;
// BBS: ams
std::map<int, DynamicPrintConfig> filament_ams_list;
std::vector<std::vector<std::string>> ams_multi_color_filment;
std::vector<std::map<int, int>> extruder_ams_counts;
// Calibrate
Preset const * calibrate_printer = nullptr;
std::set<Preset const *> calibrate_filaments;
// The project configuration values are kept separated from the print/filament/printer preset,
// they are being serialized / deserialized from / to the .amf, .3mf, .config, .gcode,
// and they are being used by slicing core.
DynamicPrintConfig project_config;
// There will be an entry for each system profile loaded,
// and the system profiles will point to the VendorProfile instances owned by PresetBundle::vendors.
VendorMap vendors;
// Orca: for OrcaFilamentLibrary
std::map<std::string, DynamicPrintConfig> m_config_maps;
std::map<std::string, std::string> m_filament_id_maps;
// Orca: Bundle metadata and cached preset names
// std::map<std::string, BundleMetadata> m_bundles;
fs::path dir_user_presets_local;
fs::path dir_user_presets_subscribed;
PresetBundleMetadata bundles;
struct ObsoletePresets
{
std::vector<std::string> prints;
std::vector<std::string> sla_prints;
std::vector<std::string> filaments;
std::vector<std::string> sla_materials;
std::vector<std::string> printers;
};
ObsoletePresets obsolete_presets;
bool has_defauls_only() const
{ return prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); }
DynamicPrintConfig full_config(bool apply_extruder = true, std::optional<std::vector<int>>filament_maps = std::nullopt, std::optional<std::vector<int>> filament_volume_maps = std::nullopt) const;
// full_config() with the some "useless" config removed.
DynamicPrintConfig full_config_secure(std::optional<std::vector<int>>filament_maps = std::nullopt) const;
// Default per-filament nozzle-volume types: each filament inherits the volume type of the
// extruder it maps to (1-based f_maps), Standard when unknown.
std::vector<int> get_default_nozzle_volume_types_for_filaments(std::vector<int>& f_maps);
// Per-extruder flush matrix [extruder_id][from_filament][to_filament] in mm^3, optionally scaled
// by the per-extruder flush_multiplier (or flush_multiplier_fast when prime_volume_mode==Fast).
// Used by the print-dispatch nozzle-mapping flush-weight estimate.
std::vector<std::vector<std::vector<float>>> get_full_flush_matrix(bool with_multiplier = true) const;
//BBS: add some functions for multiple extruders
int get_printer_extruder_count() const;
bool support_different_extruders() const;
// Orca: Ensure filament_presets has at least one slot per nozzle on FFF printers.
// Called from (load|update)_selections before the parallel project_config arrays
// (filament_colour/colour_type/map) are sized off filament_presets.size(), so a
// short saved filament list doesn't truncate the loaded colors.
void update_filament_count();
// Load user configuration and store it into the user profiles.
// This method is called by the configuration wizard.
void load_config_from_wizard(const std::string &name, DynamicPrintConfig config, Semver file_version)
{ this->load_config_file_config(name, false, std::move(config), file_version, true); }
// Load configuration that comes from a model file containing configuration, such as 3MF et al.
// This method is called by the Plater.
void load_config_model(const std::string &name, DynamicPrintConfig config, Semver file_version = Semver())
{ this->load_config_file_config(name, true, std::move(config), file_version); }
// Load an external config file containing the print, filament and printer presets.
// Instead of a config file, a G-code may be loaded containing the full set of parameters.
// In the future the configuration will likely be read from an AMF file as well.
// If the file is loaded successfully, its print / filament / printer profiles will be activated.
ConfigSubstitutions load_config_file(const std::string &path, ForwardCompatibilitySubstitutionRule compatibility_rule);
// Load a config bundle file, into presets and store the loaded presets into separate files
// of the local configuration directory.
// Load settings into the provided settings instance.
// Activate the presets stored in the config bundle.
// Returns the number of presets loaded successfully.
enum LoadConfigBundleAttribute {
// Save the profiles, which have been loaded.
SaveImported,
// Delete all old config profiles before loading.
ResetUserProfile,
// Load a system config bundle.
LoadSystem,
LoadVendorOnly,
LoadFilamentOnly,
};
using LoadConfigBundleAttributes = enum_bitmask<LoadConfigBundleAttribute>;
// Load the config bundle based on the flags.
// Don't do any config substitutions when loading a system profile, perform and report substitutions otherwise.
/*std::pair<PresetsConfigSubstitutions, size_t> load_configbundle(
const std::string &path, LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule);*/
//Orca: load config bundle from json, pass the base bundle to support cross vendor inheritance
// Orca: `dir` is where the vendor is looked for — its own directory, whether or
// not the profile JSONs are still there. A whole-vendor load comes from the
// vendor's preset cache whenever one covers the profile on disk, and is parsed
// from the JSONs (falling back to the ones in resources) only when none does.
std::pair<PresetsConfigSubstitutions, size_t> load_vendor_configs_from_json(
const std::string &dir, const std::string &vendor_name, LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule, const PresetBundle* base_bundle = nullptr);
// Export a config bundle file containing all the presets and the names of the active presets.
//void export_configbundle(const std::string &path, bool export_system_settings = false, bool export_physical_printers = false);
//BBS: add a function to export current configbundle as default
//void export_current_configbundle(const std::string &path);
//BBS: add a function to export system presets for cloud-slicer
//void export_system_configs(const std::string &path);
std::vector<std::string> export_current_configs(const std::string &path, std::function<int(std::string const &)> override_confirm,
bool include_modify, bool export_system_settings = false);
// Enable / disable the "- default -" preset.
void set_default_suppressed(bool default_suppressed);
// Set the filament preset name. As the name could come from the UI selection box,
// an optional "(modified)" suffix will be removed from the filament name.
void set_filament_preset(size_t idx, const std::string &name);
// Read out the number of extruders from an active printer preset,
// update size and content of filament_presets.
void update_multi_material_filament_presets(size_t to_delete_filament_id = size_t(-1));
void on_extruders_count_changed(int extruder_count);
// Update the is_compatible flag of all print and filament presets depending on whether they are marked
// as compatible with the currently selected printer (and print in case of filament presets).
// Also updates the is_visible flag of each preset.
// If select_other_if_incompatible is true, then the print or filament preset is switched to some compatible
// preset if the current print or filament preset is not compatible.
void update_compatible(PresetSelectCompatibleType select_other_print_if_incompatible, PresetSelectCompatibleType select_other_filament_if_incompatible);
void update_compatible(PresetSelectCompatibleType select_other_if_incompatible) { this->update_compatible(select_other_if_incompatible, select_other_if_incompatible); }
// Rewrite compatible_printers / compatible_prints references that point at a renamed system
// preset to the current name, mirroring Preset::normalize_inherits for the "inherits" field.
// Call after loading presets and before selection; requires update_system_maps() to have run.
void normalize_compatible_presets();
// Set the is_visible flag for printer vendors, printer models and printer variants
// based on the user configuration.
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
void load_installed_printers(const AppConfig &config);
const std::string& get_preset_name_by_alias(const Preset::Type& preset_type, const std::string& alias) const;
const int get_required_hrc_by_filament_type(const std::string& filament_type) const;
// Save current preset of a provided type under a new name. If the name is different from the old one,
// Unselected option would be reverted to the beginning values
//BBS: add project embedded preset logic
void save_changes_for_preset(const std::string& new_name, Preset::Type type, const std::vector<std::string>& unselected_options, bool save_to_project = false);
std::pair<PresetsConfigSubstitutions, std::string> load_system_models_from_json(ForwardCompatibilitySubstitutionRule compatibility_rule);
std::pair<PresetsConfigSubstitutions, std::string> load_system_filaments_json(ForwardCompatibilitySubstitutionRule compatibility_rule);
VendorProfile get_custom_vendor_models() const;
//orca: add 'custom' as default
static const char *ORCA_DEFAULT_BUNDLE;
static const char *ORCA_DEFAULT_PRINTER_MODEL;
static const char *ORCA_DEFAULT_PRINTER_VARIANT;
static const char *ORCA_DEFAULT_FILAMENT;
static const char *ORCA_FILAMENT_LIBRARY;
static const char *ORCA_DEFAULT_FILAMENT_PLACEHOLDER;
static std::array<Preset::Type, 3> types_list(PrinterTechnology pt) {
if (pt == ptFFF)
return { Preset::TYPE_PRINTER, Preset::TYPE_PRINT, Preset::TYPE_FILAMENT };
return { Preset::TYPE_PRINTER, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL };
}
// Orca: for validation only.
bool has_errors(bool check_duplicate_filament_subtypes = false) const;
// Orca: for validation only. Flag any system preset whose inherits / compatible_printers /
// compatible_prints references a deleted (unknown) or renamed (old) preset name.
bool check_preset_references() const;
// Merge one vendor's presets with the other vendor's presets, report duplicates.
// Public so per-vendor-cache consumers (e.g. the setup wizard) can assemble a
// bundle out of several per-vendor caches loaded into separate PresetBundle instances.
std::vector<std::string> merge_presets(PresetBundle &&other);
private:
// Load one vendor from its preset cache: the one in `dir`, or — when that is
// missing or stale — the one shipped in resources/profiles, both judged against
// the vendor as installed in `dir` and against the filament library in effect.
// False, with this bundle left clean, when neither is usable and the vendor has
// to be parsed. This is how load_vendor_configs_from_json reads a cache.
bool load_vendor_cache(const boost::filesystem::path& dir, const std::string& vendor_name);
// Read raw cache blob: verify magic, size, CRC.
static bool read_cache_blob(const std::string& path, std::string& out_blob);
// Write a cache blob with the standard 20-byte file header.
static void write_cache_blob(const std::string& path, const std::string& blob);
// (De)serialization of one collection's slice for the per-vendor cache:
// every non-default, non-external preset (system or user) plus
// m_printer_hold_alias. See save_vendor_cache/load_vendor_cache.
static void save_collection(cereal::BinaryOutputArchive& ar, const PresetCollection& coll);
static void load_collection(cereal::BinaryInputArchive& ar, PresetCollection& coll, const VendorMap& vendors);
// Whether to (re)write a per-vendor cache after a JSON parse.
bool m_generate_vendor_caches { false };
// Orca: validation only - flag any printer with two or more compatible
// filament presets sharing one filament_id (ambiguous AMS subtype match).
bool check_duplicate_filament_subtypes() const;
//std::pair<PresetsConfigSubstitutions, std::string> load_system_presets(ForwardCompatibilitySubstitutionRule compatibility_rule);
//BBS: add json related logic
std::pair<PresetsConfigSubstitutions, std::string> load_system_presets_from_json(ForwardCompatibilitySubstitutionRule compatibility_rule);
// Update the multicolor information for filaments.
void update_filament_multi_color();
// Update renamed_from and alias maps of system profiles.
void update_system_maps();
// Set the is_visible flag for filaments and sla materials,
// apply defaults based on enabled printers when no filaments/materials are installed.
void load_installed_filaments(AppConfig &config);
void load_installed_sla_materials(AppConfig &config);
// Load print, filament & printer presets from a config. If it is an external config, then the name is extracted from the external path.
// and the external config is just referenced, not stored into user profile directory.
// If it is not an external config, then the config will be stored into the user profile directory.
void load_config_file_config(const std::string &name_or_path, bool is_external, DynamicPrintConfig &&config, Semver file_version = Semver(), bool selected = false);
/*ConfigSubstitutions load_config_file_config_bundle(
const std::string &path, const boost::property_tree::ptree &tree, ForwardCompatibilitySubstitutionRule compatibility_rule);*/
DynamicPrintConfig full_fff_config(bool apply_extruder, std::optional<std::vector<int>> filament_maps=std::nullopt, std::optional<std::vector<int>> filament_volume_maps=std::nullopt) const;
DynamicPrintConfig full_sla_config() const;
// Orca: used for validation only
bool validation_mode = false;
std::string vendor_to_validate = "";
int m_errors = 0;
// Helper function: save preset to bundle directory with common logic
bool save_preset_to_bundle_dir(Preset& preset, PresetCollection* collection,
const std::string& bundle_id, const std::string& type_subdir,
const std::string& bundle_base_dir);
};
ENABLE_ENUM_BITMASK_OPERATORS(PresetBundle::LoadConfigBundleAttribute)
// True if `vendor` is installed in data_dir()/system. A build that ships preset
// caches installs the cache alone, so it — not the profile — marks a vendor
// installed, and either one on its own counts.
extern bool is_vendor_installed(const std::string& vendor);
// The version of the installed vendor: what its profile claims, or what its cache
// was stamped with where only the cache is installed. Invalid Semver if neither is.
extern Semver installed_vendor_version(const std::string& vendor);
// The vendors `dir` holds, sorted: one is named by its profile or, in a build that
// ships preset caches instead of the raw profile JSONs, by its cache alone.
extern std::set<std::string> vendor_names_in(const boost::filesystem::path& dir);
// The version a build ships `vendor` at: whichever of its preset cache and its
// profile is newer, that being the one installing lays down. Invalid Semver if the
// build ships neither.
extern Semver resource_vendor_version(const std::string& vendor);
// Install vendors from the resources directory into the data directory, each as
// its preset cache or as its profile and preset JSONs — whichever of the two the
// build ships at the newer version. Anything the previous install of that vendor
// left behind goes, so only the form just installed is there to be loaded.
// bundle_names: vendor names, without extension.
// Returns false on the first vendor that cannot be installed.
extern bool install_vendor_bundles_from_resources(const std::vector<std::string>& bundle_names,
const std::string& resource_subdir = "profiles",
const std::string& data_subdir = "system");
} // namespace Slic3r
#endif /* slic3r_PresetBundle_hpp_ */