Merge branch 'master' into fs_emboss_temp

This commit is contained in:
Filip Sykala - NTB T15p 2023-02-13 11:36:01 +01:00
commit 934da5592c
12 changed files with 237 additions and 155 deletions

View file

@ -487,6 +487,46 @@ void AppConfig::save()
m_dirty = false; m_dirty = false;
} }
bool AppConfig::erase(const std::string &section, const std::string &key)
{
if (auto it_storage = m_storage.find(section); it_storage != m_storage.end()) {
auto &section = it_storage->second;
auto it = section.find(key);
if (it != section.end()) {
section.erase(it);
m_dirty = true;
return true;
}
}
return false;
}
bool AppConfig::set_section(const std::string &section, std::map<std::string, std::string> data)
{
auto it_section = m_storage.find(section);
if (it_section == m_storage.end()) {
if (data.empty())
return false;
it_section = m_storage.insert({ section, {} }).first;
}
auto &dst = it_section->second;
if (dst == data)
return false;
dst = std::move(data);
m_dirty = true;
return true;
}
bool AppConfig::clear_section(const std::string &section)
{
if (auto it_section = m_storage.find(section); it_section != m_storage.end() && ! it_section->second.empty()) {
it_section->second.clear();
m_dirty = true;
return true;
}
return false;
}
bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const
{ {
const auto it_v = m_vendors.find(vendor); const auto it_v = m_vendors.find(vendor);
@ -495,28 +535,47 @@ bool AppConfig::get_variant(const std::string &vendor, const std::string &model,
return it_m == it_v->second.end() ? false : it_m->second.find(variant) != it_m->second.end(); return it_m == it_v->second.end() ? false : it_m->second.find(variant) != it_m->second.end();
} }
void AppConfig::set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable) bool AppConfig::set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable)
{ {
if (enable) { if (enable) {
if (get_variant(vendor, model, variant)) { return; } if (get_variant(vendor, model, variant))
return false;
m_vendors[vendor][model].insert(variant); m_vendors[vendor][model].insert(variant);
} else { } else {
auto it_v = m_vendors.find(vendor); auto it_v = m_vendors.find(vendor);
if (it_v == m_vendors.end()) { return; } if (it_v == m_vendors.end())
return false;
auto it_m = it_v->second.find(model); auto it_m = it_v->second.find(model);
if (it_m == it_v->second.end()) { return; } if (it_m == it_v->second.end())
return false;
auto it_var = it_m->second.find(variant); auto it_var = it_m->second.find(variant);
if (it_var == it_m->second.end()) { return; } if (it_var == it_m->second.end())
return false;
it_m->second.erase(it_var); it_m->second.erase(it_var);
} }
// If we got here, there was an update // If we got here, there was an update
m_dirty = true; m_dirty = true;
return true;
} }
void AppConfig::set_vendors(const AppConfig &from) bool AppConfig::set_vendors(const VendorMap &vendors)
{ {
m_vendors = from.m_vendors; if (m_vendors != vendors) {
m_dirty = true; m_vendors = vendors;
m_dirty = true;
return true;
} else
return false;
}
bool AppConfig::set_vendors(VendorMap &&vendors)
{
if (m_vendors != vendors) {
m_vendors = std::move(vendors);
m_dirty = true;
return true;
} else
return false;
} }
std::string AppConfig::get_last_dir() const std::string AppConfig::get_last_dir() const
@ -551,34 +610,52 @@ std::vector<std::string> AppConfig::get_recent_projects() const
return ret; return ret;
} }
void AppConfig::set_recent_projects(const std::vector<std::string>& recent_projects) bool AppConfig::set_recent_projects(const std::vector<std::string>& recent_projects)
{ {
auto it = m_storage.find("recent_projects"); static constexpr const char *section = "recent_projects";
if (it == m_storage.end()) auto it_section = m_storage.find(section);
it = m_storage.insert(std::map<std::string, std::map<std::string, std::string>>::value_type("recent_projects", std::map<std::string, std::string>())).first; if (it_section == m_storage.end()) {
if (recent_projects.empty())
it->second.clear(); return false;
for (unsigned int i = 0; i < (unsigned int)recent_projects.size(); ++i) it_section = m_storage.insert({ std::string(section), {} }).first;
{
it->second[std::to_string(i + 1)] = recent_projects[i];
} }
auto &dst = it_section->second;
std::map<std::string, std::string> src;
for (unsigned int i = 0; i < (unsigned int)recent_projects.size(); ++i)
src[std::to_string(i + 1)] = recent_projects[i];
if (src != dst) {
dst = std::move(src);
m_dirty = true;
return true;
} else
return false;
} }
void AppConfig::set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, bool AppConfig::set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone,
float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz) float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz)
{ {
std::string key = std::string("mouse_device:") + name; const std::string key = std::string("mouse_device:") + name;
auto it = m_storage.find(key); auto it_section = m_storage.find(key);
if (it == m_storage.end()) if (it_section == m_storage.end())
it = m_storage.insert(std::map<std::string, std::map<std::string, std::string>>::value_type(key, std::map<std::string, std::string>())).first; it_section = m_storage.insert({ key, {} }).first;
auto &dst = it_section->second;
it->second.clear(); std::map<std::string, std::string> src;
it->second["translation_speed"] = float_to_string_decimal_point(translation_speed); src["translation_speed"] = float_to_string_decimal_point(translation_speed);
it->second["translation_deadzone"] = float_to_string_decimal_point(translation_deadzone); src["translation_deadzone"] = float_to_string_decimal_point(translation_deadzone);
it->second["rotation_speed"] = float_to_string_decimal_point(rotation_speed); src["rotation_speed"] = float_to_string_decimal_point(rotation_speed);
it->second["rotation_deadzone"] = float_to_string_decimal_point(rotation_deadzone); src["rotation_deadzone"] = float_to_string_decimal_point(rotation_deadzone);
it->second["zoom_speed"] = float_to_string_decimal_point(zoom_speed); src["zoom_speed"] = float_to_string_decimal_point(zoom_speed);
it->second["swap_yz"] = swap_yz ? "1" : "0"; src["swap_yz"] = swap_yz ? "1" : "0";
if (src != dst) {
dst = std::move(src);
m_dirty = true;
return true;
} else
return false;
} }
std::vector<std::string> AppConfig::get_mouse_device_names() const std::vector<std::string> AppConfig::get_mouse_device_names() const
@ -592,16 +669,16 @@ std::vector<std::string> AppConfig::get_mouse_device_names() const
return out; return out;
} }
void AppConfig::update_config_dir(const std::string &dir) bool AppConfig::update_config_dir(const std::string &dir)
{ {
this->set("recent", "config_directory", dir); return this->set("recent", "config_directory", dir);
} }
void AppConfig::update_skein_dir(const std::string &dir) bool AppConfig::update_skein_dir(const std::string &dir)
{ {
if (is_shapes_dir(dir)) if (is_shapes_dir(dir))
return; // do not save "shapes gallery" directory return false; // do not save "shapes gallery" directory
this->set("recent", "skein_directory", dir); return this->set("recent", "skein_directory", dir);
} }
/* /*
std::string AppConfig::get_last_output_dir(const std::string &alt) const std::string AppConfig::get_last_output_dir(const std::string &alt) const
@ -636,9 +713,9 @@ std::string AppConfig::get_last_output_dir(const std::string& alt, const bool re
return is_shapes_dir(alt) ? get_last_dir() : alt; return is_shapes_dir(alt) ? get_last_dir() : alt;
} }
void AppConfig::update_last_output_dir(const std::string& dir, const bool removable) bool AppConfig::update_last_output_dir(const std::string& dir, const bool removable)
{ {
this->set("", (removable ? "last_output_path_removable" : "last_output_path"), dir); return this->set("", (removable ? "last_output_path_removable" : "last_output_path"), dir);
} }
@ -656,7 +733,7 @@ void AppConfig::reset_selections()
} }
} }
std::string AppConfig::config_path() std::string AppConfig::config_path() const
{ {
std::string path = (m_mode == EAppMode::Editor) ? std::string path = (m_mode == EAppMode::Editor) ?
(boost::filesystem::path(Slic3r::data_dir()) / (SLIC3R_APP_KEY ".ini")).make_preferred().string() : (boost::filesystem::path(Slic3r::data_dir()) / (SLIC3R_APP_KEY ".ini")).make_preferred().string() :
@ -691,7 +768,7 @@ std::string AppConfig::profile_folder_url() const
return PROFILE_FOLDER_URL; return PROFILE_FOLDER_URL;
} }
bool AppConfig::exists() bool AppConfig::exists() const
{ {
return boost::filesystem::exists(config_path()); return boost::filesystem::exists(config_path());
} }

View file

@ -58,9 +58,13 @@ public:
} }
std::string get(const std::string &section, const std::string &key) const std::string get(const std::string &section, const std::string &key) const
{ std::string value; this->get(section, key, value); return value; } { std::string value; this->get(section, key, value); return value; }
bool get_bool(const std::string &section, const std::string &key) const
{ return this->get(section, key) == "1"; }
std::string get(const std::string &key) const std::string get(const std::string &key) const
{ std::string value; this->get("", key, value); return value; } { std::string value; this->get("", key, value); return value; }
void set(const std::string &section, const std::string &key, const std::string &value) bool get_bool(const std::string &key) const
{ return this->get(key) == "1"; }
bool set(const std::string &section, const std::string &key, const std::string &value)
{ {
#ifndef NDEBUG #ifndef NDEBUG
{ {
@ -74,10 +78,12 @@ public:
if (old != value) { if (old != value) {
old = value; old = value;
m_dirty = true; m_dirty = true;
return true;
} }
return false;
} }
void set(const std::string &key, const std::string &value) bool set(const std::string &key, const std::string &value)
{ this->set("", key, value); } { return this->set("", key, value); }
bool has(const std::string &section, const std::string &key) const bool has(const std::string &section, const std::string &key) const
{ {
auto it = m_storage.find(section); auto it = m_storage.find(section);
@ -89,40 +95,32 @@ public:
bool has(const std::string &key) const bool has(const std::string &key) const
{ return this->has("", key); } { return this->has("", key); }
void erase(const std::string &section, const std::string &key) bool erase(const std::string &section, const std::string &key);
{
auto it = m_storage.find(section);
if (it != m_storage.end()) {
it->second.erase(key);
}
}
bool has_section(const std::string &section) const bool has_section(const std::string &section) const
{ return m_storage.find(section) != m_storage.end(); } { return m_storage.find(section) != m_storage.end(); }
const std::map<std::string, std::string>& get_section(const std::string &section) const const std::map<std::string, std::string>& get_section(const std::string &section) const
{ auto it = m_storage.find(section); assert(it != m_storage.end()); return it->second; } { auto it = m_storage.find(section); assert(it != m_storage.end()); return it->second; }
void set_section(const std::string &section, const std::map<std::string, std::string>& data) bool set_section(const std::string &section, std::map<std::string, std::string> data);
{ m_storage[section] = data; } bool clear_section(const std::string &section);
void clear_section(const std::string &section)
{ m_storage[section].clear(); }
typedef std::map<std::string, std::map<std::string, std::set<std::string>>> VendorMap; typedef std::map<std::string, std::map<std::string, std::set<std::string>>> VendorMap;
bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const; bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const;
void set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable); bool set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable);
void set_vendors(const AppConfig &from); bool set_vendors(const AppConfig &from) { return this->set_vendors(from.vendors()); }
void set_vendors(const VendorMap &vendors) { m_vendors = vendors; m_dirty = true; } bool set_vendors(const VendorMap &vendors);
void set_vendors(VendorMap &&vendors) { m_vendors = std::move(vendors); m_dirty = true; } bool set_vendors(VendorMap &&vendors);
const VendorMap& vendors() const { return m_vendors; } const VendorMap& vendors() const { return m_vendors; }
// return recent/skein_directory or recent/config_directory or empty string. // return recent/skein_directory or recent/config_directory or empty string.
std::string get_last_dir() const; std::string get_last_dir() const;
void update_config_dir(const std::string &dir); bool update_config_dir(const std::string &dir);
void update_skein_dir(const std::string &dir); bool update_skein_dir(const std::string &dir);
//std::string get_last_output_dir(const std::string &alt) const; //std::string get_last_output_dir(const std::string &alt) const;
//void update_last_output_dir(const std::string &dir); //void update_last_output_dir(const std::string &dir);
std::string get_last_output_dir(const std::string& alt, const bool removable = false) const; std::string get_last_output_dir(const std::string& alt, const bool removable = false) const;
void update_last_output_dir(const std::string &dir, const bool removable = false); bool update_last_output_dir(const std::string &dir, const bool removable = false);
// reset the current print / filament / printer selections, so that // reset the current print / filament / printer selections, so that
// the PresetBundle::load_selections(const AppConfig &config) call will select // the PresetBundle::load_selections(const AppConfig &config) call will select
@ -130,7 +128,7 @@ public:
void reset_selections(); void reset_selections();
// Get the default config path from Slic3r::data_dir(). // Get the default config path from Slic3r::data_dir().
std::string config_path(); std::string config_path() const;
// Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating) // Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating)
bool legacy_datadir() const { return m_legacy_datadir; } bool legacy_datadir() const { return m_legacy_datadir; }
@ -140,9 +138,9 @@ public:
// This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file. // This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file.
std::string version_check_url() const; std::string version_check_url() const;
// Get the Slic3r url to vendor index archive zip. // Get the Slic3r url to vendor index archive zip.
std::string index_archive_url() const; std::string index_archive_url() const;
// Get the Slic3r url to folder with vendor profile files. // Get the Slic3r url to folder with vendor profile files.
std::string profile_folder_url() const; std::string profile_folder_url() const;
// Returns the original Slic3r version found in the ini file before it was overwritten // Returns the original Slic3r version found in the ini file before it was overwritten
@ -150,12 +148,12 @@ public:
Semver orig_version() const { return m_orig_version; } Semver orig_version() const { return m_orig_version; }
// Does the config file exist? // Does the config file exist?
bool exists(); bool exists() const;
std::vector<std::string> get_recent_projects() const; std::vector<std::string> get_recent_projects() const;
void set_recent_projects(const std::vector<std::string>& recent_projects); bool set_recent_projects(const std::vector<std::string>& recent_projects);
void set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz); bool set_mouse_device(const std::string& name, double translation_speed, double translation_deadzone, float rotation_speed, float rotation_deadzone, double zoom_speed, bool swap_yz);
std::vector<std::string> get_mouse_device_names() const; std::vector<std::string> get_mouse_device_names() const;
bool get_mouse_device_translation_speed(const std::string& name, double& speed) const bool get_mouse_device_translation_speed(const std::string& name, double& speed) const
{ return get_3dmouse_device_numeric_value(name, "translation_speed", speed); } { return get_3dmouse_device_numeric_value(name, "translation_speed", speed); }

View file

@ -398,7 +398,7 @@ bool inside_convex_polygon(const std::pair<std::vector<Vec2d>, std::vector<Vec2d
// At min x. // At min x.
assert(pt.x() == it_bottom->x()); assert(pt.x() == it_bottom->x());
assert(pt.x() == it_top->x()); assert(pt.x() == it_top->x());
assert(it_bottom->y() <= pt.y() <= it_top->y()); assert(it_bottom->y() <= pt.y() && pt.y() <= it_top->y());
return pt.y() >= it_bottom->y() && pt.y() <= it_top->y(); return pt.y() >= it_bottom->y() && pt.y() <= it_top->y();
} }

View file

@ -4710,12 +4710,6 @@ CLIMiscConfigDef::CLIMiscConfigDef()
"or an existing PrusaSlicer window is activated. " "or an existing PrusaSlicer window is activated. "
"Overrides the \"single_instance\" configuration value from application preferences."); "Overrides the \"single_instance\" configuration value from application preferences.");
/*
def = this->add("autosave", coString);
def->label = L("Autosave");
def->tooltip = L("Automatically export current configuration to the specified file.");
*/
def = this->add("datadir", coString); def = this->add("datadir", coString);
def->label = L("Data directory"); def->label = L("Data directory");
def->tooltip = L("Load and store settings at the given directory. This is useful for maintaining different profiles or including configurations from a network storage."); def->tooltip = L("Load and store settings at the given directory. This is useful for maintaining different profiles or including configurations from a network storage.");

