diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index 17b783269..7729b6126 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -163,6 +163,7 @@ sub thread_cleanup { *Slic3r::Surface::Collection::DESTROY = sub {}; *Slic3r::Print::SupportMaterial2::DESTROY = sub {}; *Slic3r::TriangleMesh::DESTROY = sub {}; + *Slic3r::GUI::PresetBundle::DESTROY = sub {}; return undef; # this prevents a "Scalars leaked" warning } diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index 759030ec5..dc93e513f 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -172,6 +172,7 @@ sub OnInit { } } $self->{mainframe}->config_wizard if $run_wizard; + eval { $self->{preset_bundle}->load_presets($datadir) }; # $self->check_version # if $self->have_version_check diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index 4ece56499..db46c7d59 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -188,7 +188,8 @@ void ConfigBase::apply(const ConfigBase &other, const t_config_option_keys &keys continue; } // not the most efficient way, but easier than casting pointers to subclasses - if (! my_opt->deserialize(other.option(key)->serialize())) + const ConfigOption *other_opt = other.option(key); + if (other_opt != nullptr && ! my_opt->deserialize(other_opt->serialize())) CONFESS((std::string("Unexpected failure when deserializing serialized value for ") + key).c_str()); } } diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index 3aa051d1c..ea48cd1f5 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -1,11 +1,20 @@ #include "Preset.hpp" #include +#include #include #include #include +#if 0 +#define DEBUG +#define _DEBUG +#undef NDEBUG +#endif + +#include + namespace Slic3r { // Load a config file, return a C++ class Slic3r::DynamicPrintConfig with $keys initialized from the config file. @@ -67,6 +76,28 @@ PresetCollection::PresetCollection(Preset::Type type, const std::vectordefault_preset().config.keys(); + for (auto &file : boost::filesystem::directory_iterator(boost::filesystem::canonical(boost::filesystem::path(dir_path) / subdir).make_preferred())) + if (boost::filesystem::is_regular_file(file.status()) && boost::algorithm::iends_with(file.path().filename().string(), ".ini")) { + std::string name = file.path().filename().string(); + // Remove the .ini suffix. + name.erase(name.size() - 4); + try { + Preset preset(m_type, name, false); + preset.file = file.path().string(); + preset.load(keys); + m_presets.emplace_back(preset); + } catch (const boost::filesystem::filesystem_error &err) { + + } + } +} + void PresetCollection::set_default_suppressed(bool default_suppressed) { if (m_default_suppressed != default_suppressed) { @@ -162,12 +193,23 @@ PresetBundle::PresetBundle() : PresetBundle::~PresetBundle() { - delete m_bitmapCompatible; + assert(m_bitmapCompatible != nullptr); + assert(m_bitmapIncompatible != nullptr); + delete m_bitmapCompatible; + m_bitmapCompatible = nullptr; delete m_bitmapIncompatible; + m_bitmapIncompatible = nullptr; for (std::pair &bitmap : m_mapColorToBitmap) delete bitmap.second; } +void PresetBundle::load_presets(const std::string &dir_path) +{ + this->prints.load_presets(dir_path, "print"); + this->prints.load_presets(dir_path, "filament"); + this->prints.load_presets(dir_path, "printer"); +} + bool PresetBundle::load_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible) { bool loaded_compatible = m_bitmapCompatible ->LoadFile(wxString::FromUTF8(path_bitmap_compatible.c_str())); diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp index cd4bdfdf6..5c8ec8106 100644 --- a/xs/src/slic3r/GUI/Preset.hpp +++ b/xs/src/slic3r/GUI/Preset.hpp @@ -66,6 +66,9 @@ public: // Initialize the PresetCollection with the "- default -" preset. PresetCollection(Preset::Type type, const std::vector &keys); + // Load ini files of the particular type from the provided directory path. + void load_presets(const std::string &dir_path, const std::string &subdir); + // Compatible & incompatible marks, to be placed at the wxBitmapComboBox items. void set_bitmap_compatible (const wxBitmap *bmp) { m_bitmap_compatible = bmp; } void set_bitmap_incompatible(const wxBitmap *bmp) { m_bitmap_incompatible = bmp; } @@ -120,7 +123,10 @@ public: PresetBundle(); ~PresetBundle(); - bool load_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible); + bool load_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible); + + // Load ini files of all types (print, filament, printer) from the provided directory path. + void load_presets(const std::string &dir_path); PresetCollection prints; PresetCollection filaments; diff --git a/xs/xsp/GUI_Preset.xsp b/xs/xsp/GUI_Preset.xsp index f32a07d58..c6d97cabd 100644 --- a/xs/xsp/GUI_Preset.xsp +++ b/xs/xsp/GUI_Preset.xsp @@ -51,6 +51,9 @@ PresetCollection::arrayref() PresetBundle(); ~PresetBundle(); + void load_bitmaps(std::string path_bitmap_compatible, std::string path_bitmap_incompatible); + void load_presets(std::string dir_path); + Ref prints() %code%{ RETVAL = &THIS->prints; %}; Ref filaments() %code%{ RETVAL = &THIS->filaments; %}; Ref printers() %code%{ RETVAL = &THIS->printers; %};