mirror of
https://github.com/FULU-Foundation/OrcaSlicer-bambulab.git
synced 2026-05-25 01:49:22 -07:00
Merge branch 'new_cooling_logic'
This commit is contained in:
@@ -2,9 +2,13 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "Preset.hpp"
|
||||
#include "AppConfig.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <boost/nowide/cenv.hpp>
|
||||
@@ -23,14 +27,16 @@
|
||||
#include "../../libslic3r/Utils.hpp"
|
||||
#include "../../libslic3r/PlaceholderParser.hpp"
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree)
|
||||
ConfigFileType guess_config_file_type(const ptree &tree)
|
||||
{
|
||||
size_t app_config = 0;
|
||||
size_t bundle = 0;
|
||||
size_t config = 0;
|
||||
for (const boost::property_tree::ptree::value_type &v : tree) {
|
||||
for (const ptree::value_type &v : tree) {
|
||||
if (v.second.empty()) {
|
||||
if (v.first == "background_processing" ||
|
||||
v.first == "last_output_path" ||
|
||||
@@ -58,6 +64,79 @@ ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree)
|
||||
(bundle > config) ? CONFIG_FILE_TYPE_CONFIG_BUNDLE : CONFIG_FILE_TYPE_CONFIG;
|
||||
}
|
||||
|
||||
|
||||
VendorProfile VendorProfile::from_ini(const boost::filesystem::path &path, bool load_all)
|
||||
{
|
||||
ptree tree;
|
||||
boost::filesystem::ifstream ifs(path);
|
||||
boost::property_tree::read_ini(ifs, tree);
|
||||
return VendorProfile::from_ini(tree, path, load_all);
|
||||
}
|
||||
|
||||
VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all)
|
||||
{
|
||||
static const std::string printer_model_key = "printer_model:";
|
||||
const std::string id = path.stem().string();
|
||||
|
||||
if (! boost::filesystem::exists(path)) {
|
||||
throw std::runtime_error((boost::format("Cannot load Vendor Config Bundle `%1%`: File not found: `%2%`.") % id % path).str());
|
||||
}
|
||||
|
||||
VendorProfile res(id);
|
||||
|
||||
auto get_or_throw = [&](const ptree &tree, const std::string &key) -> ptree::const_assoc_iterator
|
||||
{
|
||||
auto res = tree.find(key);
|
||||
if (res == tree.not_found()) {
|
||||
throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Missing secion or key: `%2%`.") % id % key).str());
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
const auto &vendor_section = get_or_throw(tree, "vendor")->second;
|
||||
res.name = get_or_throw(vendor_section, "name")->second.data();
|
||||
|
||||
auto config_version_str = get_or_throw(vendor_section, "config_version")->second.data();
|
||||
auto config_version = Semver::parse(config_version_str);
|
||||
if (! config_version) {
|
||||
throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Cannot parse config_version: `%2%`.") % id % config_version_str).str());
|
||||
} else {
|
||||
res.config_version = std::move(*config_version);
|
||||
}
|
||||
|
||||
auto config_update_url = vendor_section.find("config_update_url");
|
||||
if (config_update_url != vendor_section.not_found()) {
|
||||
res.config_update_url = config_update_url->second.data();
|
||||
}
|
||||
|
||||
if (! load_all) {
|
||||
return res;
|
||||
}
|
||||
|
||||
for (auto §ion : tree) {
|
||||
if (boost::starts_with(section.first, printer_model_key)) {
|
||||
VendorProfile::PrinterModel model;
|
||||
model.id = section.first.substr(printer_model_key.size());
|
||||
model.name = section.second.get<std::string>("name", model.id);
|
||||
section.second.get<std::string>("variants", "");
|
||||
std::vector<std::string> variants;
|
||||
if (Slic3r::unescape_strings_cstyle(section.second.get<std::string>("variants", ""), variants)) {
|
||||
for (const std::string &variant_name : variants) {
|
||||
if (model.variant(variant_name) == nullptr)
|
||||
model.variants.emplace_back(VendorProfile::PrinterVariant(variant_name));
|
||||
}
|
||||
} else {
|
||||
// Log error? // XXX
|
||||
}
|
||||
if (! model.id.empty() && ! model.variants.empty())
|
||||
res.models.push_back(std::move(model));
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Suffix to be added to a modified preset name in the combo box.
|
||||
static std::string g_suffix_modified = " (modified)";
|
||||
const std::string& Preset::suffix_modified()
|
||||
@@ -175,6 +254,15 @@ bool Preset::update_compatible_with_printer(const Preset &active_printer, const
|
||||
return this->is_compatible = is_compatible_with_printer(active_printer, extra_config);
|
||||
}
|
||||
|
||||
void Preset::set_visible_from_appconfig(const AppConfig &app_config)
|
||||
{
|
||||
if (vendor == nullptr) { return; }
|
||||
const std::string &model = config.opt_string("printer_model");
|
||||
const std::string &variant = config.opt_string("printer_variant");
|
||||
if (model.empty() || variant.empty()) { return; }
|
||||
is_visible = app_config.get_variant(vendor->id, model, variant);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Preset::print_options()
|
||||
{
|
||||
static std::vector<std::string> s_opts {
|
||||
@@ -453,18 +541,6 @@ size_t PresetCollection::first_visible_idx() const
|
||||
return idx;
|
||||
}
|
||||
|
||||
// Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
|
||||
size_t PresetCollection::first_compatible_idx() const
|
||||
{
|
||||
size_t idx = m_default_suppressed ? 1 : 0;
|
||||
for (; idx < this->m_presets.size(); ++ idx)
|
||||
if (m_presets[idx].is_compatible)
|
||||
break;
|
||||
if (idx == this->m_presets.size())
|
||||
idx = 0;
|
||||
return idx;
|
||||
}
|
||||
|
||||
void PresetCollection::set_default_suppressed(bool default_suppressed)
|
||||
{
|
||||
if (m_default_suppressed != default_suppressed) {
|
||||
@@ -473,7 +549,7 @@ void PresetCollection::set_default_suppressed(bool default_suppressed)
|
||||
}
|
||||
}
|
||||
|
||||
void PresetCollection::update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible)
|
||||
size_t PresetCollection::update_compatible_with_printer_internal(const Preset &active_printer, bool unselect_if_incompatible)
|
||||
{
|
||||
DynamicPrintConfig config;
|
||||
config.set_key_value("printer_preset", new ConfigOptionString(active_printer.name));
|
||||
@@ -484,14 +560,12 @@ void PresetCollection::update_compatible_with_printer(const Preset &active_print
|
||||
Preset &preset_selected = m_presets[idx_preset];
|
||||
Preset &preset_edited = selected ? m_edited_preset : preset_selected;
|
||||
if (! preset_edited.update_compatible_with_printer(active_printer, &config) &&
|
||||
selected && select_other_if_incompatible)
|
||||
selected && unselect_if_incompatible)
|
||||
m_idx_selected = (size_t)-1;
|
||||
if (selected)
|
||||
preset_selected.is_compatible = preset_edited.is_compatible;
|
||||
}
|
||||
if (m_idx_selected == (size_t)-1)
|
||||
// Find some other compatible preset, or the "-- default --" preset.
|
||||
this->select_preset(first_compatible_idx());
|
||||
return m_idx_selected;
|
||||
}
|
||||
|
||||
// Save the preset under a new name. If the name is different from the old one,
|
||||
@@ -677,8 +751,8 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b
|
||||
// 1) Try to find the preset by its name.
|
||||
auto it = this->find_preset_internal(name);
|
||||
size_t idx = 0;
|
||||
if (it != m_presets.end() && it->name == name)
|
||||
// Preset found by its name.
|
||||
if (it != m_presets.end() && it->name == name && it->is_visible)
|
||||
// Preset found by its name and it is visible.
|
||||
idx = it - m_presets.begin();
|
||||
else {
|
||||
// Find the first visible preset.
|
||||
@@ -699,6 +773,46 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PresetCollection::select_preset_by_name_strict(const std::string &name)
|
||||
{
|
||||
// 1) Try to find the preset by its name.
|
||||
auto it = this->find_preset_internal(name);
|
||||
size_t idx = (size_t)-1;
|
||||
if (it != m_presets.end() && it->name == name && it->is_visible)
|
||||
// Preset found by its name.
|
||||
idx = it - m_presets.begin();
|
||||
// 2) Select the new preset.
|
||||
if (idx != (size_t)-1) {
|
||||
this->select_preset(idx);
|
||||
return true;
|
||||
}
|
||||
m_idx_selected = idx;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Merge one vendor's presets with the other vendor's presets, report duplicates.
|
||||
std::vector<std::string> PresetCollection::merge_presets(PresetCollection &&other, const std::set<VendorProfile> &new_vendors)
|
||||
{
|
||||
std::vector<std::string> duplicates;
|
||||
for (Preset &preset : other.m_presets) {
|
||||
if (preset.is_default || preset.is_external)
|
||||
continue;
|
||||
Preset key(m_type, preset.name);
|
||||
auto it = std::lower_bound(m_presets.begin() + 1, m_presets.end(), key);
|
||||
if (it == m_presets.end() || it->name != preset.name) {
|
||||
if (preset.vendor != nullptr) {
|
||||
// Re-assign a pointer to the vendor structure in the new PresetBundle.
|
||||
auto it = new_vendors.find(*preset.vendor);
|
||||
assert(it != new_vendors.end());
|
||||
preset.vendor = &(*it);
|
||||
}
|
||||
this->m_presets.emplace(it, std::move(preset));
|
||||
} else
|
||||
duplicates.emplace_back(std::move(preset.name));
|
||||
}
|
||||
return duplicates;
|
||||
}
|
||||
|
||||
std::string PresetCollection::name() const
|
||||
{
|
||||
switch (this->type()) {
|
||||
|
||||
Reference in New Issue
Block a user