View file

@ -505,7 +505,7 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
// 1) Calculate offsets of collision areas in parallel. // 1) Calculate offsets of collision areas in parallel.
std::vector<Polygons> collision_areas_offsetted(max_required_layer + 1 - min_layer_bottom); std::vector<Polygons> collision_areas_offsetted(max_required_layer + 1 - min_layer_bottom);
tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_bottom, max_required_layer + 1), tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_bottom, max_required_layer + 1),
[&outlines, &machine_border = m_machine_border, offset_value = radius + xy_distance, min_layer_bottom, &collision_areas_offsetted, &throw_on_cancel] [&outlines, &machine_border = std::as_const(m_machine_border), offset_value = radius + xy_distance, min_layer_bottom, &collision_areas_offsetted, &throw_on_cancel]
(const tbb::blocked_range<LayerIndex> &range) { (const tbb::blocked_range<LayerIndex> &range) {
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) { for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) {
Polygons collision_areas = machine_border; Polygons collision_areas = machine_border;
@ -520,14 +520,54 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
// 2) Sum over top / bottom ranges. // 2) Sum over top / bottom ranges.
const bool last = outline_idx == layer_outline_indices.size(); const bool last = outline_idx == layer_outline_indices.size();
tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_last + 1, max_layer_idx + 1), tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_last + 1, max_layer_idx + 1),
[&collision_areas_offsetted, &anti_overhang = m_anti_overhang, min_layer_bottom, radius, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last, &throw_on_cancel] [&collision_areas_offsetted, &outlines, &machine_border = m_machine_border, &anti_overhang = m_anti_overhang, min_layer_bottom, radius,
xy_distance, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last, &throw_on_cancel]
(const tbb::blocked_range<LayerIndex>& range) { (const tbb::blocked_range<LayerIndex>& range) {
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++layer_idx) { for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++layer_idx) {
Polygons collisions; Polygons collisions;
for (int i = -z_distance_bottom_layers; i <= z_distance_top_layers; ++ i) { for (int i = -z_distance_bottom_layers; i <= z_distance_top_layers; ++ i) {
int j = layer_idx + i - min_layer_bottom; int j = layer_idx + i - min_layer_bottom;
if (j >= 0 && j < int(collision_areas_offsetted.size())) if (j >= 0 && j < int(collision_areas_offsetted.size()) && i <= 0)
append(collisions, collision_areas_offsetted[j]); append(collisions, collision_areas_offsetted[j]);
else if (j >= 0 && layer_idx + i < int(outlines.size()) && i > 0) {
Polygons collision_areas_original = machine_border;
append(collision_areas_original, outlines[layer_idx + i]);
// If just the collision (including the xy distance) of the layers above is accumulated, it leads to the
// following issue:
// Example: assuming the z distance is 2 layer
// + = xy_distance
// - = model
// o = overhang of the area two layers above that should result in tips on this layer
//
// +-----+
// +-----+
// +-----+
// o +-----+
// If just the collision above is accumulated the overhang will get overwritten by the xy_distance of the
// layer below the overhang...
//
// This only causes issues if the overhang area is thinner than xy_distance
// Just accumulating areas of the model above without the xy distance is also problematic, as then support
// may get closer to the model (on the diagonal downwards) than the user intended. Example (s = support):
// +-----+
// +-----+
// +-----+
// s+-----+
// technically the calculation below is off by one layer, as the actual distance between plastic one layer
// down is 0 not layer height, as this layer is filled with said plastic. But otherwise a part of the
// overhang that is expected to be supported is overwritten by the remaining part of the xy distance of the
// layer below the to be supported area.
coord_t required_range_x =
(xy_distance - ((i - (z_distance_top_layers == 1 ? 0.5 : 0)) * xy_distance / z_distance_top_layers));
// the conditional -0.5 ensures that plastic can never touch on the diagonal
// downward when the z_distance_top_layers = 1. It is assumed to be better to
// not support an overhang<90 degree than to risk fusing to it.
collision_areas_original = offset(union_ex(collision_areas_original), radius + required_range_x, ClipperLib::jtMiter, 1.2);
append(collisions, collision_areas_original);
}
} }
collisions = last && layer_idx < int(anti_overhang.size()) ? union_(collisions, offset(union_ex(anti_overhang[layer_idx]), radius, ClipperLib::jtMiter, 1.2)) : union_(collisions); collisions = last && layer_idx < int(anti_overhang.size()) ? union_(collisions, offset(union_ex(anti_overhang[layer_idx]), radius, ClipperLib::jtMiter, 1.2)) : union_(collisions);
auto &dst = data[layer_idx - (min_layer_last + 1)]; auto &dst = data[layer_idx - (min_layer_last + 1)];
@ -644,7 +684,8 @@ void TreeModelVolumes::calculateAvoidance(const std::vector<RadiusLayerPair> &ke
BOOST_LOG_TRIVIAL(debug) << "Calculation requested for value already calculated?"; BOOST_LOG_TRIVIAL(debug) << "Calculation requested for value already calculated?";
continue; continue;
} }
if (! task.holefree() || task.radius < m_increase_until_radius + m_current_min_xy_dist_delta) if ((task.to_model ? to_model : to_build_plate) &&
(! task.holefree() || task.radius < m_increase_until_radius + m_current_min_xy_dist_delta))
avoidance_tasks.emplace_back(task); avoidance_tasks.emplace_back(task);
} }

