Implemented the "Support for support enforcers only" quick selection.

Reduced some memory leaks due to the ConfigDef::default_value pointer.
This commit is contained in:
bubnikv 2019-05-03 18:01:39 +02:00
parent 1c6006f657
commit a61e833536
14 changed files with 559 additions and 388 deletions

View File

@ -280,7 +280,7 @@ std::ostream& ConfigDef::print_cli_help(std::ostream& out, bool show_defaults, s
// right: option description // right: option description
std::string descr = def.tooltip; std::string descr = def.tooltip;
if (show_defaults && def.default_value != nullptr && def.type != coBool if (show_defaults && def.default_value && def.type != coBool
&& (def.type != coString || !def.default_value->serialize().empty())) { && (def.type != coString || !def.default_value->serialize().empty())) {
descr += " ("; descr += " (";
if (!def.sidetext.empty()) { if (!def.sidetext.empty()) {
@ -627,7 +627,7 @@ ConfigOption* DynamicConfig::optptr(const t_config_option_key &opt_key, bool cre
// Let the parent decide what to do if the opt_key is not defined by this->def(). // Let the parent decide what to do if the opt_key is not defined by this->def().
return nullptr; return nullptr;
ConfigOption *opt = nullptr; ConfigOption *opt = nullptr;
if (optdef->default_value != nullptr) { if (optdef->default_value) {
opt = (optdef->default_value->type() == coEnum) ? opt = (optdef->default_value->type() == coEnum) ?
// Special case: For a DynamicConfig, convert a templated enum to a generic enum. // Special case: For a DynamicConfig, convert a templated enum to a generic enum.
new ConfigOptionEnumGeneric(optdef->enum_keys_map, optdef->default_value->getInt()) : new ConfigOptionEnumGeneric(optdef->enum_keys_map, optdef->default_value->getInt()) :
@ -783,8 +783,8 @@ void StaticConfig::set_defaults()
for (const std::string &key : this->keys()) { for (const std::string &key : this->keys()) {
const ConfigOptionDef *def = defs->get(key); const ConfigOptionDef *def = defs->get(key);
ConfigOption *opt = this->option(key); ConfigOption *opt = this->option(key);
if (def != nullptr && opt != nullptr && def->default_value != nullptr) if (def != nullptr && opt != nullptr && def->default_value)
opt->set(def->default_value); opt->set(def->default_value.get());
} }
} }
} }

View File

@ -12,6 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "libslic3r.h" #include "libslic3r.h"
#include "clonable_ptr.hpp"
#include "Point.hpp" #include "Point.hpp"
#include <boost/format.hpp> #include <boost/format.hpp>
@ -1010,7 +1011,8 @@ public:
// What type? bool, int, string etc. // What type? bool, int, string etc.
ConfigOptionType type = coNone; ConfigOptionType type = coNone;
// Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor. // Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor.
const ConfigOption *default_value = nullptr; Slic3r::clonable_ptr<const ConfigOption> default_value = nullptr;
void set_default_value(const ConfigOption* ptr) { this->default_value = Slic3r::clonable_ptr<const ConfigOption>(ptr); }
// Usually empty. // Usually empty.
// Special values - "i_enum_open", "f_enum_open" to provide combo box for int or float selection, // Special values - "i_enum_open", "f_enum_open" to provide combo box for int or float selection,
@ -1099,12 +1101,6 @@ typedef std::map<t_config_option_key, ConfigOptionDef> t_optiondef_map;
class ConfigDef class ConfigDef
{ {
public: public:
~ConfigDef() {
for (std::pair<const t_config_option_key, ConfigOptionDef> &def : this->options)
delete def.second.default_value;
this->options.clear();
}
t_optiondef_map options; t_optiondef_map options;
bool has(const t_config_option_key &opt_key) const { return this->options.count(opt_key) > 0; } bool has(const t_config_option_key &opt_key) const { return this->options.count(opt_key) > 0; }

File diff suppressed because it is too large Load Diff

View File

@ -307,8 +307,8 @@ protected:
m_keys.emplace_back(kvp.first); m_keys.emplace_back(kvp.first);
const ConfigOptionDef *def = defs->get(kvp.first); const ConfigOptionDef *def = defs->get(kvp.first);
assert(def != nullptr); assert(def != nullptr);
if (def->default_value != nullptr) if (def->default_value)
opt->set(def->default_value); opt->set(def->default_value.get());
} }
} }

View File

@ -0,0 +1,168 @@
// clonable_ptr: a smart pointer with a usage similar to unique_ptr, with the exception, that
// the copy constructor / copy assignment operator work by calling the ->clone() method.
// derived from https://github.com/SRombauts/shared_ptr/blob/master/include/unique_ptr.hpp
/**
* @file clonable_ptr.hpp
* @brief clonable_ptr is a fake implementation to use in place of a C++11 std::clonable_ptr when compiling on an older compiler.
*
* @see http://www.cplusplus.com/reference/memory/clonable_ptr/
*
* Copyright (c) 2014-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include "assert.h"
namespace Slic3r {
// Detect whether the compiler supports C++11 noexcept exception specifications.
#if defined(_MSC_VER) && _MSC_VER < 1900 && ! defined(noexcept)
#define noexcept throw()
#endif
template<class T>
class clonable_ptr
{
public:
/// The type of the managed object, aliased as member type
typedef T element_type;
/// @brief Default constructor
clonable_ptr() noexcept :
px(nullptr)
{
}
/// @brief Constructor with the provided pointer to manage
explicit clonable_ptr(T* p) noexcept :
px(p)
{
}
/// @brief Copy constructor, clones by calling the rhs.clone() method
clonable_ptr(const clonable_ptr& rhs) :
px(rhs ? rhs.px->clone() : nullptr)
{
}
/// @brief Move constructor, never throws
clonable_ptr(clonable_ptr&& rhs) noexcept :
px(rhs.px)
{
rhs.px = nullptr;
}
/// @brief Assignment operator
clonable_ptr& operator=(const clonable_ptr& rhs)
{
delete px;
px = rhs ? rhs.px->clone() : nullptr;
return *this;
}
/// @brief Move operator, never throws
clonable_ptr& operator=(clonable_ptr&& rhs)
{
delete px;
px = rhs.px;
rhs.px = nullptr;
return *this;
}
/// @brief the destructor releases its ownership and destroy the object
inline ~clonable_ptr() noexcept
{
destroy();
}
/// @brief this reset releases its ownership and destroy the object
inline void reset() noexcept
{
destroy();
}
/// @brief this reset release its ownership and re-acquire another one
void reset(T* p) noexcept
{
assert((nullptr == p) || (px != p)); // auto-reset not allowed
destroy();
px = p;
}
/// @brief Swap method for the copy-and-swap idiom (copy constructor and swap method)
void swap(clonable_ptr& rhs) noexcept
{
T *tmp = px;
px = rhs.px;
rhs.px = tmp;
}
/// @brief release the ownership of the px pointer without destroying the object!
inline void release() noexcept
{
px = nullptr;
}
// reference counter operations :
inline operator bool() const noexcept
{
return (nullptr != px); // TODO nullptrptr
}
// underlying pointer operations :
inline T& operator*() const noexcept
{
assert(nullptr != px);
return *px;
}
inline T* operator->() const noexcept
{
assert(nullptr != px);
return px;
}
inline T* get() const noexcept
{
// no assert, can return nullptr
return px;
}
private:
/// @brief release the ownership of the px pointer and destroy the object
inline void destroy() noexcept
{
delete px;
px = nullptr;
}
/// @brief hack: const-cast release the ownership of the px pointer without destroying the object!
inline void release() const noexcept
{
px = nullptr;
}
private:
T* px; //!< Native pointer
};
// comparison operators
template<class T, class U> inline bool operator==(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
return (l.get() == r.get());
}
template<class T, class U> inline bool operator!=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
return (l.get() != r.get());
}
template<class T, class U> inline bool operator<=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
return (l.get() <= r.get());
}
template<class T, class U> inline bool operator<(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
return (l.get() < r.get());
}
template<class T, class U> inline bool operator>=(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
return (l.get() >= r.get());
}
template<class T, class U> inline bool operator>(const clonable_ptr<T>& l, const clonable_ptr<U>& r) noexcept
{
return (l.get() > r.get());
}
} // namespace Slic3r

View File

@ -68,14 +68,14 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
auto optgroup = init_shape_options_page(_(L("Rectangular"))); auto optgroup = init_shape_options_page(_(L("Rectangular")));
ConfigOptionDef def; ConfigOptionDef def;
def.type = coPoints; def.type = coPoints;
def.default_value = new ConfigOptionPoints{ Vec2d(200, 200) }; def.set_default_value(new ConfigOptionPoints{ Vec2d(200, 200) });
def.label = L("Size"); def.label = L("Size");
def.tooltip = L("Size in X and Y of the rectangular plate."); def.tooltip = L("Size in X and Y of the rectangular plate.");
Option option(def, "rect_size"); Option option(def, "rect_size");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
def.type = coPoints; def.type = coPoints;
def.default_value = new ConfigOptionPoints{ Vec2d(0, 0) }; def.set_default_value(new ConfigOptionPoints{ Vec2d(0, 0) });
def.label = L("Origin"); def.label = L("Origin");
def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle."); def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle.");
option = Option(def, "rect_origin"); option = Option(def, "rect_origin");
@ -83,7 +83,7 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
optgroup = init_shape_options_page(_(L("Circular"))); optgroup = init_shape_options_page(_(L("Circular")));
def.type = coFloat; def.type = coFloat;
def.default_value = new ConfigOptionFloat(200); def.set_default_value(new ConfigOptionFloat(200));
def.sidetext = L("mm"); def.sidetext = L("mm");
def.label = L("Diameter"); def.label = L("Diameter");
def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center."); def.tooltip = L("Diameter of the print bed. It is assumed that origin (0,0) is located in the center.");

View File

@ -499,7 +499,7 @@ PageFirmware::PageFirmware(ConfigWizard *parent)
gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices); gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
const auto &enum_values = gcode_opt.enum_values; const auto &enum_values = gcode_opt.enum_values;
auto needle = enum_values.cend(); auto needle = enum_values.cend();
if (gcode_opt.default_value != nullptr) { if (gcode_opt.default_value) {
needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize()); needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize());
} }
if (needle != enum_values.cend()) { if (needle != enum_values.cend()) {
@ -545,13 +545,13 @@ PageDiameters::PageDiameters(ConfigWizard *parent)
spin_nozzle->SetDigits(2); spin_nozzle->SetDigits(2);
spin_nozzle->SetIncrement(0.1); spin_nozzle->SetIncrement(0.1);
const auto &def_nozzle = *print_config_def.get("nozzle_diameter"); const auto &def_nozzle = *print_config_def.get("nozzle_diameter");
auto *default_nozzle = dynamic_cast<const ConfigOptionFloats*>(def_nozzle.default_value); auto *default_nozzle = dynamic_cast<const ConfigOptionFloats*>(def_nozzle.default_value.get());
spin_nozzle->SetValue(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5); spin_nozzle->SetValue(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5);
spin_filam->SetDigits(2); spin_filam->SetDigits(2);
spin_filam->SetIncrement(0.25); spin_filam->SetIncrement(0.25);
const auto &def_filam = *print_config_def.get("filament_diameter"); const auto &def_filam = *print_config_def.get("filament_diameter");
auto *default_filam = dynamic_cast<const ConfigOptionFloats*>(def_filam.default_value); auto *default_filam = dynamic_cast<const ConfigOptionFloats*>(def_filam.default_value.get());
spin_filam->SetValue(default_filam != nullptr && default_filam->size() > 0 ? default_filam->get_at(0) : 3.0); spin_filam->SetValue(default_filam != nullptr && default_filam->size() > 0 ? default_filam->get_at(0) : 3.0);
append_text(_(L("Enter the diameter of your printer's hot end nozzle."))); append_text(_(L("Enter the diameter of your printer's hot end nozzle.")));
@ -596,13 +596,13 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent)
spin_extr->SetIncrement(5.0); spin_extr->SetIncrement(5.0);
const auto &def_extr = *print_config_def.get("temperature"); const auto &def_extr = *print_config_def.get("temperature");
spin_extr->SetRange(def_extr.min, def_extr.max); spin_extr->SetRange(def_extr.min, def_extr.max);
auto *default_extr = dynamic_cast<const ConfigOptionInts*>(def_extr.default_value); auto *default_extr = dynamic_cast<const ConfigOptionInts*>(def_extr.default_value.get());
spin_extr->SetValue(default_extr != nullptr && default_extr->size() > 0 ? default_extr->get_at(0) : 200); spin_extr->SetValue(default_extr != nullptr && default_extr->size() > 0 ? default_extr->get_at(0) : 200);
spin_bed->SetIncrement(5.0); spin_bed->SetIncrement(5.0);
const auto &def_bed = *print_config_def.get("bed_temperature"); const auto &def_bed = *print_config_def.get("bed_temperature");
spin_bed->SetRange(def_bed.min, def_bed.max); spin_bed->SetRange(def_bed.min, def_bed.max);
auto *default_bed = dynamic_cast<const ConfigOptionInts*>(def_bed.default_value); auto *default_bed = dynamic_cast<const ConfigOptionInts*>(def_bed.default_value.get());
spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0); spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0);
append_text(_(L("Enter the temperature needed for extruding your filament."))); append_text(_(L("Enter the temperature needed for extruding your filament.")));

View File

@ -203,7 +203,7 @@ void TextCtrl::BUILD() {
case coFloatOrPercent: case coFloatOrPercent:
{ {
text_value = double_to_string(m_opt.default_value->getFloat()); text_value = double_to_string(m_opt.default_value->getFloat());
if (static_cast<const ConfigOptionFloatOrPercent*>(m_opt.default_value)->percent) if (static_cast<const ConfigOptionFloatOrPercent*>(m_opt.default_value.get())->percent)
text_value += "%"; text_value += "%";
break; break;
} }
@ -218,19 +218,19 @@ void TextCtrl::BUILD() {
case coFloat: case coFloat:
{ {
double val = m_opt.type == coFloats ? double val = m_opt.type == coFloats ?
static_cast<const ConfigOptionFloats*>(m_opt.default_value)->get_at(m_opt_idx) : static_cast<const ConfigOptionFloats*>(m_opt.default_value.get())->get_at(m_opt_idx) :
m_opt.type == coFloat ? m_opt.type == coFloat ?
m_opt.default_value->getFloat() : m_opt.default_value->getFloat() :
static_cast<const ConfigOptionPercents*>(m_opt.default_value)->get_at(m_opt_idx); static_cast<const ConfigOptionPercents*>(m_opt.default_value.get())->get_at(m_opt_idx);
text_value = double_to_string(val); text_value = double_to_string(val);
break; break;
} }
case coString: case coString:
text_value = static_cast<const ConfigOptionString*>(m_opt.default_value)->value; text_value = static_cast<const ConfigOptionString*>(m_opt.default_value.get())->value;
break; break;
case coStrings: case coStrings:
{ {
const ConfigOptionStrings *vec = static_cast<const ConfigOptionStrings*>(m_opt.default_value); const ConfigOptionStrings *vec = static_cast<const ConfigOptionStrings*>(m_opt.default_value.get());
if (vec == nullptr || vec->empty()) break; //for the case of empty default value if (vec == nullptr || vec->empty()) break; //for the case of empty default value
text_value = vec->get_at(m_opt_idx); text_value = vec->get_at(m_opt_idx);
break; break;
@ -373,7 +373,7 @@ void CheckBox::BUILD() {
bool check_value = m_opt.type == coBool ? bool check_value = m_opt.type == coBool ?
m_opt.default_value->getBool() : m_opt.type == coBools ? m_opt.default_value->getBool() : m_opt.type == coBools ?
static_cast<const ConfigOptionBools*>(m_opt.default_value)->get_at(m_opt_idx) : static_cast<const ConfigOptionBools*>(m_opt.default_value.get())->get_at(m_opt_idx) :
false; false;
// Set Label as a string of at least one space simbol to correct system scaling of a CheckBox // Set Label as a string of at least one space simbol to correct system scaling of a CheckBox
@ -427,7 +427,7 @@ void SpinCtrl::BUILD() {
break; break;
case coInts: case coInts:
{ {
const ConfigOptionInts *vec = static_cast<const ConfigOptionInts*>(m_opt.default_value); const ConfigOptionInts *vec = static_cast<const ConfigOptionInts*>(m_opt.default_value.get());
if (vec == nullptr || vec->empty()) break; if (vec == nullptr || vec->empty()) break;
for (size_t id = 0; id < vec->size(); ++id) for (size_t id = 0; id < vec->size(); ++id)
{ {
@ -629,7 +629,7 @@ void Choice::set_selection()
break; break;
} }
case coEnum:{ case coEnum:{
int id_value = static_cast<const ConfigOptionEnum<SeamPosition>*>(m_opt.default_value)->value; //!! int id_value = static_cast<const ConfigOptionEnum<SeamPosition>*>(m_opt.default_value.get())->value; //!!
field->SetSelection(id_value); field->SetSelection(id_value);
break; break;
} }
@ -649,7 +649,7 @@ void Choice::set_selection()
break; break;
} }
case coStrings:{ case coStrings:{
text_value = static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx); text_value = static_cast<const ConfigOptionStrings*>(m_opt.default_value.get())->get_at(m_opt_idx);
size_t idx = 0; size_t idx = 0;
for (auto el : m_opt.enum_values) for (auto el : m_opt.enum_values)
@ -886,7 +886,7 @@ void ColourPicker::BUILD()
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
// Validate the color // Validate the color
wxString clr_str(static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx)); wxString clr_str(static_cast<const ConfigOptionStrings*>(m_opt.default_value.get())->get_at(m_opt_idx));
wxColour clr(clr_str); wxColour clr(clr_str);
if (! clr.IsOk()) { if (! clr.IsOk()) {
clr = wxTransparentColour; clr = wxTransparentColour;
@ -920,7 +920,7 @@ void PointCtrl::BUILD()
const wxSize field_size(4 * m_em_unit, -1); const wxSize field_size(4 * m_em_unit, -1);
auto default_pt = static_cast<const ConfigOptionPoints*>(m_opt.default_value)->values.at(0); auto default_pt = static_cast<const ConfigOptionPoints*>(m_opt.default_value.get())->values.at(0);
double val = default_pt(0); double val = default_pt(0);
wxString X = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None); wxString X = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None);
val = default_pt(1); val = default_pt(1);
@ -1019,7 +1019,7 @@ void StaticText::BUILD()
if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit);
if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit);
const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value); const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value.get())->value);
auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE);
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetBackgroundStyle(wxBG_STYLE_PAINT);
@ -1054,7 +1054,7 @@ void SliderCtrl::BUILD()
auto temp = new wxBoxSizer(wxHORIZONTAL); auto temp = new wxBoxSizer(wxHORIZONTAL);
auto def_val = static_cast<const ConfigOptionInt*>(m_opt.default_value)->value; auto def_val = static_cast<const ConfigOptionInt*>(m_opt.default_value.get())->value;
auto min = m_opt.min == INT_MIN ? 0 : m_opt.min; auto min = m_opt.min == INT_MIN ? 0 : m_opt.min;
auto max = m_opt.max == INT_MAX ? 100 : m_opt.max; auto max = m_opt.max == INT_MAX ? 100 : m_opt.max;

View File

@ -90,7 +90,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
def.gui_type = "legend"; def.gui_type = "legend";
def.tooltip = L("Object name"); def.tooltip = L("Object name");
def.width = 21; def.width = 21;
def.default_value = new ConfigOptionString{ " " }; def.set_default_value(new ConfigOptionString{ " " });
m_og->append_single_option_line(Option(def, "object_name")); m_og->append_single_option_line(Option(def, "object_name"));
const int field_width = 5; const int field_width = 5;
@ -103,7 +103,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
for (const std::string axis : { "x", "y", "z" }) { for (const std::string axis : { "x", "y", "z" }) {
const std::string label = boost::algorithm::to_upper_copy(axis); const std::string label = boost::algorithm::to_upper_copy(axis);
def.default_value = new ConfigOptionString{ " " + label }; def.set_default_value(new ConfigOptionString{ " " + label });
Option option = Option(def, axis + "_axis_legend"); Option option = Option(def, axis + "_axis_legend");
line.append_option(option); line.append_option(option);
} }
@ -120,7 +120,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
Line line = { _(option_name), "" }; Line line = { _(option_name), "" };
ConfigOptionDef def; ConfigOptionDef def;
def.type = coFloat; def.type = coFloat;
def.default_value = new ConfigOptionFloat(0.0); def.set_default_value(new ConfigOptionFloat(0.0));
def.width = field_width/*50*/; def.width = field_width/*50*/;
// Add "uniform scaling" button in front of "Scale" option // Add "uniform scaling" button in front of "Scale" option

View File

@ -49,7 +49,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
}; };
def.type = coFloat; def.type = coFloat;
def.default_value = new ConfigOptionFloat{ 1.0 }; def.set_default_value(new ConfigOptionFloat{ 1.0 });
def.label = L("Length"); def.label = L("Length");
Option option(def, "l"); Option option(def, "l");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
@ -75,7 +75,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
}; };
def.type = coInt; def.type = coInt;
def.default_value = new ConfigOptionInt{ 1 }; def.set_default_value(new ConfigOptionInt{ 1 });
def.label = L("Radius"); def.label = L("Radius");
auto option = Option(def, "cyl_r"); auto option = Option(def, "cyl_r");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
@ -94,7 +94,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
}; };
def.type = coFloat; def.type = coFloat;
def.default_value = new ConfigOptionFloat{ 1.0 }; def.set_default_value(new ConfigOptionFloat{ 1.0 });
def.label = L("Rho"); def.label = L("Rho");
auto option = Option(def, "sph_rho"); auto option = Option(def, "sph_rho");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);
@ -112,7 +112,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
}; };
def.type = coFloat; def.type = coFloat;
def.default_value = new ConfigOptionFloat{ 1.0 }; def.set_default_value(new ConfigOptionFloat{ 1.0 });
def.label = L("Height"); def.label = L("Height");
auto option = Option(def, "slab_h"); auto option = Option(def, "slab_h");
optgroup->append_single_option_line(option); optgroup->append_single_option_line(option);

