Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Slic3r/GUI.pm34
-rw-r--r--lib/Slic3r/GUI/MainFrame.pm38
-rw-r--r--resources/icons/printers/BarBaz_M1.pngbin0 -> 10369 bytes
-rw-r--r--resources/icons/printers/BarBaz_M2.pngbin0 -> 10369 bytes
-rw-r--r--resources/icons/printers/BarBaz_M3.pngbin0 -> 10369 bytes
-rw-r--r--resources/icons/printers/Foobar_M1.pngbin0 -> 9323 bytes
-rw-r--r--resources/icons/printers/Foobar_M2.pngbin0 -> 9323 bytes
-rw-r--r--resources/icons/printers/Foobar_M3.pngbin0 -> 9323 bytes
-rw-r--r--resources/icons/printers/PrusaResearch_MK2S.pngbin0 -> 58794 bytes
-rw-r--r--resources/icons/printers/PrusaResearch_MK2SMM.pngbin0 -> 57081 bytes
-rw-r--r--resources/icons/printers/PrusaResearch_MK3.pngbin0 -> 64194 bytes
-rw-r--r--resources/profiles/BarBaz.ini985
-rw-r--r--resources/profiles/Foobar.ini985
-rw-r--r--resources/profiles/PrusaResearch.ini15
-rw-r--r--xs/CMakeLists.txt5
-rw-r--r--xs/src/libslic3r/Config.hpp1
-rw-r--r--xs/src/libslic3r/PrintConfig.cpp2
-rw-r--r--xs/src/libslic3r/Utils.hpp2
-rw-r--r--xs/src/libslic3r/utils.cpp2
-rw-r--r--xs/src/perlglue.cpp1
-rw-r--r--xs/src/slic3r/GUI/2DBed.cpp32
-rw-r--r--xs/src/slic3r/GUI/AppConfig.cpp81
-rw-r--r--xs/src/slic3r/GUI/AppConfig.hpp13
-rw-r--r--xs/src/slic3r/GUI/ConfigWizard.cpp720
-rw-r--r--xs/src/slic3r/GUI/ConfigWizard.hpp38
-rw-r--r--xs/src/slic3r/GUI/ConfigWizard_private.hpp213
-rw-r--r--xs/src/slic3r/GUI/GUI.cpp16
-rw-r--r--xs/src/slic3r/GUI/GUI.hpp6
-rw-r--r--xs/src/slic3r/GUI/Preferences.cpp1
-rw-r--r--xs/src/slic3r/GUI/Preset.cpp10
-rw-r--r--xs/src/slic3r/GUI/Preset.hpp26
-rw-r--r--xs/src/slic3r/GUI/PresetBundle.cpp43
-rw-r--r--xs/src/slic3r/GUI/PresetBundle.hpp3
-rw-r--r--xs/src/slic3r/Utils/PresetUpdater.cpp137
-rw-r--r--xs/src/slic3r/Utils/PresetUpdater.hpp30
-rw-r--r--xs/xsp/GUI.xsp6
-rw-r--r--xs/xsp/GUI_AppConfig.xsp1
-rw-r--r--xs/xsp/GUI_Preset.xsp2
-rw-r--r--xs/xsp/Utils_PresetUpdater.xsp11
-rw-r--r--xs/xsp/my.map4
40 files changed, 3378 insertions, 85 deletions
diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm
index 88e4745d1..bb56fa886 100644
--- a/lib/Slic3r/GUI.pm
+++ b/lib/Slic3r/GUI.pm
@@ -69,6 +69,8 @@ our $grey = Wx::Colour->new(200,200,200);
our $LANGUAGE_CHANGE_EVENT = Wx::NewEventType;
# 2) To inform about a change of Preferences.
our $PREFERENCES_EVENT = Wx::NewEventType;
+# To inform AppConfig about Slic3r version available online
+our $VERSION_ONLINE_EVENT = Wx::NewEventType;
sub OnInit {
my ($self) = @_;
@@ -100,6 +102,10 @@ sub OnInit {
$self->{app_config}->set('version', $Slic3r::VERSION);
$self->{app_config}->save;
+ # my $version_check = $self->{app_config}->get('version_check');
+ $self->{preset_updater} = Slic3r::PresetUpdater->new($VERSION_ONLINE_EVENT, $self->{app_config});
+ my $slic3r_update = $self->{app_config}->slic3r_update_avail;
+
Slic3r::GUI::set_app_config($self->{app_config});
Slic3r::GUI::load_language();
@@ -110,6 +116,7 @@ sub OnInit {
warn $@ . "\n";
show_error(undef, $@);
}
+ # TODO: check previously downloaded updates
$run_wizard = 1 if $self->{preset_bundle}->has_defauls_only;
Slic3r::GUI::set_preset_bundle($self->{preset_bundle});
@@ -133,14 +140,21 @@ sub OnInit {
$self->{app_config}->save if $self->{app_config}->dirty;
});
- if ($run_wizard) {
- # On OSX the UI was not initialized correctly if the wizard was called
- # before the UI was up and running.
- $self->CallAfter(sub {
+ # On OSX the UI was not initialized correctly if the wizard was called
+ # before the UI was up and running.
+ $self->CallAfter(sub {
+ # XXX: recreate_GUI ???
+ if ($slic3r_update) {
+ # TODO
+ }
+ # XXX: ?
+ if ($run_wizard) {
# Run the config wizard, don't offer the "reset user profile" checkbox.
$self->{mainframe}->config_wizard(1);
- });
- }
+ }
+
+ # $self->{preset_updater}->download($self->{preset_bundle});
+ });
# The following event is emited by the C++ menu implementation of application language change.
EVT_COMMAND($self, -1, $LANGUAGE_CHANGE_EVENT, sub{
@@ -152,6 +166,14 @@ sub OnInit {
$self->update_ui_from_settings;
});
+ # The following event is emited by PresetUpdater (C++)
+ EVT_COMMAND($self, -1, $VERSION_ONLINE_EVENT, sub {
+ my ($self, $event) = @_;
+ my $version = $event->GetString;
+ $self->{app_config}->set('version_online', $version);
+ $self->{app_config}->save;
+ });
+
return 1;
}
diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm
index 31124e432..e5b27d1dc 100644
--- a/lib/Slic3r/GUI/MainFrame.pm
+++ b/lib/Slic3r/GUI/MainFrame.pm
@@ -95,7 +95,7 @@ sub new {
});
$self->update_ui_from_settings;
-
+
return $self;
}
@@ -635,39 +635,9 @@ sub config_wizard {
my ($self, $fresh_start) = @_;
# Exit wizard if there are unsaved changes and the user cancels the action.
return unless $self->check_unsaved_changes;
- # Enumerate the profiles bundled with the Slic3r installation under resources/profiles.
- my $directory = Slic3r::resources_dir() . "/profiles";
- my @profiles = ();
- if (opendir(DIR, Slic3r::encode_path($directory))) {
- while (my $file = readdir(DIR)) {
- if ($file =~ /\.ini$/) {
- $file =~ s/\.ini$//;
- push @profiles, Slic3r::decode_path($file);
- }
- }
- closedir(DIR);
- }
- # Open the wizard.
- if (my $result = Slic3r::GUI::ConfigWizard->new($self, \@profiles, $fresh_start)->run) {
- eval {
- if ($result->{reset_user_profile}) {
- wxTheApp->{preset_bundle}->reset(1);
- }
- if (defined $result->{config}) {
- # Load and save the settings into print, filament and printer presets.
- wxTheApp->{preset_bundle}->load_config('My Settings', $result->{config});
- } else {
- # Wizard returned a name of a preset bundle bundled with the installation. Unpack it.
- wxTheApp->{preset_bundle}->install_vendor_configbundle($directory . '/' . $result->{preset_name} . '.ini');
- # Reset the print / filament / printer selections, so that following line will select some sensible defaults.
- if ($fresh_start) {
- wxTheApp->{app_config}->reset_selections;
- }
- # Reload all presets after the vendor config bundle has been installed.
- wxTheApp->{preset_bundle}->load_presets(wxTheApp->{app_config});
- }
- };
- Slic3r::GUI::catch_error($self) and return;
+
+ # TODO: Offer "reset user profile" ???
+ if (Slic3r::GUI::open_config_wizard(wxTheApp->{preset_bundle})) {
# Load the currently selected preset into the GUI, update the preset selection box.
foreach my $tab (values %{$self->{options_tabs}}) {
$tab->load_current_preset;
diff --git a/resources/icons/printers/BarBaz_M1.png b/resources/icons/printers/BarBaz_M1.png
new file mode 100644
index 000000000..5924cc88b
--- /dev/null
+++ b/resources/icons/printers/BarBaz_M1.png
Binary files differ
diff --git a/resources/icons/printers/BarBaz_M2.png b/resources/icons/printers/BarBaz_M2.png
new file mode 100644
index 000000000..5924cc88b
--- /dev/null
+++ b/resources/icons/printers/BarBaz_M2.png
Binary files differ
diff --git a/resources/icons/printers/BarBaz_M3.png b/resources/icons/printers/BarBaz_M3.png
new file mode 100644
index 000000000..5924cc88b
--- /dev/null
+++ b/resources/icons/printers/BarBaz_M3.png
Binary files differ
diff --git a/resources/icons/printers/Foobar_M1.png b/resources/icons/printers/Foobar_M1.png
new file mode 100644
index 000000000..61a76a63d
--- /dev/null
+++ b/resources/icons/printers/Foobar_M1.png
Binary files differ
diff --git a/resources/icons/printers/Foobar_M2.png b/resources/icons/printers/Foobar_M2.png
new file mode 100644
index 000000000..61a76a63d
--- /dev/null
+++ b/resources/icons/printers/Foobar_M2.png
Binary files differ
diff --git a/resources/icons/printers/Foobar_M3.png b/resources/icons/printers/Foobar_M3.png
new file mode 100644
index 000000000..61a76a63d
--- /dev/null
+++ b/resources/icons/printers/Foobar_M3.png
Binary files differ
diff --git a/resources/icons/printers/PrusaResearch_MK2S.png b/resources/icons/printers/PrusaResearch_MK2S.png
new file mode 100644
index 000000000..925447cf2
--- /dev/null
+++ b/resources/icons/printers/PrusaResearch_MK2S.png
Binary files differ
diff --git a/resources/icons/printers/PrusaResearch_MK2SMM.png b/resources/icons/printers/PrusaResearch_MK2SMM.png
new file mode 100644
index 000000000..d6ff16125
--- /dev/null
+++ b/resources/icons/printers/PrusaResearch_MK2SMM.png
Binary files differ
diff --git a/resources/icons/printers/PrusaResearch_MK3.png b/resources/icons/printers/PrusaResearch_MK3.png
new file mode 100644
index 000000000..5279ba01e
--- /dev/null
+++ b/resources/icons/printers/PrusaResearch_MK3.png
Binary files differ
diff --git a/resources/profiles/BarBaz.ini b/resources/profiles/BarBaz.ini
new file mode 100644
index 000000000..83bb15684
--- /dev/null
+++ b/resources/profiles/BarBaz.ini
@@ -0,0 +1,985 @@
+# Print profiles for the Prusa Research printers.
+
+[vendor]
+# Vendor name will be shown by the Config Wizard.
+name = Bar Baz
+# Configuration version of this file. Config file will only be installed, if the config_version differs.
+# This means, the server may force the Slic3r configuration to be downgraded.
+config_version = 0.1
+# Where to get the updates from?
+config_update_url = https://example.com
+
+# The printer models will be shown by the Configuration Wizard in this order,
+# also the first model installed & the first nozzle installed will be activated after install.
+#TODO: One day we may differentiate variants of the nozzles / hot ends,
+#for example by the melt zone size, or whether the nozzle is hardened.
+[printer_model:M1]
+name = Bar Baz Model 1
+variants = 0.4; 0.25; 0.6
+
+[printer_model:M2]
+name = Bar Baz Model 2
+variants = 0.4; 0.25; 0.6
+
+[printer_model:M3]
+# Printer model name will be shown by the installation wizard.
+name = Bar Baz Model 3
+variants = 0.4; 0.6
+
+# All presets starting with asterisk, for example *common*, are intermediate and they will
+# not make it into the user interface.
+
+# Common print preset, mostly derived from MK2 single material with a 0.4mm nozzle.
+# All other print presets will derive from the *common* print preset.
+[print:*common*]
+avoid_crossing_perimeters = 0
+bridge_acceleration = 1000
+bridge_angle = 0
+bridge_flow_ratio = 0.8
+bridge_speed = 20
+brim_width = 0
+clip_multipart_objects = 1
+compatible_printers =
+complete_objects = 0
+default_acceleration = 1000
+dont_support_bridges = 1
+elefant_foot_compensation = 0
+ensure_vertical_shell_thickness = 1
+external_fill_pattern = rectilinear
+external_perimeters_first = 0
+external_perimeter_extrusion_width = 0.45
+extra_perimeters = 0
+extruder_clearance_height = 20
+extruder_clearance_radius = 20
+extrusion_width = 0.45
+fill_angle = 45
+fill_density = 20%
+fill_pattern = cubic
+first_layer_acceleration = 1000
+first_layer_extrusion_width = 0.42
+first_layer_height = 0.2
+first_layer_speed = 30
+gap_fill_speed = 40
+gcode_comments = 0
+infill_every_layers = 1
+infill_extruder = 1
+infill_extrusion_width = 0.45
+infill_first = 0
+infill_only_where_needed = 0
+infill_overlap = 25%
+interface_shells = 0
+max_print_speed = 100
+max_volumetric_extrusion_rate_slope_negative = 0
+max_volumetric_extrusion_rate_slope_positive = 0
+max_volumetric_speed = 0
+min_skirt_length = 4
+notes =
+overhangs = 0
+only_retract_when_crossing_perimeters = 0
+ooze_prevention = 0
+output_filename_format = [input_filename_base].gcode
+perimeters = 2
+perimeter_extruder = 1
+perimeter_extrusion_width = 0.45
+post_process =
+print_settings_id =
+raft_layers = 0
+resolution = 0
+seam_position = nearest
+skirts = 1
+skirt_distance = 2
+skirt_height = 3
+small_perimeter_speed = 20
+solid_infill_below_area = 0
+solid_infill_every_layers = 0
+solid_infill_extruder = 1
+solid_infill_extrusion_width = 0.45
+spiral_vase = 0
+standby_temperature_delta = -5
+support_material = 0
+support_material_extruder = 0
+support_material_extrusion_width = 0.35
+support_material_interface_extruder = 0
+support_material_angle = 0
+support_material_buildplate_only = 0
+support_material_enforce_layers = 0
+support_material_contact_distance = 0.15
+support_material_interface_contact_loops = 0
+support_material_interface_layers = 2
+support_material_interface_spacing = 0.2
+support_material_interface_speed = 100%
+support_material_pattern = rectilinear
+support_material_spacing = 2
+support_material_speed = 50
+support_material_synchronize_layers = 0
+support_material_threshold = 45
+support_material_with_sheath = 0
+support_material_xy_spacing = 60%
+thin_walls = 0
+top_infill_extrusion_width = 0.45
+top_solid_infill_speed = 40
+travel_speed = 180
+wipe_tower = 0
+wipe_tower_per_color_wipe = 20
+wipe_tower_width = 60
+wipe_tower_x = 180
+wipe_tower_y = 140
+xy_size_compensation = 0
+
+# Print parameters common to a 0.25mm diameter nozzle.
+[print:*0.25nozzle*]
+external_perimeter_extrusion_width = 0.25
+extrusion_width = 0.25
+first_layer_extrusion_width = 0.25
+infill_extrusion_width = 0.25
+perimeter_extrusion_width = 0.25
+solid_infill_extrusion_width = 0.25
+top_infill_extrusion_width = 0.25
+support_material_extrusion_width = 0.18
+support_material_interface_layers = 0
+support_material_interface_spacing = 0.15
+support_material_spacing = 1
+support_material_xy_spacing = 150%
+
+# Print parameters common to a 0.6mm diameter nozzle.
+[print:*0.6nozzle*]
+external_perimeter_extrusion_width = 0.61
+extrusion_width = 0.67
+first_layer_extrusion_width = 0.65
+infill_extrusion_width = 0.7
+perimeter_extrusion_width = 0.65
+solid_infill_extrusion_width = 0.65
+top_infill_extrusion_width = 0.6
+
+[print:*soluble_support*]
+overhangs = 1
+skirts = 0
+support_material = 1
+support_material_contact_distance = 0
+support_material_extruder = 4
+support_material_extrusion_width = 0.45
+support_material_interface_extruder = 4
+support_material_interface_spacing = 0.1
+support_material_synchronize_layers = 1
+support_material_threshold = 80
+support_material_with_sheath = 1
+wipe_tower = 1
+
+[print:*0.05mm*]
+inherits = *common*
+bottom_solid_layers = 10
+bridge_acceleration = 300
+bridge_flow_ratio = 0.7
+default_acceleration = 500
+external_perimeter_speed = 20
+fill_density = 20%
+first_layer_acceleration = 500
+gap_fill_speed = 20
+infill_acceleration = 800
+infill_speed = 30
+max_print_speed = 80
+small_perimeter_speed = 15
+solid_infill_speed = 30
+support_material_extrusion_width = 0.3
+support_material_spacing = 1.5
+layer_height = 0.05
+perimeter_acceleration = 300
+perimeter_speed = 30
+perimeters = 3
+support_material_speed = 30
+top_solid_infill_speed = 20
+top_solid_layers = 15
+
+[print:0.05mm ULTRADETAIL]
+inherits = *0.05mm*
+infill_extrusion_width = 0.5
+
+[print:0.05mm ULTRADETAIL MK3]
+inherits = *0.05mm*
+fill_pattern = grid
+top_infill_extrusion_width = 0.4
+
+[print:0.05mm ULTRADETAIL 0.25 nozzle]
+inherits = *0.05mm*
+external_perimeter_extrusion_width = 0
+extrusion_width = 0.28
+fill_density = 20%
+first_layer_extrusion_width = 0.3
+infill_extrusion_width = 0
+infill_speed = 20
+max_print_speed = 100
+perimeter_extrusion_width = 0
+perimeter_speed = 20
+small_perimeter_speed = 10
+solid_infill_extrusion_width = 0
+solid_infill_speed = 20
+support_material_speed = 20
+top_infill_extrusion_width = 0
+
+[print:0.05mm ULTRADETAIL 0.25 nozzle MK3]
+inherits = *0.05mm*; *0.25nozzle*
+fill_pattern = grid
+top_infill_extrusion_width = 0.4
+
+[print:*0.10mm*]
+inherits = *common*
+bottom_solid_layers = 7
+bridge_flow_ratio = 0.7
+layer_height = 0.1
+perimeter_acceleration = 800
+top_solid_layers = 9
+
+[print:0.10mm DETAIL]
+inherits = *0.10mm*
+external_perimeter_speed = 40
+infill_acceleration = 2000
+infill_speed = 60
+perimeter_speed = 50
+solid_infill_speed = 50
+
+[print:0.10mm DETAIL MK3]
+inherits = *0.10mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 200
+perimeter_speed = 45
+solid_infill_speed = 170
+top_infill_extrusion_width = 0.4
+top_solid_infill_speed = 50
+
+[print:0.10mm DETAIL 0.25 nozzle]
+inherits = *0.10mm*
+bridge_acceleration = 600
+external_perimeter_speed = 20
+infill_acceleration = 1600
+infill_speed = 40
+perimeter_acceleration = 600
+perimeter_speed = 25
+small_perimeter_speed = 10
+solid_infill_speed = 40
+top_solid_infill_speed = 30
+
+[print:0.10mm DETAIL 0.25 nozzle MK3]
+inherits = *0.10mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 200
+perimeter_speed = 45
+solid_infill_speed = 170
+top_infill_extrusion_width = 0.4
+top_solid_infill_speed = 50
+
+[print:0.10mm DETAIL 0.6 nozzle MK3]
+inherits = *0.10mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 200
+perimeter_speed = 45
+solid_infill_speed = 170
+top_infill_extrusion_width = 0.4
+top_solid_infill_speed = 50
+
+[print:*0.15mm*]
+inherits = *common*
+bottom_solid_layers = 5
+external_perimeter_speed = 40
+infill_acceleration = 2000
+infill_speed = 60
+layer_height = 0.15
+perimeter_acceleration = 800
+perimeter_speed = 50
+solid_infill_speed = 50
+top_infill_extrusion_width = 0.4
+top_solid_layers = 7
+
+[print:0.15mm 100mms Linear Advance]
+inherits = *0.15mm*
+bridge_flow_ratio = 0.95
+external_perimeter_speed = 50
+infill_speed = 100
+max_print_speed = 150
+perimeter_speed = 60
+small_perimeter_speed = 30
+solid_infill_speed = 100
+support_material_speed = 60
+top_solid_infill_speed = 70
+
+[print:0.15mm OPTIMAL]
+inherits = *0.15mm*
+top_infill_extrusion_width = 0.45
+
+[print:0.15mm OPTIMAL 0.25 nozzle]
+inherits = *0.15mm*; *0.25nozzle*
+bridge_acceleration = 600
+bridge_flow_ratio = 0.7
+external_perimeter_speed = 20
+infill_acceleration = 1600
+infill_speed = 40
+perimeter_acceleration = 600
+perimeter_speed = 25
+small_perimeter_speed = 10
+solid_infill_speed = 40
+support_material_extrusion_width = 0.2
+top_solid_infill_speed = 30
+
+[print:0.15mm OPTIMAL 0.6 nozzle]
+inherits = *0.15mm*; *0.6nozzle*
+
+[print:0.15mm OPTIMAL MK3]
+inherits = *0.15mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+
+[print:0.15mm OPTIMAL SOLUBLE FULL]
+inherits = *0.15mm*; *soluble_support*
+external_perimeter_speed = 25
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder
+perimeter_speed = 40
+solid_infill_speed = 40
+top_infill_extrusion_width = 0.45
+top_solid_infill_speed = 30
+wipe_tower = 1
+
+[print:0.15mm OPTIMAL SOLUBLE INTERFACE]
+inherits = 0.15mm OPTIMAL SOLUBLE FULL
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft interface extruder
+support_material_extruder = 0
+support_material_interface_layers = 3
+support_material_with_sheath = 0
+support_material_xy_spacing = 80%
+
+[print:0.15mm OPTIMAL 0.25 nozzle MK3]
+inherits = *0.15mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+[print:*0.20mm*]
+inherits = *common*
+bottom_solid_layers = 4
+bridge_flow_ratio = 0.95
+external_perimeter_speed = 40
+infill_acceleration = 2000
+infill_speed = 60
+layer_height = 0.2
+perimeter_acceleration = 800
+perimeter_speed = 50
+solid_infill_speed = 50
+top_infill_extrusion_width = 0.4
+top_solid_layers = 5
+
+[print:0.15mm OPTIMAL 0.6 nozzle MK3]
+inherits = *0.15mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+
+[print:0.20mm 100mms Linear Advance]
+inherits = *0.20mm*
+external_perimeter_speed = 50
+infill_speed = 100
+max_print_speed = 150
+perimeter_speed = 60
+small_perimeter_speed = 30
+solid_infill_speed = 100
+support_material_speed = 60
+top_solid_infill_speed = 70
+
+[print:0.20mm FAST MK3]
+inherits = *0.20mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+
+[print:0.20mm NORMAL]
+inherits = *0.20mm*
+
+[print:0.20mm NORMAL 0.6 nozzle]
+inherits = *0.20mm*; *0.6nozzle*
+
+[print:0.20mm NORMAL SOLUBLE FULL]
+inherits = *0.20mm*; *soluble_support*
+external_perimeter_speed = 30
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder
+perimeter_speed = 40
+solid_infill_speed = 40
+top_solid_infill_speed = 30
+
+[print:0.20mm NORMAL SOLUBLE INTERFACE]
+inherits = 0.20mm NORMAL SOLUBLE FULL
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft interface extruder
+support_material_extruder = 0
+support_material_interface_layers = 3
+support_material_with_sheath = 0
+support_material_xy_spacing = 80%
+
+[print:0.20mm FAST 0.6 nozzle MK3]
+inherits = *0.20mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+
+[print:*0.35mm*]
+inherits = *common*
+bottom_solid_layers = 3
+external_perimeter_extrusion_width = 0.6
+external_perimeter_speed = 40
+first_layer_extrusion_width = 0.75
+infill_acceleration = 2000
+infill_speed = 60
+layer_height = 0.35
+perimeter_acceleration = 800
+perimeter_extrusion_width = 0.65
+perimeter_speed = 50
+solid_infill_extrusion_width = 0.65
+solid_infill_speed = 60
+top_solid_infill_speed = 50
+top_solid_layers = 4
+
+[print:0.35mm FAST]
+inherits = *0.35mm*
+bridge_flow_ratio = 0.95
+first_layer_extrusion_width = 0.42
+perimeter_extrusion_width = 0.43
+solid_infill_extrusion_width = 0.7
+top_infill_extrusion_width = 0.43
+
+[print:0.35mm FAST 0.6 nozzle]
+inherits = *0.35mm*; *0.6nozzle*
+
+[print:0.35mm FAST sol full 0.6 nozzle]
+inherits = *0.35mm*; *0.6nozzle*; *soluble_support*
+external_perimeter_extrusion_width = 0.6
+external_perimeter_speed = 30
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft interface extruder
+perimeter_speed = 40
+support_material_extrusion_width = 0.55
+support_material_interface_layers = 3
+support_material_xy_spacing = 120%
+top_infill_extrusion_width = 0.57
+
+[print:0.35mm FAST sol int 0.6 nozzle]
+inherits = 0.35mm FAST sol full 0.6 nozzle
+support_material_extruder = 0
+support_material_interface_layers = 2
+support_material_with_sheath = 0
+support_material_xy_spacing = 150%
+
+[filament:*common*]
+cooling = 1
+compatible_printers =
+end_filament_gcode = "; Filament-specific end gcode"
+extrusion_multiplier = 1
+filament_cost = 0
+filament_density = 0
+filament_diameter = 1.75
+filament_notes = ""
+filament_settings_id =
+filament_soluble = 0
+min_print_speed = 5
+slowdown_below_layer_time = 20
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
+
+[filament:*PLA*]
+inherits = *common*
+bed_temperature = 60
+bridge_fan_speed = 100
+disable_fan_first_layers = 1
+fan_always_on = 1
+fan_below_layer_time = 100
+filament_colour = #FF3232
+filament_max_volumetric_speed = 15
+filament_type = PLA
+first_layer_bed_temperature = 60
+first_layer_temperature = 215
+max_fan_speed = 100
+min_fan_speed = 100
+temperature = 210
+
+[filament:*PET*]
+inherits = *common*
+bed_temperature = 90
+bridge_fan_speed = 50
+disable_fan_first_layers = 3
+fan_always_on = 1
+fan_below_layer_time = 20
+filament_colour = #FF8000
+filament_max_volumetric_speed = 8
+filament_type = PET
+first_layer_bed_temperature = 85
+first_layer_temperature = 230
+max_fan_speed = 50
+min_fan_speed = 30
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode"
+temperature = 240
+
+[filament:*ABS*]
+inherits = *common*
+bed_temperature = 110
+bridge_fan_speed = 30
+cooling = 0
+disable_fan_first_layers = 3
+fan_always_on = 0
+fan_below_layer_time = 20
+filament_colour = #3A80CA
+filament_max_volumetric_speed = 11
+filament_type = ABS
+first_layer_bed_temperature = 100
+first_layer_temperature = 255
+max_fan_speed = 30
+min_fan_speed = 20
+temperature = 255
+
+[filament:*FLEX*]
+inherits = *common*
+bridge_fan_speed = 100
+cooling = 0
+disable_fan_first_layers = 1
+extrusion_multiplier = 1.2
+fan_always_on = 0
+fan_below_layer_time = 100
+filament_colour = #00CA0A
+filament_max_volumetric_speed = 1.5
+filament_type = FLEX
+first_layer_bed_temperature = 50
+first_layer_temperature = 240
+max_fan_speed = 90
+min_fan_speed = 70
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 240
+
+[filament:ColorFabb Brass Bronze]
+inherits = *PLA*
+extrusion_multiplier = 1.2
+filament_colour = #804040
+filament_max_volumetric_speed = 10
+
+[filament:ColorFabb HT]
+inherits = *PET*
+bed_temperature = 110
+bridge_fan_speed = 30
+cooling = 1
+disable_fan_first_layers = 3
+fan_always_on = 0
+fan_below_layer_time = 10
+first_layer_bed_temperature = 105
+first_layer_temperature = 270
+max_fan_speed = 20
+min_fan_speed = 10
+min_print_speed = 5
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode"
+temperature = 270
+
+[filament:ColorFabb PLA-PHA]
+inherits = *PLA*
+
+[filament:ColorFabb Woodfil]
+inherits = *PLA*
+extrusion_multiplier = 1.2
+filament_colour = #804040
+filament_max_volumetric_speed = 10
+first_layer_temperature = 200
+min_print_speed = 5
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 200
+
+[filament:ColorFabb XT]
+inherits = *PET*
+filament_type = PLA
+first_layer_bed_temperature = 90
+first_layer_temperature = 260
+temperature = 270
+
+[filament:ColorFabb XT-CF20]
+inherits = *PET*
+extrusion_multiplier = 1.2
+filament_colour = #804040
+filament_max_volumetric_speed = 1
+first_layer_bed_temperature = 90
+first_layer_temperature = 260
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
+temperature = 260
+
+[filament:ColorFabb nGen]
+inherits = *PET*
+bridge_fan_speed = 40
+fan_always_on = 0
+fan_below_layer_time = 10
+filament_type = NGEN
+first_layer_temperature = 240
+max_fan_speed = 35
+min_fan_speed = 20
+
+[filament:ColorFabb nGen flex]
+inherits = *FLEX*
+bed_temperature = 85
+bridge_fan_speed = 40
+cooling = 1
+disable_fan_first_layers = 3
+extrusion_multiplier = 1
+fan_below_layer_time = 10
+filament_max_volumetric_speed = 5
+first_layer_bed_temperature = 85
+first_layer_temperature = 260
+max_fan_speed = 35
+min_fan_speed = 20
+temperature = 260
+
+[filament:E3D Edge]
+inherits = *PET*
+filament_notes = "List of manufacturers tested with standart PET print settings for MK2:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladeč PETG"
+
+[filament:E3D PC-ABS]
+inherits = *ABS*
+first_layer_temperature = 270
+temperature = 270
+
+[filament:Fillamentum ABS]
+inherits = *ABS*
+first_layer_temperature = 240
+temperature = 240
+
+[filament:Fillamentum ASA]
+inherits = *ABS*
+fan_always_on = 1
+first_layer_temperature = 265
+temperature = 265
+
+[filament:Fillamentum CPE HG100 HM100]
+inherits = *PET*
+filament_notes = "CPE HG100 , CPE HM100"
+first_layer_bed_temperature = 90
+first_layer_temperature = 275
+max_fan_speed = 50
+min_fan_speed = 50
+temperature = 275
+
+[filament:Fillamentum Timberfil]
+inherits = *PLA*
+extrusion_multiplier = 1.2
+filament_colour = #804040
+filament_max_volumetric_speed = 10
+first_layer_temperature = 190
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 190
+
+[filament:Generic ABS]
+inherits = *ABS*
+filament_notes = "List of materials tested with standart ABS print settings for MK2:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladeč ABS"
+
+[filament:Generic PET]
+inherits = *PET*
+filament_notes = "List of manufacturers tested with standart PET print settings for MK2:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladeč PETG"
+
+[filament:Generic PLA]
+inherits = *PLA*
+filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
+
+[filament:Polymaker PC-Max]
+inherits = *ABS*
+bed_temperature = 115
+filament_colour = #3A80CA
+first_layer_bed_temperature = 100
+first_layer_temperature = 270
+temperature = 270
+
+[filament:Primavalue PVA]
+inherits = *PLA*
+cooling = 0
+fan_always_on = 0
+filament_colour = #FFFFD7
+filament_max_volumetric_speed = 10
+filament_notes = "List of materials tested with standart PVA print settings for MK2:\n\nPrimaSelect PVA+\nICE FILAMENTS PVA 'NAUGHTY NATURAL'\nVerbatim BVOH"
+filament_soluble = 1
+filament_type = PVA
+first_layer_temperature = 195
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 195
+
+[filament:Prusa ABS]
+inherits = *ABS*
+filament_notes = "List of materials tested with standart ABS print settings for MK2:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladeč ABS"
+
+[filament:Prusa HIPS]
+inherits = *ABS*
+bridge_fan_speed = 50
+cooling = 1
+extrusion_multiplier = 0.9
+fan_always_on = 1
+fan_below_layer_time = 10
+filament_colour = #FFFFD7
+filament_soluble = 1
+filament_type = HIPS
+first_layer_temperature = 220
+max_fan_speed = 20
+min_fan_speed = 20
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 220
+
+[filament:Prusa PET]
+inherits = *PET*
+filament_notes = "List of manufacturers tested with standart PET print settings for MK2:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladeč PETG"
+
+[filament:Prusa PLA]
+inherits = *PLA*
+filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
+
+[filament:SemiFlex or Flexfill 98A]
+inherits = *FLEX*
+
+[filament:Taulman Bridge]
+inherits = *common*
+bed_temperature = 90
+bridge_fan_speed = 40
+cooling = 0
+disable_fan_first_layers = 3
+fan_always_on = 0
+fan_below_layer_time = 20
+filament_colour = #DEE0E6
+filament_max_volumetric_speed = 10
+filament_soluble = 0
+filament_type = PET
+first_layer_bed_temperature = 60
+first_layer_temperature = 240
+max_fan_speed = 5
+min_fan_speed = 0
+min_print_speed = 5
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 250
+
+[filament:Taulman T-Glase]
+inherits = *PET*
+bridge_fan_speed = 40
+cooling = 0
+fan_always_on = 0
+first_layer_bed_temperature = 90
+first_layer_temperature = 240
+max_fan_speed = 5
+min_fan_speed = 0
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
+
+[filament:Verbatim BVOH]
+inherits = *common*
+bed_temperature = 60
+bridge_fan_speed = 100
+cooling = 0
+disable_fan_first_layers = 1
+extrusion_multiplier = 1
+fan_always_on = 0
+fan_below_layer_time = 100
+filament_colour = #FFFFD7
+filament_max_volumetric_speed = 10
+filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
+filament_soluble = 1
+filament_type = PLA
+first_layer_bed_temperature = 60
+first_layer_temperature = 215
+max_fan_speed = 100
+min_fan_speed = 100
+min_print_speed = 15
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 210
+
+[filament:Verbatim PP]
+inherits = *common*
+bed_temperature = 100
+bridge_fan_speed = 100
+cooling = 1
+disable_fan_first_layers = 2
+extrusion_multiplier = 1
+fan_always_on = 1
+fan_below_layer_time = 100
+filament_colour = #DEE0E6
+filament_max_volumetric_speed = 5
+filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nEsun PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nEUMAKERS PLA"
+filament_type = PLA
+first_layer_bed_temperature = 100
+first_layer_temperature = 220
+max_fan_speed = 100
+min_fan_speed = 100
+min_print_speed = 15
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 220
+
+[printer:*common*]
+bed_shape = 0x0,250x0,250x210,0x210
+before_layer_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\n\n
+between_objects_gcode =
+deretract_speed = 0
+end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
+extruder_colour = #FFFF00
+extruder_offset = 0x0
+gcode_flavor = marlin
+layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z]
+max_layer_height = 0.25
+min_layer_height = 0.07
+nozzle_diameter = 0.4
+octoprint_apikey =
+octoprint_host =
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\n
+printer_settings_id =
+retract_before_travel = 1
+retract_before_wipe = 0%
+retract_layer_change = 1
+retract_length = 0.8
+retract_length_toolchange = 4
+retract_lift = 0.6
+retract_lift_above = 0
+retract_lift_below = 199
+retract_restart_extra = 0
+retract_restart_extra_toolchange = 0
+retract_speed = 35
+serial_port =
+serial_speed = 250000
+single_extruder_multi_material = 0
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+toolchange_gcode =
+use_firmware_retraction = 0
+use_relative_e_distances = 1
+use_volumetric_e = 0
+variable_layer_height = 1
+wipe = 1
+z_offset = 0
+printer_model = M2
+printer_variant = 0.4
+default_print_profile = 0.15mm OPTIMAL
+default_filament_profile = Prusa PLA
+
+[printer:*multimaterial*]
+inherits = *common*
+deretract_speed = 50
+retract_before_travel = 3
+retract_before_wipe = 60%
+retract_layer_change = 0
+retract_length = 4
+retract_lift = 0.6
+retract_lift_above = 0
+retract_lift_below = 199
+retract_restart_extra = 0
+retract_restart_extra_toolchange = 0
+retract_speed = 80
+single_extruder_multi_material = 1
+printer_model = M3
+
+[printer:*mm-single*]
+inherits = *multimaterial*
+end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0
+
+[printer:*mm-multi*]
+inherits = *multimaterial*
+end_gcode = {if not has_wipe_tower}\n; Pull the filament into the cooling tubes.\nG1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\n{endif}\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors
+extruder_colour = #FFAA55;#5182DB;#4ECDD3;#FB7259
+nozzle_diameter = 0.4,0.4,0.4,0.4
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0
+variable_layer_height = 0
+
+[printer:Original Prusa i3 MK2]
+inherits = *common*
+
+[printer:Original Prusa i3 MK2 0.25 nozzle]
+inherits = *common*
+max_layer_height = 0.1
+min_layer_height = 0.05
+nozzle_diameter = 0.25
+retract_length = 1
+retract_speed = 50
+variable_layer_height = 0
+printer_variant = 0.25
+default_print_profile = 0.10mm DETAIL 0.25 nozzle
+
+[printer:Original Prusa i3 MK2 0.6 nozzle]
+inherits = *common*
+max_layer_height = 0.35
+min_layer_height = 0.1
+nozzle_diameter = 0.6
+printer_variant = 0.6
+
+[printer:Original Prusa i3 MK2 MM Single Mode]
+inherits = *mm-single*
+
+[printer:Original Prusa i3 MK2 MM Single Mode 0.6 nozzle]
+inherits = *mm-single*
+nozzle_diameter = 0.6
+printer_variant = 0.6
+
+[printer:Original Prusa i3 MK2 MultiMaterial]
+inherits = *mm-multi*
+nozzle_diameter = 0.4,0.4,0.4,0.4
+
+[printer:Original Prusa i3 MK2 MultiMaterial 0.6 nozzle]
+inherits = *mm-multi*
+nozzle_diameter = 0.6,0.6,0.6,0.6
+printer_variant = 0.6
+
+[printer:Original Prusa i3 MK3]
+inherits = *common*
+end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
+retract_lift_below = 209
+start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
+printer_model = M1
+default_print_profile = 0.15mm OPTIMAL MK3
+
+[printer:Original Prusa i3 MK3 0.25 nozzle]
+inherits = *common*
+nozzle_diameter = 0.25
+printer_variant = 0.25
+end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
+retract_lift_below = 209
+start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
+printer_model = M1
+default_print_profile = 0.10mm DETAIL MK3
+
+[printer:Original Prusa i3 MK3 0.6 nozzle]
+inherits = *common*
+nozzle_diameter = 0.6
+printer_variant = 0.6
+end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
+retract_lift_below = 209
+start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
+printer_model = M1
+default_print_profile = 0.15mm OPTIMAL MK3
diff --git a/resources/profiles/Foobar.ini b/resources/profiles/Foobar.ini
new file mode 100644
index 000000000..21681398a
--- /dev/null
+++ b/resources/profiles/Foobar.ini
@@ -0,0 +1,985 @@
+# Print profiles for the Prusa Research printers.
+
+[vendor]
+# Vendor name will be shown by the Config Wizard.
+name = Foo Bar
+# Configuration version of this file. Config file will only be installed, if the config_version differs.
+# This means, the server may force the Slic3r configuration to be downgraded.
+config_version = 0.1
+# Where to get the updates from?
+config_update_url = https://example.com
+
+# The printer models will be shown by the Configuration Wizard in this order,
+# also the first model installed & the first nozzle installed will be activated after install.
+#TODO: One day we may differentiate variants of the nozzles / hot ends,
+#for example by the melt zone size, or whether the nozzle is hardened.
+[printer_model:M1]
+name = Foo Bar Model 1
+variants = 0.4; 0.25; 0.6
+
+[printer_model:M2]
+name = Foo Bar Model 2
+variants = 0.4; 0.25; 0.6
+
+[printer_model:M3]
+# Printer model name will be shown by the installation wizard.
+name = Foo Bar Model 3
+variants = 0.4; 0.6
+
+# All presets starting with asterisk, for example *common*, are intermediate and they will
+# not make it into the user interface.
+
+# Common print preset, mostly derived from MK2 single material with a 0.4mm nozzle.
+# All other print presets will derive from the *common* print preset.
+[print:*common*]
+avoid_crossing_perimeters = 0
+bridge_acceleration = 1000
+bridge_angle = 0
+bridge_flow_ratio = 0.8
+bridge_speed = 20
+brim_width = 0
+clip_multipart_objects = 1
+compatible_printers =
+complete_objects = 0
+default_acceleration = 1000
+dont_support_bridges = 1
+elefant_foot_compensation = 0
+ensure_vertical_shell_thickness = 1
+external_fill_pattern = rectilinear
+external_perimeters_first = 0
+external_perimeter_extrusion_width = 0.45
+extra_perimeters = 0
+extruder_clearance_height = 20
+extruder_clearance_radius = 20
+extrusion_width = 0.45
+fill_angle = 45
+fill_density = 20%
+fill_pattern = cubic
+first_layer_acceleration = 1000
+first_layer_extrusion_width = 0.42
+first_layer_height = 0.2
+first_layer_speed = 30
+gap_fill_speed = 40
+gcode_comments = 0
+infill_every_layers = 1
+infill_extruder = 1
+infill_extrusion_width = 0.45
+infill_first = 0
+infill_only_where_needed = 0
+infill_overlap = 25%
+interface_shells = 0
+max_print_speed = 100
+max_volumetric_extrusion_rate_slope_negative = 0
+max_volumetric_extrusion_rate_slope_positive = 0
+max_volumetric_speed = 0
+min_skirt_length = 4
+notes =
+overhangs = 0
+only_retract_when_crossing_perimeters = 0
+ooze_prevention = 0
+output_filename_format = [input_filename_base].gcode
+perimeters = 2
+perimeter_extruder = 1
+perimeter_extrusion_width = 0.45
+post_process =
+print_settings_id =
+raft_layers = 0
+resolution = 0
+seam_position = nearest
+skirts = 1
+skirt_distance = 2
+skirt_height = 3
+small_perimeter_speed = 20
+solid_infill_below_area = 0
+solid_infill_every_layers = 0
+solid_infill_extruder = 1
+solid_infill_extrusion_width = 0.45
+spiral_vase = 0
+standby_temperature_delta = -5
+support_material = 0
+support_material_extruder = 0
+support_material_extrusion_width = 0.35
+support_material_interface_extruder = 0
+support_material_angle = 0
+support_material_buildplate_only = 0
+support_material_enforce_layers = 0
+support_material_contact_distance = 0.15
+support_material_interface_contact_loops = 0
+support_material_interface_layers = 2
+support_material_interface_spacing = 0.2
+support_material_interface_speed = 100%
+support_material_pattern = rectilinear
+support_material_spacing = 2
+support_material_speed = 50
+support_material_synchronize_layers = 0
+support_material_threshold = 45
+support_material_with_sheath = 0
+support_material_xy_spacing = 60%
+thin_walls = 0
+top_infill_extrusion_width = 0.45
+top_solid_infill_speed = 40
+travel_speed = 180
+wipe_tower = 0
+wipe_tower_per_color_wipe = 20
+wipe_tower_width = 60
+wipe_tower_x = 180
+wipe_tower_y = 140
+xy_size_compensation = 0
+
+# Print parameters common to a 0.25mm diameter nozzle.
+[print:*0.25nozzle*]
+external_perimeter_extrusion_width = 0.25
+extrusion_width = 0.25
+first_layer_extrusion_width = 0.25
+infill_extrusion_width = 0.25
+perimeter_extrusion_width = 0.25
+solid_infill_extrusion_width = 0.25
+top_infill_extrusion_width = 0.25
+support_material_extrusion_width = 0.18
+support_material_interface_layers = 0
+support_material_interface_spacing = 0.15
+support_material_spacing = 1
+support_material_xy_spacing = 150%
+
+# Print parameters common to a 0.6mm diameter nozzle.
+[print:*0.6nozzle*]
+external_perimeter_extrusion_width = 0.61
+extrusion_width = 0.67
+first_layer_extrusion_width = 0.65
+infill_extrusion_width = 0.7
+perimeter_extrusion_width = 0.65
+solid_infill_extrusion_width = 0.65
+top_infill_extrusion_width = 0.6
+
+[print:*soluble_support*]
+overhangs = 1
+skirts = 0
+support_material = 1
+support_material_contact_distance = 0
+support_material_extruder = 4
+support_material_extrusion_width = 0.45
+support_material_interface_extruder = 4
+support_material_interface_spacing = 0.1
+support_material_synchronize_layers = 1
+support_material_threshold = 80
+support_material_with_sheath = 1
+wipe_tower = 1
+
+[print:*0.05mm*]
+inherits = *common*
+bottom_solid_layers = 10
+bridge_acceleration = 300
+bridge_flow_ratio = 0.7
+default_acceleration = 500
+external_perimeter_speed = 20
+fill_density = 20%
+first_layer_acceleration = 500
+gap_fill_speed = 20
+infill_acceleration = 800
+infill_speed = 30
+max_print_speed = 80
+small_perimeter_speed = 15
+solid_infill_speed = 30
+support_material_extrusion_width = 0.3
+support_material_spacing = 1.5
+layer_height = 0.05
+perimeter_acceleration = 300
+perimeter_speed = 30
+perimeters = 3
+support_material_speed = 30
+top_solid_infill_speed = 20
+top_solid_layers = 15
+
+[print:0.05mm ULTRADETAIL]
+inherits = *0.05mm*
+infill_extrusion_width = 0.5
+
+[print:0.05mm ULTRADETAIL MK3]
+inherits = *0.05mm*
+fill_pattern = grid
+top_infill_extrusion_width = 0.4
+
+[print:0.05mm ULTRADETAIL 0.25 nozzle]
+inherits = *0.05mm*
+external_perimeter_extrusion_width = 0
+extrusion_width = 0.28
+fill_density = 20%
+first_layer_extrusion_width = 0.3
+infill_extrusion_width = 0
+infill_speed = 20
+max_print_speed = 100
+perimeter_extrusion_width = 0
+perimeter_speed = 20
+small_perimeter_speed = 10
+solid_infill_extrusion_width = 0
+solid_infill_speed = 20
+support_material_speed = 20
+top_infill_extrusion_width = 0
+
+[print:0.05mm ULTRADETAIL 0.25 nozzle MK3]
+inherits = *0.05mm*; *0.25nozzle*
+fill_pattern = grid
+top_infill_extrusion_width = 0.4
+
+[print:*0.10mm*]
+inherits = *common*
+bottom_solid_layers = 7
+bridge_flow_ratio = 0.7
+layer_height = 0.1
+perimeter_acceleration = 800
+top_solid_layers = 9
+
+[print:0.10mm DETAIL]
+inherits = *0.10mm*
+external_perimeter_speed = 40
+infill_acceleration = 2000
+infill_speed = 60
+perimeter_speed = 50
+solid_infill_speed = 50
+
+[print:0.10mm DETAIL MK3]
+inherits = *0.10mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 200
+perimeter_speed = 45
+solid_infill_speed = 170
+top_infill_extrusion_width = 0.4
+top_solid_infill_speed = 50
+
+[print:0.10mm DETAIL 0.25 nozzle]
+inherits = *0.10mm*
+bridge_acceleration = 600
+external_perimeter_speed = 20
+infill_acceleration = 1600
+infill_speed = 40
+perimeter_acceleration = 600
+perimeter_speed = 25
+small_perimeter_speed = 10
+solid_infill_speed = 40
+top_solid_infill_speed = 30
+
+[print:0.10mm DETAIL 0.25 nozzle MK3]
+inherits = *0.10mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 200
+perimeter_speed = 45
+solid_infill_speed = 170
+top_infill_extrusion_width = 0.4
+top_solid_infill_speed = 50
+
+[print:0.10mm DETAIL 0.6 nozzle MK3]
+inherits = *0.10mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 200
+perimeter_speed = 45
+solid_infill_speed = 170
+top_infill_extrusion_width = 0.4
+top_solid_infill_speed = 50
+
+[print:*0.15mm*]
+inherits = *common*
+bottom_solid_layers = 5
+external_perimeter_speed = 40
+infill_acceleration = 2000
+infill_speed = 60
+layer_height = 0.15
+perimeter_acceleration = 800
+perimeter_speed = 50
+solid_infill_speed = 50
+top_infill_extrusion_width = 0.4
+top_solid_layers = 7
+
+[print:0.15mm 100mms Linear Advance]
+inherits = *0.15mm*
+bridge_flow_ratio = 0.95
+external_perimeter_speed = 50
+infill_speed = 100
+max_print_speed = 150
+perimeter_speed = 60
+small_perimeter_speed = 30
+solid_infill_speed = 100
+support_material_speed = 60
+top_solid_infill_speed = 70
+
+[print:0.15mm OPTIMAL]
+inherits = *0.15mm*
+top_infill_extrusion_width = 0.45
+
+[print:0.15mm OPTIMAL 0.25 nozzle]
+inherits = *0.15mm*; *0.25nozzle*
+bridge_acceleration = 600
+bridge_flow_ratio = 0.7
+external_perimeter_speed = 20
+infill_acceleration = 1600
+infill_speed = 40
+perimeter_acceleration = 600
+perimeter_speed = 25
+small_perimeter_speed = 10
+solid_infill_speed = 40
+support_material_extrusion_width = 0.2
+top_solid_infill_speed = 30
+
+[print:0.15mm OPTIMAL 0.6 nozzle]
+inherits = *0.15mm*; *0.6nozzle*
+
+[print:0.15mm OPTIMAL MK3]
+inherits = *0.15mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+
+[print:0.15mm OPTIMAL SOLUBLE FULL]
+inherits = *0.15mm*; *soluble_support*
+external_perimeter_speed = 25
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder
+perimeter_speed = 40
+solid_infill_speed = 40
+top_infill_extrusion_width = 0.45
+top_solid_infill_speed = 30
+wipe_tower = 1
+
+[print:0.15mm OPTIMAL SOLUBLE INTERFACE]
+inherits = 0.15mm OPTIMAL SOLUBLE FULL
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft interface extruder
+support_material_extruder = 0
+support_material_interface_layers = 3
+support_material_with_sheath = 0
+support_material_xy_spacing = 80%
+
+[print:0.15mm OPTIMAL 0.25 nozzle MK3]
+inherits = *0.15mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+[print:*0.20mm*]
+inherits = *common*
+bottom_solid_layers = 4
+bridge_flow_ratio = 0.95
+external_perimeter_speed = 40
+infill_acceleration = 2000
+infill_speed = 60
+layer_height = 0.2
+perimeter_acceleration = 800
+perimeter_speed = 50
+solid_infill_speed = 50
+top_infill_extrusion_width = 0.4
+top_solid_layers = 5
+
+[print:0.15mm OPTIMAL 0.6 nozzle MK3]
+inherits = *0.15mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+
+[print:0.20mm 100mms Linear Advance]
+inherits = *0.20mm*
+external_perimeter_speed = 50
+infill_speed = 100
+max_print_speed = 150
+perimeter_speed = 60
+small_perimeter_speed = 30
+solid_infill_speed = 100
+support_material_speed = 60
+top_solid_infill_speed = 70
+
+[print:0.20mm FAST MK3]
+inherits = *0.20mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+
+[print:0.20mm NORMAL]
+inherits = *0.20mm*
+
+[print:0.20mm NORMAL 0.6 nozzle]
+inherits = *0.20mm*; *0.6nozzle*
+
+[print:0.20mm NORMAL SOLUBLE FULL]
+inherits = *0.20mm*; *soluble_support*
+external_perimeter_speed = 30
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder
+perimeter_speed = 40
+solid_infill_speed = 40
+top_solid_infill_speed = 30
+
+[print:0.20mm NORMAL SOLUBLE INTERFACE]
+inherits = 0.20mm NORMAL SOLUBLE FULL
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft interface extruder
+support_material_extruder = 0
+support_material_interface_layers = 3
+support_material_with_sheath = 0
+support_material_xy_spacing = 80%
+
+[print:0.20mm FAST 0.6 nozzle MK3]
+inherits = *0.20mm*
+bridge_speed = 30
+external_perimeter_speed = 35
+fill_pattern = grid
+infill_acceleration = 1500
+infill_speed = 170
+max_print_speed = 170
+perimeter_speed = 45
+solid_infill_speed = 170
+top_solid_infill_speed = 50
+
+[print:*0.35mm*]
+inherits = *common*
+bottom_solid_layers = 3
+external_perimeter_extrusion_width = 0.6
+external_perimeter_speed = 40
+first_layer_extrusion_width = 0.75
+infill_acceleration = 2000
+infill_speed = 60
+layer_height = 0.35
+perimeter_acceleration = 800
+perimeter_extrusion_width = 0.65
+perimeter_speed = 50
+solid_infill_extrusion_width = 0.65
+solid_infill_speed = 60
+top_solid_infill_speed = 50
+top_solid_layers = 4
+
+[print:0.35mm FAST]
+inherits = *0.35mm*
+bridge_flow_ratio = 0.95
+first_layer_extrusion_width = 0.42
+perimeter_extrusion_width = 0.43
+solid_infill_extrusion_width = 0.7
+top_infill_extrusion_width = 0.43
+
+[print:0.35mm FAST 0.6 nozzle]
+inherits = *0.35mm*; *0.6nozzle*
+
+[print:0.35mm FAST sol full 0.6 nozzle]
+inherits = *0.35mm*; *0.6nozzle*; *soluble_support*
+external_perimeter_extrusion_width = 0.6
+external_perimeter_speed = 30
+notes = Set your solluble extruder in Multiple Extruders > Support material/raft interface extruder
+perimeter_speed = 40
+support_material_extrusion_width = 0.55
+support_material_interface_layers = 3
+support_material_xy_spacing = 120%
+top_infill_extrusion_width = 0.57
+
+[print:0.35mm FAST sol int 0.6 nozzle]
+inherits = 0.35mm FAST sol full 0.6 nozzle
+support_material_extruder = 0
+support_material_interface_layers = 2
+support_material_with_sheath = 0
+support_material_xy_spacing = 150%
+
+[filament:*common*]
+cooling = 1
+compatible_printers =
+end_filament_gcode = "; Filament-specific end gcode"
+extrusion_multiplier = 1
+filament_cost = 0
+filament_density = 0
+filament_diameter = 1.75
+filament_notes = ""
+filament_settings_id =
+filament_soluble = 0
+min_print_speed = 5
+slowdown_below_layer_time = 20
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
+
+[filament:*PLA*]
+inherits = *common*
+bed_temperature = 60
+bridge_fan_speed = 100
+disable_fan_first_layers = 1
+fan_always_on = 1
+fan_below_layer_time = 100
+filament_colour = #FF3232
+filament_max_volumetric_speed = 15
+filament_type = PLA
+first_layer_bed_temperature = 60
+first_layer_temperature = 215
+max_fan_speed = 100
+min_fan_speed = 100
+temperature = 210
+
+[filament:*PET*]
+inherits = *common*
+bed_temperature = 90
+bridge_fan_speed = 50
+disable_fan_first_layers = 3
+fan_always_on = 1
+fan_below_layer_time = 20
+filament_colour = #FF8000
+filament_max_volumetric_speed = 8
+filament_type = PET
+first_layer_bed_temperature = 85
+first_layer_temperature = 230
+max_fan_speed = 50
+min_fan_speed = 30
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode"
+temperature = 240
+
+[filament:*ABS*]
+inherits = *common*
+bed_temperature = 110
+bridge_fan_speed = 30
+cooling = 0
+disable_fan_first_layers = 3
+fan_always_on = 0
+fan_below_layer_time = 20
+filament_colour = #3A80CA
+filament_max_volumetric_speed = 11
+filament_type = ABS
+first_layer_bed_temperature = 100
+first_layer_temperature = 255
+max_fan_speed = 30
+min_fan_speed = 20
+temperature = 255
+
+[filament:*FLEX*]
+inherits = *common*
+bridge_fan_speed = 100
+cooling = 0
+disable_fan_first_layers = 1
+extrusion_multiplier = 1.2
+fan_always_on = 0
+fan_below_layer_time = 100
+filament_colour = #00CA0A
+filament_max_volumetric_speed = 1.5
+filament_type = FLEX
+first_layer_bed_temperature = 50
+first_layer_temperature = 240
+max_fan_speed = 90
+min_fan_speed = 70
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 240
+
+[filament:ColorFabb Brass Bronze]
+inherits = *PLA*
+extrusion_multiplier = 1.2
+filament_colour = #804040
+filament_max_volumetric_speed = 10
+
+[filament:ColorFabb HT]
+inherits = *PET*
+bed_temperature = 110
+bridge_fan_speed = 30
+cooling = 1
+disable_fan_first_layers = 3
+fan_always_on = 0
+fan_below_layer_time = 10
+first_layer_bed_temperature = 105
+first_layer_temperature = 270
+max_fan_speed = 20
+min_fan_speed = 10
+min_print_speed = 5
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode"
+temperature = 270
+
+[filament:ColorFabb PLA-PHA]
+inherits = *PLA*
+
+[filament:ColorFabb Woodfil]
+inherits = *PLA*
+extrusion_multiplier = 1.2
+filament_colour = #804040
+filament_max_volumetric_speed = 10
+first_layer_temperature = 200
+min_print_speed = 5
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 200
+
+[filament:ColorFabb XT]
+inherits = *PET*
+filament_type = PLA
+first_layer_bed_temperature = 90
+first_layer_temperature = 260
+temperature = 270
+
+[filament:ColorFabb XT-CF20]
+inherits = *PET*
+extrusion_multiplier = 1.2
+filament_colour = #804040
+filament_max_volumetric_speed = 1
+first_layer_bed_temperature = 90
+first_layer_temperature = 260
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
+temperature = 260
+
+[filament:ColorFabb nGen]
+inherits = *PET*
+bridge_fan_speed = 40
+fan_always_on = 0
+fan_below_layer_time = 10
+filament_type = NGEN
+first_layer_temperature = 240
+max_fan_speed = 35
+min_fan_speed = 20
+
+[filament:ColorFabb nGen flex]
+inherits = *FLEX*
+bed_temperature = 85
+bridge_fan_speed = 40
+cooling = 1
+disable_fan_first_layers = 3
+extrusion_multiplier = 1
+fan_below_layer_time = 10
+filament_max_volumetric_speed = 5
+first_layer_bed_temperature = 85
+first_layer_temperature = 260
+max_fan_speed = 35
+min_fan_speed = 20
+temperature = 260
+
+[filament:E3D Edge]
+inherits = *PET*
+filament_notes = "List of manufacturers tested with standart PET print settings for MK2:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladeč PETG"
+
+[filament:E3D PC-ABS]
+inherits = *ABS*
+first_layer_temperature = 270
+temperature = 270
+
+[filament:Fillamentum ABS]
+inherits = *ABS*
+first_layer_temperature = 240
+temperature = 240
+
+[filament:Fillamentum ASA]
+inherits = *ABS*
+fan_always_on = 1
+first_layer_temperature = 265
+temperature = 265
+
+[filament:Fillamentum CPE HG100 HM100]
+inherits = *PET*
+filament_notes = "CPE HG100 , CPE HM100"
+first_layer_bed_temperature = 90
+first_layer_temperature = 275
+max_fan_speed = 50
+min_fan_speed = 50
+temperature = 275
+
+[filament:Fillamentum Timberfil]
+inherits = *PLA*
+extrusion_multiplier = 1.2
+filament_colour = #804040
+filament_max_volumetric_speed = 10
+first_layer_temperature = 190
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 190
+
+[filament:Generic ABS]
+inherits = *ABS*
+filament_notes = "List of materials tested with standart ABS print settings for MK2:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladeč ABS"
+
+[filament:Generic PET]
+inherits = *PET*
+filament_notes = "List of manufacturers tested with standart PET print settings for MK2:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladeč PETG"
+
+[filament:Generic PLA]
+inherits = *PLA*
+filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
+
+[filament:Polymaker PC-Max]
+inherits = *ABS*
+bed_temperature = 115
+filament_colour = #3A80CA
+first_layer_bed_temperature = 100
+first_layer_temperature = 270
+temperature = 270
+
+[filament:Primavalue PVA]
+inherits = *PLA*
+cooling = 0
+fan_always_on = 0
+filament_colour = #FFFFD7
+filament_max_volumetric_speed = 10
+filament_notes = "List of materials tested with standart PVA print settings for MK2:\n\nPrimaSelect PVA+\nICE FILAMENTS PVA 'NAUGHTY NATURAL'\nVerbatim BVOH"
+filament_soluble = 1
+filament_type = PVA
+first_layer_temperature = 195
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 195
+
+[filament:Prusa ABS]
+inherits = *ABS*
+filament_notes = "List of materials tested with standart ABS print settings for MK2:\n\nEsun ABS\nFil-A-Gehr ABS\nHatchboxABS\nPlasty Mladeč ABS"
+
+[filament:Prusa HIPS]
+inherits = *ABS*
+bridge_fan_speed = 50
+cooling = 1
+extrusion_multiplier = 0.9
+fan_always_on = 1
+fan_below_layer_time = 10
+filament_colour = #FFFFD7
+filament_soluble = 1
+filament_type = HIPS
+first_layer_temperature = 220
+max_fan_speed = 20
+min_fan_speed = 20
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 220
+
+[filament:Prusa PET]
+inherits = *PET*
+filament_notes = "List of manufacturers tested with standart PET print settings for MK2:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladeč PETG"
+
+[filament:Prusa PLA]
+inherits = *PLA*
+filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
+
+[filament:SemiFlex or Flexfill 98A]
+inherits = *FLEX*
+
+[filament:Taulman Bridge]
+inherits = *common*
+bed_temperature = 90
+bridge_fan_speed = 40
+cooling = 0
+disable_fan_first_layers = 3
+fan_always_on = 0
+fan_below_layer_time = 20
+filament_colour = #DEE0E6
+filament_max_volumetric_speed = 10
+filament_soluble = 0
+filament_type = PET
+first_layer_bed_temperature = 60
+first_layer_temperature = 240
+max_fan_speed = 5
+min_fan_speed = 0
+min_print_speed = 5
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 250
+
+[filament:Taulman T-Glase]
+inherits = *PET*
+bridge_fan_speed = 40
+cooling = 0
+fan_always_on = 0
+first_layer_bed_temperature = 90
+first_layer_temperature = 240
+max_fan_speed = 5
+min_fan_speed = 0
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
+
+[filament:Verbatim BVOH]
+inherits = *common*
+bed_temperature = 60
+bridge_fan_speed = 100
+cooling = 0
+disable_fan_first_layers = 1
+extrusion_multiplier = 1
+fan_always_on = 0
+fan_below_layer_time = 100
+filament_colour = #FFFFD7
+filament_max_volumetric_speed = 10
+filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
+filament_soluble = 1
+filament_type = PLA
+first_layer_bed_temperature = 60
+first_layer_temperature = 215
+max_fan_speed = 100
+min_fan_speed = 100
+min_print_speed = 15
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 210
+
+[filament:Verbatim PP]
+inherits = *common*
+bed_temperature = 100
+bridge_fan_speed = 100
+cooling = 1
+disable_fan_first_layers = 2
+extrusion_multiplier = 1
+fan_always_on = 1
+fan_below_layer_time = 100
+filament_colour = #DEE0E6
+filament_max_volumetric_speed = 5
+filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nEsun PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nEUMAKERS PLA"
+filament_type = PLA
+first_layer_bed_temperature = 100
+first_layer_temperature = 220
+max_fan_speed = 100
+min_fan_speed = 100
+min_print_speed = 15
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
+temperature = 220
+
+[printer:*common*]
+bed_shape = 0x0,250x0,250x210,0x210
+before_layer_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\n\n
+between_objects_gcode =
+deretract_speed = 0
+end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
+extruder_colour = #FFFF00
+extruder_offset = 0x0
+gcode_flavor = marlin
+layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z]
+max_layer_height = 0.25
+min_layer_height = 0.07
+nozzle_diameter = 0.4
+octoprint_apikey =
+octoprint_host =
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\n
+printer_settings_id =
+retract_before_travel = 1
+retract_before_wipe = 0%
+retract_layer_change = 1
+retract_length = 0.8
+retract_length_toolchange = 4
+retract_lift = 0.6
+retract_lift_above = 0
+retract_lift_below = 199
+retract_restart_extra = 0
+retract_restart_extra_toolchange = 0
+retract_speed = 35
+serial_port =
+serial_speed = 250000
+single_extruder_multi_material = 0
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+toolchange_gcode =
+use_firmware_retraction = 0
+use_relative_e_distances = 1
+use_volumetric_e = 0
+variable_layer_height = 1
+wipe = 1
+z_offset = 0
+printer_model = M2
+printer_variant = 0.4
+default_print_profile = 0.15mm OPTIMAL
+default_filament_profile = Prusa PLA
+
+[printer:*multimaterial*]
+inherits = *common*
+deretract_speed = 50
+retract_before_travel = 3
+retract_before_wipe = 60%
+retract_layer_change = 0
+retract_length = 4
+retract_lift = 0.6
+retract_lift_above = 0
+retract_lift_below = 199
+retract_restart_extra = 0
+retract_restart_extra_toolchange = 0
+retract_speed = 80
+single_extruder_multi_material = 1
+printer_model = M3
+
+[printer:*mm-single*]
+inherits = *multimaterial*
+end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0
+
+[printer:*mm-multi*]
+inherits = *multimaterial*
+end_gcode = {if not has_wipe_tower}\n; Pull the filament into the cooling tubes.\nG1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\n{endif}\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors
+extruder_colour = #FFAA55;#5182DB;#4ECDD3;#FB7259
+nozzle_diameter = 0.4,0.4,0.4,0.4
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0
+variable_layer_height = 0
+
+[printer:Original Prusa i3 MK2]
+inherits = *common*
+
+[printer:Original Prusa i3 MK2 0.25 nozzle]
+inherits = *common*
+max_layer_height = 0.1
+min_layer_height = 0.05
+nozzle_diameter = 0.25
+retract_length = 1
+retract_speed = 50
+variable_layer_height = 0
+printer_variant = 0.25
+default_print_profile = 0.10mm DETAIL 0.25 nozzle
+
+[printer:Original Prusa i3 MK2 0.6 nozzle]
+inherits = *common*
+max_layer_height = 0.35
+min_layer_height = 0.1
+nozzle_diameter = 0.6
+printer_variant = 0.6
+
+[printer:Original Prusa i3 MK2 MM Single Mode]
+inherits = *mm-single*
+
+[printer:Original Prusa i3 MK2 MM Single Mode 0.6 nozzle]
+inherits = *mm-single*
+nozzle_diameter = 0.6
+printer_variant = 0.6
+
+[printer:Original Prusa i3 MK2 MultiMaterial]
+inherits = *mm-multi*
+nozzle_diameter = 0.4,0.4,0.4,0.4
+
+[printer:Original Prusa i3 MK2 MultiMaterial 0.6 nozzle]
+inherits = *mm-multi*
+nozzle_diameter = 0.6,0.6,0.6,0.6
+printer_variant = 0.6
+
+[printer:Original Prusa i3 MK3]
+inherits = *common*
+end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
+retract_lift_below = 209
+start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
+printer_model = M1
+default_print_profile = 0.15mm OPTIMAL MK3
+
+[printer:Original Prusa i3 MK3 0.25 nozzle]
+inherits = *common*
+nozzle_diameter = 0.25
+printer_variant = 0.25
+end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
+retract_lift_below = 209
+start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
+printer_model = M1
+default_print_profile = 0.10mm DETAIL MK3
+
+[printer:Original Prusa i3 MK3 0.6 nozzle]
+inherits = *common*
+nozzle_diameter = 0.6
+printer_variant = 0.6
+end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
+printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
+retract_lift_below = 209
+start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
+printer_model = M1
+default_print_profile = 0.15mm OPTIMAL MK3
diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini
index fa4d48cda..b654b4039 100644
--- a/resources/profiles/PrusaResearch.ini
+++ b/resources/profiles/PrusaResearch.ini
@@ -7,21 +7,25 @@ name = Prusa Research
# This means, the server may force the Slic3r configuration to be downgraded.
config_version = 0.1
# Where to get the updates from?
-config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch.ini
+# TODO: proper URL
+# config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch.ini
+config_update_url = https://gist.githubusercontent.com/vojtechkral/4d8fd4a3b8699a01ec892c264178461c/raw/e9187c3e15ceaf1a90f29b7c43cf3ccc746140f0/PrusaResearch.ini
# The printer models will be shown by the Configuration Wizard in this order,
# also the first model installed & the first nozzle installed will be activated after install.
#TODO: One day we may differentiate variants of the nozzles / hot ends,
#for example by the melt zone size, or whether the nozzle is hardened.
[printer_model:MK3]
+name = Original Prusa i3 MK3
variants = 0.4; 0.25; 0.6
[printer_model:MK2S]
+name = Original Prusa i3 MK2S
variants = 0.4; 0.25; 0.6
[printer_model:MK2SMM]
# Printer model name will be shown by the installation wizard.
-name = MK2S Multi Material
+name = Original Prusa i3 MK2SMM
variants = 0.4; 0.6
# All presets starting with asterisk, for example *common*, are intermediate and they will
@@ -995,6 +999,7 @@ default_print_profile = 0.15mm OPTIMAL MK3
[printer:Original Prusa i3 MK3 0.25 nozzle]
inherits = *common*
nozzle_diameter = 0.25
+printer_variant = 0.25
end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
retract_lift_below = 209
@@ -1005,14 +1010,10 @@ default_print_profile = 0.10mm DETAIL MK3
[printer:Original Prusa i3 MK3 0.6 nozzle]
inherits = *common*
nozzle_diameter = 0.6
+printer_variant = 0.6
end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
retract_lift_below = 209
start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
printer_model = MK3
default_print_profile = 0.15mm OPTIMAL MK3
-
-[presets]
-print = 0.15mm OPTIMAL MK3
-printer = Original Prusa i3 MK3
-filament = Prusa PLA
diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt
index e01f11b26..1e777bf67 100644
--- a/xs/CMakeLists.txt
+++ b/xs/CMakeLists.txt
@@ -214,12 +214,16 @@ add_library(libslic3r_gui STATIC
${LIBDIR}/slic3r/Config/Version.hpp
${LIBDIR}/slic3r/Utils/ASCIIFolding.cpp
${LIBDIR}/slic3r/Utils/ASCIIFolding.hpp
+ ${LIBDIR}/slic3r/GUI/ConfigWizard.cpp
+ ${LIBDIR}/slic3r/GUI/ConfigWizard.hpp
${LIBDIR}/slic3r/Utils/Http.cpp
${LIBDIR}/slic3r/Utils/Http.hpp
${LIBDIR}/slic3r/Utils/OctoPrint.cpp
${LIBDIR}/slic3r/Utils/OctoPrint.hpp
${LIBDIR}/slic3r/Utils/Bonjour.cpp
${LIBDIR}/slic3r/Utils/Bonjour.hpp
+ ${LIBDIR}/slic3r/Utils/PresetUpdater.cpp
+ ${LIBDIR}/slic3r/Utils/PresetUpdater.hpp
${LIBDIR}/slic3r/Utils/Time.cpp
${LIBDIR}/slic3r/Utils/Time.hpp
)
@@ -367,6 +371,7 @@ set(XS_XSP_FILES
${XSP_DIR}/SurfaceCollection.xsp
${XSP_DIR}/TriangleMesh.xsp
${XSP_DIR}/Utils_OctoPrint.xsp
+ ${XSP_DIR}/Utils_PresetUpdater.xsp
${XSP_DIR}/XS.xsp
)
foreach (file ${XS_XSP_FILES})
diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp
index 6eb307c5c..06db9efef 100644
--- a/xs/src/libslic3r/Config.hpp
+++ b/xs/src/libslic3r/Config.hpp
@@ -659,6 +659,7 @@ public:
ConfigOptionPoints() : ConfigOptionVector<Pointf>() {}
explicit ConfigOptionPoints(size_t n, const Pointf &value) : ConfigOptionVector<Pointf>(n, value) {}
explicit ConfigOptionPoints(std::initializer_list<Pointf> il) : ConfigOptionVector<Pointf>(std::move(il)) {}
+ explicit ConfigOptionPoints(const std::vector<Pointf> &values) : ConfigOptionVector<Pointf>(values) {}
static ConfigOptionType static_type() { return coPoints; }
ConfigOptionType type() const override { return static_type(); }
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index 657e5a452..5795f044b 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -1620,7 +1620,7 @@ PrintConfigDef::PrintConfigDef()
"temperature control commands in the output.");
def->cli = "temperature=i@";
def->full_label = L("Temperature");
- def->max = 0;
+ def->min = 0;
def->max = max_temp;
def->default_value = new ConfigOptionInts { 200 };
diff --git a/xs/src/libslic3r/Utils.hpp b/xs/src/libslic3r/Utils.hpp
index 5727d6c89..f900137d3 100644
--- a/xs/src/libslic3r/Utils.hpp
+++ b/xs/src/libslic3r/Utils.hpp
@@ -3,6 +3,8 @@
#include <locale>
+#include "libslic3r.h"
+
namespace Slic3r {
extern void set_logging_level(unsigned int level);
diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp
index 733757e25..703d5ff66 100644
--- a/xs/src/libslic3r/utils.cpp
+++ b/xs/src/libslic3r/utils.cpp
@@ -119,7 +119,7 @@ static std::string g_data_dir;
void set_data_dir(const std::string &dir)
{
- g_data_dir = dir;
+ g_data_dir = dir + "-alpha"; // FIXME: Resolve backcompat problems
}
const std::string& data_dir()
diff --git a/xs/src/perlglue.cpp b/xs/src/perlglue.cpp
index d7c9a590a..9706ced2c 100644
--- a/xs/src/perlglue.cpp
+++ b/xs/src/perlglue.cpp
@@ -64,6 +64,7 @@ REGISTER_CLASS(PresetCollection, "GUI::PresetCollection");
REGISTER_CLASS(PresetBundle, "GUI::PresetBundle");
REGISTER_CLASS(PresetHints, "GUI::PresetHints");
REGISTER_CLASS(TabIface, "GUI::Tab");
+REGISTER_CLASS(PresetUpdater, "PresetUpdater");
REGISTER_CLASS(OctoPrint, "OctoPrint");
SV* ConfigBase__as_hash(ConfigBase* THIS)
diff --git a/xs/src/slic3r/GUI/2DBed.cpp b/xs/src/slic3r/GUI/2DBed.cpp
index c5d68400d..6d788cf34 100644
--- a/xs/src/slic3r/GUI/2DBed.cpp
+++ b/xs/src/slic3r/GUI/2DBed.cpp
@@ -1,4 +1,4 @@
-#include "2DBed.hpp";
+#include "2DBed.hpp"
#include <wx/dcbuffer.h>
#include "BoundingBox.hpp"
@@ -66,7 +66,7 @@ void Bed_2D::repaint()
shift.y - (cbb.max.y - GetSize().GetHeight()));
// draw bed fill
- dc.SetBrush(*new wxBrush(*new wxColour(255, 255, 255), wxSOLID));
+ dc.SetBrush(wxBrush(wxColour(255, 255, 255), wxSOLID));
wxPointList pt_list;
for (auto pt: m_bed_shape)
{
@@ -87,7 +87,7 @@ void Bed_2D::repaint()
}
polylines = intersection_pl(polylines, bed_polygon);
- dc.SetPen(*new wxPen(*new wxColour(230, 230, 230), 1, wxSOLID));
+ dc.SetPen(wxPen(wxColour(230, 230, 230), 1, wxSOLID));
for (auto pl : polylines)
{
for (size_t i = 0; i < pl.points.size()-1; i++){
@@ -98,8 +98,8 @@ void Bed_2D::repaint()
}
// draw bed contour
- dc.SetPen(*new wxPen(*new wxColour(0, 0, 0), 1, wxSOLID));
- dc.SetBrush(*new wxBrush(*new wxColour(0, 0, 0), wxTRANSPARENT));
+ dc.SetPen(wxPen(wxColour(0, 0, 0), 1, wxSOLID));
+ dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxTRANSPARENT));
dc.DrawPolygon(&pt_list, 0, 0);
auto origin_px = to_pixels(Pointf(0, 0));
@@ -108,7 +108,7 @@ void Bed_2D::repaint()
auto axes_len = 50;
auto arrow_len = 6;
auto arrow_angle = Geometry::deg2rad(45.0);
- dc.SetPen(*new wxPen(*new wxColour(255, 0, 0), 2, wxSOLID)); // red
+ dc.SetPen(wxPen(wxColour(255, 0, 0), 2, wxSOLID)); // red
auto x_end = Pointf(origin_px.x + axes_len, origin_px.y);
dc.DrawLine(wxPoint(origin_px.x, origin_px.y), wxPoint(x_end.x, x_end.y));
for (auto angle : { -arrow_angle, arrow_angle }){
@@ -118,7 +118,7 @@ void Bed_2D::repaint()
dc.DrawLine(wxPoint(x_end.x, x_end.y), wxPoint(end.x, end.y));
}
- dc.SetPen(*new wxPen(*new wxColour(0, 255, 0), 2, wxSOLID)); // green
+ dc.SetPen(wxPen(wxColour(0, 255, 0), 2, wxSOLID)); // green
auto y_end = Pointf(origin_px.x, origin_px.y - axes_len);
dc.DrawLine(wxPoint(origin_px.x, origin_px.y), wxPoint(y_end.x, y_end.y));
for (auto angle : { -arrow_angle, arrow_angle }) {
@@ -129,19 +129,23 @@ void Bed_2D::repaint()
}
// draw origin
- dc.SetPen(*new wxPen(*new wxColour(0, 0, 0), 1, wxSOLID));
- dc.SetBrush(*new wxBrush(*new wxColour(0, 0, 0), wxSOLID));
+ dc.SetPen(wxPen(wxColour(0, 0, 0), 1, wxSOLID));
+ dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxSOLID));
dc.DrawCircle(origin_px.x, origin_px.y, 3);
- dc.SetTextForeground(*new wxColour(0, 0, 0));
- dc.SetFont(*new wxFont(10, wxDEFAULT, wxNORMAL, wxNORMAL));
- dc.DrawText("(0,0)", origin_px.x + 1, origin_px.y + 2);
+ static const auto origin_label = wxString("(0,0)");
+ dc.SetTextForeground(wxColour(0, 0, 0));
+ dc.SetFont(wxFont(10, wxDEFAULT, wxNORMAL, wxNORMAL));
+ auto extent = dc.GetTextExtent(origin_label);
+ const auto origin_label_x = origin_px.x <= cw / 2 ? origin_px.x + 1 : origin_px.x - 1 - extent.GetWidth();
+ const auto origin_label_y = origin_px.y <= ch / 2 ? origin_px.y + 1 : origin_px.y - 1 - extent.GetHeight();
+ dc.DrawText(origin_label, origin_label_x, origin_label_y);
// draw current position
if (m_pos!= Pointf(0, 0)) {
auto pos_px = to_pixels(m_pos);
- dc.SetPen(*new wxPen(*new wxColour(200, 0, 0), 2, wxSOLID));
- dc.SetBrush(*new wxBrush(*new wxColour(200, 0, 0), wxTRANSPARENT));
+ dc.SetPen(wxPen(wxColour(200, 0, 0), 2, wxSOLID));
+ dc.SetBrush(wxBrush(wxColour(200, 0, 0), wxTRANSPARENT));
dc.DrawCircle(pos_px.x, pos_px.y, 5);
dc.DrawLine(pos_px.x - 15, pos_px.y, pos_px.x + 15, pos_px.y);
diff --git a/xs/src/slic3r/GUI/AppConfig.cpp b/xs/src/slic3r/GUI/AppConfig.cpp
index e32b645b4..9e5ce5f1b 100644
--- a/xs/src/slic3r/GUI/AppConfig.cpp
+++ b/xs/src/slic3r/GUI/AppConfig.cpp
@@ -1,5 +1,3 @@
-#include <GL/glew.h>
-
#include "../../libslic3r/libslic3r.h"
#include "../../libslic3r/Utils.hpp"
#include "AppConfig.hpp"
@@ -9,15 +7,20 @@
#include <string.h>
#include <utility>
#include <assert.h>
+#include <vector>
#include <boost/filesystem.hpp>
#include <boost/nowide/cenv.hpp>
#include <boost/nowide/fstream.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/ptree.hpp>
+#include <boost/algorithm/string/predicate.hpp>
namespace Slic3r {
+static const std::string VENDOR_PREFIX = "vendor:";
+static const std::string MODEL_PREFIX = "model:";
+
void AppConfig::reset()
{
m_storage.clear();
@@ -42,9 +45,11 @@ void AppConfig::set_defaults()
set("no_defaults", "1");
if (get("show_incompatible_presets").empty())
set("show_incompatible_presets", "0");
- // Version check is enabled by default in the config, but it is not implemented yet.
+ // Version check is enabled by default in the config, but it is not implemented yet. // XXX
if (get("version_check").empty())
set("version_check", "1");
+ if (get("preset_update").empty())
+ set("preset_update", "1");
// Use OpenGL 1.1 even if OpenGL 2.0 is available. This is mainly to support some buggy Intel HD Graphics drivers.
// https://github.com/prusa3d/Slic3r/issues/233
if (get("use_legacy_opengl").empty())
@@ -67,6 +72,19 @@ void AppConfig::load()
if (! data.empty())
// If there is a non-empty data, then it must be a top-level (without a section) config entry.
m_storage[""][section.first] = data;
+ } else if (boost::starts_with(section.first, VENDOR_PREFIX)) {
+ // This is a vendor section listing enabled model / variants
+ const auto vendor_name = section.first.substr(VENDOR_PREFIX.size());
+ auto &vendor = m_vendors[vendor_name];
+ for (const auto &kvp : section.second) {
+ if (! boost::starts_with(kvp.first, MODEL_PREFIX)) { continue; }
+ const auto model_name = kvp.first.substr(MODEL_PREFIX.size());
+ std::vector<std::string> variants;
+ if (! unescape_strings_cstyle(kvp.second.data(), variants)) { continue; }
+ for (const auto &variant : variants) {
+ vendor[model_name].insert(variant);
+ }
+ }
} else {
// This must be a section name. Read the entries of a section.
std::map<std::string, std::string> &storage = m_storage[section.first];
@@ -96,10 +114,57 @@ void AppConfig::save()
for (const std::pair<std::string, std::string> &kvp : category.second)
c << kvp.first << " = " << kvp.second << std::endl;
}
+ // Write vendor sections
+ for (const auto &vendor : m_vendors) {
+ size_t size_sum = 0;
+ for (const auto &model : vendor.second) { size_sum += model.second.size(); }
+ if (size_sum == 0) { continue; }
+
+ c << std::endl << "[" << VENDOR_PREFIX << vendor.first << "]" << std::endl;
+
+ for (const auto &model : vendor.second) {
+ if (model.second.size() == 0) { continue; }
+ const std::vector<std::string> variants(model.second.begin(), model.second.end());
+ const auto escaped = escape_strings_cstyle(variants);
+ c << MODEL_PREFIX << model.first << " = " << escaped << std::endl;
+ }
+ }
c.close();
m_dirty = false;
}
+bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const
+{
+ const auto it_v = m_vendors.find(vendor);
+ if (it_v == m_vendors.end()) { return false; }
+ const auto it_m = it_v->second.find(model);
+ return it_m == it_v->second.end() ? false : it_m->second.find(variant) != it_m->second.end();
+}
+
+void AppConfig::set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable)
+{
+ if (enable) {
+ if (get_variant(vendor, model, variant)) { return; }
+ m_vendors[vendor][model].insert(variant);
+ } else {
+ auto it_v = m_vendors.find(vendor);
+ if (it_v == m_vendors.end()) { return; }
+ auto it_m = it_v->second.find(model);
+ if (it_m == it_v->second.end()) { return; }
+ auto it_var = it_m->second.find(variant);
+ if (it_var == it_m->second.end()) { return; }
+ it_m->second.erase(it_var);
+ }
+ // If we got here, there was an update
+ m_dirty = true;
+}
+
+void AppConfig::set_vendors(const AppConfig &from)
+{
+ m_vendors = from.m_vendors;
+ m_dirty = true;
+}
+
std::string AppConfig::get_last_dir() const
{
const auto it = m_storage.find("recent");
@@ -156,6 +221,16 @@ void AppConfig::reset_selections()
}
}
+bool AppConfig::version_check_enabled() const
+{
+ return get("version_check") == "1";
+}
+
+bool AppConfig::slic3r_update_avail() const
+{
+ return version_check_enabled() && get("version_online") != SLIC3R_VERSION;
+}
+
std::string AppConfig::config_path()
{
return (boost::filesystem::path(Slic3r::data_dir()) / "slic3r.ini").make_preferred().string();
diff --git a/xs/src/slic3r/GUI/AppConfig.hpp b/xs/src/slic3r/GUI/AppConfig.hpp
index 9b1d5a712..7aac95fd6 100644
--- a/xs/src/slic3r/GUI/AppConfig.hpp
+++ b/xs/src/slic3r/GUI/AppConfig.hpp
@@ -1,9 +1,12 @@
#ifndef slic3r_AppConfig_hpp_
#define slic3r_AppConfig_hpp_
+#include <set>
#include <map>
#include <string>
+#include "libslic3r/Config.hpp"
+
namespace Slic3r {
class AppConfig
@@ -65,6 +68,10 @@ public:
void clear_section(const std::string &section)
{ m_storage[section].clear(); }
+ bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const;
+ void set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable);
+ void set_vendors(const AppConfig &from);
+
// return recent/skein_directory or recent/config_directory or empty string.
std::string get_last_dir() const;
void update_config_dir(const std::string &dir);
@@ -78,6 +85,10 @@ public:
// the first non-default preset when called.
void reset_selections();
+ // Whether the Slic3r version available online differs from this one
+ bool version_check_enabled() const;
+ bool slic3r_update_avail() const;
+
// Get the default config path from Slic3r::data_dir().
static std::string config_path();
@@ -87,6 +98,8 @@ public:
private:
// Map of section, name -> value
std::map<std::string, std::map<std::string, std::string>> m_storage;
+ // Map of enabled vendors / models / variants
+ std::map<std::string, std::map<std::string, std::set<std::string>>> m_vendors;
// Has any value been modified since the config.ini has been last saved or loaded?
bool m_dirty;
};
diff --git a/xs/src/slic3r/GUI/ConfigWizard.cpp b/xs/src/slic3r/GUI/ConfigWizard.cpp
new file mode 100644
index 000000000..f13448c37
--- /dev/null
+++ b/xs/src/slic3r/GUI/ConfigWizard.cpp
@@ -0,0 +1,720 @@
+#include "ConfigWizard_private.hpp"
+
+#include <algorithm>
+#include <utility>
+#include <boost/filesystem.hpp>
+
+#include <wx/settings.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/dcclient.h>
+#include <wx/statbmp.h>
+#include <wx/checkbox.h>
+#include <wx/statline.h>
+
+#include "libslic3r/Utils.hpp"
+#include "PresetBundle.hpp"
+#include "GUI.hpp"
+
+namespace fs = boost::filesystem;
+
+namespace Slic3r {
+namespace GUI {
+
+
+// Printer model picker GUI control
+
+struct PrinterPickerEvent : public wxEvent
+{
+ std::string vendor_id;
+ std::string model_id;
+ std::string variant_name;
+ bool enable;
+
+ PrinterPickerEvent(wxEventType eventType, int winid, std::string vendor_id, std::string model_id, std::string variant_name, bool enable) :
+ wxEvent(winid, eventType),
+ vendor_id(std::move(vendor_id)),
+ model_id(std::move(model_id)),
+ variant_name(std::move(variant_name)),
+ enable(enable)
+ {}
+
+ virtual wxEvent *Clone() const
+ {
+ return new PrinterPickerEvent(*this);
+ }
+};
+
+wxDEFINE_EVENT(EVT_PRINTER_PICK, PrinterPickerEvent);
+
+PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, const AppConfig &appconfig_vendors) :
+ wxPanel(parent),
+ variants_checked(0)
+{
+ const auto vendor_id = vendor.id;
+ const auto &models = vendor.models;
+
+ auto *printer_grid = new wxFlexGridSizer(models.size(), 0, 20);
+ printer_grid->SetFlexibleDirection(wxVERTICAL);
+ SetSizer(printer_grid);
+
+ auto namefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ namefont.SetWeight(wxFONTWEIGHT_BOLD);
+
+ for (auto model = models.cbegin(); model != models.cend(); ++model) {
+ auto *panel = new wxPanel(this);
+ auto *sizer = new wxBoxSizer(wxVERTICAL);
+ panel->SetSizer(sizer);
+
+ auto *title = new wxStaticText(panel, wxID_ANY, model->name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+ title->SetFont(namefont);
+ sizer->Add(title, 0, wxBOTTOM, 3);
+
+ auto bitmap_file = wxString::Format("printers/%s_%s.png", vendor.id, model->id);
+ wxBitmap bitmap(GUI::from_u8(Slic3r::var(bitmap_file.ToStdString())), wxBITMAP_TYPE_PNG);
+ auto *bitmap_widget = new wxStaticBitmap(panel, wxID_ANY, bitmap);
+ sizer->Add(bitmap_widget, 0, wxBOTTOM, 3);
+
+ sizer->AddSpacer(20);
+
+ const auto model_id = model->id;
+
+ for (const auto &variant : model->variants) {
+ const auto variant_name = variant.name;
+ auto *cbox = new wxCheckBox(panel, wxID_ANY, wxString::Format("%s %s %s", variant.name, _(L("mm")), _(L("nozzle"))));
+ bool enabled = appconfig_vendors.get_variant("PrusaResearch", model_id, variant_name);
+ variants_checked += enabled;
+ cbox->SetValue(enabled);
+ sizer->Add(cbox, 0, wxBOTTOM, 3);
+ cbox->Bind(wxEVT_CHECKBOX, [=](wxCommandEvent &event) {
+ this->variants_checked += event.IsChecked() ? 1 : -1;
+ PrinterPickerEvent evt(EVT_PRINTER_PICK, this->GetId(), std::move(vendor_id), std::move(model_id), std::move(variant_name), event.IsChecked());
+ this->AddPendingEvent(evt);
+ });
+ }
+
+ printer_grid->Add(panel);
+ }
+
+}
+
+
+// Wizard page base
+
+ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname) :
+ wxPanel(parent),
+ parent(parent),
+ shortname(std::move(shortname)),
+ p_prev(nullptr),
+ p_next(nullptr)
+{
+ auto *sizer = new wxBoxSizer(wxVERTICAL);
+
+ auto *text = new wxStaticText(this, wxID_ANY, std::move(title), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+ auto font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ font.SetWeight(wxFONTWEIGHT_BOLD);
+ font.SetPointSize(14);
+ text->SetFont(font);
+ sizer->Add(text, 0, wxALIGN_LEFT, 0);
+ sizer->AddSpacer(10);
+
+ content = new wxBoxSizer(wxVERTICAL);
+ sizer->Add(content, 1);
+
+ SetSizer(sizer);
+
+ this->Hide();
+
+ Bind(wxEVT_SIZE, [this](wxSizeEvent &event) {
+ this->Layout();
+ event.Skip();
+ });
+}
+
+ConfigWizardPage::~ConfigWizardPage() {}
+
+ConfigWizardPage* ConfigWizardPage::chain(ConfigWizardPage *page)
+{
+ if (p_next != nullptr) { p_next->p_prev = nullptr; }
+ p_next = page;
+ if (page != nullptr) {
+ if (page->p_prev != nullptr) { page->p_prev->p_next = nullptr; }
+ page->p_prev = this;
+ }
+
+ return page;
+}
+
+void ConfigWizardPage::append_text(wxString text)
+{
+ auto *widget = new wxStaticText(this, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+ widget->Wrap(CONTENT_WIDTH);
+ widget->SetMinSize(wxSize(CONTENT_WIDTH, -1));
+ append(widget);
+}
+
+void ConfigWizardPage::append_spacer(int space)
+{
+ content->AddSpacer(space);
+}
+
+bool ConfigWizardPage::Show(bool show)
+{
+ if (extra_buttons() != nullptr) { extra_buttons()->Show(show); }
+ return wxPanel::Show(show);
+}
+
+void ConfigWizardPage::enable_next(bool enable) { parent->p->enable_next(enable); }
+
+
+// Wizard pages
+
+PageWelcome::PageWelcome(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Welcome to the Slic3r Configuration assistant")), _(L("Welcome"))),
+ printer_picker(nullptr),
+ others_buttons(new wxPanel(parent))
+{
+ append_text(_(L("Hello, welcome to Slic3r Prusa Edition! TODO: This text.")));
+
+ const PresetBundle &bundle = wizard_p()->bundle_vendors;
+ const auto &vendors = bundle.vendors;
+ const auto vendor_prusa = std::find(vendors.cbegin(), vendors.cend(), VendorProfile("PrusaResearch"));
+
+ if (vendor_prusa != vendors.cend()) {
+ const auto &models = vendor_prusa->models;
+
+ AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors;
+
+ printer_picker = new PrinterPicker(this, *vendor_prusa, appconfig_vendors);
+ printer_picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) {
+ appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable);
+ this->on_variant_checked();
+ });
+
+ append(printer_picker);
+ }
+
+ const size_t num_other_vendors = vendors.size() - (vendor_prusa != vendors.cend());
+ auto *sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto *other_vendors = new wxButton(others_buttons, wxID_ANY, _(L("Other vendors")));
+ other_vendors->Enable(num_other_vendors > 0);
+ auto *custom_setup = new wxButton(others_buttons, wxID_ANY, _(L("Custom setup")));
+
+ sizer->Add(other_vendors);
+ sizer->AddSpacer(BTN_SPACING);
+ sizer->Add(custom_setup);
+
+ other_vendors->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->wizard_p()->on_other_vendors(); });
+ custom_setup->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->wizard_p()->on_custom_setup(); });
+
+ others_buttons->SetSizer(sizer);
+}
+
+void PageWelcome::on_page_set()
+{
+ chain(wizard_p()->page_update);
+ on_variant_checked();
+}
+
+void PageWelcome::on_variant_checked()
+{
+ enable_next(printer_picker != nullptr ? printer_picker->variants_checked > 0 : false);
+}
+
+PageUpdate::PageUpdate(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Automatic updates")), _(L("Updates"))),
+ version_check(true),
+ preset_update(true)
+{
+ const AppConfig *app_config = GUI::get_app_config();
+
+ append_text(_(L("TODO: text")));
+ auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for Slic3r updates")));
+ box_slic3r->SetValue(app_config->get("version_check") == "1");
+ append(box_slic3r);
+
+ append_text(_(L("TODO: text")));
+ auto *box_presets = new wxCheckBox(this, wxID_ANY, _(L("Update built-in Presets automatically")));
+ box_presets->SetValue(app_config->get("preset_update") == "1");
+ append(box_presets);
+
+ box_slic3r->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->version_check = event.IsChecked(); });
+ box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); });
+}
+
+PageVendors::PageVendors(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Other Vendors")), _(L("Other Vendors")))
+{
+ append_text(_(L("Pick another vendor supported by Slic3r PE:")));
+
+ const PresetBundle &bundle = wizard_p()->bundle_vendors;
+ auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ boldfont.SetWeight(wxFONTWEIGHT_BOLD);
+
+ AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors;
+ wxArrayString choices_vendors;
+
+ for (const auto &vendor : bundle.vendors) {
+ if (vendor.id == "PrusaResearch") { continue; }
+
+ auto *picker = new PrinterPicker(this, vendor, appconfig_vendors);
+ picker->Hide();
+ pickers.push_back(picker);
+ choices_vendors.Add(vendor.name);
+
+ picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) {
+ appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable);
+ this->on_variant_checked();
+ });
+ }
+
+ auto *vendor_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices_vendors);
+ if (choices_vendors.GetCount() > 0) {
+ vendor_picker->SetSelection(0);
+ on_vendor_pick(0);
+ }
+
+ vendor_picker->Bind(wxEVT_CHOICE, [this](wxCommandEvent &evt) {
+ this->on_vendor_pick(evt.GetInt());
+ });
+
+ append(vendor_picker);
+ for (PrinterPicker *picker : pickers) { this->append(picker); }
+}
+
+void PageVendors::on_page_set()
+{
+ on_variant_checked();
+}
+
+void PageVendors::on_vendor_pick(size_t i)
+{
+ for (PrinterPicker *picker : pickers) { picker->Hide(); }
+ if (i < pickers.size()) {
+ pickers[i]->Show();
+ wizard_p()->layout_fit();
+ }
+}
+
+void PageVendors::on_variant_checked()
+{
+ size_t variants_checked = 0;
+ for (const PrinterPicker *picker : pickers) { variants_checked += picker->variants_checked; }
+ enable_next(variants_checked > 0);
+}
+
+PageFirmware::PageFirmware(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware"))),
+ gcode_opt(print_config_def.options["gcode_flavor"]),
+ gcode_picker(nullptr)
+{
+ append_text(_(L("Choose the type of firmware used by your printer.")));
+ append_text(gcode_opt.tooltip);
+
+ wxArrayString choices;
+ choices.Alloc(gcode_opt.enum_labels.size());
+ for (const auto &label : gcode_opt.enum_labels) {
+ choices.Add(label);
+ }
+
+ gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
+ const auto &enum_values = gcode_opt.enum_values;
+ auto needle = enum_values.cend();
+ if (gcode_opt.default_value != nullptr) {
+ needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize());
+ }
+ if (needle != enum_values.cend()) {
+ gcode_picker->SetSelection(needle - enum_values.cbegin());
+ } else {
+ gcode_picker->SetSelection(0);
+ }
+
+ append(gcode_picker);
+}
+
+void PageFirmware::apply_custom_config(DynamicPrintConfig &config)
+{
+ ConfigOptionEnum<GCodeFlavor> opt;
+
+ auto sel = gcode_picker->GetSelection();
+ if (sel != wxNOT_FOUND && opt.deserialize(gcode_picker->GetString(sel).ToStdString())) {
+ config.set_key_value("gcode_flavor", &opt);
+ }
+}
+
+PageBedShape::PageBedShape(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Bed Shape and Size")), _(L("Bed Shape"))),
+ shape_panel(new BedShapePanel(this))
+{
+ append_text(_(L("Set the shape of your printer's bed.")));
+
+ shape_panel->build_panel(wizard_p()->custom_config->option<ConfigOptionPoints>("bed_shape"));
+ append(shape_panel);
+}
+
+void PageBedShape::apply_custom_config(DynamicPrintConfig &config)
+{
+ const auto points(shape_panel->GetValue());
+ auto *opt = new ConfigOptionPoints(points);
+ config.set_key_value("bed_shape", opt);
+}
+
+PageDiameters::PageDiameters(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Filament and Nozzle Diameters")), _(L("Print Diameters"))),
+ spin_nozzle(new wxSpinCtrlDouble(this, wxID_ANY)),
+ spin_filam(new wxSpinCtrlDouble(this, wxID_ANY))
+{
+ spin_nozzle->SetDigits(2);
+ spin_nozzle->SetIncrement(0.1);
+ const auto &def_nozzle = print_config_def.options["nozzle_diameter"];
+ auto *default_nozzle = dynamic_cast<const ConfigOptionFloats*>(def_nozzle.default_value);
+ spin_nozzle->SetValue(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5);
+
+ spin_filam->SetDigits(2);
+ spin_filam->SetIncrement(0.25);
+ const auto &def_filam = print_config_def.options["filament_diameter"];
+ auto *default_filam = dynamic_cast<const ConfigOptionFloats*>(def_filam.default_value);
+ spin_filam->SetValue(default_filam != nullptr && default_filam->size() > 0 ? default_filam->get_at(0) : 3.0);
+
+ append_text(_(L("Enter the diameter of your printer's hot end nozzle.")));
+
+ auto *sizer_nozzle = new wxFlexGridSizer(3, 5, 5);
+ auto *text_nozzle = new wxStaticText(this, wxID_ANY, _(L("Nozzle Diameter:")));
+ auto *unit_nozzle = new wxStaticText(this, wxID_ANY, _(L("mm")));
+ sizer_nozzle->AddGrowableCol(0, 1);
+ sizer_nozzle->Add(text_nozzle, 0, wxALIGN_CENTRE_VERTICAL);
+ sizer_nozzle->Add(spin_nozzle);
+ sizer_nozzle->Add(unit_nozzle, 0, wxALIGN_CENTRE_VERTICAL);
+ append(sizer_nozzle);
+
+ append_spacer(VERTICAL_SPACING);
+
+ append_text(_(L("Enter the diameter of your filament.")));
+ append_text(_(L("Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average.")));
+
+ auto *sizer_filam = new wxFlexGridSizer(3, 5, 5);
+ auto *text_filam = new wxStaticText(this, wxID_ANY, _(L("Filament Diameter:")));
+ auto *unit_filam = new wxStaticText(this, wxID_ANY, _(L("mm")));
+ sizer_filam->AddGrowableCol(0, 1);
+ sizer_filam->Add(text_filam, 0, wxALIGN_CENTRE_VERTICAL);
+ sizer_filam->Add(spin_filam);
+ sizer_filam->Add(unit_filam, 0, wxALIGN_CENTRE_VERTICAL);
+ append(sizer_filam);
+}
+
+void PageDiameters::apply_custom_config(DynamicPrintConfig &config)
+{
+ auto *opt_nozzle = new ConfigOptionFloats(1, spin_nozzle->GetValue());
+ config.set_key_value("nozzle_diameter", opt_nozzle);
+ auto *opt_filam = new ConfigOptionFloats(1, spin_filam->GetValue());
+ config.set_key_value("filament_diameter", opt_filam);
+}
+
+PageTemperatures::PageTemperatures(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Extruder and Bed Temperatures")), _(L("Temperatures"))),
+ spin_extr(new wxSpinCtrlDouble(this, wxID_ANY)),
+ spin_bed(new wxSpinCtrlDouble(this, wxID_ANY))
+{
+ spin_extr->SetIncrement(5.0);
+ const auto &def_extr = print_config_def.options["temperature"];
+ spin_extr->SetRange(def_extr.min, def_extr.max);
+ auto *default_extr = dynamic_cast<const ConfigOptionInts*>(def_extr.default_value);
+ spin_extr->SetValue(default_extr != nullptr && default_extr->size() > 0 ? default_extr->get_at(0) : 200);
+
+ spin_bed->SetIncrement(5.0);
+ const auto &def_bed = print_config_def.options["bed_temperature"];
+ spin_bed->SetRange(def_bed.min, def_bed.max);
+ auto *default_bed = dynamic_cast<const ConfigOptionInts*>(def_bed.default_value);
+ spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0);
+
+ append_text(_(L("Enter the temperature needed for extruding your filament.")));
+ append_text(_(L("A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS.")));
+
+ auto *sizer_extr = new wxFlexGridSizer(3, 5, 5);
+ auto *text_extr = new wxStaticText(this, wxID_ANY, _(L("Extrusion Temperature:")));
+ auto *unit_extr = new wxStaticText(this, wxID_ANY, _(L("°C")));
+ sizer_extr->AddGrowableCol(0, 1);
+ sizer_extr->Add(text_extr, 0, wxALIGN_CENTRE_VERTICAL);
+ sizer_extr->Add(spin_extr);
+ sizer_extr->Add(unit_extr, 0, wxALIGN_CENTRE_VERTICAL);
+ append(sizer_extr);
+
+ append_spacer(VERTICAL_SPACING);
+
+ append_text(_(L("Enter the bed temperature needed for getting your filament to stick to your heated bed.")));
+ append_text(_(L("A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed.")));
+
+ auto *sizer_bed = new wxFlexGridSizer(3, 5, 5);
+ auto *text_bed = new wxStaticText(this, wxID_ANY, _(L("Bed Temperature:")));
+ auto *unit_bed = new wxStaticText(this, wxID_ANY, _(L("°C")));
+ sizer_bed->AddGrowableCol(0, 1);
+ sizer_bed->Add(text_bed, 0, wxALIGN_CENTRE_VERTICAL);
+ sizer_bed->Add(spin_bed);
+ sizer_bed->Add(unit_bed, 0, wxALIGN_CENTRE_VERTICAL);
+ append(sizer_bed);
+}
+
+void PageTemperatures::apply_custom_config(DynamicPrintConfig &config)
+{
+ auto *opt_extr = new ConfigOptionInts(1, spin_extr->GetValue());
+ config.set_key_value("temperature", opt_extr);
+ auto *opt_extr1st = new ConfigOptionInts(1, spin_extr->GetValue());
+ config.set_key_value("first_layer_temperature", opt_extr1st);
+ auto *opt_bed = new ConfigOptionInts(1, spin_bed->GetValue());
+ config.set_key_value("bed_temperature", opt_bed);
+ auto *opt_bed1st = new ConfigOptionInts(1, spin_bed->GetValue());
+ config.set_key_value("first_layer_bed_temperature", opt_bed1st);
+}
+
+
+// Index
+
+ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) :
+ wxPanel(parent),
+ bg(GUI::from_u8(Slic3r::var("Slic3r_192px_transparent.png")), wxBITMAP_TYPE_PNG),
+ bullet_black(GUI::from_u8(Slic3r::var("bullet_black.png")), wxBITMAP_TYPE_PNG),
+ bullet_blue(GUI::from_u8(Slic3r::var("bullet_blue.png")), wxBITMAP_TYPE_PNG),
+ bullet_white(GUI::from_u8(Slic3r::var("bullet_white.png")), wxBITMAP_TYPE_PNG)
+{
+ SetMinSize(bg.GetSize());
+
+ wxClientDC dc(this);
+ text_height = dc.GetCharHeight();
+
+ // Add logo bitmap.
+ // This could be done in on_paint() along with the index labels, but I've found it tricky
+ // to get the bitmap rendered well on all platforms with transparent background.
+ // In some cases it didn't work at all. And so wxStaticBitmap is used here instead,
+ // because it has all the platform quirks figured out.
+ auto *sizer = new wxBoxSizer(wxVERTICAL);
+ auto *logo = new wxStaticBitmap(this, wxID_ANY, bg);
+ sizer->AddStretchSpacer();
+ sizer->Add(logo);
+ SetSizer(sizer);
+
+ Bind(wxEVT_PAINT, &ConfigWizardIndex::on_paint, this);
+}
+
+void ConfigWizardIndex::load_items(ConfigWizardPage *firstpage)
+{
+ items.clear();
+ item_active = items.cend();
+
+ for (auto *page = firstpage; page != nullptr; page = page->page_next()) {
+ items.emplace_back(page->shortname);
+ }
+
+ Refresh();
+}
+
+void ConfigWizardIndex::set_active(ConfigWizardPage *page)
+{
+ item_active = std::find(items.cbegin(), items.cend(), page->shortname);
+ Refresh();
+}
+
+void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
+{
+ enum {
+ MARGIN = 10,
+ SPACING = 5,
+ };
+
+ const auto size = GetClientSize();
+ if (size.GetHeight() == 0 || size.GetWidth() == 0) { return; }
+
+ wxPaintDC dc(this);
+
+ const auto bullet_w = bullet_black.GetSize().GetWidth();
+ const auto bullet_h = bullet_black.GetSize().GetHeight();
+ const int yoff_icon = bullet_h < text_height ? (text_height - bullet_h) / 2 : 0;
+ const int yoff_text = bullet_h > text_height ? (bullet_h - text_height) / 2 : 0;
+ const int yinc = std::max(bullet_h, text_height) + SPACING;
+
+ unsigned y = 0;
+ for (auto it = items.cbegin(); it != items.cend(); ++it) {
+ if (it < item_active) { dc.DrawBitmap(bullet_black, MARGIN, y + yoff_icon, false); }
+ if (it == item_active) { dc.DrawBitmap(bullet_blue, MARGIN, y + yoff_icon, false); }
+ if (it > item_active) { dc.DrawBitmap(bullet_white, MARGIN, y + yoff_icon, false); }
+ dc.DrawText(*it, MARGIN + bullet_w + SPACING, y + yoff_text);
+ y += yinc;
+ }
+}
+
+
+
+// priv
+
+void ConfigWizard::priv::load_vendors()
+{
+ const auto vendor_dir = fs::path(Slic3r::data_dir()) / "vendor";
+ for (fs::directory_iterator it(vendor_dir); it != fs::directory_iterator(); ++it) {
+ if (it->path().extension() == ".ini") {
+ bundle_vendors.load_configbundle(it->path().string(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY);
+ }
+ }
+
+ appconfig_vendors.set_vendors(*GUI::get_app_config());
+}
+
+void ConfigWizard::priv::index_refresh()
+{
+ index->load_items(page_welcome);
+}
+
+void ConfigWizard::priv::add_page(ConfigWizardPage *page)
+{
+ topsizer->Add(page, 0, wxEXPAND);
+
+ auto *extra_buttons = page->extra_buttons();
+ if (extra_buttons != nullptr) {
+ btnsizer->Prepend(extra_buttons, 0);
+ }
+}
+
+void ConfigWizard::priv::set_page(ConfigWizardPage *page)
+{
+ if (page == nullptr) { return; }
+ if (page_current != nullptr) { page_current->Hide(); }
+ page_current = page;
+ enable_next(true);
+
+ page->on_page_set();
+ index->load_items(page_welcome);
+ index->set_active(page);
+ page->Show();
+
+ btn_prev->Enable(page->page_prev() != nullptr);
+ btn_next->Show(page->page_next() != nullptr);
+ btn_finish->Show(page->page_next() == nullptr);
+
+ layout_fit();
+}
+
+void ConfigWizard::priv::layout_fit()
+{
+ q->Layout();
+ q->Fit();
+}
+
+void ConfigWizard::priv::enable_next(bool enable)
+{
+ btn_next->Enable(enable);
+ btn_finish->Enable(enable);
+}
+
+void ConfigWizard::priv::on_other_vendors()
+{
+ page_welcome
+ ->chain(page_vendors)
+ ->chain(page_update);
+ set_page(page_vendors);
+}
+
+void ConfigWizard::priv::on_custom_setup()
+{
+ page_welcome->chain(page_firmware);
+ page_temps->chain(page_update);
+ set_page(page_firmware);
+}
+
+void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle)
+{
+ const bool is_custom_setup = page_welcome->page_next() == page_firmware;
+
+ if (! is_custom_setup) {
+ app_config->set_vendors(appconfig_vendors);
+ app_config->set("version_check", page_update->version_check ? "1" : "0");
+ app_config->set("preset_update", page_update->preset_update ? "1" : "0");
+ app_config->reset_selections(); // XXX: only on "fresh start"?
+ preset_bundle->load_presets(*app_config);
+ } else {
+ for (ConfigWizardPage *page = page_firmware; page != nullptr; page = page->page_next()) {
+ page->apply_custom_config(*custom_config);
+ }
+ preset_bundle->load_config("My Settings", *custom_config);
+ }
+}
+
+// Public
+
+ConfigWizard::ConfigWizard(wxWindow *parent) :
+ wxDialog(parent, wxID_ANY, _(L("Configuration Assistant")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
+ p(new priv(this))
+{
+ p->load_vendors();
+ p->custom_config.reset(DynamicPrintConfig::new_from_defaults_keys({
+ "gcode_flavor", "bed_shape", "nozzle_diameter", "filament_diameter", "temperature", "bed_temperature",
+ }));
+
+ p->index = new ConfigWizardIndex(this);
+
+ auto *vsizer = new wxBoxSizer(wxVERTICAL);
+ p->topsizer = new wxBoxSizer(wxHORIZONTAL);
+ auto *hline = new wxStaticLine(this);
+ p->btnsizer = new wxBoxSizer(wxHORIZONTAL);
+
+ p->topsizer->Add(p->index, 0, wxEXPAND);
+ p->topsizer->AddSpacer(INDEX_MARGIN);
+
+ p->btn_prev = new wxButton(this, wxID_BACKWARD);
+ p->btn_next = new wxButton(this, wxID_FORWARD);
+ p->btn_finish = new wxButton(this, wxID_APPLY, _(L("&Finish")));
+ p->btn_cancel = new wxButton(this, wxID_CANCEL);
+ p->btnsizer->AddStretchSpacer();
+ p->btnsizer->Add(p->btn_prev, 0, wxLEFT, BTN_SPACING);
+ p->btnsizer->Add(p->btn_next, 0, wxLEFT, BTN_SPACING);
+ p->btnsizer->Add(p->btn_finish, 0, wxLEFT, BTN_SPACING);
+ p->btnsizer->Add(p->btn_cancel, 0, wxLEFT, BTN_SPACING);
+
+ p->add_page(p->page_welcome = new PageWelcome(this));
+ p->add_page(p->page_update = new PageUpdate(this));
+ p->add_page(p->page_vendors = new PageVendors(this));
+ p->add_page(p->page_firmware = new PageFirmware(this));
+ p->add_page(p->page_bed = new PageBedShape(this));
+ p->add_page(p->page_diams = new PageDiameters(this));
+ p->add_page(p->page_temps = new PageTemperatures(this));
+ p->index_refresh();
+
+ p->page_welcome->chain(p->page_update);
+ p->page_firmware
+ ->chain(p->page_bed)
+ ->chain(p->page_diams)
+ ->chain(p->page_temps);
+
+ vsizer->Add(p->topsizer, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
+ vsizer->Add(hline, 0, wxEXPAND);
+ vsizer->Add(p->btnsizer, 0, wxEXPAND | wxALL, DIALOG_MARGIN);
+
+ p->set_page(p->page_welcome);
+ SetSizerAndFit(vsizer);
+ SetMinSize(GetSize());
+
+ p->btn_prev->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_prev(); });
+ p->btn_next->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_next(); });
+ p->btn_finish->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->EndModal(wxID_OK); });
+}
+
+ConfigWizard::~ConfigWizard() {}
+
+bool ConfigWizard::run(wxWindow *parent, PresetBundle *preset_bundle)
+{
+ const auto profiles_dir = fs::path(resources_dir()) / "profiles";
+ for (fs::directory_iterator it(profiles_dir); it != fs::directory_iterator(); ++it) {
+ if (it->path().extension() == ".ini") {
+ PresetBundle::install_vendor_configbundle(it->path());
+ }
+ }
+
+ ConfigWizard wizard(parent);
+ if (wizard.ShowModal() == wxID_OK) {
+ wizard.p->apply_config(GUI::get_app_config(), preset_bundle);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+}
+}
diff --git a/xs/src/slic3r/GUI/ConfigWizard.hpp b/xs/src/slic3r/GUI/ConfigWizard.hpp
new file mode 100644
index 000000000..40ecf09a1
--- /dev/null
+++ b/xs/src/slic3r/GUI/ConfigWizard.hpp
@@ -0,0 +1,38 @@
+#ifndef slic3r_ConfigWizard_hpp_
+#define slic3r_ConfigWizard_hpp_
+
+#include <memory>
+
+#include <wx/dialog.h>
+
+namespace Slic3r {
+
+class PresetBundle;
+
+namespace GUI {
+
+
+class ConfigWizard: public wxDialog
+{
+public:
+ ConfigWizard(wxWindow *parent);
+ ConfigWizard(ConfigWizard &&) = delete;
+ ConfigWizard(const ConfigWizard &) = delete;
+ ConfigWizard &operator=(ConfigWizard &&) = delete;
+ ConfigWizard &operator=(const ConfigWizard &) = delete;
+ ~ConfigWizard();
+
+ static bool run(wxWindow *parent, PresetBundle *preset_bundle);
+private:
+ struct priv;
+ std::unique_ptr<priv> p;
+
+ friend class ConfigWizardPage;
+};
+
+
+
+}
+}
+
+#endif
diff --git a/xs/src/slic3r/GUI/ConfigWizard_private.hpp b/xs/src/slic3r/GUI/ConfigWizard_private.hpp
new file mode 100644
index 000000000..652328aaa
--- /dev/null
+++ b/xs/src/slic3r/GUI/ConfigWizard_private.hpp
@@ -0,0 +1,213 @@
+#ifndef slic3r_ConfigWizard_private_hpp_
+#define slic3r_ConfigWizard_private_hpp_
+
+#include "ConfigWizard.hpp"
+
+#include <vector>
+
+#include <wx/sizer.h>
+#include <wx/panel.h>
+#include <wx/button.h>
+#include <wx/choice.h>
+#include <wx/spinctrl.h>
+
+#include "libslic3r/PrintConfig.hpp"
+#include "AppConfig.hpp"
+#include "PresetBundle.hpp"
+#include "BedShapeDialog.hpp"
+
+
+namespace Slic3r {
+namespace GUI {
+
+
+enum {
+ CONTENT_WIDTH = 500,
+
+ DIALOG_MARGIN = 15,
+ INDEX_MARGIN = 40,
+ BTN_SPACING = 10,
+ INDENT_SPACING = 30,
+ VERTICAL_SPACING = 10,
+};
+
+struct PrinterPicker: wxPanel
+{
+ unsigned variants_checked;
+
+ PrinterPicker(wxWindow *parent, const VendorProfile &vendor, const AppConfig &appconfig_vendors);
+};
+
+struct ConfigWizardPage: wxPanel
+{
+ ConfigWizard *parent;
+ const wxString shortname;
+ wxBoxSizer *content;
+
+ ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname);
+
+ virtual ~ConfigWizardPage();
+
+ ConfigWizardPage* page_prev() const { return p_prev; }
+ ConfigWizardPage* page_next() const { return p_next; }
+ ConfigWizardPage* chain(ConfigWizardPage *page);
+
+ template<class T>
+ void append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
+ {
+ content->Add(thing, proportion, flag, border);
+ }
+
+ void append_text(wxString text);
+ void append_spacer(int space);
+
+ ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
+
+ virtual bool Show(bool show = true);
+ virtual bool Hide() { return Show(false); }
+ virtual wxPanel* extra_buttons() { return nullptr; }
+ virtual void on_page_set() {}
+ virtual void apply_custom_config(DynamicPrintConfig &config) {}
+
+ void enable_next(bool enable);
+private:
+ ConfigWizardPage *p_prev;
+ ConfigWizardPage *p_next;
+};
+
+struct PageWelcome: ConfigWizardPage
+{
+ PrinterPicker *printer_picker;
+ wxPanel *others_buttons;
+
+ PageWelcome(ConfigWizard *parent);
+
+ virtual wxPanel* extra_buttons() { return others_buttons; }
+ virtual void on_page_set();
+
+ void on_variant_checked();
+};
+
+struct PageUpdate: ConfigWizardPage
+{
+ bool version_check;
+ bool preset_update;
+
+ PageUpdate(ConfigWizard *parent);
+};
+
+struct PageVendors: ConfigWizardPage
+{
+ std::vector<PrinterPicker*> pickers;
+
+ PageVendors(ConfigWizard *parent);
+
+ virtual void on_page_set();
+
+ void on_vendor_pick(size_t i);
+ void on_variant_checked();
+};
+
+struct PageFirmware: ConfigWizardPage
+{
+ const ConfigOptionDef &gcode_opt;
+ wxChoice *gcode_picker;
+
+ PageFirmware(ConfigWizard *parent);
+ virtual void apply_custom_config(DynamicPrintConfig &config);
+};
+
+struct PageBedShape: ConfigWizardPage
+{
+ BedShapePanel *shape_panel;
+
+ PageBedShape(ConfigWizard *parent);
+ virtual void apply_custom_config(DynamicPrintConfig &config);
+};
+
+struct PageDiameters: ConfigWizardPage
+{
+ wxSpinCtrlDouble *spin_nozzle;
+ wxSpinCtrlDouble *spin_filam;
+
+ PageDiameters(ConfigWizard *parent);
+ virtual void apply_custom_config(DynamicPrintConfig &config);
+};
+
+struct PageTemperatures: ConfigWizardPage
+{
+ wxSpinCtrlDouble *spin_extr;
+ wxSpinCtrlDouble *spin_bed;
+
+ PageTemperatures(ConfigWizard *parent);
+ virtual void apply_custom_config(DynamicPrintConfig &config);
+};
+
+
+class ConfigWizardIndex: public wxPanel
+{
+public:
+ ConfigWizardIndex(wxWindow *parent);
+
+ void load_items(ConfigWizardPage *firstpage);
+ void set_active(ConfigWizardPage *page);
+private:
+ const wxBitmap bg;
+ const wxBitmap bullet_black;
+ const wxBitmap bullet_blue;
+ const wxBitmap bullet_white;
+ int text_height;
+
+ std::vector<wxString> items;
+ std::vector<wxString>::const_iterator item_active;
+
+ void on_paint(wxPaintEvent &evt);
+};
+
+struct ConfigWizard::priv
+{
+ ConfigWizard *q;
+ AppConfig appconfig_vendors;
+ PresetBundle bundle_vendors;
+ std::unique_ptr<DynamicPrintConfig> custom_config;
+
+ wxBoxSizer *topsizer = nullptr;
+ wxBoxSizer *btnsizer = nullptr;
+ ConfigWizardPage *page_current = nullptr;
+ ConfigWizardIndex *index = nullptr;
+ wxButton *btn_prev = nullptr;
+ wxButton *btn_next = nullptr;
+ wxButton *btn_finish = nullptr;
+ wxButton *btn_cancel = nullptr;
+
+ PageWelcome *page_welcome = nullptr;
+ PageUpdate *page_update = nullptr;
+ PageVendors *page_vendors = nullptr;
+ PageFirmware *page_firmware = nullptr;
+ PageBedShape *page_bed = nullptr;
+ PageDiameters *page_diams = nullptr;
+ PageTemperatures *page_temps = nullptr;
+
+ priv(ConfigWizard *q) : q(q) {}
+
+ void load_vendors();
+ void add_page(ConfigWizardPage *page);
+ void index_refresh();
+ void set_page(ConfigWizardPage *page);
+ void layout_fit();
+ void go_prev() { if (page_current != nullptr) { set_page(page_current->page_prev()); } }
+ void go_next() { if (page_current != nullptr) { set_page(page_current->page_next()); } }
+ void enable_next(bool enable);
+
+ void on_other_vendors();
+ void on_custom_setup();
+
+ void apply_config(AppConfig *app_config, PresetBundle *preset_bundle);
+};
+
+
+
+}
+}
+
+#endif
diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp
index 0a163bf28..dcb21f644 100644
--- a/xs/src/slic3r/GUI/GUI.cpp
+++ b/xs/src/slic3r/GUI/GUI.cpp
@@ -46,6 +46,7 @@
#include "AppConfig.hpp"
#include "ConfigSnapshotDialog.hpp"
#include "Utils.hpp"
+#include "ConfigWizard.hpp"
#include "Preferences.hpp"
#include "PresetBundle.hpp"
@@ -397,6 +398,21 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l
menu->Append(local_menu, _(L("&Configuration")));
}
+bool open_config_wizard(PresetBundle *preset_bundle)
+{
+ if (g_wxMainFrame == nullptr) {
+ throw std::runtime_error("Main frame not set");
+ }
+
+ return ConfigWizard::run(g_wxMainFrame, preset_bundle);
+}
+
+void open_preferences_dialog(int event_preferences)
+{
+ auto dlg = new PreferencesDialog(g_wxMainFrame, event_preferences);
+ dlg->ShowModal();
+}
+
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed)
{
add_created_tab(new TabPrint (g_wxTabPanel, no_controller));
diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp
index 0cbdf8729..938eed498 100644
--- a/xs/src/slic3r/GUI/GUI.hpp
+++ b/xs/src/slic3r/GUI/GUI.hpp
@@ -84,6 +84,12 @@ wxColour* get_sys_label_clr();
void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_language_change);
+// Opens the first-time configuration wizard, returns true if wizard is finished & accepted.
+bool open_config_wizard(PresetBundle *preset_bundle);
+
+// Create "Preferences" dialog after selecting menu "Preferences" in Perl part
+void open_preferences_dialog(int event_preferences);
+
// Create a new preset tab (print, filament and printer),
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed);
TabIface* get_preset_tab_iface(char *name);
diff --git a/xs/src/slic3r/GUI/Preferences.cpp b/xs/src/slic3r/GUI/Preferences.cpp
index 0009b17ec..6731cd394 100644
--- a/xs/src/slic3r/GUI/Preferences.cpp
+++ b/xs/src/slic3r/GUI/Preferences.cpp
@@ -14,6 +14,7 @@ void PreferencesDialog::build()
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
};
+ // TODO
// $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
// opt_id = > 'version_check',
// type = > 'bool',
diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp
index c437f8b41..66836074e 100644
--- a/xs/src/slic3r/GUI/Preset.cpp
+++ b/xs/src/slic3r/GUI/Preset.cpp
@@ -2,6 +2,7 @@
#include <cassert>
#include "Preset.hpp"
+#include "AppConfig.hpp"
#include <fstream>
#include <boost/filesystem.hpp>
@@ -175,6 +176,15 @@ bool Preset::update_compatible_with_printer(const Preset &active_printer, const
return this->is_compatible = is_compatible_with_printer(active_printer, extra_config);
}
+void Preset::set_visible_from_appconfig(const AppConfig &app_config)
+{
+ if (vendor == nullptr) { return; }
+ const std::string &model = config.opt_string("printer_model");
+ const std::string &variant = config.opt_string("printer_variant");
+ if (model.empty() || variant.empty()) { return; }
+ is_visible = app_config.get_variant(vendor->id, model, variant);
+}
+
const std::vector<std::string>& Preset::print_options()
{
static std::vector<std::string> s_opts {
diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp
index 3634c5dd9..4f734b85e 100644
--- a/xs/src/slic3r/GUI/Preset.hpp
+++ b/xs/src/slic3r/GUI/Preset.hpp
@@ -13,6 +13,8 @@ class wxItemContainer;
namespace Slic3r {
+class AppConfig;
+
enum ConfigFileType
{
CONFIG_FILE_TYPE_UNKNOWN,
@@ -35,14 +37,12 @@ public:
PrinterVariant() {}
PrinterVariant(const std::string &name) : name(name) {}
std::string name;
- bool enabled = true;
};
struct PrinterModel {
PrinterModel() {}
- PrinterModel(const std::string &name) : name(name) {}
+ std::string id;
std::string name;
- bool enabled = true;
std::vector<PrinterVariant> variants;
PrinterVariant* variant(const std::string &name) {
for (auto &v : this->variants)
@@ -51,11 +51,10 @@ public:
return nullptr;
}
const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
-
- bool operator< (const PrinterModel &rhs) const { return this->name < rhs.name; }
- bool operator==(const PrinterModel &rhs) const { return this->name == rhs.name; }
};
- std::set<PrinterModel> models;
+ std::vector<PrinterModel> models;
+
+ VendorProfile(std::string id) : id(std::move(id)) {}
size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
@@ -86,7 +85,8 @@ public:
bool is_external = false;
// System preset is read-only.
bool is_system = false;
- // Preset is visible, if it is compatible with the active Printer.
+ // Preset is visible, if it is associated with a printer model / variant that is enabled in the AppConfig
+ // or if it has no printer model / variant association.
// Also the "default" preset is only visible, if it is the only preset in the list.
bool is_visible = true;
// Has this preset been modified?
@@ -132,6 +132,9 @@ public:
// 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);
+ // Set is_visible according to application config
+ void set_visible_from_appconfig(const AppConfig &app_config);
+
// Resize the extruder specific fields, initialize them with the content of the 1st extruder.
void set_num_extruders(unsigned int n) { set_num_extruders(this->config, n); }
@@ -163,6 +166,13 @@ public:
PresetCollection(Preset::Type type, const std::vector<std::string> &keys);
~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(); }
+
void reset(bool delete_files);
Preset::Type type() const { return m_type; }
diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp
index 7131bf771..bd9e35ca8 100644
--- a/xs/src/slic3r/GUI/PresetBundle.cpp
+++ b/xs/src/slic3r/GUI/PresetBundle.cpp
@@ -4,6 +4,7 @@
#include "PresetBundle.hpp"
#include "BitmapCache.hpp"
+#include <algorithm>
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/algorithm/clamp.hpp>
@@ -104,6 +105,7 @@ void PresetBundle::setup_directories()
std::initializer_list<boost::filesystem::path> paths = {
data_dir,
data_dir / "vendor",
+ data_dir / "cache", // TODO: rename as vendor-cache? (Check usage elsewhere!)
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
// Store the print/filament/printer presets into a "presets" directory.
data_dir / "presets",
@@ -198,7 +200,9 @@ static inline std::string remove_ini_suffix(const std::string &name)
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
void PresetBundle::load_installed_printers(const AppConfig &config)
{
- // m_storage
+ for (auto &preset : printers) {
+ preset.set_visible_from_appconfig(config);
+ }
}
// Load selections (current print, current filaments, current printer) from config.ini
@@ -218,6 +222,10 @@ void PresetBundle::load_selections(const AppConfig &config)
break;
this->set_filament_preset(i, remove_ini_suffix(config.get("presets", name)));
}
+
+ // Update visibility of presets based on application vendor / model / variant configuration.
+ this->load_installed_printers(config);
+
// 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,
// as the application may have been closed with an active "external" preset, which does not
@@ -667,7 +675,7 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree)
static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorProfile &vendor_profile)
{
const std::string printer_model_key = "printer_model:";
- for (auto &section : tree)
+ for (auto &section : tree) {
if (section.first == "vendor") {
// Load the names of the active presets.
for (auto &kvp : section.second) {
@@ -682,7 +690,8 @@ static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorP
}
} else if (boost::starts_with(section.first, printer_model_key)) {
VendorProfile::PrinterModel model;
- model.name = section.first.substr(printer_model_key.size());
+ model.id = section.first.substr(printer_model_key.size());
+ model.name = section.second.get<std::string>("name", model.id);
section.second.get<std::string>("variants", "");
std::vector<std::string> variants;
if (Slic3r::unescape_strings_cstyle(section.second.get<std::string>("variants", ""), variants)) {
@@ -693,9 +702,10 @@ static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorP
} else {
// Log error?
}
- if (! model.name.empty() && ! model.variants.empty())
- vendor_profile.models.insert(model);
+ if (! model.id.empty() && ! model.variants.empty())
+ vendor_profile.models.push_back(std::move(model));
}
+ }
}
// Load a config bundle file, into presets and store the loaded presets into separate files
@@ -703,6 +713,11 @@ static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorP
void PresetBundle::install_vendor_configbundle(const std::string &src_path0)
{
boost::filesystem::path src_path(src_path0);
+ install_vendor_configbundle(src_path);
+}
+
+void PresetBundle::install_vendor_configbundle(const boost::filesystem::path &src_path)
+{
boost::filesystem::copy_file(src_path, (boost::filesystem::path(data_dir()) / "vendor" / src_path.filename()).make_preferred(), boost::filesystem::copy_option::overwrite_if_exists);
}
@@ -719,12 +734,11 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
pt::ptree tree;
boost::nowide::ifstream ifs(path);
pt::read_ini(ifs, tree);
- // Flatten the config bundle by applying the inheritance rules. Internal profiles (with names starting with '*') are removed.
- flatten_configbundle_hierarchy(tree);
const VendorProfile *vendor_profile = nullptr;
- if (flags & LOAD_CFGBNDLE_SYSTEM) {
- VendorProfile vp;
+ if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) {
+ boost::filesystem::path fspath(path);
+ VendorProfile vp(fspath.stem().string());
load_vendor_profile(tree, vp);
if (vp.name.empty())
throw std::runtime_error(std::string("Vendor Config Bundle is not valid: Missing vendor name key."));
@@ -732,6 +746,13 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
return 0;
vendor_profile = &(*this->vendors.insert(vp).first);
}
+
+ if (flags & LOAD_CFGBUNDLE_VENDOR_ONLY) {
+ return 0;
+ }
+
+ // 1.5) Flatten the config bundle by applying the inheritance rules. Internal profiles (with names starting with '*') are removed.
+ flatten_configbundle_hierarchy(tree);
// 2) Parse the property_tree, extract the active preset names and the profiles, save them into local config files.
std::vector<std::string> loaded_prints;
@@ -803,7 +824,9 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
section.first << "\" defines no printer variant, it will be ignored.";
continue;
}
- auto it_model = vendor_profile->models.find(VendorProfile::PrinterModel(printer_model));
+ auto it_model = std::find_if(vendor_profile->models.cbegin(), vendor_profile->models.cend(),
+ [&](const VendorProfile::PrinterModel &m) { return m.id == printer_model; }
+ );
if (it_model == vendor_profile->models.end()) {
BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
section.first << "\" defines invalid printer model \"" << printer_model << "\", it will be ignored.";
diff --git a/xs/src/slic3r/GUI/PresetBundle.hpp b/xs/src/slic3r/GUI/PresetBundle.hpp
index f481ba374..4189e6c46 100644
--- a/xs/src/slic3r/GUI/PresetBundle.hpp
+++ b/xs/src/slic3r/GUI/PresetBundle.hpp
@@ -5,6 +5,7 @@
#include "Preset.hpp"
#include <set>
+#include <boost/filesystem/path.hpp>
namespace Slic3r {
@@ -81,12 +82,14 @@ public:
LOAD_CFGBNDLE_RESET_USER_PROFILE = 2,
// Load a system config bundle.
LOAD_CFGBNDLE_SYSTEM = 4,
+ LOAD_CFGBUNDLE_VENDOR_ONLY = 8,
};
// Load the config bundle, store it to the user profile directory by default.
size_t load_configbundle(const std::string &path, unsigned int flags = LOAD_CFGBNDLE_SAVE);
// Install the Vendor specific config bundle into user's directory.
void install_vendor_configbundle(const std::string &src_path);
+ static void install_vendor_configbundle(const boost::filesystem::path &src_path);
// Export a config bundle file containing all the presets and the names of the active presets.
void export_configbundle(const std::string &path); // , const DynamicPrintConfig &settings);
diff --git a/xs/src/slic3r/Utils/PresetUpdater.cpp b/xs/src/slic3r/Utils/PresetUpdater.cpp
new file mode 100644
index 000000000..040d326b5
--- /dev/null
+++ b/xs/src/slic3r/Utils/PresetUpdater.cpp
@@ -0,0 +1,137 @@
+#include "PresetUpdater.hpp"
+
+#include <iostream> // XXX
+#include <thread>
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/fstream.hpp>
+
+#include <wx/app.h>
+#include <wx/event.h>
+
+#include "libslic3r/Utils.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/PresetBundle.hpp"
+#include "slic3r/Utils/Http.hpp"
+#include "slic3r/Utils/Semver.hpp"
+
+namespace fs = boost::filesystem;
+
+
+namespace Slic3r {
+
+
+// TODO: proper URL
+static const std::string SLIC3R_VERSION_URL = "https://gist.githubusercontent.com/vojtechkral/4d8fd4a3b8699a01ec892c264178461c/raw/e9187c3e15ceaf1a90f29b7c43cf3ccc746140f0/slic3rPE.version";
+enum {
+ SLIC3R_VERSION_BODY_MAX = 256,
+};
+
+struct PresetUpdater::priv
+{
+ int version_online_event;
+ bool version_check;
+ bool preset_update;
+
+ fs::path cache_path;
+ bool cancel;
+ std::thread thread;
+
+ priv(int event);
+
+ void download(const std::set<VendorProfile> vendors) const;
+};
+
+PresetUpdater::priv::priv(int event) :
+ version_online_event(event),
+ version_check(false),
+ preset_update(false),
+ cache_path(fs::path(Slic3r::data_dir()) / "cache"),
+ cancel(false)
+{}
+
+void PresetUpdater::priv::download(const std::set<VendorProfile> vendors) const
+{
+ std::cerr << "PresetUpdater::priv::download()" << std::endl;
+
+ if (!version_check) { return; }
+
+ // Download current Slic3r version
+ Http::get(SLIC3R_VERSION_URL)
+ .size_limit(SLIC3R_VERSION_BODY_MAX)
+ .on_progress([this](Http::Progress, bool &cancel) {
+ cancel = this->cancel;
+ })
+ .on_complete([&](std::string body, unsigned http_status) {
+ boost::trim(body);
+ std::cerr << "Got version: " << http_status << ", body: \"" << body << '"' << std::endl;
+ wxCommandEvent* evt = new wxCommandEvent(version_online_event);
+ evt->SetString(body);
+ GUI::get_app()->QueueEvent(evt);
+ })
+ .perform_sync();
+
+ if (!preset_update) { return; }
+
+ // Donwload vendor preset bundles
+ std::cerr << "Bundle vendors: " << vendors.size() << std::endl;
+ for (const auto &vendor : vendors) {
+ std::cerr << "vendor: " << vendor.name << std::endl;
+ std::cerr << " URL: " << vendor.config_update_url << std::endl;
+
+ if (cancel) { return; }
+
+ // TODO: Proper caching
+
+ auto target_path = cache_path / vendor.id;
+ target_path += ".ini";
+ std::cerr << "target_path: " << target_path << std::endl;
+
+ Http::get(vendor.config_update_url)
+ .on_progress([this](Http::Progress, bool &cancel) {
+ cancel = this->cancel;
+ })
+ .on_complete([&](std::string body, unsigned http_status) {
+ std::cerr << "Got ini: " << http_status << ", body: " << body.size() << std::endl;
+ fs::fstream file(target_path, std::ios::out | std::ios::binary | std::ios::trunc);
+ file.write(body.c_str(), body.size());
+ })
+ .perform_sync();
+ }
+}
+
+PresetUpdater::PresetUpdater(int version_online_event, AppConfig *app_config) :
+ p(new priv(version_online_event))
+{
+ p->preset_update = app_config->get("preset_update") == "1";
+ // preset_update implies version_check:
+ p->version_check = p->preset_update || app_config->get("version_check") == "1";
+}
+
+
+// Public
+
+PresetUpdater::~PresetUpdater()
+{
+ if (p && p->thread.joinable()) {
+ p->cancel = true;
+ p->thread.join();
+ }
+}
+
+void PresetUpdater::download(PresetBundle *preset_bundle)
+{
+ std::cerr << "PresetUpdater::download()" << std::endl;
+
+ // Copy the whole vendors data for use in the background thread
+ // Unfortunatelly as of C++11, it needs to be copied again
+ // into the closure (but perhaps the compiler can elide this).
+ std::set<VendorProfile> vendors = preset_bundle->vendors;
+
+ p->thread = std::move(std::thread([this, vendors]() {
+ this->p->download(std::move(vendors));
+ }));
+}
+
+
+}
diff --git a/xs/src/slic3r/Utils/PresetUpdater.hpp b/xs/src/slic3r/Utils/PresetUpdater.hpp
new file mode 100644
index 000000000..aafe9569b
--- /dev/null
+++ b/xs/src/slic3r/Utils/PresetUpdater.hpp
@@ -0,0 +1,30 @@
+#ifndef slic3r_PresetUpdate_hpp_
+#define slic3r_PresetUpdate_hpp_
+
+#include <memory>
+
+namespace Slic3r {
+
+
+class AppConfig;
+class PresetBundle;
+
+class PresetUpdater
+{
+public:
+ PresetUpdater(int version_online_event, AppConfig *app_config);
+ PresetUpdater(PresetUpdater &&) = delete;
+ PresetUpdater(const PresetUpdater &) = delete;
+ PresetUpdater &operator=(PresetUpdater &&) = delete;
+ PresetUpdater &operator=(const PresetUpdater &) = delete;
+ ~PresetUpdater();
+
+ void download(PresetBundle *preset_bundle);
+private:
+ struct priv;
+ std::unique_ptr<priv> p;
+};
+
+
+}
+#endif
diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp
index c8d76adba..8dba13caf 100644
--- a/xs/xsp/GUI.xsp
+++ b/xs/xsp/GUI.xsp
@@ -57,6 +57,12 @@ int combochecklist_get_flags(SV *ui)
void set_app_config(AppConfig *app_config)
%code%{ Slic3r::GUI::set_app_config(app_config); %};
+bool open_config_wizard(PresetBundle *preset_bundle)
+ %code%{ RETVAL=Slic3r::GUI::open_config_wizard(preset_bundle); %};
+
+void open_preferences_dialog(int preferences_event)
+ %code%{ Slic3r::GUI::open_preferences_dialog(preferences_event); %};
+
void set_preset_bundle(PresetBundle *preset_bundle)
%code%{ Slic3r::GUI::set_preset_bundle(preset_bundle); %};
diff --git a/xs/xsp/GUI_AppConfig.xsp b/xs/xsp/GUI_AppConfig.xsp
index 08a88883d..de0e5a22b 100644
--- a/xs/xsp/GUI_AppConfig.xsp
+++ b/xs/xsp/GUI_AppConfig.xsp
@@ -43,4 +43,5 @@
void update_last_output_dir(char *dir);
void reset_selections();
+ bool slic3r_update_avail() const;
};
diff --git a/xs/xsp/GUI_Preset.xsp b/xs/xsp/GUI_Preset.xsp
index 84efdde53..1187a1cf5 100644
--- a/xs/xsp/GUI_Preset.xsp
+++ b/xs/xsp/GUI_Preset.xsp
@@ -147,7 +147,7 @@ PresetCollection::arrayref()
void install_vendor_configbundle(const char *path)
%code%{
try {
- THIS->install_vendor_configbundle(path);
+ THIS->install_vendor_configbundle(std::string(path));
} catch (std::exception& e) {
croak("Installing a vendor config bundle %s failed:\n%s\n", path, e.what());
}
diff --git a/xs/xsp/Utils_PresetUpdater.xsp b/xs/xsp/Utils_PresetUpdater.xsp
new file mode 100644
index 000000000..666379f02
--- /dev/null
+++ b/xs/xsp/Utils_PresetUpdater.xsp
@@ -0,0 +1,11 @@
+%module{Slic3r::XS};
+
+%{
+#include <xsinit.h>
+#include "slic3r/Utils/PresetUpdater.hpp"
+%}
+
+%name{Slic3r::PresetUpdater} class PresetUpdater {
+ PresetUpdater(int version_online_event, AppConfig *app_config);
+ void download(PresetBundle* preset_bundle);
+};
diff --git a/xs/xsp/my.map b/xs/xsp/my.map
index 87a8d8d86..c1ca58827 100644
--- a/xs/xsp/my.map
+++ b/xs/xsp/my.map
@@ -236,6 +236,10 @@ Ref<PresetHints> O_OBJECT_SLIC3R_T
TabIface* O_OBJECT_SLIC3R
Ref<TabIface> O_OBJECT_SLIC3R_T
+PresetUpdater* O_OBJECT_SLIC3R
+Ref<PresetUpdater> O_OBJECT_SLIC3R_T
+Clone<PresetUpdater> O_OBJECT_SLIC3R_T
+
OctoPrint* O_OBJECT_SLIC3R
Ref<OctoPrint> O_OBJECT_SLIC3R_T
Clone<OctoPrint> O_OBJECT_SLIC3R_T