View file

@ -496,15 +496,15 @@ static std::optional<std::pair<Point, size_t>> polyline_sample_next_point_at_dis
Vec2d xf = p0f - foot_pt; Vec2d xf = p0f - foot_pt;
// Squared distance of "start_pt" from the ray (p0, p1). // Squared distance of "start_pt" from the ray (p0, p1).
double l2_from_line = xf.squaredNorm(); double l2_from_line = xf.squaredNorm();
double det = dist2 - l2_from_line; // Squared distance of an intersection point of a circle with center at the foot point.
if (double l2_intersection = dist2 - l2_from_line;
if (det > - SCALED_EPSILON) { l2_intersection > - SCALED_EPSILON) {
// The ray (p0, p1) touches or intersects a circle centered at "start_pt" with radius "dist". // The ray (p0, p1) touches or intersects a circle centered at "start_pt" with radius "dist".
// Distance of the circle intersection point from the foot point. // Distance of the circle intersection point from the foot point.
double dist_circle_intersection = std::sqrt(std::max(0., det)); l2_intersection = std::max(l2_intersection, 0.);
if ((v - foot_pt).cast<double>().norm() > dist_circle_intersection) { if ((v - foot_pt).cast<double>().squaredNorm() >= l2_intersection) {
// Intersection of the circle with the segment (p0, p1) is on the right side (close to p1) from the foot point. // Intersection of the circle with the segment (p0, p1) is on the right side (close to p1) from the foot point.
Point p = p0 + (foot_pt + v * (dist_circle_intersection / sqrt(l2v))).cast<coord_t>(); Point p = p0 + (foot_pt + v * sqrt(l2_intersection / l2v)).cast<coord_t>();
validate_range(p); validate_range(p);
return std::pair<Point, size_t>{ p, i - 1 }; return std::pair<Point, size_t>{ p, i - 1 };
} }
@ -916,7 +916,7 @@ static void generate_initial_areas(
//FIXME Vojtech: This is not sufficient for support enforcers to work. //FIXME Vojtech: This is not sufficient for support enforcers to work.
//FIXME There is no account for the support overhang angle. //FIXME There is no account for the support overhang angle.
//FIXME There is no account for the width of the collision regions. //FIXME There is no account for the width of the collision regions.
const coord_t extra_outset = std::max(coord_t(0), mesh_config.min_radius - mesh_config.support_line_width) + (min_xy_dist ? mesh_config.support_line_width / 2 : 0) const coord_t extra_outset = std::max(coord_t(0), mesh_config.min_radius - mesh_config.support_line_width / 2) + (min_xy_dist ? mesh_config.support_line_width / 2 : 0)
//FIXME this is a heuristic value for support enforcers to work. //FIXME this is a heuristic value for support enforcers to work.
// + 10 * mesh_config.support_line_width; // + 10 * mesh_config.support_line_width;
; ;
@ -1079,9 +1079,8 @@ static void generate_initial_areas(
Polygons overhang_regular; Polygons overhang_regular;
{ {
const Polygons &overhang_raw = overhangs[layer_idx + z_distance_delta]; const Polygons &overhang_raw = overhangs[layer_idx + z_distance_delta];
overhang_regular = mesh_group_settings.support_offset == 0 ? // When support_offset = 0 safe_offset_inc will only be the difference between overhang_raw and relevant_forbidden, that has to be calculated anyway.
overhang_raw : overhang_regular = safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1);
safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1);
//check_self_intersections(overhang_regular, "overhang_regular1"); //check_self_intersections(overhang_regular, "overhang_regular1");
// offset ensures that areas that could be supported by a part of a support line, are not considered unsupported overhang // offset ensures that areas that could be supported by a part of a support line, are not considered unsupported overhang

View file

@ -36,10 +36,8 @@ void Camera::set_type(EType type)
{ {
if (m_type != type && (type == EType::Ortho || type == EType::Perspective)) { if (m_type != type && (type == EType::Ortho || type == EType::Perspective)) {
m_type = type; m_type = type;
if (m_update_config_on_type_change_enabled) { if (m_update_config_on_type_change_enabled)
wxGetApp().app_config->set("use_perspective_camera", (m_type == EType::Perspective) ? "1" : "0"); wxGetApp().app_config->set("use_perspective_camera", (m_type == EType::Perspective) ? "1" : "0");
wxGetApp().app_config->save();
}
} }
} }

View file

@ -804,7 +804,7 @@ void GUI_App::post_init()
} }
// show "Did you know" notification // show "Did you know" notification
if (app_config->get("show_hints") == "1" && ! is_gcode_viewer()) if (app_config->get_bool("show_hints") && ! is_gcode_viewer())
plater_->get_notification_manager()->push_hint_notification(true); plater_->get_notification_manager()->push_hint_notification(true);
// The extra CallAfter() is needed because of Mac, where this is the only way // The extra CallAfter() is needed because of Mac, where this is the only way
@ -832,7 +832,6 @@ void GUI_App::post_init()
// Set PrusaSlicer version and save to PrusaSlicer.ini or PrusaSlicerGcodeViewer.ini. // Set PrusaSlicer version and save to PrusaSlicer.ini or PrusaSlicerGcodeViewer.ini.
app_config->set("version", SLIC3R_VERSION); app_config->set("version", SLIC3R_VERSION);
app_config->save();
#ifdef _WIN32 #ifdef _WIN32
// Sets window property to mainframe so other instances can indentify it. // Sets window property to mainframe so other instances can indentify it.
@ -859,14 +858,9 @@ GUI_App::GUI_App(EAppMode mode)
GUI_App::~GUI_App() GUI_App::~GUI_App()
{ {
if (app_config != nullptr) delete app_config;
delete app_config; delete preset_bundle;
delete preset_updater;
if (preset_bundle != nullptr)
delete preset_bundle;
if (preset_updater != nullptr)
delete preset_updater;
} }
// If formatted for github, plaintext with OpenGL extensions enclosed into <details>. // If formatted for github, plaintext with OpenGL extensions enclosed into <details>.
@ -1145,8 +1139,8 @@ bool GUI_App::on_init_inner()
// If load_language() fails, the application closes. // If load_language() fails, the application closes.
load_language(wxString(), true); load_language(wxString(), true);
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
bool init_dark_color_mode = app_config->get("dark_color_mode") == "1"; bool init_dark_color_mode = app_config->get_bool("dark_color_mode");
bool init_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1"; bool init_sys_menu_enabled = app_config->get_bool("sys_menu_enabled");
NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled); NppDarkMode::InitDarkMode(init_dark_color_mode, init_sys_menu_enabled);
#endif #endif
// initialize label colors and fonts // initialize label colors and fonts
@ -1169,13 +1163,13 @@ bool GUI_App::on_init_inner()
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
// app_config can be updated in check_older_app_config(), so check if dark_color_mode and sys_menu_enabled was changed // app_config can be updated in check_older_app_config(), so check if dark_color_mode and sys_menu_enabled was changed
if (bool new_dark_color_mode = app_config->get("dark_color_mode") == "1"; if (bool new_dark_color_mode = app_config->get_bool("dark_color_mode");
init_dark_color_mode != new_dark_color_mode) { init_dark_color_mode != new_dark_color_mode) {
NppDarkMode::SetDarkMode(new_dark_color_mode); NppDarkMode::SetDarkMode(new_dark_color_mode);
init_ui_colours(); init_ui_colours();
update_ui_colours_from_appconfig(); update_ui_colours_from_appconfig();
} }
if (bool new_sys_menu_enabled = app_config->get("sys_menu_enabled") == "1"; if (bool new_sys_menu_enabled = app_config->get_bool("sys_menu_enabled");
init_sys_menu_enabled != new_sys_menu_enabled) init_sys_menu_enabled != new_sys_menu_enabled)
NppDarkMode::SetSystemMenuForApp(new_sys_menu_enabled); NppDarkMode::SetSystemMenuForApp(new_sys_menu_enabled);
#endif #endif
@ -1201,7 +1195,7 @@ bool GUI_App::on_init_inner()
} }
SplashScreen* scrn = nullptr; SplashScreen* scrn = nullptr;
if (app_config->get("show_splash_screen") == "1") { if (app_config->get_bool("show_splash_screen")) {
// make a bitmap with dark grey banner on the left side // make a bitmap with dark grey banner on the left side
wxBitmap bmp = SplashScreen::MakeBitmap(wxBitmap(from_u8(var(is_editor() ? "splashscreen.jpg" : "splashscreen-gcodepreview.jpg")), wxBITMAP_TYPE_JPEG)); wxBitmap bmp = SplashScreen::MakeBitmap(wxBitmap(from_u8(var(is_editor() ? "splashscreen.jpg" : "splashscreen-gcodepreview.jpg")), wxBITMAP_TYPE_JPEG));
@ -1248,9 +1242,9 @@ bool GUI_App::on_init_inner()
if (is_editor()) { if (is_editor()) {
#ifdef __WXMSW__ #ifdef __WXMSW__
if (app_config->get("associate_3mf") == "1") if (app_config->get_bool("associate_3mf"))
associate_3mf_files(); associate_3mf_files();
if (app_config->get("associate_stl") == "1") if (app_config->get_bool("associate_stl"))
associate_stl_files(); associate_stl_files();
#endif // __WXMSW__ #endif // __WXMSW__
@ -1290,14 +1284,14 @@ bool GUI_App::on_init_inner()
} }
else { else {
#ifdef __WXMSW__ #ifdef __WXMSW__
if (app_config->get("associate_gcode") == "1") if (app_config->get_bool("associate_gcode"))
associate_gcode_files(); associate_gcode_files();
#endif // __WXMSW__ #endif // __WXMSW__
} }
std::string delayed_error_load_presets; std::string delayed_error_load_presets;
// Suppress the '- default -' presets. // Suppress the '- default -' presets.
preset_bundle->set_default_suppressed(app_config->get("no_defaults") == "1"); preset_bundle->set_default_suppressed(app_config->get_bool("no_defaults"));
try { try {
// Enable all substitutions (in both user and system profiles), but log the substitutions in user profiles only. // Enable all substitutions (in both user and system profiles), but log the substitutions in user profiles only.
// If there are substitutions in system profiles, then a "reconfigure" event shall be triggered, which will force // If there are substitutions in system profiles, then a "reconfigure" event shall be triggered, which will force
@ -1387,7 +1381,7 @@ bool GUI_App::on_init_inner()
this->post_init(); this->post_init();
} }
if (m_post_initialized && app_config->dirty() && app_config->get("autosave") == "1") if (m_post_initialized && app_config->dirty())
app_config->save(); app_config->save();
}); });
@ -1448,7 +1442,7 @@ bool GUI_App::dark_mode()
return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode(); return wxPlatformInfo::Get().CheckOSVersion(10, 14) && mac_dark_mode();
#else #else
if (wxGetApp().app_config->has("dark_color_mode")) if (wxGetApp().app_config->has("dark_color_mode"))
return wxGetApp().app_config->get("dark_color_mode") == "1"; return wxGetApp().app_config->get_bool("dark_color_mode");
return check_dark_mode(); return check_dark_mode();
#endif #endif
} }
@ -1685,7 +1679,6 @@ void GUI_App::set_label_clr_modified(const wxColour& clr)
m_color_label_modified = clr; m_color_label_modified = clr;
const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue())); const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue()));
app_config->set("label_clr_modified", str); app_config->set("label_clr_modified", str);
app_config->save();
} }
void GUI_App::set_label_clr_sys(const wxColour& clr) void GUI_App::set_label_clr_sys(const wxColour& clr)
@ -1695,7 +1688,6 @@ void GUI_App::set_label_clr_sys(const wxColour& clr)
m_color_label_sys = clr; m_color_label_sys = clr;
const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue())); const std::string str = encode_color(ColorRGB(clr.Red(), clr.Green(), clr.Blue()));
app_config->set("label_clr_sys", str); app_config->set("label_clr_sys", str);
app_config->save();
} }
const std::string& GUI_App::get_mode_btn_color(int mode_id) const std::string& GUI_App::get_mode_btn_color(int mode_id)
@ -1727,13 +1719,12 @@ void GUI_App::set_mode_palette(const std::vector<wxColour>& palette)
if (save) { if (save) {
mainframe->update_mode_markers(); mainframe->update_mode_markers();
app_config->set("mode_palette", escape_strings_cstyle(m_mode_palette)); app_config->set("mode_palette", escape_strings_cstyle(m_mode_palette));
app_config->save();
} }
} }
bool GUI_App::tabs_as_menu() const bool GUI_App::tabs_as_menu() const
{ {
return app_config->get("tabs_as_menu") == "1"; // || dark_mode(); return app_config->get_bool("tabs_as_menu"); // || dark_mode();
} }
wxSize GUI_App::get_min_size() const wxSize GUI_App::get_min_size() const
@ -1902,14 +1893,14 @@ static void update_scrolls(wxWindow* window)
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
void GUI_App::force_menu_update() void GUI_App::force_menu_update()
{ {
NppDarkMode::SetSystemMenuForApp(app_config->get("sys_menu_enabled") == "1"); NppDarkMode::SetSystemMenuForApp(app_config->get_bool("sys_menu_enabled"));
} }
#endif //_MSW_DARK_MODE #endif //_MSW_DARK_MODE
void GUI_App::force_colors_update() void GUI_App::force_colors_update()
{ {
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
NppDarkMode::SetDarkMode(app_config->get("dark_color_mode") == "1"); NppDarkMode::SetDarkMode(app_config->get_bool("dark_color_mode"));
if (WXHWND wxHWND = wxToolTip::GetToolTipCtrl()) if (WXHWND wxHWND = wxToolTip::GetToolTipCtrl())
NppDarkMode::SetDarkExplorerTheme((HWND)wxHWND); NppDarkMode::SetDarkExplorerTheme((HWND)wxHWND);
NppDarkMode::SetDarkTitleBar(mainframe->GetHWND()); NppDarkMode::SetDarkTitleBar(mainframe->GetHWND());
@ -2158,7 +2149,6 @@ bool GUI_App::select_language()
// m_wxLocale->GetCanonicalName() // m_wxLocale->GetCanonicalName()
// 3) new_language_info->CanonicalName is a safe bet. It points to a valid dictionary name. // 3) new_language_info->CanonicalName is a safe bet. It points to a valid dictionary name.
app_config->set("translation_language", new_language_info->CanonicalName.ToUTF8().data()); app_config->set("translation_language", new_language_info->CanonicalName.ToUTF8().data());
app_config->save();
return true; return true;
} }
} }
@ -2367,7 +2357,6 @@ bool GUI_App::save_mode(const /*ConfigOptionMode*/int mode)
return false; return false;
} }
app_config->set("view_mode", mode_str); app_config->set("view_mode", mode_str);
app_config->save();
update_mode(); update_mode();
return true; return true;
} }
@ -2569,13 +2558,13 @@ void GUI_App::open_preferences(const std::string& highlight_option /*= std::stri
#ifdef _WIN32 #ifdef _WIN32
if (is_editor()) { if (is_editor()) {
if (app_config->get("associate_3mf") == "1") if (app_config->get_bool("associate_3mf"))
associate_3mf_files(); associate_3mf_files();
if (app_config->get("associate_stl") == "1") if (app_config->get_bool("associate_stl"))
associate_stl_files(); associate_stl_files();
} }
else { else {
if (app_config->get("associate_gcode") == "1") if (app_config->get_bool("associate_gcode"))
associate_gcode_files(); associate_gcode_files();
} }
#endif // _WIN32 #endif // _WIN32
@ -3178,7 +3167,6 @@ void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name)
WindowMetrics metrics = WindowMetrics::from_window(window); WindowMetrics metrics = WindowMetrics::from_window(window);
app_config->set(config_key, metrics.serialize()); app_config->set(config_key, metrics.serialize());
app_config->save();
} }
void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized) void GUI_App::window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized)
@ -3372,7 +3360,6 @@ void GUI_App::associate_gcode_files()
void GUI_App::on_version_read(wxCommandEvent& evt) void GUI_App::on_version_read(wxCommandEvent& evt)
{ {
app_config->set("version_online", into_u8(evt.GetString())); app_config->set("version_online", into_u8(evt.GetString()));
app_config->save();
std::string opt = app_config->get("notify_release"); std::string opt = app_config->get("notify_release");
if (this->plater_ == nullptr || (!m_app_updater->get_triggered_by_user() && opt != "all" && opt != "release")) { if (this->plater_ == nullptr || (!m_app_updater->get_triggered_by_user() && opt != "all" && opt != "release")) {
BOOST_LOG_TRIVIAL(info) << "Version online: " << evt.GetString() << ". User does not wish to be notified."; BOOST_LOG_TRIVIAL(info) << "Version online: " << evt.GetString() << ". User does not wish to be notified.";

View file

@ -56,7 +56,6 @@ int GUI_Run(GUI_InitParams &params)
} }
} }
// gui->autosave = m_config.opt_string("autosave");
GUI::GUI_App::SetInstance(gui); GUI::GUI_App::SetInstance(gui);
gui->init_params = &params; gui->init_params = &params;
return wxEntry(params.argc, params.argv); return wxEntry(params.argc, params.argv);

View file

@ -652,7 +652,8 @@ void MainFrame::shutdown()
wxGetApp().other_instance_message_handler()->shutdown(this); wxGetApp().other_instance_message_handler()->shutdown(this);
// Save the slic3r.ini.Usually the ini file is saved from "on idle" callback, // Save the slic3r.ini.Usually the ini file is saved from "on idle" callback,
// but in rare cases it may not have been called yet. // but in rare cases it may not have been called yet.
wxGetApp().app_config->save(); if (wxGetApp().app_config->dirty())
wxGetApp().app_config->save();
// if (m_plater) // if (m_plater)
// m_plater->print = undef; // m_plater->print = undef;
// Slic3r::GUI::deregister_on_request_update_callback(); // Slic3r::GUI::deregister_on_request_update_callback();
@ -1253,7 +1254,6 @@ void MainFrame::init_menubar_as_editor()
recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i))); recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i)));
} }
wxGetApp().app_config->set_recent_projects(recent_projects); wxGetApp().app_config->set_recent_projects(recent_projects);
wxGetApp().app_config->save();
} }
} }
}, wxID_FILE1, wxID_FILE9); }, wxID_FILE1, wxID_FILE9);
@ -2182,7 +2182,6 @@ void MainFrame::add_to_recent_projects(const wxString& filename)
recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i))); recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i)));
} }
wxGetApp().app_config->set_recent_projects(recent_projects); wxGetApp().app_config->set_recent_projects(recent_projects);
wxGetApp().app_config->save();
} }
} }

View file

@ -464,7 +464,6 @@ void PreferencesDialog::build()
m_icon_size_sizer->ShowItems(boost::any_cast<bool>(value)); m_icon_size_sizer->ShowItems(boost::any_cast<bool>(value));
refresh_og(m_optgroup_gui); refresh_og(m_optgroup_gui);
get_app_config()->set("use_custom_toolbar_size", boost::any_cast<bool>(value) ? "1" : "0"); get_app_config()->set("use_custom_toolbar_size", boost::any_cast<bool>(value) ? "1" : "0");
get_app_config()->save();
wxGetApp().plater()->get_current_canvas3D()->render(); wxGetApp().plater()->get_current_canvas3D()->render();
return; return;
} }
@ -768,7 +767,6 @@ void PreferencesDialog::accept(wxEvent&)
for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it) for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it)
app_config->set(it->first, it->second); app_config->set(it->first, it->second);
app_config->save();
if (wxGetApp().is_editor()) { if (wxGetApp().is_editor()) {
wxGetApp().set_label_clr_sys(m_sys_colour->GetColour()); wxGetApp().set_label_clr_sys(m_sys_colour->GetColour());
wxGetApp().set_label_clr_modified(m_mod_colour->GetColour()); wxGetApp().set_label_clr_modified(m_mod_colour->GetColour());
@ -797,23 +795,17 @@ void PreferencesDialog::revert(wxEvent&)
{ {
auto app_config = get_app_config(); auto app_config = get_app_config();
bool save_app_config = false;
if (m_custom_toolbar_size != atoi(app_config->get("custom_toolbar_size").c_str())) { if (m_custom_toolbar_size != atoi(app_config->get("custom_toolbar_size").c_str())) {
app_config->set("custom_toolbar_size", (boost::format("%d") % m_custom_toolbar_size).str()); app_config->set("custom_toolbar_size", (boost::format("%d") % m_custom_toolbar_size).str());
m_icon_size_slider->SetValue(m_custom_toolbar_size); m_icon_size_slider->SetValue(m_custom_toolbar_size);
save_app_config |= true;
} }
if (m_use_custom_toolbar_size != (get_app_config()->get("use_custom_toolbar_size") == "1")) { if (m_use_custom_toolbar_size != (get_app_config()->get("use_custom_toolbar_size") == "1")) {
app_config->set("use_custom_toolbar_size", m_use_custom_toolbar_size ? "1" : "0"); app_config->set("use_custom_toolbar_size", m_use_custom_toolbar_size ? "1" : "0");
save_app_config |= true;
m_optgroup_gui->set_value("use_custom_toolbar_size", m_use_custom_toolbar_size); m_optgroup_gui->set_value("use_custom_toolbar_size", m_use_custom_toolbar_size);
m_icon_size_sizer->ShowItems(m_use_custom_toolbar_size); m_icon_size_sizer->ShowItems(m_use_custom_toolbar_size);
refresh_og(m_optgroup_gui); refresh_og(m_optgroup_gui);
} }
if (save_app_config)
app_config->save();
for (auto value : m_values) { for (auto value : m_values) {
const std::string& key = value.first; const std::string& key = value.first;
@ -955,7 +947,6 @@ void PreferencesDialog::create_icon_size_slider()
auto val = m_icon_size_slider->GetValue(); auto val = m_icon_size_slider->GetValue();
app_config->set("custom_toolbar_size", (boost::format("%d") % val).str()); app_config->set("custom_toolbar_size", (boost::format("%d") % val).str());
app_config->save();
wxGetApp().plater()->get_current_canvas3D()->render(); wxGetApp().plater()->get_current_canvas3D()->render();
if (val_label) if (val_label)

View file

@ -121,37 +121,37 @@ void EmbossStylesSerializable::store_style(AppConfig & cfg,
const EmbossStyle &fi, const EmbossStyle &fi,
unsigned index) unsigned index)
{ {
std::string section_name = create_section_name(index); std::map<std::string, std::string> data;
cfg.clear_section(section_name); data[APP_CONFIG_FONT_NAME] = fi.name;
cfg.set(section_name, APP_CONFIG_FONT_NAME, fi.name); data[APP_CONFIG_FONT_DESCRIPTOR] = fi.path;
cfg.set(section_name, APP_CONFIG_FONT_DESCRIPTOR, fi.path);
const FontProp &fp = fi.prop; const FontProp &fp = fi.prop;
cfg.set(section_name, APP_CONFIG_FONT_LINE_HEIGHT, std::to_string(fp.size_in_mm)); data[APP_CONFIG_FONT_LINE_HEIGHT] = std::to_string(fp.size_in_mm);
cfg.set(section_name, APP_CONFIG_FONT_DEPTH, std::to_string(fp.emboss)); data[APP_CONFIG_FONT_DEPTH] = std::to_string(fp.emboss);
if (fp.use_surface) if (fp.use_surface)
cfg.set(section_name, APP_CONFIG_FONT_USE_SURFACE, "true"); data[APP_CONFIG_FONT_USE_SURFACE] = "true";
if (fp.boldness.has_value()) if (fp.boldness.has_value())
cfg.set(section_name, APP_CONFIG_FONT_BOLDNESS, std::to_string(*fp.boldness)); data[APP_CONFIG_FONT_BOLDNESS] = std::to_string(*fp.boldness);
if (fp.skew.has_value()) if (fp.skew.has_value())
cfg.set(section_name, APP_CONFIG_FONT_SKEW, std::to_string(*fp.skew)); data[APP_CONFIG_FONT_SKEW] = std::to_string(*fp.skew);
if (fp.distance.has_value()) if (fp.distance.has_value())
cfg.set(section_name, APP_CONFIG_FONT_DISTANCE, std::to_string(*fp.distance)); data[APP_CONFIG_FONT_DISTANCE] = std::to_string(*fp.distance);
if (fp.angle.has_value()) if (fp.angle.has_value())
cfg.set(section_name, APP_CONFIG_FONT_ANGLE, std::to_string(*fp.angle)); data[APP_CONFIG_FONT_ANGLE] = std::to_string(*fp.angle);
if (fp.collection_number.has_value()) if (fp.collection_number.has_value())
cfg.set(section_name, APP_CONFIG_FONT_COLLECTION, std::to_string(*fp.collection_number)); data[APP_CONFIG_FONT_COLLECTION] = std::to_string(*fp.collection_number);
if (fp.char_gap.has_value()) if (fp.char_gap.has_value())
cfg.set(section_name, APP_CONFIG_FONT_CHAR_GAP, std::to_string(*fp.char_gap)); data[APP_CONFIG_FONT_CHAR_GAP] = std::to_string(*fp.char_gap);
if (fp.line_gap.has_value()) if (fp.line_gap.has_value())
cfg.set(section_name, APP_CONFIG_FONT_LINE_GAP, std::to_string(*fp.line_gap)); data[APP_CONFIG_FONT_LINE_GAP] = std::to_string(*fp.line_gap);
cfg.set_section(create_section_name(index), std::move(data));
} }
void EmbossStylesSerializable::store_style_index(AppConfig &cfg, unsigned index) { void EmbossStylesSerializable::store_style_index(AppConfig &cfg, unsigned index) {
// store actual font index // store actual font index
cfg.clear_section(AppConfig::SECTION_EMBOSS_STYLE); // active font first index is +1 to correspond with section name
// activ font first index is +1 to correspond with section name std::map<std::string, std::string> data;
std::string active_font = std::to_string(index); data[APP_CONFIG_ACTIVE_FONT] = std::to_string(index);
cfg.set(AppConfig::SECTION_EMBOSS_STYLE, APP_CONFIG_ACTIVE_FONT, active_font); cfg.set_section(AppConfig::SECTION_EMBOSS_STYLE, std::move(data));
} }
std::optional<size_t> EmbossStylesSerializable::load_style_index(const AppConfig &cfg) std::optional<size_t> EmbossStylesSerializable::load_style_index(const AppConfig &cfg)
@ -198,5 +198,4 @@ void EmbossStylesSerializable::store_styles(AppConfig &cfg, const EmbossStyles&
cfg.clear_section(section_name); cfg.clear_section(section_name);
section_name = create_section_name(++index); section_name = create_section_name(++index);
} }
cfg.save();
} }