View File

@ -394,16 +394,27 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
} }
new_conf.set_key_value("brim_width", new ConfigOptionFloat(new_val)); new_conf.set_key_value("brim_width", new ConfigOptionFloat(new_val));
} }
else { //(opt_key == "support") else {
assert(opt_key == "support");
const wxString& selection = boost::any_cast<wxString>(value); const wxString& selection = boost::any_cast<wxString>(value);
PrinterTechnology printer_technology = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
auto support_material = selection == _("None") ? false : true; auto support_material = selection == _("None") ? false : true;
new_conf.set_key_value("support_material", new ConfigOptionBool(support_material)); new_conf.set_key_value("support_material", new ConfigOptionBool(support_material));
if (selection == _("Everywhere")) if (selection == _("Everywhere")) {
new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false)); new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false));
else if (selection == _("Support on build plate only")) if (printer_technology == ptFFF)
new_conf.set_key_value("support_material_auto", new ConfigOptionBool(true));
} else if (selection == _("Support on build plate only")) {
new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true)); new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true));
if (printer_technology == ptFFF)
new_conf.set_key_value("support_material_auto", new ConfigOptionBool(true));
} else if (selection == _("For support enforcers only")) {
assert(printer_technology == ptFFF);
new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false));
new_conf.set_key_value("support_material_auto", new ConfigOptionBool(false));
}
} }
tab_print->load_config(new_conf); tab_print->load_config(new_conf);
} }
@ -421,12 +432,9 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
support_def.tooltip = L("Select what kind of support do you need"); support_def.tooltip = L("Select what kind of support do you need");
support_def.enum_labels.push_back(L("None")); support_def.enum_labels.push_back(L("None"));
support_def.enum_labels.push_back(L("Support on build plate only")); support_def.enum_labels.push_back(L("Support on build plate only"));
support_def.enum_labels.push_back(L("For support enforcers only"));
support_def.enum_labels.push_back(L("Everywhere")); support_def.enum_labels.push_back(L("Everywhere"));
std::string selection = !config->opt_bool("support_material") ? support_def.set_default_value(new ConfigOptionStrings{ "None" });
"None" : config->opt_bool("support_material_buildplate_only") ?
"Support on build plate only" :
"Everywhere";
support_def.default_value = new ConfigOptionStrings{ selection };
Option option = Option(support_def, "support"); Option option = Option(support_def, "support");
option.opt.full_width = true; option.opt.full_width = true;
line.append_option(option); line.append_option(option);
@ -447,7 +455,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
def.type = coBool; def.type = coBool;
def.tooltip = L("This flag enables the brim that will be printed around each object on the first layer."); def.tooltip = L("This flag enables the brim that will be printed around each object on the first layer.");
def.gui_type = ""; def.gui_type = "";
def.default_value = new ConfigOptionBool{ m_brim_width > 0.0 ? true : false }; def.set_default_value(new ConfigOptionBool{ m_brim_width > 0.0 ? true : false });
option = Option(def, "brim"); option = Option(def, "brim");
option.opt.sidetext = " "; option.opt.sidetext = " ";
line.append_option(option); line.append_option(option);
@ -493,8 +501,9 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
tab->set_value(opt_key, value); tab->set_value(opt_key, value);
tab->update(); tab->update();
} }
else //(opt_key == "support") else
{ {
assert(opt_key == "support");
DynamicPrintConfig new_conf = *config_sla; DynamicPrintConfig new_conf = *config_sla;
const wxString& selection = boost::any_cast<wxString>(value); const wxString& selection = boost::any_cast<wxString>(value);
@ -514,17 +523,15 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
line = Line{ "", "" }; line = Line{ "", "" };
selection = !config_sla->opt_bool("supports_enable") ? ConfigOptionDef support_def_sla = support_def;
"None" : config_sla->opt_bool("support_buildplate_only") ? support_def_sla.set_default_value(new ConfigOptionStrings{ "None" });
"Support on build plate only" : assert(support_def_sla.enum_labels[2] == L("For support enforcers only"));
"Everywhere"; support_def_sla.enum_labels.erase(support_def_sla.enum_labels.begin() + 2);
support_def.default_value = new ConfigOptionStrings{ selection }; option = Option(support_def_sla, "support");
option = Option(support_def, "support");
option.opt.full_width = true; option.opt.full_width = true;
line.append_option(option); line.append_option(option);
m_og_sla->append_line(line); m_og_sla->append_line(line);
line = Line{ "", "" }; line = Line{ "", "" };
option = m_og_sla->get_option("pad_enable"); option = m_og_sla->get_option("pad_enable");

View File

@ -37,7 +37,7 @@ void PreferencesDialog::build()
def.type = coBool; def.type = coBool;
def.tooltip = L("If this is enabled, Slic3r will prompt the last output directory " def.tooltip = L("If this is enabled, Slic3r will prompt the last output directory "
"instead of the one containing the input files."); "instead of the one containing the input files.");
def.default_value = new ConfigOptionBool{ app_config->has("remember_output_path") ? app_config->get("remember_output_path") == "1" : true }; def.set_default_value(new ConfigOptionBool{ app_config->has("remember_output_path") ? app_config->get("remember_output_path") == "1" : true });
Option option(def, "remember_output_path"); Option option(def, "remember_output_path");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
@ -45,7 +45,7 @@ void PreferencesDialog::build()
def.type = coBool; def.type = coBool;
def.tooltip = L("If this is enabled, Slic3r will auto-center objects " def.tooltip = L("If this is enabled, Slic3r will auto-center objects "
"around the print bed center."); "around the print bed center.");
def.default_value = new ConfigOptionBool{ app_config->get("autocenter") == "1" }; def.set_default_value(new ConfigOptionBool{ app_config->get("autocenter") == "1" });
option = Option (def,"autocenter"); option = Option (def,"autocenter");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
@ -53,7 +53,7 @@ void PreferencesDialog::build()
def.type = coBool; def.type = coBool;
def.tooltip = L("If this is enabled, Slic3r will pre-process objects as soon " def.tooltip = L("If this is enabled, Slic3r will pre-process objects as soon "
"as they\'re loaded in order to save time when exporting G-code."); "as they\'re loaded in order to save time when exporting G-code.");
def.default_value = new ConfigOptionBool{ app_config->get("background_processing") == "1" }; def.set_default_value(new ConfigOptionBool{ app_config->get("background_processing") == "1" });
option = Option (def,"background_processing"); option = Option (def,"background_processing");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
@ -61,7 +61,7 @@ void PreferencesDialog::build()
def.label = L("Check for application updates"); def.label = L("Check for application updates");
def.type = coBool; def.type = coBool;
def.tooltip = L("If enabled, Slic3r checks for new versions of " SLIC3R_APP_NAME " online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done."); def.tooltip = L("If enabled, Slic3r checks for new versions of " SLIC3R_APP_NAME " online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done.");
def.default_value = new ConfigOptionBool(app_config->get("version_check") == "1"); def.set_default_value(new ConfigOptionBool(app_config->get("version_check") == "1"));
option = Option (def, "version_check"); option = Option (def, "version_check");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
@ -69,7 +69,7 @@ void PreferencesDialog::build()
def.label = L("Update built-in Presets automatically"); def.label = L("Update built-in Presets automatically");
def.type = coBool; def.type = coBool;
def.tooltip = L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded into a separate temporary location. When a new preset version becomes available it is offered at application startup."); def.tooltip = L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded into a separate temporary location. When a new preset version becomes available it is offered at application startup.");
def.default_value = new ConfigOptionBool(app_config->get("preset_update") == "1"); def.set_default_value(new ConfigOptionBool(app_config->get("preset_update") == "1"));
option = Option (def, "preset_update"); option = Option (def, "preset_update");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
@ -77,7 +77,7 @@ void PreferencesDialog::build()
def.type = coBool; def.type = coBool;
def.tooltip = L("Suppress \" - default - \" presets in the Print / Filament / Printer " def.tooltip = L("Suppress \" - default - \" presets in the Print / Filament / Printer "
"selections once there are any other valid presets available."); "selections once there are any other valid presets available.");
def.default_value = new ConfigOptionBool{ app_config->get("no_defaults") == "1" }; def.set_default_value(new ConfigOptionBool{ app_config->get("no_defaults") == "1" });
option = Option (def,"no_defaults"); option = Option (def,"no_defaults");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
@ -85,7 +85,7 @@ void PreferencesDialog::build()
def.type = coBool; def.type = coBool;
def.tooltip = L("When checked, the print and filament presets are shown in the preset editor " def.tooltip = L("When checked, the print and filament presets are shown in the preset editor "
"even if they are marked as incompatible with the active printer"); "even if they are marked as incompatible with the active printer");
def.default_value = new ConfigOptionBool{ app_config->get("show_incompatible_presets") == "1" }; def.set_default_value(new ConfigOptionBool{ app_config->get("show_incompatible_presets") == "1" });
option = Option (def,"show_incompatible_presets"); option = Option (def,"show_incompatible_presets");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
@ -95,7 +95,7 @@ void PreferencesDialog::build()
def.tooltip = L("If you have rendering issues caused by a buggy OpenGL 2.0 driver, " def.tooltip = L("If you have rendering issues caused by a buggy OpenGL 2.0 driver, "
"you may try to check this checkbox. This will disable the layer height " "you may try to check this checkbox. This will disable the layer height "
"editing and anti aliasing, so it is likely better to upgrade your graphics driver."); "editing and anti aliasing, so it is likely better to upgrade your graphics driver.");
def.default_value = new ConfigOptionBool{ app_config->get("use_legacy_opengl") == "1" }; def.set_default_value(new ConfigOptionBool{ app_config->get("use_legacy_opengl") == "1" });
option = Option (def,"use_legacy_opengl"); option = Option (def,"use_legacy_opengl");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
@ -104,7 +104,7 @@ void PreferencesDialog::build()
def.type = coBool; def.type = coBool;
def.tooltip = L("If enabled, the 3D scene will be rendered in Retina resolution. " def.tooltip = L("If enabled, the 3D scene will be rendered in Retina resolution. "
"If you are experiencing 3D performance problems, disabling this option may help."); "If you are experiencing 3D performance problems, disabling this option may help.");
def.default_value = new ConfigOptionBool{ app_config->get("use_retina_opengl") == "1" }; def.set_default_value(new ConfigOptionBool{ app_config->get("use_retina_opengl") == "1" });
option = Option (def, "use_retina_opengl"); option = Option (def, "use_retina_opengl");
m_optgroup->append_single_option_line(option); m_optgroup->append_single_option_line(option);
#endif #endif

View File

@ -815,6 +815,19 @@ void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bo
update(); update();
} }
static wxString support_combo_value_for_config(const DynamicPrintConfig &config, bool is_fff)
{
const std::string support = is_fff ? "support_material" : "supports_enable";
const std::string buildplate_only = is_fff ? "support_material_buildplate_only" : "support_buildplate_only";
return
! config.opt_bool(support) ?
_("None") :
(is_fff && !config.opt_bool("support_material_auto")) ?
_("For support enforcers only") :
(config.opt_bool(buildplate_only) ? _("Support on build plate only") :
_("Everywhere"));
}
void Tab::on_value_change(const std::string& opt_key, const boost::any& value) void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
{ {
if (wxGetApp().plater() == nullptr) { if (wxGetApp().plater() == nullptr) {
@ -829,16 +842,10 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
og_freq_chng_params->set_value(opt_key, val); og_freq_chng_params->set_value(opt_key, val);
} }
if ( is_fff && (opt_key == "support_material" || opt_key == "support_material_buildplate_only") || if (is_fff ?
!is_fff && (opt_key == "supports_enable" || opt_key == "support_buildplate_only")) (opt_key == "support_material" || opt_key == "support_material_auto" || opt_key == "support_material_buildplate_only") :
{ (opt_key == "supports_enable" || opt_key == "support_buildplate_only"))
const std::string support = is_fff ? "support_material" : "supports_enable"; og_freq_chng_params->set_value("support", support_combo_value_for_config(*m_config, is_fff));
const std::string buildplate_only = is_fff ? "support_material_buildplate_only" : "support_buildplate_only";
wxString new_selection = !m_config->opt_bool(support) ? _("None") :
m_config->opt_bool(buildplate_only) ? _("Support on build plate only") :
_("Everywhere");
og_freq_chng_params->set_value("support", new_selection);
}
if (opt_key == "brim_width") if (opt_key == "brim_width")
{ {
@ -964,18 +971,11 @@ void Tab::update_preset_description_line()
void Tab::update_frequently_changed_parameters() void Tab::update_frequently_changed_parameters()
{ {
auto og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(supports_printer_technology(ptFFF)); const bool is_fff = supports_printer_technology(ptFFF);
auto og_freq_chng_params = wxGetApp().sidebar().og_freq_chng_params(is_fff);
if (!og_freq_chng_params) return; if (!og_freq_chng_params) return;
const bool is_fff = supports_printer_technology(ptFFF); og_freq_chng_params->set_value("support", support_combo_value_for_config(*m_config, is_fff));
const std::string support = is_fff ? "support_material" : "supports_enable";
const std::string buildplate_only = is_fff ? "support_material_buildplate_only" : "support_buildplate_only";
wxString new_selection = !m_config->opt_bool(support) ? _("None") :
m_config->opt_bool(buildplate_only) ? _("Support on build plate only") :
_("Everywhere");
og_freq_chng_params->set_value("support", new_selection);
const std::string updated_value_key = is_fff ? "fill_density" : "pad_enable"; const std::string updated_value_key = is_fff ? "fill_density" : "pad_enable";
@ -1840,7 +1840,7 @@ void TabPrinter::build_fff()
optgroup = page->new_optgroup(_(L("Capabilities"))); optgroup = page->new_optgroup(_(L("Capabilities")));
ConfigOptionDef def; ConfigOptionDef def;
def.type = coInt, def.type = coInt,
def.default_value = new ConfigOptionInt(1); def.set_default_value(new ConfigOptionInt(1));
def.label = L("Extruders"); def.label = L("Extruders");
def.tooltip = L("Number of extruders of the printer."); def.tooltip = L("Number of extruders of the printer.");
def.min = 1; def.min = 1;
@ -2148,13 +2148,13 @@ PageShp TabPrinter::build_kinematics_page()
def.gui_type = "legend"; def.gui_type = "legend";
def.mode = comAdvanced; def.mode = comAdvanced;
def.tooltip = L("Values in this column are for Full Power mode"); def.tooltip = L("Values in this column are for Full Power mode");
def.default_value = new ConfigOptionString{ L("Full Power") }; def.set_default_value(new ConfigOptionString{ L("Full Power") });
auto option = Option(def, "full_power_legend"); auto option = Option(def, "full_power_legend");
line.append_option(option); line.append_option(option);
def.tooltip = L("Values in this column are for Silent mode"); def.tooltip = L("Values in this column are for Silent mode");
def.default_value = new ConfigOptionString{ L("Silent") }; def.set_default_value(new ConfigOptionString{ L("Silent") });
option = Option(def, "silent_legend"); option = Option(def, "silent_legend");
line.append_option(option); line.append_option(option);

View File

@ -223,8 +223,8 @@ print_config_def()
(void)hv_stores( hv, "labels", newRV_noinc((SV*)av) ); (void)hv_stores( hv, "labels", newRV_noinc((SV*)av) );
} }
if (optdef->default_value != NULL) if (optdef->default_value)
(void)hv_stores( hv, "default", ConfigOption_to_SV(*optdef->default_value, *optdef) ); (void)hv_stores( hv, "default", ConfigOption_to_SV(*optdef->default_value.get(), *optdef) );
(void)hv_store( options_hv, opt_key.c_str(), opt_key.length(), newRV_noinc((SV*)hv), 0 ); (void)hv_store( options_hv, opt_key.c_str(), opt_key.length(), newRV_noinc((SV*)hv), 0 );
} }