mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 00:31:11 -06:00
Next step of Perl to C++ configuration layer conversion.
This commit is contained in:
parent
337f6c5808
commit
95c284c764
15 changed files with 414 additions and 394 deletions
|
@ -143,7 +143,7 @@ void AppConfig::update_last_output_dir(const std::string &dir)
|
|||
|
||||
std::string AppConfig::config_path()
|
||||
{
|
||||
return boost::filesystem::canonical(boost::filesystem::path(Slic3r::data_dir()) / "config.ini").make_preferred().string();
|
||||
return (boost::filesystem::path(Slic3r::data_dir()) / "slic3r.ini").make_preferred().string();
|
||||
}
|
||||
|
||||
bool AppConfig::exists()
|
||||
|
|
|
@ -16,9 +16,9 @@ public:
|
|||
// Override missing or keys with their defaults.
|
||||
void set_defaults();
|
||||
|
||||
// Load the config.ini from a user profile directory (or a datadir, if configured).
|
||||
// Load the slic3r.ini from a user profile directory (or a datadir, if configured).
|
||||
void load();
|
||||
// Store the config.ini into a user profile directory (or a datadir, if configured).
|
||||
// Store the slic3r.ini into a user profile directory (or a datadir, if configured).
|
||||
void save();
|
||||
|
||||
// Does this config need to be saved?
|
||||
|
@ -62,6 +62,9 @@ public:
|
|||
bool has(const std::string &key) const
|
||||
{ return this->has("", key); }
|
||||
|
||||
void clear_section(const std::string §ion)
|
||||
{ m_storage[section].clear(); }
|
||||
|
||||
// return recent/skein_directory or recent/config_directory or empty string.
|
||||
std::string get_last_dir() const;
|
||||
void update_config_dir(const std::string &dir);
|
||||
|
|
|
@ -28,6 +28,39 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
ConfigFileType guess_config_file_type(const boost::property_tree::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) {
|
||||
if (v.second.empty()) {
|
||||
if (v.first == "background_processing" ||
|
||||
v.first == "last_output_path" ||
|
||||
v.first == "no_controller" ||
|
||||
v.first == "no_defaults")
|
||||
++ app_config;
|
||||
else if (v.first == "nozzle_diameter" ||
|
||||
v.first == "filament_diameter")
|
||||
++ config;
|
||||
} else if (boost::algorithm::starts_with(v.first, "print:") ||
|
||||
boost::algorithm::starts_with(v.first, "filament:") ||
|
||||
boost::algorithm::starts_with(v.first, "printer:") ||
|
||||
v.first == "settings")
|
||||
++ bundle;
|
||||
else if (v.first == "presets") {
|
||||
++ app_config;
|
||||
++ bundle;
|
||||
} else if (v.first == "recent") {
|
||||
for (auto &kvp : v.second)
|
||||
if (kvp.first == "config_directory" || kvp.first == "skein_directory")
|
||||
++ app_config;
|
||||
}
|
||||
}
|
||||
return (app_config > bundle && app_config > config) ? CONFIG_FILE_TYPE_APP_CONFIG :
|
||||
(bundle > config) ? CONFIG_FILE_TYPE_CONFIG_BUNDLE : CONFIG_FILE_TYPE_CONFIG;
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
@ -43,40 +76,26 @@ std::string Preset::remove_suffix_modified(const std::string &name)
|
|||
name;
|
||||
}
|
||||
|
||||
// Load keys from a config file or a G-code.
|
||||
// Throw exceptions with reasonable messages if something goes wrong.
|
||||
void Preset::load_config_file(DynamicPrintConfig &config, const std::string &path)
|
||||
void Preset::set_num_extruders(DynamicPrintConfig &config, unsigned int num_extruders)
|
||||
{
|
||||
try {
|
||||
if (boost::algorithm::iends_with(path, ".gcode") || boost::algorithm::iends_with(path, ".g"))
|
||||
config.load_from_gcode(path);
|
||||
else
|
||||
config.load(path);
|
||||
} catch (const std::ifstream::failure&) {
|
||||
throw std::runtime_error(std::string("The selected preset does not exist anymore: ") + path);
|
||||
} catch (const std::runtime_error&) {
|
||||
throw std::runtime_error(std::string("Failed loading the preset file: ") + path);
|
||||
}
|
||||
|
||||
// Update new extruder fields at the printer profile.
|
||||
auto keys = config.keys();
|
||||
const auto &defaults = FullPrintConfig::defaults();
|
||||
if (std::find(keys.begin(), keys.end(), "nozzle_diameter") != keys.end()) {
|
||||
// Loaded the Printer settings. Verify, that all extruder dependent values have enough values.
|
||||
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
|
||||
size_t num_extruders = nozzle_diameter->values.size();
|
||||
auto *deretract_speed = dynamic_cast<ConfigOptionFloats*>(config.option("deretract_speed"));
|
||||
deretract_speed->values.resize(num_extruders, deretract_speed->values.empty() ?
|
||||
defaults.deretract_speed.values.front() : deretract_speed->values.front());
|
||||
auto *extruder_colour = dynamic_cast<ConfigOptionStrings*>(config.option("extruder_colour"));
|
||||
extruder_colour->values.resize(num_extruders, extruder_colour->values.empty() ?
|
||||
defaults.extruder_colour.values.front() : extruder_colour->values.front());
|
||||
auto *retract_before_wipe = dynamic_cast<ConfigOptionPercents*>(config.option("retract_before_wipe"));
|
||||
retract_before_wipe->values.resize(num_extruders, retract_before_wipe->values.empty() ?
|
||||
defaults.retract_before_wipe.values.front() : retract_before_wipe->values.front());
|
||||
for (const std::string &key : Preset::nozzle_options()) {
|
||||
auto *opt = config.option(key, false);
|
||||
assert(opt != nullptr);
|
||||
assert(opt->is_vector());
|
||||
static_cast<ConfigOptionVectorBase*>(opt)->resize(num_extruders, defaults.option(key));
|
||||
}
|
||||
}
|
||||
|
||||
// Update new extruder fields at the printer profile.
|
||||
void Preset::normalize(DynamicPrintConfig &config)
|
||||
{
|
||||
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
|
||||
if (nozzle_diameter != nullptr)
|
||||
// Loaded the Printer settings. Verify, that all extruder dependent values have enough values.
|
||||
set_num_extruders(config, (unsigned int)nozzle_diameter->values.size());
|
||||
}
|
||||
|
||||
// Load a config file, return a C++ class Slic3r::DynamicPrintConfig with $keys initialized from the config file.
|
||||
// In case of a "default" config item, return the default values.
|
||||
DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys)
|
||||
|
@ -84,9 +103,17 @@ DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys)
|
|||
// Set the configuration from the defaults.
|
||||
Slic3r::FullPrintConfig defaults;
|
||||
this->config.apply_only(defaults, keys.empty() ? defaults.keys() : keys);
|
||||
if (! this->is_default)
|
||||
if (! this->is_default) {
|
||||
// Load the preset file, apply preset values on top of defaults.
|
||||
load_config_file(this->config, this->file);
|
||||
try {
|
||||
this->config.load(this->file);
|
||||
Preset::normalize(this->config);
|
||||
} catch (const std::ifstream::failure&) {
|
||||
throw std::runtime_error(std::string("The selected preset does not exist anymore: ") + this->file);
|
||||
} catch (const std::runtime_error&) {
|
||||
throw std::runtime_error(std::string("Failed loading the preset file: ") + this->file);
|
||||
}
|
||||
}
|
||||
this->loaded = true;
|
||||
return this->config;
|
||||
}
|
||||
|
@ -111,6 +138,74 @@ bool Preset::enable_compatible(const std::string &active_printer)
|
|||
return this->is_visible;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Preset::print_options()
|
||||
{
|
||||
static std::vector<std::string> s_opts {
|
||||
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "top_solid_layers", "bottom_solid_layers",
|
||||
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
||||
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "external_fill_pattern",
|
||||
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
|
||||
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
|
||||
"max_volumetric_speed", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
|
||||
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
|
||||
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
|
||||
"bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
|
||||
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height",
|
||||
"min_skirt_length", "brim_width", "support_material", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
|
||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
|
||||
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
|
||||
"support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
|
||||
"extruder_clearance_height", "gcode_comments", "output_filename_format", "post_process", "perimeter_extruder",
|
||||
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
|
||||
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
|
||||
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"wipe_tower_width", "wipe_tower_per_color_wipe"
|
||||
};
|
||||
return s_opts;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Preset::filament_options()
|
||||
{
|
||||
static std::vector<std::string> s_opts {
|
||||
"filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
|
||||
"extrusion_multiplier", "filament_density", "filament_cost", "temperature", "first_layer_temperature", "bed_temperature",
|
||||
"first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", "max_fan_speed", "bridge_fan_speed",
|
||||
"disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "start_filament_gcode",
|
||||
"end_filament_gcode"
|
||||
};
|
||||
return s_opts;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Preset::printer_options()
|
||||
{
|
||||
static std::vector<std::string> s_opts;
|
||||
if (s_opts.empty()) {
|
||||
s_opts = {
|
||||
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
|
||||
"octoprint_host", "octoprint_apikey", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
|
||||
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
|
||||
"printer_notes"
|
||||
};
|
||||
s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end());
|
||||
}
|
||||
return s_opts;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Preset::nozzle_options()
|
||||
{
|
||||
// ConfigOptionFloats, ConfigOptionPercents, ConfigOptionBools, ConfigOptionStrings
|
||||
static std::vector<std::string> s_opts {
|
||||
"nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset",
|
||||
"retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed",
|
||||
"retract_before_wipe", "retract_restart_extra", "retract_before_travel", "wipe",
|
||||
"retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour"
|
||||
};
|
||||
return s_opts;
|
||||
}
|
||||
|
||||
PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys) :
|
||||
m_type(type),
|
||||
m_edited_preset(type, "", false),
|
||||
|
@ -203,6 +298,7 @@ void PresetCollection::save_current_preset(const std::string &new_name)
|
|||
}
|
||||
m_edited_preset = m_presets[m_idx_selected];
|
||||
m_presets[m_idx_selected].save();
|
||||
m_presets.front().is_visible = ! m_default_suppressed || m_idx_selected > 0;
|
||||
}
|
||||
|
||||
void PresetCollection::delete_current_preset()
|
||||
|
@ -254,7 +350,7 @@ void PresetCollection::set_default_suppressed(bool default_suppressed)
|
|||
{
|
||||
if (m_default_suppressed != default_suppressed) {
|
||||
m_default_suppressed = default_suppressed;
|
||||
m_presets.front().is_visible = ! default_suppressed || m_presets.size() > 1;
|
||||
m_presets.front().is_visible = ! default_suppressed || (m_presets.size() > 1 && m_idx_selected > 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,6 +416,7 @@ bool PresetCollection::update_dirty_ui(wxItemContainer *ui)
|
|||
bool was_dirty = this->get_selected_preset().is_dirty;
|
||||
bool is_dirty = current_is_dirty();
|
||||
this->get_selected_preset().is_dirty = is_dirty;
|
||||
this->get_edited_preset().is_dirty = is_dirty;
|
||||
// 2) Update the labels.
|
||||
for (unsigned int ui_id = 0; ui_id < ui->GetCount(); ++ ui_id) {
|
||||
std::string old_label = ui->GetString(ui_id).utf8_str().data();
|
||||
|
@ -345,6 +442,7 @@ Preset& PresetCollection::select_preset(size_t idx)
|
|||
idx = first_visible_idx();
|
||||
m_idx_selected = idx;
|
||||
m_edited_preset = m_presets[idx];
|
||||
m_presets.front().is_visible = ! m_default_suppressed || m_idx_selected > 0;
|
||||
return m_presets[idx];
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,16 @@ class wxItemContainer;
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
enum ConfigFileType
|
||||
{
|
||||
CONFIG_FILE_TYPE_UNKNOWN,
|
||||
CONFIG_FILE_TYPE_APP_CONFIG,
|
||||
CONFIG_FILE_TYPE_CONFIG,
|
||||
CONFIG_FILE_TYPE_CONFIG_BUNDLE,
|
||||
};
|
||||
|
||||
extern ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree);
|
||||
|
||||
class Preset
|
||||
{
|
||||
public:
|
||||
|
@ -70,13 +80,25 @@ public:
|
|||
// Mark this preset as visible if it is compatible with active_printer.
|
||||
bool enable_compatible(const std::string &active_printer);
|
||||
|
||||
// Resize the extruder specific fields, initialize them with the content of the 1st extruder.
|
||||
void set_num_extruders(unsigned int n) { set_num_extruders(this->config, n); }
|
||||
|
||||
// Sort lexicographically by a preset name. The preset name shall be unique across a single PresetCollection.
|
||||
bool operator<(const Preset &other) const { return this->name < other.name; }
|
||||
|
||||
static const std::vector<std::string>& print_options();
|
||||
static const std::vector<std::string>& filament_options();
|
||||
// Printer options contain the nozzle options.
|
||||
static const std::vector<std::string>& printer_options();
|
||||
// Nozzle options of the printer options.
|
||||
static const std::vector<std::string>& nozzle_options();
|
||||
|
||||
protected:
|
||||
friend class PresetCollection;
|
||||
friend class PresetBundle;
|
||||
static void load_config_file(DynamicPrintConfig &config, const std::string &path);
|
||||
static void normalize(DynamicPrintConfig &config);
|
||||
// Resize the extruder specific vectors ()
|
||||
static void set_num_extruders(DynamicPrintConfig &config, unsigned int n);
|
||||
static const std::string& suffix_modified();
|
||||
static std::string remove_suffix_modified(const std::string &name);
|
||||
};
|
||||
|
@ -117,7 +139,7 @@ public:
|
|||
|
||||
// Enable / disable the "- default -" preset.
|
||||
void set_default_suppressed(bool default_suppressed);
|
||||
bool is_default_suppressed() const { return m_default_suppressed || m_presets.size() <= 1; }
|
||||
bool is_default_suppressed() const { return m_default_suppressed; }
|
||||
|
||||
// Select a preset. If an invalid index is provided, the first visible preset is selected.
|
||||
Preset& select_preset(size_t idx);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/clamp.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <boost/nowide/cenv.hpp>
|
||||
|
@ -23,9 +24,9 @@
|
|||
namespace Slic3r {
|
||||
|
||||
PresetBundle::PresetBundle() :
|
||||
prints(Preset::TYPE_PRINT, print_options()),
|
||||
filaments(Preset::TYPE_FILAMENT, filament_options()),
|
||||
printers(Preset::TYPE_PRINTER, printer_options()),
|
||||
prints(Preset::TYPE_PRINT, Preset::print_options()),
|
||||
filaments(Preset::TYPE_FILAMENT, Preset::filament_options()),
|
||||
printers(Preset::TYPE_PRINTER, Preset::printer_options()),
|
||||
m_bitmapCompatible(new wxBitmap),
|
||||
m_bitmapIncompatible(new wxBitmap)
|
||||
{
|
||||
|
@ -66,7 +67,7 @@ void PresetBundle::setup_directories()
|
|||
throw std::runtime_error(std::string("datadir does not exist: ") + Slic3r::data_dir());
|
||||
std::initializer_list<const char*> names = { "print", "filament", "printer" };
|
||||
for (const char *name : names) {
|
||||
boost::filesystem::path subdir = (dir / subdir).make_preferred();
|
||||
boost::filesystem::path subdir = (dir / name).make_preferred();
|
||||
if (! boost::filesystem::is_directory(subdir) &&
|
||||
! boost::filesystem::create_directory(subdir))
|
||||
throw std::runtime_error(std::string("Slic3r was unable to create its data directory at ") + subdir.string());
|
||||
|
@ -87,28 +88,33 @@ void PresetBundle::load_selections(const AppConfig &config)
|
|||
{
|
||||
prints.select_preset_by_name(config.get("presets", "print"), true);
|
||||
filaments.select_preset_by_name(config.get("presets", "filament"), true);
|
||||
printers.select_preset_by_name(config.get("presets", "printer"), true);
|
||||
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
|
||||
size_t num_extruders = nozzle_diameter->values.size();
|
||||
this->set_filament_preset(0, filaments.get_selected_preset().name);
|
||||
for (int i = 1; i < 1000; ++ i) {
|
||||
for (unsigned int i = 1; i < (unsigned int)num_extruders; ++ i) {
|
||||
char name[64];
|
||||
sprintf(name, "filament_%d", i);
|
||||
if (! config.has("presets", name))
|
||||
break;
|
||||
this->set_filament_preset(i, name);
|
||||
this->set_filament_preset(i, config.get("presets", name));
|
||||
}
|
||||
printers.select_preset_by_name(config.get("presets", "printer"), true);
|
||||
}
|
||||
|
||||
// Export selections (current print, current filaments, current printer) into config.ini
|
||||
void PresetBundle::export_selections(AppConfig &config)
|
||||
{
|
||||
config.set("presets", "print", prints .get_selected_preset().name);
|
||||
config.set("presets", "filament", filaments.get_selected_preset().name);
|
||||
for (int i = 1; i < 1000; ++ i) {
|
||||
assert(filament_presets.size() >= 1);
|
||||
assert(filament_presets.size() > 1 || filaments.get_selected_preset().name == filament_presets.front());
|
||||
config.clear_section("presets");
|
||||
config.set("presets", "print", prints.get_selected_preset().name);
|
||||
config.set("presets", "filament", filament_presets.front());
|
||||
for (int i = 1; i < filament_presets.size(); ++i) {
|
||||
char name[64];
|
||||
sprintf(name, "filament_%d", i);
|
||||
config.set("presets", name, filament_presets[i]);
|
||||
}
|
||||
config.set("presets", "printer", printers .get_selected_preset().name);
|
||||
config.set("presets", "printer", printers.get_selected_preset().name);
|
||||
}
|
||||
|
||||
bool PresetBundle::load_compatible_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible)
|
||||
|
@ -175,7 +181,7 @@ DynamicPrintConfig PresetBundle::full_config() const
|
|||
std::string key = std::string(keys[i]) + "_extruder";
|
||||
auto *opt = dynamic_cast<ConfigOptionInt*>(out.option(key, false));
|
||||
assert(opt != nullptr);
|
||||
opt->value = std::min<int>(opt->value, std::min<int>(0, int(num_extruders) - 1));
|
||||
opt->value = boost::algorithm::clamp<int>(opt->value, 0, int(num_extruders));
|
||||
}
|
||||
|
||||
return out;
|
||||
|
@ -186,16 +192,44 @@ DynamicPrintConfig PresetBundle::full_config() const
|
|||
// 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.
|
||||
void PresetBundle::load_config_file(const std::string &path)
|
||||
{
|
||||
// 1) Try to load the config file into a boost property tree.
|
||||
boost::property_tree::ptree tree;
|
||||
try {
|
||||
boost::nowide::ifstream ifs(path);
|
||||
boost::property_tree::read_ini(ifs, tree);
|
||||
} catch (const std::ifstream::failure&) {
|
||||
throw std::runtime_error(std::string("The config file cannot be loaded: ") + path);
|
||||
} catch (const std::runtime_error&) {
|
||||
throw std::runtime_error(std::string("Failed loading the preset file: ") + path);
|
||||
}
|
||||
|
||||
// 2) Continue based on the type of the configuration file.
|
||||
ConfigFileType config_file_type = guess_config_file_type(tree);
|
||||
switch (config_file_type) {
|
||||
case CONFIG_FILE_TYPE_UNKNOWN:
|
||||
throw std::runtime_error(std::string("Unknown configuration file type: ") + path);
|
||||
case CONFIG_FILE_TYPE_APP_CONFIG:
|
||||
throw std::runtime_error(std::string("Invalid configuration file: ") + path + ". This is an application config file.");
|
||||
case CONFIG_FILE_TYPE_CONFIG:
|
||||
load_config_file_config(path, tree);
|
||||
break;
|
||||
case CONFIG_FILE_TYPE_CONFIG_BUNDLE:
|
||||
load_config_file_config_bundle(path, tree);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Load a config file from a boost property_tree. This is a private method called from load_config_file.
|
||||
void PresetBundle::load_config_file_config(const std::string &path, const boost::property_tree::ptree &tree)
|
||||
{
|
||||
// 1) Initialize a config from full defaults.
|
||||
DynamicPrintConfig config;
|
||||
config.apply(FullPrintConfig());
|
||||
config.load(tree);
|
||||
Preset::normalize(config);
|
||||
|
||||
// 2) Try to load the config file.
|
||||
// Throw exceptions with reasonable messages if something goes wrong.
|
||||
Preset::load_config_file(config, path);
|
||||
|
||||
// 3) Create a name from the file name.
|
||||
// 2) Create a name from the file name.
|
||||
// Keep the suffix (.ini, .gcode, .amf, .3mf etc) to differentiate it from the normal profiles.
|
||||
std::string name = boost::filesystem::path(path).filename().string();
|
||||
|
||||
|
@ -245,6 +279,32 @@ void PresetBundle::load_config_file(const std::string &path)
|
|||
}
|
||||
}
|
||||
|
||||
// Load the active configuration of a config bundle from a boost property_tree. This is a private method called from load_config_file.
|
||||
void PresetBundle::load_config_file_config_bundle(const std::string &path, const boost::property_tree::ptree &tree)
|
||||
{
|
||||
// 1) Load the config bundle into a temp data.
|
||||
PresetBundle tmp_bundle;
|
||||
tmp_bundle.load_configbundle(path);
|
||||
|
||||
// 2) Extract active configs from the config bundle, copy them and activate them in this bundle.
|
||||
if (tmp_bundle.prints.get_selected_preset().is_default)
|
||||
this->prints.select_preset(0);
|
||||
else {
|
||||
std::string new_name = tmp_bundle.prints.get_selected_preset().name;
|
||||
Preset *existing = this->prints.find_preset(new_name, false);
|
||||
if (existing == nullptr) {
|
||||
// Save under the new_name.
|
||||
} else if (existing->config == tmp_bundle.prints.get_selected_preset().config) {
|
||||
// Don't save as the config exists in the current bundle and its content is the same.
|
||||
new_name.clear();
|
||||
} else {
|
||||
// Generate a new unique name.
|
||||
}
|
||||
if (! new_name.empty())
|
||||
this->prints.load_preset(path, new_name, tmp_bundle.prints.get_selected_preset().config);
|
||||
}
|
||||
}
|
||||
|
||||
// Load a config bundle file, into presets and store the loaded presets into separate files
|
||||
// of the local configuration directory.
|
||||
size_t PresetBundle::load_configbundle(const std::string &path)
|
||||
|
@ -333,17 +393,18 @@ size_t PresetBundle::load_configbundle(const std::string &path)
|
|||
void PresetBundle::update_multi_material_filament_presets()
|
||||
{
|
||||
// Verify and select the filament presets.
|
||||
auto *nozzle_diameter = static_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
|
||||
auto *nozzle_diameter = static_cast<const ConfigOptionFloats*>(printers.get_edited_preset().config.option("nozzle_diameter"));
|
||||
size_t num_extruders = nozzle_diameter->values.size();
|
||||
// Verify validity of the current filament presets.
|
||||
printf("PresetBundle::update_multi_material_filament_presets, old: %d, new: %d\n", int(this->filament_presets.size()), int(num_extruders));
|
||||
for (size_t i = 0; i < std::min(this->filament_presets.size(), num_extruders); ++ i)
|
||||
this->filament_presets[i] = this->filaments.find_preset(this->filament_presets[i], true)->name;
|
||||
// Append the rest of filament presets.
|
||||
if (this->filament_presets.size() < num_extruders)
|
||||
this->filament_presets.resize(num_extruders, this->filaments.first_visible().name);
|
||||
// if (this->filament_presets.size() < num_extruders)
|
||||
this->filament_presets.resize(num_extruders, this->filament_presets.empty() ? this->filaments.first_visible().name : this->filament_presets.back());
|
||||
}
|
||||
|
||||
void PresetBundle::export_configbundle(const std::string &path, const DynamicPrintConfig &settings)
|
||||
void PresetBundle::export_configbundle(const std::string &path) //, const DynamicPrintConfig &settings
|
||||
{
|
||||
boost::nowide::ofstream c;
|
||||
c.open(path, std::ios::out | std::ios::trunc);
|
||||
|
@ -358,14 +419,14 @@ void PresetBundle::export_configbundle(const std::string &path, const DynamicPri
|
|||
if (preset.is_default || preset.is_external)
|
||||
// Only export the common presets, not external files or the default preset.
|
||||
continue;
|
||||
c << "[" << presets.name() << ":" << preset.name << "]" << std::endl;
|
||||
c << std::endl << "[" << presets.name() << ":" << preset.name << "]" << std::endl;
|
||||
for (const std::string &opt_key : preset.config.keys())
|
||||
c << opt_key << " = " << preset.config.serialize(opt_key) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Export the names of the active presets.
|
||||
c << "[presets]" << std::endl;
|
||||
c << std::endl << "[presets]" << std::endl;
|
||||
c << "print = " << this->prints.get_selected_preset().name << std::endl;
|
||||
c << "printer = " << this->printers.get_selected_preset().name << std::endl;
|
||||
for (size_t i = 0; i < this->filament_presets.size(); ++ i) {
|
||||
|
@ -377,12 +438,13 @@ void PresetBundle::export_configbundle(const std::string &path, const DynamicPri
|
|||
c << "filament" << suffix << " = " << this->filament_presets[i] << std::endl;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Export the following setting values from the provided setting repository.
|
||||
static const char *settings_keys[] = { "autocenter" };
|
||||
c << "[presets]" << std::endl;
|
||||
c << "print = " << this->prints.get_selected_preset().name << std::endl;
|
||||
c << "[settings]" << std::endl;
|
||||
for (size_t i = 0; i < sizeof(settings_keys) / sizeof(settings_keys[0]); ++ i)
|
||||
c << settings_keys[i] << " = " << settings.serialize(settings_keys[i]) << std::endl;
|
||||
#endif
|
||||
|
||||
c.close();
|
||||
}
|
||||
|
@ -530,69 +592,6 @@ void PresetBundle::update_platter_filament_ui_colors(unsigned int idx_extruder,
|
|||
ui->Thaw();
|
||||
}
|
||||
|
||||
const std::vector<std::string>& PresetBundle::print_options()
|
||||
{
|
||||
const char *opts[] = {
|
||||
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "top_solid_layers", "bottom_solid_layers",
|
||||
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
||||
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "external_fill_pattern",
|
||||
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
|
||||
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
|
||||
"max_volumetric_speed", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
|
||||
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
|
||||
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
|
||||
"bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
|
||||
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height",
|
||||
"min_skirt_length", "brim_width", "support_material", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
|
||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
|
||||
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
|
||||
"support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
|
||||
"extruder_clearance_height", "gcode_comments", "output_filename_format", "post_process", "perimeter_extruder",
|
||||
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
|
||||
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
|
||||
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"wipe_tower_width", "wipe_tower_per_color_wipe"
|
||||
};
|
||||
static std::vector<std::string> s_opts;
|
||||
if (s_opts.empty())
|
||||
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
|
||||
return s_opts;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& PresetBundle::filament_options()
|
||||
{
|
||||
const char *opts[] = {
|
||||
"filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
|
||||
"extrusion_multiplier", "filament_density", "filament_cost", "temperature", "first_layer_temperature", "bed_temperature",
|
||||
"first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", "max_fan_speed", "bridge_fan_speed",
|
||||
"disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "start_filament_gcode",
|
||||
"end_filament_gcode"
|
||||
};
|
||||
static std::vector<std::string> s_opts;
|
||||
if (s_opts.empty())
|
||||
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
|
||||
return s_opts;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& PresetBundle::printer_options()
|
||||
{
|
||||
const char *opts[] = {
|
||||
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
|
||||
"octoprint_host", "octoprint_apikey", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
|
||||
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
|
||||
"nozzle_diameter", "extruder_offset", "retract_length", "retract_lift", "retract_speed", "deretract_speed",
|
||||
"retract_before_wipe", "retract_restart_extra", "retract_before_travel", "retract_layer_change", "wipe",
|
||||
"retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour", "printer_notes"
|
||||
};
|
||||
static std::vector<std::string> s_opts;
|
||||
if (s_opts.empty())
|
||||
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
|
||||
return s_opts;
|
||||
}
|
||||
|
||||
void PresetBundle::set_default_suppressed(bool default_suppressed)
|
||||
{
|
||||
prints.set_default_suppressed(default_suppressed);
|
||||
|
|
|
@ -47,17 +47,13 @@ public:
|
|||
size_t load_configbundle(const std::string &path);
|
||||
|
||||
// Export a config bundle file containing all the presets and the names of the active presets.
|
||||
void export_configbundle(const std::string &path, const DynamicPrintConfig &settings);
|
||||
void export_configbundle(const std::string &path); // , const DynamicPrintConfig &settings);
|
||||
|
||||
// Update a filament selection combo box on the platter for an idx_extruder.
|
||||
void update_platter_filament_ui(unsigned int idx_extruder, wxBitmapComboBox *ui);
|
||||
// Update the colors preview at the platter extruder combo box.
|
||||
void update_platter_filament_ui_colors(unsigned int idx_extruder, wxBitmapComboBox *ui);
|
||||
|
||||
static const std::vector<std::string>& print_options();
|
||||
static const std::vector<std::string>& filament_options();
|
||||
static const std::vector<std::string>& printer_options();
|
||||
|
||||
// Enable / disable the "- default -" preset.
|
||||
void set_default_suppressed(bool default_suppressed);
|
||||
|
||||
|
@ -70,6 +66,8 @@ public:
|
|||
void update_multi_material_filament_presets();
|
||||
|
||||
private:
|
||||
void load_config_file_config(const std::string &path, const boost::property_tree::ptree &tree);
|
||||
void load_config_file_config_bundle(const std::string &path, const boost::property_tree::ptree &tree);
|
||||
bool load_compatible_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible);
|
||||
|
||||
// Indicator, that the preset is compatible with the selected printer.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue