Merge remote-tracking branch 'origin/SLA_ui' into dev

This commit is contained in:
YuSanka 2018-08-24 12:20:24 +02:00
commit ada6970053
18 changed files with 1102 additions and 323 deletions

View File

@ -154,6 +154,10 @@ sub _init_tabpanel {
my $value = $event->GetInt();
$self->{plater}->on_extruders_change($value);
}
if ($opt_key eq 'printer_technology'){
my $value = $event->GetInt();# 0 ~ "ptFFF"; 1 ~ "ptSLA"
$self->{plater}->show_preset_comboboxes($value);
}
}
# don't save while loading for the first time
$self->config->save($Slic3r::GUI::autosave) if $Slic3r::GUI::autosave && $self->{loaded};
@ -166,7 +170,7 @@ sub _init_tabpanel {
my $tab = Slic3r::GUI::get_preset_tab($tab_name);
if ($self->{plater}) {
# Update preset combo boxes (Print settings, Filament, Printer) from their respective tabs.
# Update preset combo boxes (Print settings, Filament, Material, Printer) from their respective tabs.
my $presets = $tab->get_presets;
if (defined $presets){
my $reload_dependent_tabs = $tab->get_dependent_tabs;
@ -174,7 +178,7 @@ sub _init_tabpanel {
$self->{plater}->{"selected_item_$tab_name"} = $tab->get_selected_preset_item;
if ($tab_name eq 'printer') {
# Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors.
for my $tab_name_other (qw(print filament)) {
for my $tab_name_other (qw(print filament sla_material)) {
# If the printer tells us that the print or filament preset has been switched or invalidated,
# refresh the print or filament tab page. Otherwise just refresh the combo box.
my $update_action = ($reload_dependent_tabs && (first { $_ eq $tab_name_other } (@{$reload_dependent_tabs})))
@ -190,7 +194,7 @@ sub _init_tabpanel {
});
Slic3r::GUI::create_preset_tabs($self->{no_controller}, $VALUE_CHANGE_EVENT, $PRESETS_CHANGED_EVENT);
$self->{options_tabs} = {};
for my $tab_name (qw(print filament printer)) {
for my $tab_name (qw(print filament sla_material printer)) {
$self->{options_tabs}{$tab_name} = Slic3r::GUI::get_preset_tab("$tab_name");
}
@ -202,8 +206,14 @@ sub _init_tabpanel {
# load initial config
my $full_config = wxTheApp->{preset_bundle}->full_config;
$self->{plater}->on_config_change($full_config);
# Show a correct number of filament fields.
$self->{plater}->on_extruders_change(int(@{$full_config->nozzle_diameter}));
if (defined $full_config->nozzle_diameter){ # nozzle_diameter is undefined when SLA printer is selected
$self->{plater}->on_extruders_change(int(@{$full_config->nozzle_diameter}));
}
# Show correct preset comboboxes according to the printer_technology
$self->{plater}->show_preset_comboboxes(($full_config->printer_technology eq "FFF") ? 0 : 1);
}
}

View File

@ -520,20 +520,21 @@ sub new {
{
my $presets;
{
$presets = $self->{presets_sizer} = Wx::FlexGridSizer->new(3, 2, 1, 2);
$presets = $self->{presets_sizer} = Wx::FlexGridSizer->new(4, 2, 1, 2);
$presets->AddGrowableCol(1, 1);
$presets->SetFlexibleDirection(wxHORIZONTAL);
my %group_labels = (
print => L('Print settings'),
filament => L('Filament'),
sla_material=> L('SLA material'),
printer => L('Printer'),
);
# UI Combo boxes for a print, multiple filaments, and a printer.
# UI Combo boxes for a print, multiple filaments, SLA material and a printer.
# Initially a single filament combo box is created, but the number of combo boxes for the filament selection may increase,
# once a printer preset with multiple extruders is activated.
# $self->{preset_choosers}{$group}[$idx]
$self->{preset_choosers} = {};
for my $group (qw(print filament printer)) {
for my $group (qw(print filament sla_material printer)) {
my $text = Wx::StaticText->new($self->{right_panel}, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
$text->SetFont($Slic3r::GUI::small_font);
my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY);
@ -554,7 +555,7 @@ sub new {
$presets->Layout;
}
my $frequently_changed_parameters_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
my $frequently_changed_parameters_sizer = $self->{frequently_changed_parameters_sizer} = Wx::BoxSizer->new(wxHORIZONTAL);
Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets);
my $object_info_sizer;
@ -726,16 +727,17 @@ sub update_ui_from_settings
}
}
# Update preset combo boxes (Print settings, Filament, Printer) from their respective tabs.
# Update preset combo boxes (Print settings, Filament, Material, Printer) from their respective tabs.
# Called by
# Slic3r::GUI::Tab::Print::_on_presets_changed
# Slic3r::GUI::Tab::Filament::_on_presets_changed
# Slic3r::GUI::Tab::Material::_on_presets_changed
# Slic3r::GUI::Tab::Printer::_on_presets_changed
# when the presets are loaded or the user selects another preset.
# For Print settings and Printer, synchronize the selection index with their tabs.
# For Filament, synchronize the selection index for a single extruder printer only, otherwise keep the selection.
sub update_presets {
# $group: one of qw(print filament printer)
# $group: one of qw(print filament sla_material printer)
# $presets: PresetCollection
my ($self, $group, $presets) = @_;
my @choosers = @{$self->{preset_choosers}{$group}};
@ -751,6 +753,8 @@ sub update_presets {
}
} elsif ($group eq 'print') {
wxTheApp->{preset_bundle}->print->update_platter_ui($choosers[0]);
} elsif ($group eq 'sla_material') {
wxTheApp->{preset_bundle}->sla_material->update_platter_ui($choosers[0]);
} elsif ($group eq 'printer') {
# Update the print choosers to only contain the compatible presets, update the dirty flags.
wxTheApp->{preset_bundle}->print->update_platter_ui($self->{preset_choosers}{print}->[0]);
@ -1931,6 +1935,24 @@ sub update {
$self->{preview3D}->reload_print if $self->{preview3D};
}
# When a printer technology is changed, the UI needs to be updated to show/hide needed preset combo boxes.
sub show_preset_comboboxes{
my ($self, $showSLA) = @_; #if showSLA is oposite value to "ptFFF"
my $choices = $self->{preset_choosers}{filament};
my $print_filament_ctrls_cnt = 2 + 2 * ($#$choices+1);
foreach (0..$print_filament_ctrls_cnt-1){
$self->{presets_sizer}->Show($_, !$showSLA);
}
$self->{presets_sizer}->Show($print_filament_ctrls_cnt , $showSLA);
$self->{presets_sizer}->Show($print_filament_ctrls_cnt+1, $showSLA);
$self->{frequently_changed_parameters_sizer}->Show(0,!$showSLA);
$self->Layout;
}
# When a number of extruders changes, the UI needs to be updated to show a single filament selection combo box per extruder.
# Also the wxTheApp->{preset_bundle}->filament_presets needs to be resized accordingly
# and some reasonable default has to be selected for the additional extruders.

View File

@ -49,9 +49,9 @@ enum ConfigOptionType {
coPercents = coPercent + coVectorType,
// a fraction or an absolute value
coFloatOrPercent = 5,
// single 2d point. Currently not used.
// single 2d point (Point2f). Currently not used.
coPoint = 6,
// vector of 2d points. Currently used for the definition of the print bed and for the extruder offsets.
// vector of 2d points (Point2f). Currently used for the definition of the print bed and for the extruder offsets.
coPoints = coPoint + coVectorType,
// single boolean value
coBool = 7,
@ -821,12 +821,7 @@ public:
bool deserialize(const std::string &str, bool append = false) override
{
UNUSED(append);
const t_config_enum_values &enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
auto it = enum_keys_map.find(str);
if (it == enum_keys_map.end())
return false;
this->value = static_cast<T>(it->second);
return true;
return from_string(str, this->value);
}
static bool has(T value)
@ -838,7 +833,7 @@ public:
}
// Map from an enum name to an enum integer value.
static t_config_enum_names& get_enum_names()
static const t_config_enum_names& get_enum_names()
{
static t_config_enum_names names;
if (names.empty()) {
@ -855,7 +850,17 @@ public:
return names;
}
// Map from an enum name to an enum integer value.
static t_config_enum_values& get_enum_values();
static const t_config_enum_values& get_enum_values();
static bool from_string(const std::string &str, T &value)
{
const t_config_enum_values &enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
auto it = enum_keys_map.find(str);
if (it == enum_keys_map.end())
return false;
value = static_cast<T>(it->second);
return true;
}
};
// Generic enum configuration value.
@ -900,7 +905,7 @@ public:
// What type? bool, int, string etc.
ConfigOptionType type = coNone;
// Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor.
ConfigOption *default_value = nullptr;
const ConfigOption *default_value = nullptr;
// Usually empty.
// Special values - "i_enum_open", "f_enum_open" to provide combo box for int or float selection,
@ -958,7 +963,7 @@ public:
std::vector<std::string> enum_labels;
// For enums (when type == coEnum). Maps enum_values to enums.
// Initialized by ConfigOptionEnum<xxx>::get_enum_values()
t_config_enum_values *enum_keys_map = nullptr;
const t_config_enum_values *enum_keys_map = nullptr;
bool has_enum_value(const std::string &value) const {
for (const std::string &v : enum_values)

View File

@ -17,9 +17,51 @@ namespace Slic3r {
#define L(s) Slic3r::I18N::translate(s)
PrintConfigDef::PrintConfigDef()
{
this->init_common_params();
this->init_fff_params();
this->init_sla_params();
}
void PrintConfigDef::init_common_params()
{
t_optiondef_map &Options = this->options;
ConfigOptionDef* def;
def = this->add("printer_technology", coEnum);
def->label = L("Printer technology");
def->tooltip = L("Printer technology");
def->cli = "printer-technology=s";
def->enum_keys_map = &ConfigOptionEnum<PrinterTechnology>::get_enum_values();
def->enum_values.push_back("FFF");
def->enum_values.push_back("SLA");
def->default_value = new ConfigOptionEnum<PrinterTechnology>(ptFFF);
def = this->add("bed_shape", coPoints);
def->label = L("Bed shape");
def->default_value = new ConfigOptionPoints { Pointf(0,0), Pointf(200,0), Pointf(200,200), Pointf(0,200) };
def = this->add("layer_height", coFloat);
def->label = L("Layer height");
def->category = L("Layers and Perimeters");
def->tooltip = L("This setting controls the height (and thus the total number) of the slices/layers. "
"Thinner layers give better accuracy but take more time to print.");
def->sidetext = L("mm");
def->cli = "layer-height=f";
def->min = 0;
def->default_value = new ConfigOptionFloat(0.3);
def = this->add("max_print_height", coFloat);
def->label = L("Max print height");
def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
def->sidetext = L("mm");
def->cli = "max-print-height=f";
def->default_value = new ConfigOptionFloat(200.0);
}
void PrintConfigDef::init_fff_params()
{
t_optiondef_map &Options = this->options;
ConfigOptionDef* def;
// Maximum extruder temperature, bumped to 1500 to support printing of glass.
@ -33,10 +75,6 @@ PrintConfigDef::PrintConfigDef()
def->cli = "avoid-crossing-perimeters!";
def->default_value = new ConfigOptionBool(false);
def = this->add("bed_shape", coPoints);
def->label = L("Bed shape");
def->default_value = new ConfigOptionPoints { Vec2d(0,0), Vec2d(200,0), Vec2d(200,200), Vec2d(0,200) };
def = this->add("bed_temperature", coInts);
def->label = L("Other layers");
def->tooltip = L("Bed temperature for layers after the first one. "
@ -906,16 +944,6 @@ PrintConfigDef::PrintConfigDef()
def->height = 50;
def->default_value = new ConfigOptionString("");
def = this->add("layer_height", coFloat);
def->label = L("Layer height");
def->category = L("Layers and Perimeters");
def->tooltip = L("This setting controls the height (and thus the total number) of the slices/layers. "
"Thinner layers give better accuracy but take more time to print.");
def->sidetext = L("mm");
def->cli = "layer-height=f";
def->min = 0;
def->default_value = new ConfigOptionFloat(0.3);
def = this->add("remaining_times", coBool);
def->label = L("Supports remaining times");
def->tooltip = L("Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute"
@ -1036,13 +1064,6 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->default_value = new ConfigOptionFloats { 0. };
def = this->add("max_print_height", coFloat);
def->label = L("Max print height");
def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
def->sidetext = L("mm");
def->cli = "max-print-height=f";
def->default_value = new ConfigOptionFloat(200.0);
def = this->add("max_print_speed", coFloat);
def->label = L("Max print speed");
def->tooltip = L("When setting other speed settings to 0 Slic3r will autocalculate the optimal speed "
@ -2087,6 +2108,103 @@ PrintConfigDef::PrintConfigDef()
def->default_value = new ConfigOptionFloat(0);
}
void PrintConfigDef::init_sla_params()
{
t_optiondef_map &Options = this->options;
ConfigOptionDef* def;
// SLA Printer settings
def = this->add("display_width", coFloat);
def->label = L("Display width");
def->tooltip = L("Width of the display");
def->cli = "display-width=f";
def->min = 1;
def->default_value = new ConfigOptionFloat(150.);
def = this->add("display_height", coFloat);
def->label = L("Display height");
def->tooltip = L("Height of the display");
def->cli = "display-height=f";
def->min = 1;
def->default_value = new ConfigOptionFloat(100.);
def = this->add("display_pixels_x", coInt);
def->full_label = L("Number of pixels in");
def->label = ("X");
def->tooltip = L("Number of pixels in X");
def->cli = "display-pixels-x=i";
def->min = 100;
def->default_value = new ConfigOptionInt(2000);
def = this->add("display_pixels_y", coInt);
def->label = ("Y");
def->tooltip = L("Number of pixels in Y");
def->cli = "display-pixels-y=i";
def->min = 100;
def->default_value = new ConfigOptionInt(1000);
def = this->add("printer_correction", coFloats);
def->full_label = L("Printer scaling correction");
def->tooltip = L("Printer scaling correction");
def->min = 0;
def->default_value = new ConfigOptionFloats( { 1., 1., 1. } );
// SLA Material settings.
def = this->add("initial_layer_height", coFloat);
def->label = L("Initial layer height");
def->tooltip = L("Initial layer height");
def->sidetext = L("mm");
def->cli = "initial-layer-height=f";
def->min = 0;
def->default_value = new ConfigOptionFloat(0.3);
def = this->add("exposure_time", coFloat);
def->label = L("Exposure time");
def->tooltip = L("Exposure time");
def->sidetext = L("s");
def->cli = "exposure-time=f";
def->min = 0;
def->default_value = new ConfigOptionFloat(10);
def = this->add("initial_exposure_time", coFloat);
def->label = L("Initial exposure time");
def->tooltip = L("Initial exposure time");
def->sidetext = L("s");
def->cli = "initial-exposure-time=f";
def->min = 0;
def->default_value = new ConfigOptionFloat(15);
def = this->add("material_correction_printing", coFloats);
def->full_label = L("Correction for expansion when printing");
def->tooltip = L("Correction for expansion when printing");
def->min = 0;
def->default_value = new ConfigOptionFloats( { 1. , 1., 1. } );
def = this->add("material_correction_curing", coFloats);
def->full_label = L("Correction for expansion after curing");
def->tooltip = L("Correction for expansion after curing");
def->min = 0;
def->default_value = new ConfigOptionFloats( { 1. , 1., 1. } );
def = this->add("material_notes", coString);
def->label = L("SLA print material notes");
def->tooltip = L("You can put your notes regarding the SLA print material here.");
def->cli = "material-notes=s";
def->multiline = true;
def->full_width = true;
def->height = 130;
def->default_value = new ConfigOptionString("");
def = this->add("default_sla_material_profile", coString);
def->label = L("Default SLA material profile");
def->tooltip = L("Default print profile associated with the current printer profile. "
"On selection of the current printer profile, this print profile will be activated.");
def->default_value = new ConfigOptionString();
def = this->add("sla_material_settings_id", coString);
def->default_value = new ConfigOptionString("");
}
void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value)
{
// handle legacy options
@ -2410,4 +2528,8 @@ StaticPrintConfig::StaticCache<class Slic3r::PrintConfig> PrintConfig::s_c
StaticPrintConfig::StaticCache<class Slic3r::HostConfig> HostConfig::s_cache_HostConfig;
StaticPrintConfig::StaticCache<class Slic3r::FullPrintConfig> FullPrintConfig::s_cache_FullPrintConfig;
StaticPrintConfig::StaticCache<class Slic3r::SLAMaterialConfig> SLAMaterialConfig::s_cache_SLAMaterialConfig;
StaticPrintConfig::StaticCache<class Slic3r::SLAPrinterConfig> SLAPrinterConfig::s_cache_SLAPrinterConfig;
StaticPrintConfig::StaticCache<class Slic3r::SLAFullPrintConfig> SLAFullPrintConfig::s_cache_SLAFullPrintConfig;
}

View File

@ -22,6 +22,14 @@
namespace Slic3r {
enum PrinterTechnology
{
// Fused Filament Fabrication
ptFFF,
// Stereolitography
ptSLA,
};
enum GCodeFlavor {
gcfRepRap, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit,
gcfSmoothie, gcfNoExtrusion,
@ -48,7 +56,16 @@ enum FilamentType {
ftPLA, ftABS, ftPET, ftHIPS, ftFLEX, ftSCAFF, ftEDGE, ftNGEN, ftPVA
};
template<> inline t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["FFF"] = ptFFF;
keys_map["SLA"] = ptSLA;
}
return keys_map;
}
template<> inline const t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["reprap"] = gcfRepRap;
@ -94,7 +111,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enu
return keys_map;
}
template<> inline t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>::get_enum_values() {
template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["rectilinear"] = smpRectilinear;
@ -104,7 +121,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>
return keys_map;
}
template<> inline t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() {
template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["random"] = spRandom;
@ -115,7 +132,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum
return keys_map;
}
template<> inline t_config_enum_values& ConfigOptionEnum<FilamentType>::get_enum_values() {
template<> inline const t_config_enum_values& ConfigOptionEnum<FilamentType>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["PLA"] = ftPLA;
@ -139,6 +156,11 @@ public:
PrintConfigDef();
static void handle_legacy(t_config_option_key &opt_key, std::string &value);
private:
void init_common_params();
void init_fff_params();
void init_sla_params();
};
// The one and only global definition of SLic3r configuration options.
@ -847,6 +869,73 @@ protected:
}
};
class SLAMaterialConfig : public StaticPrintConfig
{
STATIC_PRINT_CONFIG_CACHE(SLAMaterialConfig)
public:
ConfigOptionFloat layer_height;
ConfigOptionFloat initial_layer_height;
ConfigOptionFloat exposure_time;
ConfigOptionFloat initial_exposure_time;
ConfigOptionFloats material_correction_printing;
ConfigOptionFloats material_correction_curing;
protected:
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
OPT_PTR(layer_height);
OPT_PTR(initial_layer_height);
OPT_PTR(exposure_time);
OPT_PTR(initial_exposure_time);
OPT_PTR(material_correction_printing);
OPT_PTR(material_correction_curing);
}
};
class SLAPrinterConfig : public StaticPrintConfig
{
STATIC_PRINT_CONFIG_CACHE(SLAPrinterConfig)
public:
ConfigOptionEnum<PrinterTechnology> printer_technology;
ConfigOptionPoints bed_shape;
ConfigOptionFloat max_print_height;
ConfigOptionFloat display_width;
ConfigOptionFloat display_height;
ConfigOptionInt display_pixels_x;
ConfigOptionInt display_pixels_y;
ConfigOptionFloats printer_correction;
protected:
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
OPT_PTR(printer_technology);
OPT_PTR(bed_shape);
OPT_PTR(max_print_height);
OPT_PTR(display_width);
OPT_PTR(display_height);
OPT_PTR(display_pixels_x);
OPT_PTR(display_pixels_y);
OPT_PTR(printer_correction);
}
};
class SLAFullPrintConfig : public SLAPrinterConfig, public SLAMaterialConfig
{
STATIC_PRINT_CONFIG_CACHE_DERIVED(SLAFullPrintConfig)
SLAFullPrintConfig() : SLAPrinterConfig(0), SLAMaterialConfig(0) { initialize_cache(); *this = s_cache_SLAFullPrintConfig.defaults(); }
public:
// Validate the SLAFullPrintConfig. Returns an empty string on success, otherwise an error message is returned.
// std::string validate();
protected:
// Protected constructor to be called to initialize ConfigCache::m_default.
SLAFullPrintConfig(int) : SLAPrinterConfig(0), SLAMaterialConfig(0) {}
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
this->SLAPrinterConfig ::initialize(cache, base_ptr);
this->SLAMaterialConfig::initialize(cache, base_ptr);
}
};
#undef STATIC_PRINT_CONFIG_CACHE
#undef STATIC_PRINT_CONFIG_CACHE_BASE
#undef STATIC_PRINT_CONFIG_CACHE_DERIVED

View File

@ -233,6 +233,7 @@ void AppConfig::reset_selections()
if (it != m_storage.end()) {
it->second.erase("print");
it->second.erase("filament");
it->second.erase("sla_material");
it->second.erase("printer");
m_dirty = true;
}

View File

@ -274,7 +274,7 @@ void CheckBox::BUILD() {
bool check_value = m_opt.type == coBool ?
m_opt.default_value->getBool() : m_opt.type == coBools ?
static_cast<ConfigOptionBools*>(m_opt.default_value)->get_at(m_opt_idx) :
static_cast<const ConfigOptionBools*>(m_opt.default_value)->get_at(m_opt_idx) :
false;
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
@ -599,7 +599,7 @@ void ColourPicker::BUILD()
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
wxString clr(static_cast<ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx));
wxString clr(static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx));
auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size);
// // recast as a wxWindow to fit the calling convention
@ -631,7 +631,7 @@ void PointCtrl::BUILD()
//
wxSize field_size(40, -1);
auto default_pt = static_cast<ConfigOptionPoints*>(m_opt.default_value)->values.at(0);
auto default_pt = static_cast<const ConfigOptionPoints*>(m_opt.default_value)->values.at(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);
val = default_pt(1);
@ -695,7 +695,7 @@ void StaticText::BUILD()
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
wxString legend(static_cast<ConfigOptionString*>(m_opt.default_value)->value);
wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value);
auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size);
temp->SetFont(bold_font());

View File

@ -38,6 +38,7 @@ wxString double_to_string(double const value);
class MyButton : public wxButton
{
bool hidden = false; // never show button if it's hidden ones
public:
MyButton() {}
MyButton(wxWindow* parent, wxWindowID id, const wxString& label = wxEmptyString,
@ -52,6 +53,12 @@ public:
// overridden from wxWindow base class
virtual bool
AcceptsFocusFromKeyboard() const { return false; }
virtual bool Show(bool show = true) override {
if (!show)
hidden = true;
return wxButton::Show(!hidden);
}
};
class Field {

View File

@ -496,20 +496,33 @@ void open_preferences_dialog(int event_preferences)
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed)
{
update_label_colours_from_appconfig();
add_created_tab(new TabPrint (g_wxTabPanel, no_controller));
add_created_tab(new TabFilament (g_wxTabPanel, no_controller));
add_created_tab(new TabPrinter (g_wxTabPanel, no_controller));
for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++ i) {
Tab *tab = dynamic_cast<Tab*>(g_wxTabPanel->GetPage(i));
if (! tab)
continue;
tab->set_event_value_change(wxEventType(event_value_change));
tab->set_event_presets_changed(wxEventType(event_presets_changed));
}
add_created_tab(new TabPrint (g_wxTabPanel, no_controller), event_value_change, event_presets_changed);
add_created_tab(new TabFilament (g_wxTabPanel, no_controller), event_value_change, event_presets_changed);
add_created_tab(new TabSLAMaterial (g_wxTabPanel, no_controller), event_value_change, event_presets_changed);
add_created_tab(new TabPrinter (g_wxTabPanel, no_controller), event_value_change, event_presets_changed);
}
std::vector<PresetTab> preset_tabs = {
{ "print", nullptr, ptFFF },
{ "filament", nullptr, ptFFF },
{ "sla_material", nullptr, ptSLA }
};
const std::vector<PresetTab>& get_preset_tabs() {
return preset_tabs;
}
Tab* get_tab(const std::string& name)
{
std::vector<PresetTab>::iterator it = std::find_if(preset_tabs.begin(), preset_tabs.end(),
[name](PresetTab& tab){ return name == tab.name; });
return it != preset_tabs.end() ? it->panel : nullptr;
}
TabIface* get_preset_tab_iface(char *name)
{
Tab* tab = get_tab(name);
if (tab) return new TabIface(tab);
for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++ i) {
Tab *tab = dynamic_cast<Tab*>(g_wxTabPanel->GetPage(i));
if (! tab)
@ -629,13 +642,28 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
}
}
void add_created_tab(Tab* panel)
void add_created_tab(Tab* panel, int event_value_change, int event_presets_changed)
{
panel->create_preset_tab(g_PresetBundle);
// Load the currently selected preset into the GUI, update the preset selection box.
panel->load_current_preset();
g_wxTabPanel->AddPage(panel, panel->title());
panel->set_event_value_change(wxEventType(event_value_change));
panel->set_event_presets_changed(wxEventType(event_presets_changed));
const wxString& tab_name = panel->GetName();
bool add_panel = true;
auto it = std::find_if( preset_tabs.begin(), preset_tabs.end(),
[tab_name](PresetTab& tab){return tab.name == tab_name; });
if (it != preset_tabs.end()) {
it->panel = panel;
add_panel = it->technology == g_PresetBundle->printers.get_edited_preset().printer_technology();
}
if (add_panel)
g_wxTabPanel->AddPage(panel, panel->title());
}
void load_current_presets()
@ -676,6 +704,10 @@ PresetBundle* get_preset_bundle()
return g_PresetBundle;
}
wxNotebook* get_tab_panel() {
return g_wxTabPanel;
}
const wxColour& get_label_clr_modified() {
return g_color_label_modified;
}

View File

@ -3,7 +3,7 @@
#include <string>
#include <vector>
#include "Config.hpp"
#include "PrintConfig.hpp"
#include "../../libslic3r/Utils.hpp"
#include <wx/intl.h>
@ -80,6 +80,13 @@ inline t_file_wild_card& get_file_wild_card() {
return FILE_WILDCARDS;
}
struct PresetTab {
std::string name;
Tab* panel;
PrinterTechnology technology;
};
void disable_screensaver();
void enable_screensaver();
bool debugged();
@ -97,6 +104,7 @@ void set_3DScene(_3DScene *scene);
AppConfig* get_app_config();
wxApp* get_app();
PresetBundle* get_preset_bundle();
wxNotebook* get_tab_panel();
const wxColour& get_label_clr_modified();
const wxColour& get_label_clr_sys();
@ -108,6 +116,9 @@ void set_label_clr_sys(const wxColour& clr);
const wxFont& small_font();
const wxFont& bold_font();
Tab* get_tab(const std::string& name);
const std::vector<PresetTab>& get_preset_tabs();
extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change);
// This is called when closing the application, when loading a config file or when starting the config wizard
@ -130,7 +141,7 @@ void create_preset_tabs(bool no_controller, int event_value_change, int event_pr
TabIface* get_preset_tab_iface(char *name);
// add it at the end of the tab panel.
void add_created_tab(Tab* panel);
void add_created_tab(Tab* panel, int event_value_change, int event_presets_changed);
// Change option value in config
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index = 0);

View File

@ -120,6 +120,11 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
VendorProfile::PrinterModel model;
model.id = section.first.substr(printer_model_key.size());
model.name = section.second.get<std::string>("name", model.id);
auto technology_field = section.second.get<std::string>("technology", "FFF");
if (! ConfigOptionEnum<PrinterTechnology>::from_string(technology_field, model.technology)) {
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Invalid printer technology field: `%2%`") % id % technology_field;
model.technology = ptFFF;
}
section.second.get<std::string>("variants", "");
const auto variants_field = section.second.get<std::string>("variants", "");
std::vector<std::string> variants;
@ -177,7 +182,7 @@ void Preset::normalize(DynamicPrintConfig &config)
{
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
if (nozzle_diameter != nullptr)
// Loaded the Printer settings. Verify, that all extruder dependent values have enough values.
// Loaded the FFF Printer settings. Verify, that all extruder dependent values have enough values.
set_num_extruders(config, (unsigned int)nozzle_diameter->values.size());
if (config.option("filament_diameter") != nullptr) {
// This config contains single or multiple filament presets.
@ -204,12 +209,9 @@ void Preset::normalize(DynamicPrintConfig &config)
}
}
// Load a config file, return a C++ class Slic3r::DynamicPrintConfig with $keys initialized from the config file.
// In case of a "default" config item, return the default values.
DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys)
DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys, const StaticPrintConfig &defaults)
{
// Set the configuration from the defaults.
Slic3r::FullPrintConfig defaults;
this->config.apply_only(defaults, keys.empty() ? defaults.keys() : keys);
if (! this->is_default) {
// Load the preset file, apply preset values on top of defaults.
@ -260,8 +262,9 @@ bool Preset::is_compatible_with_printer(const Preset &active_printer) const
{
DynamicPrintConfig config;
config.set_key_value("printer_preset", new ConfigOptionString(active_printer.name));
config.set_key_value("num_extruders", new ConfigOptionInt(
(int)static_cast<const ConfigOptionFloats*>(active_printer.config.option("nozzle_diameter"))->values.size()));
const ConfigOption *opt = active_printer.config.option("nozzle_diameter");
if (opt)
config.set_key_value("num_extruders", new ConfigOptionInt((int)static_cast<const ConfigOptionFloats*>(opt)->values.size()));
return this->is_compatible_with_printer(active_printer, &config);
}
@ -329,8 +332,10 @@ const std::vector<std::string>& Preset::printer_options()
static std::vector<std::string> s_opts;
if (s_opts.empty()) {
s_opts = {
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed", "host_type",
"print_host", "printhost_apikey", "printhost_cafile", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
"printer_technology",
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
"use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
"host_type", "print_host", "printhost_apikey", "printhost_cafile",
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
"between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
"cooling_tube_length", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits",
@ -360,7 +365,39 @@ const std::vector<std::string>& Preset::nozzle_options()
return s_opts;
}
PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys) :
const std::vector<std::string>& Preset::sla_printer_options()
{
static std::vector<std::string> s_opts;
if (s_opts.empty()) {
s_opts = {
"printer_technology",
"bed_shape", "max_print_height",
"display_width", "display_height", "display_pixels_x", "display_pixels_y",
"printer_correction",
"printer_notes",
"inherits"
};
}
return s_opts;
}
const std::vector<std::string>& Preset::sla_material_options()
{
static std::vector<std::string> s_opts;
if (s_opts.empty()) {
s_opts = {
"layer_height", "initial_layer_height",
"exposure_time", "initial_exposure_time",
"material_correction_printing", "material_correction_curing",
"material_notes",
"compatible_printers",
"compatible_printers_condition", "inherits"
};
}
return s_opts;
}
PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name) :
m_type(type),
m_edited_preset(type, "", false),
m_idx_selected(0),
@ -368,8 +405,7 @@ PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::str
m_bitmap_cache(new GUI::BitmapCache)
{
// Insert just the default preset.
m_presets.emplace_back(Preset(type, "- default -", true));
m_presets.front().load(keys);
this->add_default_preset(keys, defaults, default_name);
m_edited_preset.config.apply(m_presets.front().config);
}
@ -383,7 +419,7 @@ PresetCollection::~PresetCollection()
void PresetCollection::reset(bool delete_files)
{
if (m_presets.size() > 1) {
if (m_presets.size() > m_num_default_presets) {
if (delete_files) {
// Erase the preset files.
for (Preset &preset : m_presets)
@ -391,11 +427,19 @@ void PresetCollection::reset(bool delete_files)
boost::nowide::remove(preset.file.c_str());
}
// Don't use m_presets.resize() here as it requires a default constructor for Preset.
m_presets.erase(m_presets.begin() + 1, m_presets.end());
m_presets.erase(m_presets.begin() + m_num_default_presets, m_presets.end());
this->select_preset(0);
}
}
void PresetCollection::add_default_preset(const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &preset_name)
{
// Insert just the default preset.
m_presets.emplace_back(Preset(this->type(), preset_name, true));
m_presets.back().load(keys, defaults);
++ m_num_default_presets;
}
// Load all presets found in dir_path.
// Throws an exception on error.
void PresetCollection::load_presets(const std::string &dir_path, const std::string &subdir)
@ -418,14 +462,15 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri
try {
Preset preset(m_type, name, false);
preset.file = dir_entry.path().string();
preset.load(keys);
//FIXME One should initialize with SLAFullPrintConfig for the SLA profiles!
preset.load(keys, static_cast<const HostConfig&>(FullPrintConfig::defaults()));
m_presets.emplace_back(preset);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
errors_cummulative += "\n";
}
}
std::sort(m_presets.begin() + 1, m_presets.end());
std::sort(m_presets.begin() + m_num_default_presets, m_presets.end());
this->select_preset(first_visible_idx());
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
@ -643,7 +688,7 @@ Preset* PresetCollection::find_preset(const std::string &name, bool first_visibl
// Return index of the first visible preset. Certainly at least the '- default -' preset shall be visible.
size_t PresetCollection::first_visible_idx() const
{
size_t idx = m_default_suppressed ? 1 : 0;
size_t idx = m_default_suppressed ? m_num_default_presets : 0;
for (; idx < this->m_presets.size(); ++ idx)
if (m_presets[idx].is_visible)
break;
@ -656,7 +701,7 @@ void PresetCollection::set_default_suppressed(bool default_suppressed)
{
if (m_default_suppressed != default_suppressed) {
m_default_suppressed = default_suppressed;
m_presets.front().is_visible = ! default_suppressed || (m_presets.size() > 1 && m_idx_selected > 0);
m_presets.front().is_visible = ! default_suppressed || (m_presets.size() > m_num_default_presets && m_idx_selected > 0);
}
}
@ -664,9 +709,10 @@ size_t PresetCollection::update_compatible_with_printer_internal(const Preset &a
{
DynamicPrintConfig config;
config.set_key_value("printer_preset", new ConfigOptionString(active_printer.name));
config.set_key_value("num_extruders", new ConfigOptionInt(
(int)static_cast<const ConfigOptionFloats*>(active_printer.config.option("nozzle_diameter"))->values.size()));
for (size_t idx_preset = 1; idx_preset < m_presets.size(); ++ idx_preset) {
const ConfigOption *opt = active_printer.config.option("nozzle_diameter");
if (opt)
config.set_key_value("num_extruders", new ConfigOptionInt((int)static_cast<const ConfigOptionFloats*>(opt)->values.size()));
for (size_t idx_preset = m_num_default_presets; idx_preset < m_presets.size(); ++ idx_preset) {
bool selected = idx_preset == m_idx_selected;
Preset &preset_selected = m_presets[idx_preset];
Preset &preset_edited = selected ? m_edited_preset : preset_selected;
@ -707,7 +753,7 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui)
wxString selected = "";
if (!this->m_presets.front().is_visible)
ui->Append("------- " +_(L("System presets")) + " -------", wxNullBitmap);
for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++i) {
for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++i) {
const Preset &preset = this->m_presets[i];
if (! preset.is_visible || (! preset.is_compatible && i != m_idx_selected))
continue;
@ -745,7 +791,7 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui)
if (i == m_idx_selected)
selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str());
}
if (preset.is_default)
if (i + 1 == m_num_default_presets)
ui->Append("------- " + _(L("System presets")) + " -------", wxNullBitmap);
}
if (!nonsys_presets.empty())
@ -775,7 +821,7 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati
wxString selected = "";
if (!this->m_presets.front().is_visible)
ui->Append("------- " + _(L("System presets")) + " -------", wxNullBitmap);
for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++i) {
for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++i) {
const Preset &preset = this->m_presets[i];
if (! preset.is_visible || (! show_incompatible && ! preset.is_compatible && i != m_idx_selected))
continue;
@ -805,7 +851,7 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati
if (i == m_idx_selected)
selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str());
}
if (preset.is_default)
if (i + 1 == m_num_default_presets)
ui->Append("------- " + _(L("System presets")) + " -------", wxNullBitmap);
}
if (!nonsys_presets.empty())
@ -853,11 +899,11 @@ bool PresetCollection::update_dirty_ui(wxBitmapComboBox *ui)
return was_dirty != is_dirty;
}
std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type /*= false*/)
std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, const Preset *reference, const bool deep_compare /*= false*/)
{
std::vector<std::string> changed;
if (edited != nullptr && reference != nullptr) {
changed = is_printer_type ?
changed = deep_compare ?
reference->config.deep_diff(edited->config) :
reference->config.diff(edited->config);
// The "compatible_printers" option key is handled differently from the others:
@ -897,7 +943,7 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b
idx = it - m_presets.begin();
else {
// Find the first visible preset.
for (size_t i = m_default_suppressed ? 1 : 0; i < m_presets.size(); ++ i)
for (size_t i = m_default_suppressed ? m_num_default_presets : 0; i < m_presets.size(); ++ i)
if (m_presets[i].is_visible) {
idx = i;
break;
@ -939,7 +985,7 @@ std::vector<std::string> PresetCollection::merge_presets(PresetCollection &&othe
if (preset.is_default || preset.is_external)
continue;
Preset key(m_type, preset.name);
auto it = std::lower_bound(m_presets.begin() + 1, m_presets.end(), key);
auto it = std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key);
if (it == m_presets.end() || it->name != preset.name) {
if (preset.vendor != nullptr) {
// Re-assign a pointer to the vendor structure in the new PresetBundle.

View File

@ -52,6 +52,7 @@ public:
PrinterModel() {}
std::string id;
std::string name;
PrinterTechnology technology;
std::vector<PrinterVariant> variants;
PrinterVariant* variant(const std::string &name) {
for (auto &v : this->variants)
@ -83,6 +84,7 @@ public:
TYPE_INVALID,
TYPE_PRINT,
TYPE_FILAMENT,
TYPE_SLA_MATERIAL,
TYPE_PRINTER,
};
@ -123,8 +125,7 @@ public:
DynamicPrintConfig config;
// Load this profile for the following keys only.
// Throws std::runtime_error in case the file cannot be read.
DynamicPrintConfig& load(const std::vector<std::string> &keys);
DynamicPrintConfig& load(const std::vector<std::string> &keys, const StaticPrintConfig &defaults);
void save();
@ -149,6 +150,10 @@ public:
std::string& compatible_printers_condition() { return Preset::compatible_printers_condition(this->config); }
const std::string& compatible_printers_condition() const { return Preset::compatible_printers_condition(const_cast<Preset*>(this)->config); }
static PrinterTechnology& printer_technology(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionEnum<PrinterTechnology>>("printer_technology", true)->value; }
PrinterTechnology& printer_technology() { return Preset::printer_technology(this->config); }
const PrinterTechnology& printer_technology() const { return Preset::printer_technology(const_cast<Preset*>(this)->config); }
// Mark this preset as compatible if it is compatible with active_printer.
bool update_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config);
@ -167,6 +172,10 @@ public:
static const std::vector<std::string>& printer_options();
// Nozzle options of the printer options.
static const std::vector<std::string>& nozzle_options();
static const std::vector<std::string>& sla_printer_options();
static const std::vector<std::string>& sla_material_options();
static void update_suffix_modified();
protected:
@ -184,15 +193,15 @@ class PresetCollection
{
public:
// Initialize the PresetCollection with the "- default -" preset.
PresetCollection(Preset::Type type, const std::vector<std::string> &keys);
PresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name = "- default -");
~PresetCollection();
typedef std::deque<Preset>::iterator Iterator;
typedef std::deque<Preset>::const_iterator ConstIterator;
Iterator begin() { return m_presets.begin() + 1; }
ConstIterator begin() const { return m_presets.begin() + 1; }
Iterator end() { return m_presets.end(); }
ConstIterator end() const { return m_presets.end(); }
Iterator begin() { return m_presets.begin() + m_num_default_presets; }
ConstIterator begin() const { return m_presets.begin() + m_num_default_presets; }
Iterator end() { return m_presets.end(); }
ConstIterator end() const { return m_presets.end(); }
void reset(bool delete_files);
@ -200,6 +209,9 @@ public:
std::string name() const;
const std::deque<Preset>& operator()() const { return m_presets; }
// Add default preset at the start of the collection, increment the m_default_preset counter.
void add_default_preset(const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &preset_name);
// Load ini files of the particular type from the provided directory path.
void load_presets(const std::string &dir_path, const std::string &subdir);
@ -247,6 +259,8 @@ public:
Preset& get_selected_preset() { return m_presets[m_idx_selected]; }
const Preset& get_selected_preset() const { return m_presets[m_idx_selected]; }
int get_selected_idx() const { return m_idx_selected; }
// Returns the name of the selected preset, or an empty string if no preset is selected.
std::string get_selected_preset_name() const { return (m_idx_selected == -1) ? std::string() : this->get_selected_preset().name; }
// For the current edited preset, return the parent preset if there is one.
// If there is no parent preset, nullptr is returned.
// The parent preset may be a system preset or a user preset, which will be
@ -283,7 +297,7 @@ public:
template<typename PreferedCondition>
size_t first_compatible_idx(PreferedCondition prefered_condition) const
{
size_t i = m_default_suppressed ? 1 : 0;
size_t i = m_default_suppressed ? m_num_default_presets : 0;
size_t n = this->m_presets.size();
size_t i_compatible = n;
for (; i < n; ++ i)
@ -309,7 +323,8 @@ public:
const Preset& first_compatible() const { return this->preset(this->first_compatible_idx()); }
// Return number of presets including the "- default -" preset.
size_t size() const { return this->m_presets.size(); }
size_t size() const { return m_presets.size(); }
bool has_defaults_only() const { return m_presets.size() <= m_num_default_presets; }
// For Print / Filament presets, disable those, which are not compatible with the printer.
template<typename PreferedCondition>
@ -327,11 +342,11 @@ public:
// Compare the content of get_selected_preset() with get_edited_preset() configs, return true if they differ.
bool current_is_dirty() const { return ! this->current_dirty_options().empty(); }
// Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
std::vector<std::string> current_dirty_options(const bool is_printer_type = false) const
{ return dirty_options(&this->get_edited_preset(), &this->get_selected_preset(), is_printer_type); }
std::vector<std::string> current_dirty_options(const bool deep_compare = false) const
{ return dirty_options(&this->get_edited_preset(), &this->get_selected_preset(), deep_compare); }
// Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
std::vector<std::string> current_different_from_parent_options(const bool is_printer_type = false) const
{ return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), is_printer_type); }
std::vector<std::string> current_different_from_parent_options(const bool deep_compare = false) const
{ return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), deep_compare); }
// Update the choice UI from the list of presets.
// If show_incompatible, all presets are shown, otherwise only the compatible presets are shown.
@ -374,8 +389,16 @@ private:
std::deque<Preset>::iterator find_preset_internal(const std::string &name)
{
Preset key(m_type, name);
auto it = std::lower_bound(m_presets.begin() + 1, m_presets.end(), key);
return ((it == m_presets.end() || it->name != name) && m_presets.front().name == name) ? m_presets.begin() : it;
auto it = std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key);
if (it == m_presets.end() || it->name != name) {
// Preset has not been not found in the sorted list of non-default presets. Try the defaults.
for (size_t i = 0; i < m_num_default_presets; ++ i)
if (m_presets[i].name == name) {
it = m_presets.begin() + i;
break;
}
}
return it;
}
std::deque<Preset>::const_iterator find_preset_internal(const std::string &name) const
{ return const_cast<PresetCollection*>(this)->find_preset_internal(name); }
@ -395,7 +418,8 @@ private:
// Selected preset.
int m_idx_selected;
// Is the "- default -" preset suppressed?
bool m_default_suppressed = true;
bool m_default_suppressed = true;
size_t m_num_default_presets = 0;
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items of a Platter.
// These bitmaps are not owned by PresetCollection, but by a PresetBundle.
const wxBitmap *m_bitmap_compatible = nullptr;

View File

@ -40,9 +40,10 @@ static std::vector<std::string> s_project_options {
};
PresetBundle::PresetBundle() :
prints(Preset::TYPE_PRINT, Preset::print_options()),
filaments(Preset::TYPE_FILAMENT, Preset::filament_options()),
printers(Preset::TYPE_PRINTER, Preset::printer_options()),
prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
sla_materials(Preset::TYPE_SLA_MATERIAL, Preset::sla_material_options(), static_cast<const SLAMaterialConfig&>(SLAFullPrintConfig::defaults())),
printers(Preset::TYPE_PRINTER, Preset::printer_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults()), "- default FFF -"),
m_bitmapCompatible(new wxBitmap),
m_bitmapIncompatible(new wxBitmap),
m_bitmapLock(new wxBitmap),
@ -69,24 +70,35 @@ PresetBundle::PresetBundle() :
this->filaments.default_preset().compatible_printers_condition();
this->filaments.default_preset().inherits();
this->printers.default_preset().config.optptr("printer_settings_id", true);
this->printers.default_preset().config.optptr("printer_vendor", true);
this->printers.default_preset().config.optptr("printer_model", true);
this->printers.default_preset().config.optptr("printer_variant", true);
this->printers.default_preset().config.optptr("default_print_profile", true);
this->printers.default_preset().config.option<ConfigOptionStrings>("default_filament_profile", true)->values = { "" };
this->printers.default_preset().inherits();
this->sla_materials.default_preset().config.optptr("sla_material_settings_id", true);
this->sla_materials.default_preset().compatible_printers_condition();
this->sla_materials.default_preset().inherits();
this->printers.add_default_preset(Preset::sla_printer_options(), static_cast<const SLAMaterialConfig&>(SLAFullPrintConfig::defaults()), "- default SLA -");
this->printers.preset(1).printer_technology() = ptSLA;
for (size_t i = 0; i < 2; ++ i) {
Preset &preset = this->printers.preset(i);
preset.config.optptr("printer_settings_id", true);
preset.config.optptr("printer_vendor", true);
preset.config.optptr("printer_model", true);
preset.config.optptr("printer_variant", true);
preset.config.optptr("default_print_profile", true);
preset.config.option<ConfigOptionStrings>("default_filament_profile", true)->values = { "" };
preset.inherits();
}
// Load the default preset bitmaps.
this->prints .load_bitmap_default("cog.png");
this->filaments.load_bitmap_default("spool.png");
this->printers .load_bitmap_default("printer_empty.png");
this->prints .load_bitmap_default("cog.png");
this->filaments .load_bitmap_default("spool.png");
this->sla_materials.load_bitmap_default("package_green.png");
this->printers .load_bitmap_default("printer_empty.png");
this->load_compatible_bitmaps();
// Re-activate the default presets, so their "edited" preset copies will be updated with the additional configuration values above.
this->prints .select_preset(0);
this->filaments.select_preset(0);
this->printers .select_preset(0);
this->prints .select_preset(0);
this->filaments .select_preset(0);
this->sla_materials.select_preset(0);
this->printers .select_preset(0);
this->project_config.apply_only(FullPrintConfig::defaults(), s_project_options);
}
@ -113,13 +125,15 @@ void PresetBundle::reset(bool delete_files)
{
// Clear the existing presets, delete their respective files.
this->vendors.clear();
this->prints .reset(delete_files);
this->filaments.reset(delete_files);
this->printers .reset(delete_files);
this->prints .reset(delete_files);
this->filaments .reset(delete_files);
this->sla_materials.reset(delete_files);
this->printers .reset(delete_files);
this->filament_presets.clear();
this->filament_presets.emplace_back(this->filaments.get_selected_preset().name);
this->filament_presets.emplace_back(this->filaments.get_selected_preset_name());
this->obsolete_presets.prints.clear();
this->obsolete_presets.filaments.clear();
this->obsolete_presets.sla_materials.clear();
this->obsolete_presets.printers.clear();
}
@ -135,11 +149,13 @@ void PresetBundle::setup_directories()
data_dir / "presets",
data_dir / "presets" / "print",
data_dir / "presets" / "filament",
data_dir / "presets" / "sla_material",
data_dir / "presets" / "printer"
#else
// Store the print/filament/printer presets at the same location as the upstream Slic3r.
data_dir / "print",
data_dir / "filament",
data_dir / "sla_material",
data_dir / "printer"
#endif
};
@ -175,6 +191,11 @@ void PresetBundle::load_presets(const AppConfig &config)
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
this->sla_materials.load_presets(dir_user_presets, "sla_material");
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
this->printers.load_presets(dir_user_presets, "printer");
} catch (const std::runtime_error &err) {
@ -238,13 +259,16 @@ std::string PresetBundle::load_system_presets()
std::vector<std::string> PresetBundle::merge_presets(PresetBundle &&other)
{
this->vendors.insert(other.vendors.begin(), other.vendors.end());
std::vector<std::string> duplicate_prints = this->prints .merge_presets(std::move(other.prints), this->vendors);
std::vector<std::string> duplicate_filaments = this->filaments.merge_presets(std::move(other.filaments), this->vendors);
std::vector<std::string> duplicate_printers = this->printers .merge_presets(std::move(other.printers), this->vendors);
append(this->obsolete_presets.prints, std::move(other.obsolete_presets.prints));
append(this->obsolete_presets.filaments, std::move(other.obsolete_presets.filaments));
append(this->obsolete_presets.printers, std::move(other.obsolete_presets.printers));
std::vector<std::string> duplicate_prints = this->prints .merge_presets(std::move(other.prints), this->vendors);
std::vector<std::string> duplicate_filaments = this->filaments .merge_presets(std::move(other.filaments), this->vendors);
std::vector<std::string> duplicate_sla_materials = this->sla_materials.merge_presets(std::move(other.sla_materials), this->vendors);
std::vector<std::string> duplicate_printers = this->printers .merge_presets(std::move(other.printers), this->vendors);
append(this->obsolete_presets.prints, std::move(other.obsolete_presets.prints));
append(this->obsolete_presets.filaments, std::move(other.obsolete_presets.filaments));
append(this->obsolete_presets.sla_materials, std::move(other.obsolete_presets.sla_materials));
append(this->obsolete_presets.printers, std::move(other.obsolete_presets.printers));
append(duplicate_prints, std::move(duplicate_filaments));
append(duplicate_prints, std::move(duplicate_sla_materials));
append(duplicate_prints, std::move(duplicate_printers));
return duplicate_prints;
}
@ -275,9 +299,10 @@ void PresetBundle::load_selections(const AppConfig &config)
this->load_installed_printers(config);
// Parse the initial print / filament / printer profile names.
std::string initial_print_profile_name = remove_ini_suffix(config.get("presets", "print"));
std::string initial_filament_profile_name = remove_ini_suffix(config.get("presets", "filament"));
std::string initial_printer_profile_name = remove_ini_suffix(config.get("presets", "printer"));
std::string initial_print_profile_name = remove_ini_suffix(config.get("presets", "print"));
std::string initial_filament_profile_name = remove_ini_suffix(config.get("presets", "filament"));
std::string initial_sla_material_profile_name = remove_ini_suffix(config.get("presets", "sla_material"));
std::string initial_printer_profile_name = remove_ini_suffix(config.get("presets", "printer"));
// Activate print / filament / printer profiles from the config.
// If the printer profile enumerated by the config are not visible, select an alternate preset.
@ -285,21 +310,24 @@ void PresetBundle::load_selections(const AppConfig &config)
// will be selected by the following call of this->update_compatible_with_printer(true).
prints.select_preset_by_name_strict(initial_print_profile_name);
filaments.select_preset_by_name_strict(initial_filament_profile_name);
sla_materials.select_preset_by_name_strict(initial_sla_material_profile_name);
printers.select_preset_by_name(initial_printer_profile_name, true);
// Load the names of the other filament profiles selected for a multi-material printer.
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
size_t num_extruders = nozzle_diameter->values.size();
this->filament_presets = { initial_filament_profile_name };
for (unsigned int i = 1; i < (unsigned int)num_extruders; ++ i) {
char name[64];
sprintf(name, "filament_%d", i);
if (! config.has("presets", name))
break;
this->filament_presets.emplace_back(remove_ini_suffix(config.get("presets", name)));
if (printers.get_selected_preset().printer_technology() == ptFFF){
// Load the names of the other filament profiles selected for a multi-material printer.
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
size_t num_extruders = nozzle_diameter->values.size();
this->filament_presets = { initial_filament_profile_name };
for (unsigned int i = 1; i < (unsigned int)num_extruders; ++i) {
char name[64];
sprintf(name, "filament_%d", i);
if (!config.has("presets", name))
break;
this->filament_presets.emplace_back(remove_ini_suffix(config.get("presets", name)));
}
// Do not define the missing filaments, so that the update_compatible_with_printer() will use the preferred filaments.
this->filament_presets.resize(num_extruders, "");
}
// Do not define the missing filaments, so that the update_compatible_with_printer() will use the preferred filaments.
this->filament_presets.resize(num_extruders, "");
// Update visibility of presets based on their compatibility with the active printer.
// Always try to select a compatible print and filament preset to the current printer preset,
@ -313,25 +341,33 @@ void PresetBundle::load_selections(const AppConfig &config)
void PresetBundle::export_selections(AppConfig &config)
{
assert(filament_presets.size() >= 1);
assert(filament_presets.size() > 1 || filaments.get_selected_preset().name == filament_presets.front());
assert(filament_presets.size() > 1 || filaments.get_selected_preset_name() == filament_presets.front());
config.clear_section("presets");
config.set("presets", "print", prints.get_selected_preset().name);
config.set("presets", "filament", filament_presets.front());
config.set("presets", "print", prints.get_selected_preset_name());
config.set("presets", "filament", filament_presets.front());
for (int i = 1; i < filament_presets.size(); ++i) {
char name[64];
sprintf(name, "filament_%d", i);
config.set("presets", name, filament_presets[i]);
}
config.set("presets", "printer", printers.get_selected_preset().name);
config.set("presets", "sla_material", sla_materials.get_selected_preset_name());
config.set("presets", "printer", printers.get_selected_preset_name());
}
void PresetBundle::export_selections(PlaceholderParser &pp)
{
assert(filament_presets.size() >= 1);
assert(filament_presets.size() > 1 || filaments.get_selected_preset().name == filament_presets.front());
pp.set("print_preset", prints.get_selected_preset().name);
pp.set("filament_preset", filament_presets);
pp.set("printer_preset", printers.get_selected_preset().name);
assert(filament_presets.size() > 1 || filaments.get_selected_preset_name() == filament_presets.front());
switch (printers.get_edited_preset().printer_technology()) {
case ptFFF:
pp.set("print_preset", prints.get_selected_preset().name);
pp.set("filament_preset", filament_presets);
break;
case ptSLA:
pp.set("sla_material_preset", sla_materials.get_selected_preset().name);
break;
}
pp.set("printer_preset", printers.get_selected_preset().name);
}
bool PresetBundle::load_compatible_bitmaps()
@ -349,32 +385,43 @@ bool PresetBundle::load_compatible_bitmaps()
bool loaded_lock_open = m_bitmapLockOpen->LoadFile(
wxString::FromUTF8(Slic3r::var(path_bitmap_lock_open).c_str()), wxBITMAP_TYPE_PNG);
if (loaded_compatible) {
prints .set_bitmap_compatible(m_bitmapCompatible);
filaments.set_bitmap_compatible(m_bitmapCompatible);
prints .set_bitmap_compatible(m_bitmapCompatible);
filaments .set_bitmap_compatible(m_bitmapCompatible);
sla_materials.set_bitmap_compatible(m_bitmapCompatible);
// printers .set_bitmap_compatible(m_bitmapCompatible);
}
if (loaded_incompatible) {
prints .set_bitmap_incompatible(m_bitmapIncompatible);
filaments.set_bitmap_incompatible(m_bitmapIncompatible);
// printers .set_bitmap_incompatible(m_bitmapIncompatible);
prints .set_bitmap_incompatible(m_bitmapIncompatible);
filaments .set_bitmap_incompatible(m_bitmapIncompatible);
sla_materials.set_bitmap_incompatible(m_bitmapIncompatible);
// printers .set_bitmap_incompatible(m_bitmapIncompatible);
}
if (loaded_lock) {
prints .set_bitmap_lock(m_bitmapLock);
filaments.set_bitmap_lock(m_bitmapLock);
printers .set_bitmap_lock(m_bitmapLock);
prints .set_bitmap_lock(m_bitmapLock);
filaments .set_bitmap_lock(m_bitmapLock);
sla_materials.set_bitmap_lock(m_bitmapLock);
printers .set_bitmap_lock(m_bitmapLock);
}
if (loaded_lock_open) {
prints .set_bitmap_lock_open(m_bitmapLock);
filaments.set_bitmap_lock_open(m_bitmapLock);
printers .set_bitmap_lock_open(m_bitmapLock);
prints .set_bitmap_lock_open(m_bitmapLock);
filaments .set_bitmap_lock_open(m_bitmapLock);
sla_materials.set_bitmap_lock_open(m_bitmapLock);
printers .set_bitmap_lock_open(m_bitmapLock);
}
return loaded_compatible && loaded_incompatible && loaded_lock && loaded_lock_open;
}
DynamicPrintConfig PresetBundle::full_config() const
{
return (this->printers.get_edited_preset().printer_technology() == ptFFF) ?
this->full_fff_config() :
this->full_sla_config();
}
DynamicPrintConfig PresetBundle::full_fff_config() const
{
DynamicPrintConfig out;
out.apply(FullPrintConfig());
out.apply(FullPrintConfig::defaults());
out.apply(this->prints.get_edited_preset().config);
// Add the default filament preset to have the "filament_preset_id" defined.
out.apply(this->filaments.default_preset().config);
@ -466,6 +513,48 @@ DynamicPrintConfig PresetBundle::full_config() const
return out;
}
DynamicPrintConfig PresetBundle::full_sla_config() const
{
DynamicPrintConfig out;
out.apply(SLAFullPrintConfig::defaults());
out.apply(this->sla_materials.get_edited_preset().config);
out.apply(this->printers.get_edited_preset().config);
// There are no project configuration values as of now, the project_config is reserved for FFF printers.
// out.apply(this->project_config);
// Collect the "compatible_printers_condition" and "inherits" values over all presets (sla_materials, printers) into a single vector.
std::vector<std::string> compatible_printers_condition;
std::vector<std::string> inherits;
compatible_printers_condition.emplace_back(this->/*prints*/sla_materials.get_edited_preset().compatible_printers_condition());
inherits .emplace_back(this->/*prints*/sla_materials.get_edited_preset().inherits());
inherits .emplace_back(this->printers.get_edited_preset().inherits());
// These two value types clash between the print and filament profiles. They should be renamed.
out.erase("compatible_printers");
out.erase("compatible_printers_condition");
out.erase("inherits");
out.option<ConfigOptionString >("sla_material_settings_id", true)->value = this->sla_materials.get_selected_preset().name;
out.option<ConfigOptionString >("printer_settings_id", true)->value = this->printers.get_selected_preset().name;
// Serialize the collected "compatible_printers_condition" and "inherits" fields.
// There will be 1 + num_exturders fields for "inherits" and 2 + num_extruders for "compatible_printers_condition" stored.
// The vector will not be stored if all fields are empty strings.
auto add_if_some_non_empty = [&out](std::vector<std::string> &&values, const std::string &key) {
bool nonempty = false;
for (const std::string &v : values)
if (! v.empty()) {
nonempty = true;
break;
}
if (nonempty)
out.set_key_value(key, new ConfigOptionStrings(std::move(values)));
};
add_if_some_non_empty(std::move(compatible_printers_condition), "compatible_printers_condition_cummulative");
add_if_some_non_empty(std::move(inherits), "inherits_cummulative");
return out;
}
// Load an external config file containing the print, filament and printer presets.
// Instead of a config file, a G-code may be loaded containing the full set of parameters.
// In the future the configuration will likely be read from an AMF file as well.
@ -530,6 +619,8 @@ void PresetBundle::load_config_string(const char* str, const char* source_filena
// Load a config file from a boost property_tree. This is a private method called from load_config_file.
void PresetBundle::load_config_file_config(const std::string &name_or_path, bool is_external, DynamicPrintConfig &&config)
{
PrinterTechnology printer_technology = Preset::printer_technology(config);
// The "compatible_printers" field should not have been exported into a config.ini or a G-code anyway,
// but some of the alpha versions of Slic3r did.
{
@ -541,8 +632,10 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
}
}
size_t num_extruders = std::min(config.option<ConfigOptionFloats>("nozzle_diameter" )->values.size(),
config.option<ConfigOptionFloats>("filament_diameter")->values.size());
size_t num_extruders = (printer_technology == ptFFF) ?
std::min(config.option<ConfigOptionFloats>("nozzle_diameter" )->values.size(),
config.option<ConfigOptionFloats>("filament_diameter")->values.size()) :
0;
// Make a copy of the "compatible_printers_condition_cummulative" and "inherits_cummulative" vectors, which
// accumulate values over all presets (print, filaments, printers).
// These values will be distributed into their particular presets when loading.
@ -553,7 +646,8 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
compatible_printers_condition_values.resize(num_extruders + 2, std::string());
inherits_values.resize(num_extruders + 2, std::string());
// The "default_filament_profile" will be later extracted into the printer profile.
config.option<ConfigOptionStrings>("default_filament_profile", true)->values.resize(num_extruders, std::string());
if (printer_technology == ptFFF)
config.option<ConfigOptionStrings>("default_filament_profile", true)->values.resize(num_extruders, std::string());
// 1) Create a name from the file name.
// Keep the suffix (.ini, .gcode, .amf, .3mf etc) to differentiate it from the normal profiles.
@ -562,81 +656,83 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
// 2) If the loading succeeded, split and load the config into print / filament / printer settings.
// First load the print and printer presets.
for (size_t i_group = 0; i_group < 2; ++ i_group) {
PresetCollection &presets = (i_group == 0) ? this->prints : this->printers;
PresetCollection &presets = (i_group == 0) ? ((printer_technology == ptFFF) ? this->prints : this->sla_materials) : this->printers;
// Split the "compatible_printers_condition" and "inherits" values one by one from a single vector to the print & printer profiles.
size_t idx = (i_group == 0) ? 0 : num_extruders + 1;
inherits = inherits_values[idx];
compatible_printers_condition = compatible_printers_condition_values[idx];
if (is_external)
presets.load_external_preset(name_or_path, name,
config.opt_string((i_group == 0) ? "print_settings_id" : "printer_settings_id", true),
config.opt_string((i_group == 0) ? ((printer_technology == ptFFF) ? "print_settings_id" : "sla_material_id") : "printer_settings_id", true),
config);
else
presets.load_preset(presets.path_from_name(name), name, config).save();
}
// 3) Now load the filaments. If there are multiple filament presets, split them and load them.
auto old_filament_profile_names = config.option<ConfigOptionStrings>("filament_settings_id", true);
old_filament_profile_names->values.resize(num_extruders, std::string());
if (Preset::printer_technology(config) == ptFFF) {
// 3) Now load the filaments. If there are multiple filament presets, split them and load them.
auto old_filament_profile_names = config.option<ConfigOptionStrings>("filament_settings_id", true);
old_filament_profile_names->values.resize(num_extruders, std::string());
if (num_extruders <= 1) {
// Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets.
inherits = inherits_values[1];
compatible_printers_condition = compatible_printers_condition_values[1];
if (is_external)
this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config);
else
this->filaments.load_preset(this->filaments.path_from_name(name), name, config).save();
this->filament_presets.clear();
this->filament_presets.emplace_back(name);
} else {
// Split the filament presets, load each of them separately.
std::vector<DynamicPrintConfig> configs(num_extruders, this->filaments.default_preset().config);
// loop through options and scatter them into configs.
for (const t_config_option_key &key : this->filaments.default_preset().config.keys()) {
const ConfigOption *other_opt = config.option(key);
if (other_opt == nullptr)
continue;
if (other_opt->is_scalar()) {
for (size_t i = 0; i < configs.size(); ++ i)
configs[i].option(key, false)->set(other_opt);
} else if (key != "compatible_printers") {
for (size_t i = 0; i < configs.size(); ++ i)
static_cast<ConfigOptionVectorBase*>(configs[i].option(key, false))->set_at(other_opt, 0, i);
}
}
// Load the configs into this->filaments and make them active.
this->filament_presets.clear();
for (size_t i = 0; i < configs.size(); ++ i) {
DynamicPrintConfig &cfg = configs[i];
if (num_extruders <= 1) {
// Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets.
cfg.opt_string("compatible_printers_condition", true) = compatible_printers_condition_values[i + 1];
cfg.opt_string("inherits", true) = inherits_values[i + 1];
// Load all filament presets, but only select the first one in the preset dialog.
Preset *loaded = nullptr;
inherits = inherits_values[1];
compatible_printers_condition = compatible_printers_condition_values[1];
if (is_external)
loaded = &this->filaments.load_external_preset(name_or_path, name,
(i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "",
std::move(cfg), i == 0);
else {
// Used by the config wizard when creating a custom setup.
// Therefore this block should only be called for a single extruder.
char suffix[64];
if (i == 0)
suffix[0] = 0;
else
sprintf(suffix, "%d", i);
std::string new_name = name + suffix;
loaded = &this->filaments.load_preset(this->filaments.path_from_name(new_name),
new_name, std::move(cfg), i == 0);
loaded->save();
this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config);
else
this->filaments.load_preset(this->filaments.path_from_name(name), name, config).save();
this->filament_presets.clear();
this->filament_presets.emplace_back(name);
} else {
// Split the filament presets, load each of them separately.
std::vector<DynamicPrintConfig> configs(num_extruders, this->filaments.default_preset().config);
// loop through options and scatter them into configs.
for (const t_config_option_key &key : this->filaments.default_preset().config.keys()) {
const ConfigOption *other_opt = config.option(key);
if (other_opt == nullptr)
continue;
if (other_opt->is_scalar()) {
for (size_t i = 0; i < configs.size(); ++ i)
configs[i].option(key, false)->set(other_opt);
} else if (key != "compatible_printers") {
for (size_t i = 0; i < configs.size(); ++ i)
static_cast<ConfigOptionVectorBase*>(configs[i].option(key, false))->set_at(other_opt, 0, i);
}
}
// Load the configs into this->filaments and make them active.
this->filament_presets.clear();
for (size_t i = 0; i < configs.size(); ++ i) {
DynamicPrintConfig &cfg = configs[i];
// Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets.
cfg.opt_string("compatible_printers_condition", true) = compatible_printers_condition_values[i + 1];
cfg.opt_string("inherits", true) = inherits_values[i + 1];
// Load all filament presets, but only select the first one in the preset dialog.
Preset *loaded = nullptr;
if (is_external)
loaded = &this->filaments.load_external_preset(name_or_path, name,
(i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "",
std::move(cfg), i == 0);
else {
// Used by the config wizard when creating a custom setup.
// Therefore this block should only be called for a single extruder.
char suffix[64];
if (i == 0)
suffix[0] = 0;
else
sprintf(suffix, "%d", i);
std::string new_name = name + suffix;
loaded = &this->filaments.load_preset(this->filaments.path_from_name(new_name),
new_name, std::move(cfg), i == 0);
loaded->save();
}
this->filament_presets.emplace_back(loaded->name);
}
this->filament_presets.emplace_back(loaded->name);
}
}
// 4) Load the project config values (the per extruder wipe matrix etc).
this->project_config.apply_only(config, s_project_options);
// 4) Load the project config values (the per extruder wipe matrix etc).
this->project_config.apply_only(config, s_project_options);
}
this->update_compatible_with_printer(false);
}
@ -691,9 +787,10 @@ void PresetBundle::load_config_file_config_bundle(const std::string &path, const
collection_dst.load_preset(path, preset_name_dst, std::move(preset_src->config), activate).is_external = true;
return preset_name_dst;
};
load_one(this->prints, tmp_bundle.prints, tmp_bundle.prints .get_selected_preset().name, true);
load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filaments.get_selected_preset().name, true);
load_one(this->printers, tmp_bundle.printers, tmp_bundle.printers .get_selected_preset().name, true);
load_one(this->prints, tmp_bundle.prints, tmp_bundle.prints .get_selected_preset().name, true);
load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filaments .get_selected_preset().name, true);
load_one(this->sla_materials, tmp_bundle.sla_materials, tmp_bundle.sla_materials.get_selected_preset().name, true);
load_one(this->printers, tmp_bundle.printers, tmp_bundle.printers .get_selected_preset().name, true);
this->update_multi_material_filament_presets();
for (size_t i = 1; i < std::min(tmp_bundle.filament_presets.size(), this->filament_presets.size()); ++ i)
this->filament_presets[i] = load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filament_presets[i], false);
@ -817,6 +914,7 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree)
{
flatten_configbundle_hierarchy(tree, "print");
flatten_configbundle_hierarchy(tree, "filament");
flatten_configbundle_hierarchy(tree, "sla_material");
flatten_configbundle_hierarchy(tree, "printer");
}
@ -853,9 +951,11 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
// Parse the obsolete preset names, to be deleted when upgrading from the old configuration structure.
std::vector<std::string> loaded_prints;
std::vector<std::string> loaded_filaments;
std::vector<std::string> loaded_sla_materials;
std::vector<std::string> loaded_printers;
std::string active_print;
std::vector<std::string> active_filaments;
std::string active_sla_material;
std::string active_printer;
size_t presets_loaded = 0;
for (const auto &section : tree) {
@ -870,6 +970,10 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
presets = &this->filaments;
loaded = &loaded_filaments;
preset_name = section.first.substr(9);
} else if (boost::starts_with(section.first, "sla_material:")) {
presets = &this->sla_materials;
loaded = &loaded_sla_materials;
preset_name = section.first.substr(9);
} else if (boost::starts_with(section.first, "printer:")) {
presets = &this->printers;
loaded = &loaded_printers;
@ -886,6 +990,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
active_filaments.resize(idx + 1, std::string());
active_filaments[idx] = kvp.second.data();
}
} else if (kvp.first == "sla_material") {
active_sla_material = kvp.second.data();
} else if (kvp.first == "printer") {
active_printer = kvp.second.data();
}
@ -899,6 +1005,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
dst = &this->obsolete_presets.prints;
else if (kvp.first == "filament")
dst = &this->obsolete_presets.filaments;
else if (kvp.first == "sla_material")
dst = &this->obsolete_presets.sla_materials;
else if (kvp.first == "printer")
dst = &this->obsolete_presets.printers;
if (dst)
@ -999,6 +1107,8 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
if ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) {
if (! active_print.empty())
prints.select_preset_by_name(active_print, true);
if (! active_sla_material.empty())
sla_materials.select_preset_by_name(active_sla_material, true);
if (! active_printer.empty())
printers.select_preset_by_name(active_printer, true);
// Activate the first filament preset.
@ -1015,6 +1125,9 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
void PresetBundle::update_multi_material_filament_presets()
{
if (printers.get_edited_preset().printer_technology() != ptFFF)
return;
// Verify and select the filament presets.
auto *nozzle_diameter = static_cast<const ConfigOptionFloats*>(printers.get_edited_preset().config.option("nozzle_diameter"));
size_t num_extruders = nozzle_diameter->values.size();
@ -1055,36 +1168,51 @@ void PresetBundle::update_multi_material_filament_presets()
void PresetBundle::update_compatible_with_printer(bool select_other_if_incompatible)
{
const Preset &printer_preset = this->printers.get_edited_preset();
const std::string &prefered_print_profile = printer_preset.config.opt_string("default_print_profile");
const std::vector<std::string> &prefered_filament_profiles = printer_preset.config.option<ConfigOptionStrings>("default_filament_profile")->values;
prefered_print_profile.empty() ?
this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
[&prefered_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; });
prefered_filament_profiles.empty() ?
this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
[&prefered_filament_profiles](const std::string& profile_name)
{ return std::find(prefered_filament_profiles.begin(), prefered_filament_profiles.end(), profile_name) != prefered_filament_profiles.end(); });
if (select_other_if_incompatible) {
// Verify validity of the current filament presets.
this->filament_presets.front() = this->filaments.get_edited_preset().name;
for (size_t idx = 1; idx < this->filament_presets.size(); ++ idx) {
std::string &filament_name = this->filament_presets[idx];
Preset *preset = this->filaments.find_preset(filament_name, false);
if (preset == nullptr || ! preset->is_compatible) {
// Pick a compatible profile. If there are prefered_filament_profiles, use them.
if (prefered_filament_profiles.empty())
filament_name = this->filaments.first_compatible().name;
else {
const std::string &preferred = (idx < prefered_filament_profiles.size()) ?
prefered_filament_profiles[idx] : prefered_filament_profiles.front();
filament_name = this->filaments.first_compatible(
[&preferred](const std::string& profile_name){ return profile_name == preferred; }).name;
switch (printers.get_edited_preset().printer_technology()) {
case ptFFF:
{
const std::string &prefered_print_profile = printer_preset.config.opt_string("default_print_profile");
const std::vector<std::string> &prefered_filament_profiles = printer_preset.config.option<ConfigOptionStrings>("default_filament_profile")->values;
prefered_print_profile.empty() ?
this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
[&prefered_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; });
prefered_filament_profiles.empty() ?
this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
[&prefered_filament_profiles](const std::string& profile_name)
{ return std::find(prefered_filament_profiles.begin(), prefered_filament_profiles.end(), profile_name) != prefered_filament_profiles.end(); });
if (select_other_if_incompatible) {
// Verify validity of the current filament presets.
this->filament_presets.front() = this->filaments.get_edited_preset().name;
for (size_t idx = 1; idx < this->filament_presets.size(); ++ idx) {
std::string &filament_name = this->filament_presets[idx];
Preset *preset = this->filaments.find_preset(filament_name, false);
if (preset == nullptr || ! preset->is_compatible) {
// Pick a compatible profile. If there are prefered_filament_profiles, use them.
if (prefered_filament_profiles.empty())
filament_name = this->filaments.first_compatible().name;
else {
const std::string &preferred = (idx < prefered_filament_profiles.size()) ?
prefered_filament_profiles[idx] : prefered_filament_profiles.front();
filament_name = this->filaments.first_compatible(
[&preferred](const std::string& profile_name){ return profile_name == preferred; }).name;
}
}
}
}
}
case ptSLA:
{
const std::string &prefered_print_profile = printer_preset.config.opt_string("default_print_profile");
const std::vector<std::string> &prefered_filament_profiles = printer_preset.config.option<ConfigOptionStrings>("default_filament_profile")->values;
prefered_print_profile.empty() ?
this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
[&prefered_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; });
}
}
}
void PresetBundle::export_configbundle(const std::string &path) //, const DynamicPrintConfig &settings
@ -1111,6 +1239,7 @@ void PresetBundle::export_configbundle(const std::string &path) //, const Dynami
// Export the names of the active presets.
c << std::endl << "[presets]" << std::endl;
c << "print = " << this->prints.get_selected_preset().name << std::endl;
c << "sla_material = " << this->sla_materials.get_selected_preset().name << std::endl;
c << "printer = " << this->printers.get_selected_preset().name << std::endl;
for (size_t i = 0; i < this->filament_presets.size(); ++ i) {
char suffix[64];
@ -1170,7 +1299,7 @@ bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out
void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitmapComboBox *ui)
{
if (ui == nullptr)
if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA)
return;
unsigned char rgb[3];
@ -1265,6 +1394,7 @@ void PresetBundle::set_default_suppressed(bool default_suppressed)
{
prints.set_default_suppressed(default_suppressed);
filaments.set_default_suppressed(default_suppressed);
sla_materials.set_default_suppressed(default_suppressed);
printers.set_default_suppressed(default_suppressed);
}

View File

@ -40,6 +40,7 @@ public:
PresetCollection prints;
PresetCollection filaments;
PresetCollection sla_materials;
PresetCollection printers;
// Filament preset names for a multi-extruder or multi-material print.
// extruders.size() should be the same as printers.get_edited_preset().config.nozzle_diameter.size()
@ -57,12 +58,13 @@ public:
struct ObsoletePresets {
std::vector<std::string> prints;
std::vector<std::string> filaments;
std::vector<std::string> sla_materials;
std::vector<std::string> printers;
};
ObsoletePresets obsolete_presets;
bool has_defauls_only() const
{ return prints.size() <= 1 && filaments.size() <= 1 && printers.size() <= 1; }
{ return prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); }
DynamicPrintConfig full_config() const;
@ -146,6 +148,9 @@ private:
void load_config_file_config_bundle(const std::string &path, const boost::property_tree::ptree &tree);
bool load_compatible_bitmaps();
DynamicPrintConfig full_fff_config() const;
DynamicPrintConfig full_sla_config() const;
// Indicator, that the preset is compatible with the selected printer.
wxBitmap *m_bitmapCompatible;
// Indicator, that the preset is NOT compatible with the selected printer.

View File

@ -214,7 +214,7 @@ void Tab::load_initial_data()
m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns;
}
PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages/* = false*/)
Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages /*= false*/)
{
// Index of icon in an icon list $self->{icons}.
auto icon_idx = 0;
@ -238,7 +238,8 @@ PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bo
page->SetScrollbars(1, 1, 1, 1);
page->Hide();
m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5);
if (!is_extruder_pages)
if (!is_extruder_pages)
m_pages.push_back(page);
page->set_config(m_config);
@ -313,10 +314,10 @@ void Tab::update_changed_ui()
if (m_postpone_update_ui)
return;
const bool is_printer_type = (name() == "printer");
auto dirty_options = m_presets->current_dirty_options(is_printer_type);
auto nonsys_options = m_presets->current_different_from_parent_options(is_printer_type);
if (is_printer_type){
const bool deep_compare = (m_name == "printer" || m_name == "sla_material");
auto dirty_options = m_presets->current_dirty_options(deep_compare);
auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare);
if (name() == "printer"){
TabPrinter* tab = static_cast<TabPrinter*>(this);
if (tab->m_initial_extruders_count != tab->m_extruders_count)
dirty_options.emplace_back("extruders_count");
@ -397,7 +398,7 @@ void Tab::init_options_list()
}
template<class T>
void add_correct_opts_to_options_list(const std::string &opt_key, std::map<std::string, int>& map, TabPrinter *tab, const int& value)
void add_correct_opts_to_options_list(const std::string &opt_key, std::map<std::string, int>& map, Tab *tab, const int& value)
{
T *opt_cur = static_cast<T*>(tab->m_config->option(opt_key));
for (int i = 0; i < opt_cur->values.size(); i++)
@ -429,6 +430,30 @@ void TabPrinter::init_options_list()
m_options_list.emplace("extruders_count", m_opt_status_value);
}
void TabSLAMaterial::init_options_list()
{
if (!m_options_list.empty())
m_options_list.clear();
for (const auto opt_key : m_config->keys())
{
if (opt_key == "compatible_printers"){
m_options_list.emplace(opt_key, m_opt_status_value);
continue;
}
switch (m_config->option(opt_key)->type())
{
case coInts: add_correct_opts_to_options_list<ConfigOptionInts >(opt_key, m_options_list, this, m_opt_status_value); break;
case coBools: add_correct_opts_to_options_list<ConfigOptionBools >(opt_key, m_options_list, this, m_opt_status_value); break;
case coFloats: add_correct_opts_to_options_list<ConfigOptionFloats >(opt_key, m_options_list, this, m_opt_status_value); break;
case coStrings: add_correct_opts_to_options_list<ConfigOptionStrings >(opt_key, m_options_list, this, m_opt_status_value); break;
case coPercents:add_correct_opts_to_options_list<ConfigOptionPercents >(opt_key, m_options_list, this, m_opt_status_value); break;
case coPoints: add_correct_opts_to_options_list<ConfigOptionPoints >(opt_key, m_options_list, this, m_opt_status_value); break;
default: m_options_list.emplace(opt_key, m_opt_status_value); break;
}
}
}
void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page)
{
auto opt = m_options_list.find(opt_key);
@ -649,6 +674,15 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
int val = boost::any_cast<size_t>(value);
event.SetInt(val);
}
if (opt_key == "printer_technology")
{
int val = boost::any_cast<PrinterTechnology>(value);
event.SetInt(val);
g_wxMainFrame->ProcessWindowEvent(event);
return;
}
g_wxMainFrame->ProcessWindowEvent(event);
}
if (opt_key == "fill_density")
@ -677,9 +711,10 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
update();
}
// Show/hide the 'purging volumes' button
void Tab::update_wiping_button_visibility() {
if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
bool wipe_tower_enabled = dynamic_cast<ConfigOptionBool*>( (m_preset_bundle->prints.get_edited_preset().config ).option("wipe_tower"))->value;
bool multiple_extruders = dynamic_cast<ConfigOptionFloats*>((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1;
bool single_extruder_mm = dynamic_cast<ConfigOptionBool*>( (m_preset_bundle->printers.get_edited_preset().config).option("single_extruder_multi_material"))->value;
@ -1007,6 +1042,9 @@ void TabPrint::reload_config(){
void TabPrint::update()
{
if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
Freeze();
double fill_density = m_config->option<ConfigOptionPercent>("fill_density")->value;
@ -1366,6 +1404,9 @@ void TabFilament::reload_config(){
void TabFilament::update()
{
if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA)
return; // ys_FIXME
Freeze();
wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset()));
m_cooling_description_line->SetText(text);
@ -1411,6 +1452,17 @@ void TabPrinter::build()
m_presets = &m_preset_bundle->printers;
load_initial_data();
m_printer_technology = m_presets->get_selected_preset().printer_technology();
m_presets->get_selected_preset().printer_technology() == ptSLA ? build_sla() : build_fff();
// on_value_change("printer_technology", m_printer_technology); // to update show/hide preset ComboBoxes
}
void TabPrinter::build_fff()
{
if (!m_pages.empty())
m_pages.resize(0);
// to avoid redundant memory allocation / deallocation during extruders count changing
m_pages.reserve(30);
@ -1697,6 +1749,76 @@ void TabPrinter::build()
update_serial_ports();
}
void TabPrinter::build_sla()
{
if (!m_pages.empty())
m_pages.resize(0);
auto page = add_options_page(_(L("General")), "printer_empty.png");
auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
Line line{ _(L("Bed shape")), "" };
line.widget = [this](wxWindow* parent){
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
// btn->SetFont(Slic3r::GUI::small_font);
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e)
{
auto dlg = new BedShapeDialog(this);
dlg->build_dialog(m_config->option<ConfigOptionPoints>("bed_shape"));
if (dlg->ShowModal() == wxID_OK){
load_key_value("bed_shape", dlg->GetValue());
update_changed_ui();
}
}));
return sizer;
};
optgroup->append_line(line, &m_colored_Label);
optgroup->append_single_option_line("max_print_height");
optgroup = page->new_optgroup(_(L("Display")));
optgroup->append_single_option_line("display_width");
optgroup->append_single_option_line("display_height");
auto option = optgroup->get_option("display_pixels_x");
line = { _(option.opt.full_label), "" };
line.append_option(option);
line.append_option(optgroup->get_option("display_pixels_y"));
optgroup->append_line(line);
optgroup = page->new_optgroup(_(L("Corrections")));
line = Line{ m_config->def()->get("printer_correction")->full_label, "" };
std::vector<std::string> axes{ "X", "Y", "Z" };
int id = 0;
for (auto& axis : axes) {
auto opt = optgroup->get_option("printer_correction", id);
opt.opt.label = axis;
line.append_option(opt);
++id;
}
optgroup->append_line(line);
page = add_options_page(_(L("Notes")), "note.png");
optgroup = page->new_optgroup(_(L("Notes")), 0);
option = optgroup->get_option("printer_notes");
option.opt.full_width = true;
option.opt.height = 250;
optgroup->append_single_option_line(option);
page = add_options_page(_(L("Dependencies")), "wrench.png");
optgroup = page->new_optgroup(_(L("Profile dependencies")));
line = Line{ "", "" };
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
return description_line_widget(parent, &m_parent_preset_description_line);
};
optgroup->append_line(line);
}
void TabPrinter::update_serial_ports(){
Field *field = get_field("serial_port");
Choice *choice = static_cast<Choice *>(field);
@ -1888,7 +2010,38 @@ void TabPrinter::on_preset_loaded()
extruders_count_changed(extruders_count);
}
void TabPrinter::update(){
void TabPrinter::update_pages()
{
// update m_pages ONLY if printer technology is changed
if (m_presets->get_edited_preset().printer_technology() == m_printer_technology)
return;
// hide all old pages
for (auto& el : m_pages)
el.get()->Hide();
// set m_pages to m_pages_(technology before changing)
m_printer_technology == ptFFF ? m_pages.swap(m_pages_fff) : m_pages.swap(m_pages_sla);
// build Tab according to the technology, if it's not exist jet OR
// set m_pages_(technology after changing) to m_pages
if (m_presets->get_edited_preset().printer_technology() == ptFFF)
m_pages_fff.empty() ? build_fff() : m_pages.swap(m_pages_fff);
else
m_pages_sla.empty() ? build_sla() : m_pages.swap(m_pages_sla);
rebuild_page_tree(true);
on_value_change("printer_technology", m_presets->get_edited_preset().printer_technology()); // to update show/hide preset ComboBoxes
}
void TabPrinter::update()
{
m_presets->get_edited_preset().printer_technology() == ptFFF ? update_fff() : update_sla();
}
void TabPrinter::update_fff()
{
Freeze();
bool en;
@ -1991,20 +2144,25 @@ void TabPrinter::update(){
Thaw();
}
void TabPrinter::update_sla(){ ; }
// Initialize the UI from the current preset
void Tab::load_current_preset()
{
auto preset = m_presets->get_edited_preset();
(preset.is_default || preset.is_system) ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true);
update();
// For the printer profile, generate the extruder pages.
on_preset_loaded();
// Reload preset pages with the new configuration values.
reload_config();
update();
// For the printer profile, generate the extruder pages.
if (preset.printer_technology() == ptFFF)
on_preset_loaded();
// Reload preset pages with the new configuration values.
reload_config();
m_bmp_non_system = m_presets->get_selected_preset_parent() ? &m_bmp_value_unlock : &m_bmp_white_bullet;
m_ttg_non_system = m_presets->get_selected_preset_parent() ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns;
m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns;
m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns;
m_undo_to_sys_btn->Enable(!preset.is_default);
@ -2016,7 +2174,28 @@ void Tab::load_current_preset()
// checking out if this Tab exists till this moment
if (!checked_tab(this))
return;
update_tab_ui();
update_tab_ui();
// update show/hide tabs
if (m_name == "printer"){
PrinterTechnology& printer_technology = m_presets->get_edited_preset().printer_technology();
if (printer_technology != static_cast<TabPrinter*>(this)->m_printer_technology)
{
for (auto& tab : get_preset_tabs()){
if (tab.technology != printer_technology)
{
int page_id = get_tab_panel()->FindPage(tab.panel);
get_tab_panel()->GetPage(page_id)->Show(false);
get_tab_panel()->RemovePage(page_id);
}
else
get_tab_panel()->InsertPage(get_tab_panel()->FindPage(this), tab.panel, tab.panel->title());
}
static_cast<TabPrinter*>(this)->m_printer_technology = printer_technology;
}
}
on_presets_changed();
if (name() == "print")
@ -2034,7 +2213,7 @@ void Tab::load_current_preset()
}
//Regerenerate content of the page tree.
void Tab::rebuild_page_tree()
void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/)
{
Freeze();
// get label of the currently selected item
@ -2049,9 +2228,9 @@ void Tab::rebuild_page_tree()
m_treectrl->SetItemTextColour(itemId, p->get_item_colour());
if (p->title() == selected) {
if (!(p->title() == _(L("Machine limits")) || p->title() == _(L("Single extruder MM setup")))) // These Pages have to be updated inside OnTreeSelChange
m_disable_tree_sel_changed_event = 1;
m_disable_tree_sel_changed_event = !tree_sel_change_event;
m_treectrl->SelectItem(itemId);
m_disable_tree_sel_changed_event = 0;
m_disable_tree_sel_changed_event = false;
have_selection = 1;
}
}
@ -2066,48 +2245,53 @@ void Tab::rebuild_page_tree()
// Called by the UI combo box when the user switches profiles.
// Select a preset by a name.If !defined(name), then the default preset is selected.
// If the current profile is modified, user is asked to save the changes.
void Tab::select_preset(const std::string& preset_name /*= ""*/)
void Tab::select_preset(std::string preset_name /*= ""*/)
{
std::string name = preset_name;
auto force = false;
auto presets = m_presets;
// If no name is provided, select the "-- default --" preset.
if (name.empty())
name= presets->default_preset().name;
auto current_dirty = presets->current_is_dirty();
auto canceled = false;
auto printer_tab = presets->name().compare("printer")==0;
if (preset_name.empty())
preset_name = m_presets->default_preset().name;
auto current_dirty = m_presets->current_is_dirty();
auto printer_tab = m_presets->name() == "printer";
auto canceled = false;
m_reload_dependent_tabs = {};
if (!force && current_dirty && !may_discard_current_dirty_preset()) {
if (current_dirty && !may_discard_current_dirty_preset()) {
canceled = true;
} else if(printer_tab) {
} else if (printer_tab) {
// Before switching the printer to a new one, verify, whether the currently active print and filament
// are compatible with the new printer.
// If they are not compatible and the current print or filament are dirty, let user decide
// whether to discard the changes or keep the current printer selection.
auto new_printer_preset = presets->find_preset(name, true);
auto print_presets = &m_preset_bundle->prints;
bool print_preset_dirty = print_presets->current_is_dirty();
bool print_preset_compatible = print_presets->get_edited_preset().is_compatible_with_printer(*new_printer_preset);
canceled = !force && print_preset_dirty && !print_preset_compatible &&
!may_discard_current_dirty_preset(print_presets, name);
auto filament_presets = &m_preset_bundle->filaments;
bool filament_preset_dirty = filament_presets->current_is_dirty();
bool filament_preset_compatible = filament_presets->get_edited_preset().is_compatible_with_printer(*new_printer_preset);
if (!canceled && !force) {
canceled = filament_preset_dirty && !filament_preset_compatible &&
!may_discard_current_dirty_preset(filament_presets, name);
//
// With the introduction of the SLA printer types, we need to support switching between
// the FFF and SLA printers.
const Preset &new_printer_preset = *m_presets->find_preset(preset_name, true);
PrinterTechnology old_printer_technology = m_presets->get_edited_preset().printer_technology();
PrinterTechnology new_printer_technology = new_printer_preset.printer_technology();
struct PresetUpdate {
std::string name;
PresetCollection *presets;
PrinterTechnology technology;
bool old_preset_dirty;
bool new_preset_compatible;
};
std::vector<PresetUpdate> updates = {
{ "print", &m_preset_bundle->prints, ptFFF },
{ "filament", &m_preset_bundle->filaments, ptFFF },
{ "sla_material", &m_preset_bundle->sla_materials, ptSLA }
};
for (PresetUpdate &pu : updates) {
pu.old_preset_dirty = (old_printer_technology == pu.technology) && pu.presets->current_is_dirty();
pu.new_preset_compatible = (new_printer_technology == pu.technology) && pu.presets->get_edited_preset().is_compatible_with_printer(new_printer_preset);
if (! canceled)
canceled = pu.old_preset_dirty && ! pu.new_preset_compatible && ! may_discard_current_dirty_preset(pu.presets, preset_name);
}
if (!canceled) {
if (!print_preset_compatible) {
if (! canceled) {
for (PresetUpdate &pu : updates) {
// The preset will be switched to a different, compatible preset, or the '-- default --'.
m_reload_dependent_tabs.push_back("print");
if (print_preset_dirty) print_presets->discard_current_changes();
}
if (!filament_preset_compatible) {
// The preset will be switched to a different, compatible preset, or the '-- default --'.
m_reload_dependent_tabs.push_back("filament");
if (filament_preset_dirty) filament_presets->discard_current_changes();
if (pu.technology == new_printer_technology)
m_reload_dependent_tabs.emplace_back(pu.name);
if (pu.old_preset_dirty)
pu.presets->discard_current_changes();
}
}
}
@ -2116,19 +2300,20 @@ void Tab::select_preset(const std::string& preset_name /*= ""*/)
// Trigger the on_presets_changed event so that we also restore the previous value in the plater selector,
// if this action was initiated from the platter.
on_presets_changed();
}
else {
if (current_dirty) presets->discard_current_changes() ;
presets->select_preset_by_name(name, force);
} else {
if (current_dirty)
m_presets->discard_current_changes() ;
m_presets->select_preset_by_name(preset_name, false);
// Mark the print & filament enabled if they are compatible with the currently selected preset.
// The following method should not discard changes of current print or filament presets on change of a printer profile,
// if they are compatible with the current printer.
if (current_dirty || printer_tab)
m_preset_bundle->update_compatible_with_printer(true);
// Initialize the UI from the current preset.
if (printer_tab)
static_cast<TabPrinter*>(this)->update_pages();
load_current_preset();
}
}
// If the current preset is dirty, the user is asked whether the changes may be discarded.
@ -2770,5 +2955,71 @@ void SavePresetWindow::accept()
}
}
void TabSLAMaterial::build()
{
m_presets = &m_preset_bundle->sla_materials;
load_initial_data();
auto page = add_options_page(_(L("Material")), "package_green.png");
auto optgroup = page->new_optgroup(_(L("Layers")));
optgroup->append_single_option_line("layer_height");
optgroup->append_single_option_line("initial_layer_height");
optgroup = page->new_optgroup(_(L("Exposure")));
optgroup->append_single_option_line("exposure_time");
optgroup->append_single_option_line("initial_exposure_time");
optgroup = page->new_optgroup(_(L("Corrections")));
optgroup->label_width = 190;
std::vector<std::string> corrections = { "material_correction_printing", "material_correction_curing" };
std::vector<std::string> axes{ "X", "Y", "Z" };
for (auto& opt_key : corrections){
auto line = Line{ m_config->def()->get(opt_key)->full_label, "" };
int id = 0;
for (auto& axis : axes) {
auto opt = optgroup->get_option(opt_key, id);
opt.opt.label = axis;
opt.opt.width = 60;
line.append_option(opt);
++id;
}
optgroup->append_line(line);
}
page = add_options_page(_(L("Notes")), "note.png");
optgroup = page->new_optgroup(_(L("Notes")), 0);
optgroup->label_width = 0;
Option option = optgroup->get_option("material_notes");
option.opt.full_width = true;
option.opt.height = 250;
optgroup->append_single_option_line(option);
page = add_options_page(_(L("Dependencies")), "wrench.png");
optgroup = page->new_optgroup(_(L("Profile dependencies")));
auto line = Line { _(L("Compatible printers")), "" };
line.widget = [this](wxWindow* parent){
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
};
optgroup->append_line(line, &m_colored_Label);
option = optgroup->get_option("compatible_printers_condition");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
line = Line{ "", "" };
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
return description_line_widget(parent, &m_parent_preset_description_line);
};
optgroup->append_line(line);
}
void TabSLAMaterial::update()
{
if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptFFF)
return; // ys_FIXME
}
} // GUI
} // Slic3r

View File

@ -218,8 +218,8 @@ public:
void create_preset_tab(PresetBundle *preset_bundle);
void load_current_preset();
void rebuild_page_tree();
void select_preset(const std::string& preset_name = "");
void rebuild_page_tree(bool tree_sel_change_event = false);
void select_preset(std::string preset_name = "");
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = "");
wxSizer* compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn);
@ -319,6 +319,9 @@ class TabPrinter : public Tab
bool m_use_silent_mode = false;
void append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key);
bool m_rebuild_kinematics_page = false;
std::vector<PageShp> m_pages_fff;
std::vector<PageShp> m_pages_sla;
public:
wxButton* m_serial_test_btn;
wxButton* m_print_host_test_btn;
@ -329,12 +332,19 @@ public:
size_t m_initial_extruders_count;
size_t m_sys_extruders_count;
PrinterTechnology m_printer_technology = ptFFF;
TabPrinter() {}
TabPrinter(wxNotebook* parent, bool no_controller) : Tab(parent, _(L("Printer Settings")), "printer", no_controller) {}
~TabPrinter(){}
void build() override;
void update() override;
void build_fff();
void build_sla();
void update() override;
void update_fff();
void update_sla();
void update_pages(); // update m_pages according to printer technology
void update_serial_ports();
void extruders_count_changed(size_t extruders_count);
PageShp build_kinematics_page();
@ -343,6 +353,19 @@ public:
void init_options_list() override;
};
class TabSLAMaterial : public Tab
{
public:
TabSLAMaterial() {}
TabSLAMaterial(wxNotebook* parent, bool no_controller) :
Tab(parent, _(L("SLA Material Settings")), "sla_material", no_controller) {}
~TabSLAMaterial(){}
void build() override;
void update() override;
void init_options_list() override;
};
class SavePresetWindow :public wxDialog
{
public:

View File

@ -447,6 +447,7 @@ void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons
for (const auto &name : bundle.obsolete_presets.prints) { obsolete_remover("print", name); }
for (const auto &name : bundle.obsolete_presets.filaments) { obsolete_remover("filament", name); }
for (const auto &name : bundle.obsolete_presets.filaments) { obsolete_remover("sla_material", name); }
for (const auto &name : bundle.obsolete_presets.printers) { obsolete_remover("printer", name); }
}
}

View File

@ -32,7 +32,6 @@
%name{Slic3r::GUI::PresetCollection} class PresetCollection {
Ref<Preset> preset(size_t idx) %code%{ RETVAL = &THIS->preset(idx); %};
Ref<Preset> default_preset() %code%{ RETVAL = &THIS->default_preset(); %};
size_t size() const;
size_t num_visible() const;
std::string name() const;
@ -133,6 +132,7 @@ PresetCollection::arrayref()
Ref<PresetCollection> print() %code%{ RETVAL = &THIS->prints; %};
Ref<PresetCollection> filament() %code%{ RETVAL = &THIS->filaments; %};
Ref<PresetCollection> sla_material() %code%{ RETVAL = &THIS->sla_materials; %};
Ref<PresetCollection> printer() %code%{ RETVAL = &THIS->printers; %};
Ref<DynamicPrintConfig> project_config() %code%{ RETVAL = &THIS->project_config; %};