diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb3d6dfd6c..e8b2a6faaa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,7 +22,6 @@ option(SLIC3R_STATIC "Compile Slic3r with static libraries (Boost, TBB, glew)
option(SLIC3R_GUI "Compile Slic3r with GUI components (OpenGL, wxWidgets)" 1)
option(SLIC3R_PRUSACONTROL "Compile Slic3r with the PrusaControl prject file format (requires wxWidgets base library)" 1)
option(SLIC3R_PROFILE "Compile Slic3r with an invasive Shiny profiler" 0)
-option(SLIC3R_HAS_BROKEN_CROAK "Compile Slic3r for a broken Strawberry Perl 64bit" 0)
option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
if (MSVC AND SLIC3R_MSVC_COMPILE_PARALLEL)
diff --git a/cmake/msvc/xs.wperl64d.props b/cmake/msvc/xs.wperl.props.in
similarity index 61%
rename from cmake/msvc/xs.wperl64d.props
rename to cmake/msvc/xs.wperl.props.in
index b604a56e23..5c7461dc71 100644
--- a/cmake/msvc/xs.wperl64d.props
+++ b/cmake/msvc/xs.wperl.props.in
@@ -1,18 +1,22 @@
+
- $(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(FxCopDir);$(PATH);c:\wperl64d\bin\;
+ $(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(FxCopDir);$(PATH);${PROPS_PERL_BIN_PATH}\;
- C:\wperl64d\bin\perl.exe
+ ${PROPS_PERL_EXECUTABLE}
slic3r.pl
WindowsLocalDebugger
- ..\..
+ ${PROPS_CMAKE_SOURCE_DIR}
diff --git a/doc/updating/Updatig.md b/doc/updating/Updatig.md
new file mode 100644
index 0000000000..3ce1f109c4
--- /dev/null
+++ b/doc/updating/Updatig.md
@@ -0,0 +1,52 @@
+# Slic3r PE 1.40 configuration update
+
+Slic3r PE 1.40.0 comes with a major re-work of the way configuration presets work.
+There are three new features:
+
++ A two-tier system of presets being divided into _System_ and _User_ groups
++ Configuration snapshots
++ Configuration updating from the internet
+
+## System and User presets
+
+- _System preset_: These are the presets that come with Slic3r PE installation. They come from a vendor configuration bundle (not individual files like before). They are **read-only** – a user cannot modify them, but may instead create a derived User preset based on a System preset
+- _User preset_: These are regular presets stored in files just like before. Additionally, they may be derived (inherited) from one of the System presets
+
+A derived User preset keeps track of wich settings are inherited from the parent System preset and which are modified by the user. When a system preset is updated (either via installation of a new Slic3r or automatically from the internet), in a User preset the settings that are modified by the user will stay that way, while the ones that are inherited reflect the updated System preset.
+
+This system ensures that we don't overwrite user's settings when there is an update to the built in presets.
+
+Slic3r GUI now displays accurately which settings are inherited and which are modified.
+A setting derived from a System preset is represeted by green label and a locked lock icon:
+
+
+
+A settings modified in a User preset has an open lock icon:
+
+
+
+Clickign the open lock icon restored the system setting.
+
+Additionaly, any setting that is modified but not yet saved onto disk is represented by orange label and a back-arrow:
+
+
+
+Clicking the back-arrow restores the value that was previously saved in this Preset.
+
+## Configuration snapshots
+
+Configuration snapshots can now be taken via the _Configuration_ menu.
+A snapshot contains complete configuration from the point when the snapshot was taken.
+Users may move back and forth between snapshots at will using a dialog:
+
+
+
+
+# Updating from the internet
+
+Slic3r PE 1.40.0 checks for updates of the built-in System presets and downloads them.
+The first-time configuration assistant will ask you if you want to enable this feature - it is **not** mandatory.
+
+Updates are checked for and downloaded in the background. If there's is an update, Slic3r will prompt about it
+next time it is launched, never during normal program operation. An update may be either accepted or refused.
+Before any update is applied a configuration snapshot (as described above) is taken.
diff --git a/doc/updating/setting_mod.png b/doc/updating/setting_mod.png
new file mode 100644
index 0000000000..e4d3b7e7bd
Binary files /dev/null and b/doc/updating/setting_mod.png differ
diff --git a/doc/updating/setting_sys.png b/doc/updating/setting_sys.png
new file mode 100644
index 0000000000..842a8bf736
Binary files /dev/null and b/doc/updating/setting_sys.png differ
diff --git a/doc/updating/setting_user.png b/doc/updating/setting_user.png
new file mode 100644
index 0000000000..ffec5e0f3e
Binary files /dev/null and b/doc/updating/setting_user.png differ
diff --git a/doc/updating/snapshots_dialog.png b/doc/updating/snapshots_dialog.png
new file mode 100644
index 0000000000..d4d2895505
Binary files /dev/null and b/doc/updating/snapshots_dialog.png differ
diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm
index e55e24a7ad..0c6c81bb57 100644
--- a/lib/Slic3r.pm
+++ b/lib/Slic3r.pm
@@ -161,7 +161,13 @@ sub thread_cleanup {
*Slic3r::Print::SupportMaterial2::DESTROY = sub {};
*Slic3r::TriangleMesh::DESTROY = sub {};
*Slic3r::GUI::AppConfig::DESTROY = sub {};
+ *Slic3r::GUI::GCodePreviewData::DESTROY = sub {};
*Slic3r::GUI::PresetBundle::DESTROY = sub {};
+ *Slic3r::GUI::Tab::DESTROY = sub {};
+ *Slic3r::GUI::PresetHints::DESTROY = sub {};
+ *Slic3r::GUI::TabIface::DESTROY = sub {};
+ *Slic3r::OctoPrint::DESTROY = sub {};
+ *Slic3r::PresetUpdater::DESTROY = sub {};
return undef; # this prevents a "Scalars leaked" warning
}
@@ -277,5 +283,6 @@ sub system_info
# this package declaration prevents an ugly fatal warning to be emitted when
# spawning a new thread
package GLUquadricObjPtr;
+package Wx::Printout;
1;
diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm
index 4ec388c147..04dc803231 100644
--- a/lib/Slic3r/GUI.pm
+++ b/lib/Slic3r/GUI.pm
@@ -7,9 +7,7 @@ use File::Basename qw(basename);
use FindBin;
use List::Util qw(first);
use Slic3r::GUI::2DBed;
-use Slic3r::GUI::AboutDialog;
use Slic3r::GUI::BedShapeDialog;
-use Slic3r::GUI::ConfigWizard;
use Slic3r::GUI::Controller;
use Slic3r::GUI::Controller::ManualControlDialog;
use Slic3r::GUI::Controller::PrinterPanel;
@@ -70,6 +68,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) = @_;
@@ -86,7 +86,9 @@ sub OnInit {
Slic3r::GUI::set_wxapp($self);
$self->{app_config} = Slic3r::GUI::AppConfig->new;
+ Slic3r::GUI::set_app_config($self->{app_config});
$self->{preset_bundle} = Slic3r::GUI::PresetBundle->new;
+ Slic3r::GUI::set_preset_bundle($self->{preset_bundle});
# just checking for existence of Slic3r::data_dir is not enough: it may be an empty directory
# supplied as argument to --datadir; in that case we should still run the wizard
@@ -95,13 +97,24 @@ sub OnInit {
warn $@ . "\n";
fatal_error(undef, $@);
}
- my $run_wizard = ! $self->{app_config}->exists;
+ my $app_conf_exists = $self->{app_config}->exists;
# load settings
- $self->{app_config}->load if ! $run_wizard;
+ $self->{app_config}->load if $app_conf_exists;
$self->{app_config}->set('version', $Slic3r::VERSION);
$self->{app_config}->save;
- Slic3r::GUI::set_app_config($self->{app_config});
+ $self->{preset_updater} = Slic3r::PresetUpdater->new($VERSION_ONLINE_EVENT);
+ Slic3r::GUI::set_preset_updater($self->{preset_updater});
+ eval {
+ if (! $self->{preset_updater}->config_update()) {
+ exit 0;
+ }
+ };
+ if ($@) {
+ warn $@ . "\n";
+ fatal_error(undef, $@);
+ }
+
Slic3r::GUI::load_language();
# Suppress the '- default -' presets.
@@ -111,11 +124,9 @@ sub OnInit {
warn $@ . "\n";
show_error(undef, $@);
}
- $run_wizard = 1 if $self->{preset_bundle}->has_defauls_only;
- Slic3r::GUI::set_preset_bundle($self->{preset_bundle});
-
# application frame
+ print STDERR "Creating main frame...\n";
Wx::Image::FindHandlerType(wxBITMAP_TYPE_PNG) || Wx::Image::AddHandler(Wx::PNGHandler->new);
$self->{mainframe} = my $frame = Slic3r::GUI::MainFrame->new(
# If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden.
@@ -126,7 +137,6 @@ sub OnInit {
);
$self->SetTopWindow($frame);
- #EVT_IDLE($frame, sub {
EVT_IDLE($self->{mainframe}, sub {
while (my $cb = shift @cb) {
$cb->();
@@ -134,17 +144,19 @@ 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 {
- # Run the config wizard, don't offer the "reset user profile" checkbox.
- $self->{mainframe}->config_wizard(1);
- });
- }
+ # On OSX the UI was not initialized correctly if the wizard was called
+ # before the UI was up and running.
+ $self->CallAfter(sub {
+ if (! Slic3r::GUI::config_wizard_startup($app_conf_exists)) {
+ # Only notify if there was not wizard so as not to bother too much ...
+ $self->{preset_updater}->slic3r_update_notify();
+ }
+ $self->{preset_updater}->sync($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{
+ print STDERR "LANGUAGE_CHANGE_EVENT\n";
$self->recreate_GUI;
});
@@ -153,10 +165,19 @@ 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;
}
sub recreate_GUI{
+ print STDERR "recreate_GUI\n";
my ($self) = @_;
my $topwindow = $self->GetTopWindow();
$self->{mainframe} = my $frame = Slic3r::GUI::MainFrame->new(
@@ -180,22 +201,12 @@ sub recreate_GUI{
$self->{app_config}->save if $self->{app_config}->dirty;
});
- my $run_wizard = 1 if $self->{preset_bundle}->has_defauls_only;
- 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 {
- # Run the config wizard, don't offer the "reset user profile" checkbox.
- $self->{mainframe}->config_wizard(1);
- });
- }
-}
-
-sub about {
- my ($self) = @_;
- my $about = Slic3r::GUI::AboutDialog->new(undef);
- $about->ShowModal;
- $about->Destroy;
+ # On OSX the UI was not initialized correctly if the wizard was called
+ # before the UI was up and running.
+ $self->CallAfter(sub {
+ # Run the config wizard, don't offer the "reset user profile" checkbox.
+ Slic3r::GUI::config_wizard_startup(1);
+ });
}
sub system_info {
@@ -238,7 +249,7 @@ sub catch_error {
# static method accepting a wxWindow object as first parameter
sub show_error {
my ($parent, $message) = @_;
- Wx::MessageDialog->new($parent, $message, 'Error', wxOK | wxICON_ERROR)->ShowModal;
+ Slic3r::GUI::show_error_id($parent ? $parent->GetId() : 0, $message);
}
# static method accepting a wxWindow object as first parameter
diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm
index 13460cfed2..1b6adf800e 100644
--- a/lib/Slic3r/GUI/3DScene.pm
+++ b/lib/Slic3r/GUI/3DScene.pm
@@ -70,6 +70,7 @@ __PACKAGE__->mk_accessors( qw(_quat _dirty init
_legend_enabled
_warning_enabled
_apply_zoom_to_volumes_filter
+ _mouse_dragging
) );
@@ -146,6 +147,7 @@ sub new {
$self->_warning_enabled(0);
$self->use_plain_shader(0);
$self->_apply_zoom_to_volumes_filter(0);
+ $self->_mouse_dragging(0);
# Collection of GLVolume objects
$self->volumes(Slic3r::GUI::_3DScene::GLVolume::Collection->new);
@@ -199,6 +201,10 @@ sub new {
$self->select_view('left');
} elsif ($key == ord('6')) {
$self->select_view('right');
+ } elsif ($key == ord('z')) {
+ $self->zoom_to_volumes;
+ } elsif ($key == ord('b')) {
+ $self->zoom_to_bed;
} else {
$event->Skip;
}
@@ -381,7 +387,9 @@ sub mouse_event {
my $pos = Slic3r::Pointf->new($e->GetPositionXY);
my $object_idx_selected = $self->{layer_height_edit_last_object_id} = ($self->layer_editing_enabled && $self->{print}) ? $self->_first_selected_object_id_for_variable_layer_height_editing : -1;
- if ($e->Entering && &Wx::wxMSW) {
+ $self->_mouse_dragging($e->Dragging);
+
+ if ($e->Entering && (&Wx::wxMSW || $^O eq 'linux')) {
# wxMSW needs focus in order to catch mouse wheel events
$self->SetFocus;
$self->_drag_start_xy(undef);
@@ -595,22 +603,23 @@ sub mouse_wheel_event {
$zoom = $zoom_min if defined $zoom_min && $zoom < $zoom_min;
$self->_zoom($zoom);
- # In order to zoom around the mouse point we need to translate
- # the camera target
- my $size = Slic3r::Pointf->new($self->GetSizeWH);
- my $pos = Slic3r::Pointf->new($e->GetX, $size->y - $e->GetY); #-
- $self->_camera_target->translate(
- # ($pos - $size/2) represents the vector from the viewport center
- # to the mouse point. By multiplying it by $zoom we get the new,
- # transformed, length of such vector.
- # Since we want that point to stay fixed, we move our camera target
- # in the opposite direction by the delta of the length of such vector
- # ($zoom - 1). We then scale everything by 1/$self->_zoom since
- # $self->_camera_target is expressed in terms of model units.
- -($pos->x - $size->x/2) * ($zoom) / $self->_zoom,
- -($pos->y - $size->y/2) * ($zoom) / $self->_zoom,
- 0,
- ) if 0;
+# # In order to zoom around the mouse point we need to translate
+# # the camera target
+# my $size = Slic3r::Pointf->new($self->GetSizeWH);
+# my $pos = Slic3r::Pointf->new($e->GetX, $size->y - $e->GetY); #-
+# $self->_camera_target->translate(
+# # ($pos - $size/2) represents the vector from the viewport center
+# # to the mouse point. By multiplying it by $zoom we get the new,
+# # transformed, length of such vector.
+# # Since we want that point to stay fixed, we move our camera target
+# # in the opposite direction by the delta of the length of such vector
+# # ($zoom - 1). We then scale everything by 1/$self->_zoom since
+# # $self->_camera_target is expressed in terms of model units.
+# -($pos->x - $size->x/2) * ($zoom) / $self->_zoom,
+# -($pos->y - $size->y/2) * ($zoom) / $self->_zoom,
+# 0,
+# ) if 0;
+
$self->on_viewport_changed->() if $self->on_viewport_changed;
$self->Resize($self->GetSizeWH) if $self->IsShownOnScreen;
$self->Refresh;
@@ -678,10 +687,85 @@ sub select_view {
}
sub get_zoom_to_bounding_box_factor {
- my ($self, $bb) = @_;
- return undef if ($bb->empty);
- my $max_size = max(@{$bb->size}) * 2;
- return ($max_size == 0) ? undef : min($self->GetSizeWH) / $max_size;
+ my ($self, $bb) = @_;
+ my $max_bb_size = max(@{ $bb->size });
+ return undef if ($max_bb_size == 0);
+
+ # project the bbox vertices on a plane perpendicular to the camera forward axis
+ # then calculates the vertices coordinate on this plane along the camera xy axes
+
+ # we need the view matrix, we let opengl calculate it (same as done in render sub)
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ if (!TURNTABLE_MODE) {
+ # Shift the perspective camera.
+ my $camera_pos = Slic3r::Pointf3->new(0,0,-$self->_camera_distance);
+ glTranslatef(@$camera_pos);
+ }
+
+ if (TURNTABLE_MODE) {
+ # Turntable mode is enabled by default.
+ glRotatef(-$self->_stheta, 1, 0, 0); # pitch
+ glRotatef($self->_sphi, 0, 0, 1); # yaw
+ } else {
+ # Shift the perspective camera.
+ my $camera_pos = Slic3r::Pointf3->new(0,0,-$self->_camera_distance);
+ glTranslatef(@$camera_pos);
+ my @rotmat = quat_to_rotmatrix($self->quat);
+ glMultMatrixd_p(@rotmat[0..15]);
+ }
+ glTranslatef(@{ $self->_camera_target->negative });
+
+ # get the view matrix back from opengl
+ my @matrix = glGetFloatv_p(GL_MODELVIEW_MATRIX);
+
+ # camera axes
+ my $right = Slic3r::Pointf3->new($matrix[0], $matrix[4], $matrix[8]);
+ my $up = Slic3r::Pointf3->new($matrix[1], $matrix[5], $matrix[9]);
+ my $forward = Slic3r::Pointf3->new($matrix[2], $matrix[6], $matrix[10]);
+
+ my $bb_min = $bb->min_point();
+ my $bb_max = $bb->max_point();
+ my $bb_center = $bb->center();
+
+ # bbox vertices in world space
+ my @vertices = ();
+ push(@vertices, $bb_min);
+ push(@vertices, Slic3r::Pointf3->new($bb_max->x(), $bb_min->y(), $bb_min->z()));
+ push(@vertices, Slic3r::Pointf3->new($bb_max->x(), $bb_max->y(), $bb_min->z()));
+ push(@vertices, Slic3r::Pointf3->new($bb_min->x(), $bb_max->y(), $bb_min->z()));
+ push(@vertices, Slic3r::Pointf3->new($bb_min->x(), $bb_min->y(), $bb_max->z()));
+ push(@vertices, Slic3r::Pointf3->new($bb_max->x(), $bb_min->y(), $bb_max->z()));
+ push(@vertices, $bb_max);
+ push(@vertices, Slic3r::Pointf3->new($bb_min->x(), $bb_max->y(), $bb_max->z()));
+
+ my $max_x = 0.0;
+ my $max_y = 0.0;
+
+ # margin factor to give some empty space around the bbox
+ my $margin_factor = 1.25;
+
+ foreach my $v (@vertices) {
+ # project vertex on the plane perpendicular to camera forward axis
+ my $pos = Slic3r::Pointf3->new($v->x() - $bb_center->x(), $v->y() - $bb_center->y(), $v->z() - $bb_center->z());
+ my $proj_on_normal = $pos->x() * $forward->x() + $pos->y() * $forward->y() + $pos->z() * $forward->z();
+ my $proj_on_plane = Slic3r::Pointf3->new($pos->x() - $proj_on_normal * $forward->x(), $pos->y() - $proj_on_normal * $forward->y(), $pos->z() - $proj_on_normal * $forward->z());
+
+ # calculates vertex coordinate along camera xy axes
+ my $x_on_plane = $proj_on_plane->x() * $right->x() + $proj_on_plane->y() * $right->y() + $proj_on_plane->z() * $right->z();
+ my $y_on_plane = $proj_on_plane->x() * $up->x() + $proj_on_plane->y() * $up->y() + $proj_on_plane->z() * $up->z();
+
+ $max_x = max($max_x, $margin_factor * 2 * abs($x_on_plane));
+ $max_y = max($max_y, $margin_factor * 2 * abs($y_on_plane));
+ }
+
+ return undef if (($max_x == 0) || ($max_y == 0));
+
+ my ($cw, $ch) = $self->GetSizeWH;
+ my $min_ratio = min($cw / $max_x, $ch / $max_y);
+
+ return $min_ratio;
}
sub zoom_to_bounding_box {
@@ -693,6 +777,8 @@ sub zoom_to_bounding_box {
# center view around bounding box center
$self->_camera_target($bb->center);
$self->on_viewport_changed->() if $self->on_viewport_changed;
+ $self->Resize($self->GetSizeWH) if $self->IsShownOnScreen;
+ $self->Refresh;
}
}
@@ -822,6 +908,9 @@ sub deselect_volumes {
sub select_volume {
my ($self, $volume_idx) = @_;
+
+ return if ($volume_idx >= scalar(@{$self->volumes}));
+
$self->volumes->[$volume_idx]->set_selected(1)
if $volume_idx != -1;
}
@@ -1027,8 +1116,8 @@ sub Resize {
#FIXME setting the size of the box 10x larger than necessary
# is only a workaround for an incorrectly set camera.
# This workaround harms Z-buffer accuracy!
-# my $depth = 1.05 * $self->max_bounding_box->radius();
- my $depth = 10.0 * $self->max_bounding_box->radius();
+# my $depth = 1.05 * $self->max_bounding_box->radius();
+ my $depth = 5.0 * max(@{ $self->max_bounding_box->size });
glOrtho(
-$x/2, $x/2, -$y/2, $y/2,
-$depth, $depth,
@@ -1066,6 +1155,8 @@ sub InitGL {
$self->volumes->finalize_geometry(1)
if ($^O eq 'linux' && $self->UseVBOs);
+ $self->zoom_to_bed;
+
glClearColor(0, 0, 0, 1);
glColor3f(1, 0, 0);
glEnable(GL_DEPTH_TEST);
@@ -1158,7 +1249,7 @@ sub Render {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- {
+ if (!TURNTABLE_MODE) {
# Shift the perspective camera.
my $camera_pos = Slic3r::Pointf3->new(0,0,-$self->_camera_distance);
glTranslatef(@$camera_pos);
@@ -1182,7 +1273,7 @@ sub Render {
# Head light
glLightfv_p(GL_LIGHT1, GL_POSITION, 1, 0, 1, 0);
- if ($self->enable_picking) {
+ if ($self->enable_picking && !$self->_mouse_dragging) {
if (my $pos = $self->_mouse_pos) {
# Render the object for picking.
# FIXME This cannot possibly work in a multi-sampled context as the color gets mangled by the anti-aliasing.
@@ -1281,10 +1372,7 @@ sub Render {
# disable depth testing so that axes are not covered by ground
glDisable(GL_DEPTH_TEST);
my $origin = $self->origin;
- my $axis_len = max(
- 0.3 * max(@{ $self->bed_bounding_box->size }),
- 2 * max(@{ $volumes_bb->size }),
- );
+ my $axis_len = $self->use_plain_shader ? 0.3 * max(@{ $self->bed_bounding_box->size }) : 2 * max(@{ $volumes_bb->size });
glLineWidth(2);
glBegin(GL_LINES);
# draw line for x axis
@@ -1330,8 +1418,8 @@ sub Render {
glEnable(GL_CULL_FACE) if ($self->enable_picking);
}
- # draw cutting plane
if (defined $self->cutting_plane_z) {
+ # draw cutting plane
my $plane_z = $self->cutting_plane_z;
my $bb = $volumes_bb;
glDisable(GL_CULL_FACE);
@@ -1347,6 +1435,15 @@ sub Render {
glEnd();
glEnable(GL_CULL_FACE);
glDisable(GL_BLEND);
+
+ # draw cutting contours
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glLineWidth(2);
+ glColor3f(0, 0, 0);
+ glVertexPointer_c(3, GL_FLOAT, 0, $self->cut_lines_vertices->ptr());
+ glDrawArrays(GL_LINES, 0, $self->cut_lines_vertices->elements / 3);
+ glVertexPointer_c(3, GL_FLOAT, 0, 0);
+ glDisableClientState(GL_VERTEX_ARRAY);
}
# draw warning message
@@ -1393,18 +1490,10 @@ sub draw_volumes {
$volume->render;
}
glDisableClientState(GL_NORMAL_ARRAY);
- glDisable(GL_BLEND);
-
- glEnable(GL_CULL_FACE);
-
- if (defined $self->cutting_plane_z) {
- glLineWidth(2);
- glColor3f(0, 0, 0);
- glVertexPointer_c(3, GL_FLOAT, 0, $self->cut_lines_vertices->ptr());
- glDrawArrays(GL_LINES, 0, $self->cut_lines_vertices->elements / 3);
- glVertexPointer_c(3, GL_FLOAT, 0, 0);
- }
glDisableClientState(GL_VERTEX_ARRAY);
+
+ glDisable(GL_BLEND);
+ glEnable(GL_CULL_FACE);
}
sub mark_volumes_for_layer_height {
@@ -1753,8 +1842,8 @@ sub _vertex_shader_Gouraud {
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
-#define LIGHT_TOP_SPECULAR (0.25 * INTENSITY_CORRECTION)
-#define LIGHT_TOP_SHININESS 200.0
+#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
@@ -1784,15 +1873,9 @@ varying vec3 delta_box_max;
void main()
{
- vec3 eye = -normalize((gl_ModelViewMatrix * gl_Vertex).xyz);
-
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
- // Now normalize the light's direction. Note that according to the OpenGL specification, the light is stored in eye space.
- // Also since we're talking about a directional light, the position field is actually direction.
- vec3 halfVector = normalize(LIGHT_TOP_DIR + eye);
-
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
@@ -1801,7 +1884,7 @@ void main()
intensity.y = 0.0;
if (NdotL > 0.0)
- intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(normal, halfVector), 0.0), LIGHT_TOP_SHININESS);
+ intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(normal, reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
@@ -1926,8 +2009,8 @@ sub _vertex_shader_variable_layer_height {
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
-#define LIGHT_TOP_SPECULAR (0.25 * INTENSITY_CORRECTION)
-#define LIGHT_TOP_SHININESS 200.0
+#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SHININESS 20.0
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
@@ -1943,15 +2026,9 @@ varying float object_z;
void main()
{
- vec3 eye = -normalize((gl_ModelViewMatrix * gl_Vertex).xyz);
-
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
- // Now normalize the light's direction. Note that according to the OpenGL specification, the light is stored in eye space.
- // Also since we're talking about a directional light, the position field is actually direction.
- vec3 halfVector = normalize(LIGHT_TOP_DIR + eye);
-
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
@@ -1960,7 +2037,7 @@ void main()
intensity.y = 0.0;
if (NdotL > 0.0)
- intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(normal, halfVector), 0.0), LIGHT_TOP_SHININESS);
+ intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(normal, reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular)
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
diff --git a/lib/Slic3r/GUI/AboutDialog.pm b/lib/Slic3r/GUI/AboutDialog.pm
deleted file mode 100644
index 0879ea35b5..0000000000
--- a/lib/Slic3r/GUI/AboutDialog.pm
+++ /dev/null
@@ -1,122 +0,0 @@
-package Slic3r::GUI::AboutDialog;
-use strict;
-use warnings;
-use utf8;
-
-use Wx qw(:font :html :misc :dialog :sizer :systemsettings :frame :id);
-use Wx::Event qw(EVT_HTML_LINK_CLICKED EVT_LEFT_DOWN EVT_BUTTON);
-use Wx::Print;
-use Wx::Html;
-use base 'Wx::Dialog';
-
-sub new {
- my $class = shift;
- my ($parent) = @_;
- my $self = $class->SUPER::new($parent, -1, 'About Slic3r', wxDefaultPosition, [600, 340], wxCAPTION);
-
- $self->SetBackgroundColour(Wx::wxWHITE);
- my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
- $self->SetSizer($hsizer);
-
- # logo
- my $logo = Slic3r::GUI::AboutDialog::Logo->new($self, -1, wxDefaultPosition, wxDefaultSize);
- $logo->SetBackgroundColour(Wx::wxWHITE);
- $hsizer->Add($logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 30);
-
- my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
- $hsizer->Add($vsizer, 1, wxEXPAND, 0);
-
- # title
- my $title = Wx::StaticText->new($self, -1, $Slic3r::FORK_NAME, wxDefaultPosition, wxDefaultSize);
- my $title_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
- $title_font->SetWeight(wxFONTWEIGHT_BOLD);
- $title_font->SetFamily(wxFONTFAMILY_ROMAN);
- $title_font->SetPointSize(24);
- $title->SetFont($title_font);
- $vsizer->Add($title, 0, wxALIGN_LEFT | wxTOP, 30);
-
- # version
- my $version = Wx::StaticText->new($self, -1, "Version $Slic3r::VERSION", wxDefaultPosition, wxDefaultSize);
- my $version_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
- $version_font->SetPointSize(&Wx::wxMSW ? 9 : 11);
- $version->SetFont($version_font);
- $vsizer->Add($version, 0, wxALIGN_LEFT | wxBOTTOM, 10);
-
- # text
- my $text =
- '' .
- '
' .
- '' .
- 'Copyright © 2016 Vojtech Bubnik, Prusa Research.
' .
- 'Copyright © 2011-2016 Alessandro Ranellucci.
' .
- 'Slic3r is licensed under the ' .
- 'GNU Affero General Public License, version 3.' .
- '
' .
- 'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Y. Sapir, Mike Sheldrake and numerous others. ' .
- 'Manual by Gary Hodgson. Inspired by the RepRap community.
' .
- 'Slic3r logo designed by Corey Daniels, Silk Icon Set designed by Mark James. ' .
- '' .
- '' .
- '';
- my $html = Wx::HtmlWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER);
- my $font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
- my $size = &Wx::wxMSW ? 8 : 10;
- $html->SetFonts($font->GetFaceName, $font->GetFaceName, [$size, $size, $size, $size, $size, $size, $size]);
- $html->SetBorders(2);
- $html->SetPage($text);
- $vsizer->Add($html, 1, wxEXPAND | wxALIGN_LEFT | wxRIGHT | wxBOTTOM, 20);
- EVT_HTML_LINK_CLICKED($self, $html, \&link_clicked);
-
- my $buttons = $self->CreateStdDialogButtonSizer(wxOK);
- $self->SetEscapeId(wxID_CLOSE);
- EVT_BUTTON($self, wxID_CLOSE, sub {
- $self->EndModal(wxID_CLOSE);
- $self->Close;
- });
- $vsizer->Add($buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);
-
- EVT_LEFT_DOWN($self, sub { $self->Close });
- EVT_LEFT_DOWN($logo, sub { $self->Close });
-
- return $self;
-}
-
-sub link_clicked {
- my ($self, $event) = @_;
-
- Wx::LaunchDefaultBrowser($event->GetLinkInfo->GetHref);
- $event->Skip(0);
-}
-
-package Slic3r::GUI::AboutDialog::Logo;
-use Wx qw(:bitmap :dc);
-use Wx::Event qw(EVT_PAINT);
-use base 'Wx::Panel';
-
-sub new {
- my $class = shift;
- my $self = $class->SUPER::new(@_);
-
- $self->{logo} = Wx::Bitmap->new(Slic3r::var("Slic3r_192px.png"), wxBITMAP_TYPE_PNG);
- $self->SetMinSize(Wx::Size->new($self->{logo}->GetWidth, $self->{logo}->GetHeight));
-
- EVT_PAINT($self, \&repaint);
-
- return $self;
-}
-
-sub repaint {
- my ($self, $event) = @_;
-
- my $dc = Wx::PaintDC->new($self);
- $dc->SetBackgroundMode(wxTRANSPARENT);
-
- my $size = $self->GetSize;
- my $logo_w = $self->{logo}->GetWidth;
- my $logo_h = $self->{logo}->GetHeight;
- $dc->DrawBitmap($self->{logo}, ($size->GetWidth - $logo_w) / 2, ($size->GetHeight - $logo_h) / 2, 1);
-
- $event->Skip;
-}
-
-1;
diff --git a/lib/Slic3r/GUI/ConfigWizard.pm b/lib/Slic3r/GUI/ConfigWizard.pm
deleted file mode 100644
index a32d345ed0..0000000000
--- a/lib/Slic3r/GUI/ConfigWizard.pm
+++ /dev/null
@@ -1,458 +0,0 @@
-# The config wizard is executed when the Slic3r is first started.
-# The wizard helps the user to specify the 3D printer properties.
-
-package Slic3r::GUI::ConfigWizard;
-use strict;
-use warnings;
-use utf8;
-
-use Wx;
-use base 'Wx::Wizard';
-
-# adhere to various human interface guidelines
-our $wizard = 'Wizard';
-$wizard = 'Assistant' if &Wx::wxMAC || &Wx::wxGTK;
-
-sub new {
- my ($class, $parent, $presets, $fresh_start) = @_;
- my $self = $class->SUPER::new($parent, -1, "Configuration $wizard");
-
- # initialize an empty repository
- $self->{config} = Slic3r::Config->new;
-
- my $welcome_page = Slic3r::GUI::ConfigWizard::Page::Welcome->new($self, $fresh_start);
- $self->add_page($welcome_page);
- $self->add_page(Slic3r::GUI::ConfigWizard::Page::Firmware->new($self));
- $self->add_page(Slic3r::GUI::ConfigWizard::Page::Bed->new($self));
- $self->add_page(Slic3r::GUI::ConfigWizard::Page::Nozzle->new($self));
- $self->add_page(Slic3r::GUI::ConfigWizard::Page::Filament->new($self));
- $self->add_page(Slic3r::GUI::ConfigWizard::Page::Temperature->new($self));
- $self->add_page(Slic3r::GUI::ConfigWizard::Page::BedTemperature->new($self));
- $self->add_page(Slic3r::GUI::ConfigWizard::Page::Finished->new($self));
-
- $_->build_index for @{$self->{pages}};
-
- $welcome_page->set_selection_presets([@{$presets}, 'Other']);
-
- return $self;
-}
-
-sub add_page {
- my ($self, $page) = @_;
-
- my $n = push @{$self->{pages}}, $page;
- # add first page to the page area sizer
- $self->GetPageAreaSizer->Add($page) if $n == 1;
- # link pages
- $self->{pages}[$n-2]->set_next_page($page) if $n >= 2;
- $page->set_previous_page($self->{pages}[$n-2]) if $n >= 2;
-}
-
-sub run {
- my ($self) = @_;
- my $result;
- if (Wx::Wizard::RunWizard($self, $self->{pages}[0])) {
- my $preset_name = $self->{pages}[0]->{preset_name};
- $result = {
- preset_name => $preset_name,
- reset_user_profile => $self->{pages}[0]->{reset_user_profile}
- };
- if ($preset_name eq 'Other') {
- # it would be cleaner to have these defined inside each page class,
- # in some event getting called before leaving the page
- # set first_layer_height + layer_height based on nozzle_diameter
- my $nozzle = $self->{config}->nozzle_diameter;
- $self->{config}->set('first_layer_height', $nozzle->[0]);
- $self->{config}->set('layer_height', $nozzle->[0] - 0.1);
-
- # set first_layer_temperature to temperature + 5
- $self->{config}->set('first_layer_temperature', [$self->{config}->temperature->[0] + 5]);
-
- # set first_layer_bed_temperature to temperature + 5
- $self->{config}->set('first_layer_bed_temperature',
- [ ($self->{config}->bed_temperature->[0] > 0) ? ($self->{config}->bed_temperature->[0] + 5) : 0 ]);
- $result->{config} = $self->{config};
- }
- }
- $self->Destroy;
- return $result;
-}
-
-package Slic3r::GUI::ConfigWizard::Index;
-use Wx qw(:bitmap :dc :font :misc :sizer :systemsettings :window);
-use Wx::Event qw(EVT_ERASE_BACKGROUND EVT_PAINT);
-use base 'Wx::Panel';
-
-sub new {
- my $class = shift;
- my ($parent, $title) = @_;
- my $self = $class->SUPER::new($parent);
-
- push @{$self->{titles}}, $title;
- $self->{own_index} = 0;
-
- $self->{bullets}->{before} = Wx::Bitmap->new(Slic3r::var("bullet_black.png"), wxBITMAP_TYPE_PNG);
- $self->{bullets}->{own} = Wx::Bitmap->new(Slic3r::var("bullet_blue.png"), wxBITMAP_TYPE_PNG);
- $self->{bullets}->{after} = Wx::Bitmap->new(Slic3r::var("bullet_white.png"), wxBITMAP_TYPE_PNG);
-
- $self->{background} = Wx::Bitmap->new(Slic3r::var("Slic3r_192px_transparent.png"), wxBITMAP_TYPE_PNG);
- $self->SetMinSize(Wx::Size->new($self->{background}->GetWidth, $self->{background}->GetHeight));
-
- EVT_PAINT($self, \&repaint);
-
- return $self;
-}
-
-sub repaint {
- my ($self, $event) = @_;
- my $size = $self->GetClientSize;
- my $gap = 5;
-
- my $dc = Wx::PaintDC->new($self);
- $dc->SetBackgroundMode(wxTRANSPARENT);
- $dc->SetFont($self->GetFont);
- $dc->SetTextForeground($self->GetForegroundColour);
-
- my $background_h = $self->{background}->GetHeight;
- my $background_w = $self->{background}->GetWidth;
- $dc->DrawBitmap($self->{background}, ($size->GetWidth - $background_w) / 2, ($size->GetHeight - $background_h) / 2, 1);
-
- my $label_h = $self->{bullets}->{own}->GetHeight;
- $label_h = $dc->GetCharHeight if $dc->GetCharHeight > $label_h;
- my $label_w = $size->GetWidth;
-
- my $i = 0;
- foreach (@{$self->{titles}}) {
- my $bullet = $self->{bullets}->{own};
- $bullet = $self->{bullets}->{before} if $i < $self->{own_index};
- $bullet = $self->{bullets}->{after} if $i > $self->{own_index};
-
- $dc->SetTextForeground(Wx::Colour->new(128, 128, 128)) if $i > $self->{own_index};
- $dc->DrawLabel($_, $bullet, Wx::Rect->new(0, $i * ($label_h + $gap), $label_w, $label_h));
- # Only show the first bullet if this is the only wizard page to be displayed.
- last if $i == 0 && $self->{just_welcome};
- $i++;
- }
-
- $event->Skip;
-}
-
-sub prepend_title {
- my $self = shift;
- my ($title) = @_;
-
- unshift @{$self->{titles}}, $title;
- $self->{own_index}++;
- $self->Refresh;
-}
-
-sub append_title {
- my $self = shift;
- my ($title) = @_;
-
- push @{$self->{titles}}, $title;
- $self->Refresh;
-}
-
-package Slic3r::GUI::ConfigWizard::Page;
-use Wx qw(:font :misc :sizer :staticline :systemsettings);
-use base 'Wx::WizardPage';
-
-sub new {
- my $class = shift;
- my ($parent, $title, $short_title) = @_;
- my $self = $class->SUPER::new($parent);
-
- my $sizer = Wx::FlexGridSizer->new(0, 2, 10, 10);
- $sizer->AddGrowableCol(1, 1);
- $sizer->AddGrowableRow(1, 1);
- $sizer->AddStretchSpacer(0);
- $self->SetSizer($sizer);
-
- # title
- my $text = Wx::StaticText->new($self, -1, $title, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
- my $bold_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
- $bold_font->SetWeight(wxFONTWEIGHT_BOLD);
- $bold_font->SetPointSize(14);
- $text->SetFont($bold_font);
- $sizer->Add($text, 0, wxALIGN_LEFT, 0);
-
- # index
- $self->{short_title} = $short_title ? $short_title : $title;
- $self->{index} = Slic3r::GUI::ConfigWizard::Index->new($self, $self->{short_title});
- $sizer->Add($self->{index}, 1, wxEXPAND | wxTOP | wxRIGHT, 10);
-
- # contents
- $self->{width} = 430;
- $self->{vsizer} = Wx::BoxSizer->new(wxVERTICAL);
- $sizer->Add($self->{vsizer}, 1);
-
- return $self;
-}
-
-sub append_text {
- my $self = shift;
- my ($text) = @_;
-
- my $para = Wx::StaticText->new($self, -1, $text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
- $para->Wrap($self->{width});
- $para->SetMinSize([$self->{width}, -1]);
- $self->{vsizer}->Add($para, 0, wxALIGN_LEFT | wxTOP | wxBOTTOM, 10);
-}
-
-sub append_option {
- my $self = shift;
- my ($full_key) = @_;
-
- # populate repository with the factory default
- my ($opt_key, $opt_index) = split /#/, $full_key, 2;
- $self->config->apply(Slic3r::Config::new_from_defaults_keys([$opt_key]));
-
- # draw the control
- my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new(
- parent => $self,
- title => '',
- config => $self->config,
- full_labels => 1,
- );
- $optgroup->append_single_option_line($opt_key, $opt_index);
- $self->{vsizer}->Add($optgroup->sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
-}
-
-sub append_panel {
- my ($self, $panel) = @_;
- $self->{vsizer}->Add($panel, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
-}
-
-sub set_previous_page {
- my $self = shift;
- my ($previous_page) = @_;
- $self->{previous_page} = $previous_page;
-}
-
-sub GetPrev {
- my $self = shift;
- return $self->{previous_page};
-}
-
-sub set_next_page {
- my $self = shift;
- my ($next_page) = @_;
- $self->{next_page} = $next_page;
-}
-
-sub GetNext {
- my $self = shift;
- return $self->{next_page};
-}
-
-sub get_short_title {
- my $self = shift;
- return $self->{short_title};
-}
-
-sub build_index {
- my $self = shift;
-
- my $page = $self;
- $self->{index}->prepend_title($page->get_short_title) while ($page = $page->GetPrev);
- $page = $self;
- $self->{index}->append_title($page->get_short_title) while ($page = $page->GetNext);
-}
-
-sub config {
- my ($self) = @_;
- return $self->GetParent->{config};
-}
-
-package Slic3r::GUI::ConfigWizard::Page::Welcome;
-use base 'Slic3r::GUI::ConfigWizard::Page';
-use Wx qw(:misc :sizer wxID_FORWARD);
-use Wx::Event qw(EVT_ACTIVATE EVT_CHOICE EVT_CHECKBOX);
-
-sub new {
- my ($class, $parent, $fresh_start) = @_;
- my $self = $class->SUPER::new($parent, "Welcome to the Slic3r Configuration $wizard", 'Welcome');
- $self->{full_wizard_workflow} = 1;
- $self->{reset_user_profile} = 0;
-
- # Test for the existence of the old config path.
- my $message_has_legacy;
- {
- my $datadir = Slic3r::data_dir;
- if ($datadir =~ /Slic3rPE/) {
- # Check for existence of the legacy Slic3r directory.
- my $datadir_legacy = substr $datadir, 0, -2;
- my $dir_enc = Slic3r::encode_path($datadir_legacy);
- if (-e $dir_enc && -d $dir_enc &&
- -e ($dir_enc . '/print') && -d ($dir_enc . '/print') &&
- -e ($dir_enc . '/filament') && -d ($dir_enc . '/filament') &&
- -e ($dir_enc . '/printer') && -d ($dir_enc . '/printer') &&
- -e ($dir_enc . '/slic3r.ini')) {
- $message_has_legacy = "Starting with Slic3r 1.38.4, the user profile directory has been renamed to $datadir. You may consider closing Slic3r and renaming $datadir_legacy to $datadir.";
- }
- }
- }
-
- $self->append_text('Hello, welcome to Slic3r Prusa Edition! This '.lc($wizard).' helps you with the initial configuration; just a few settings and you will be ready to print.');
- $self->append_text('Please select your printer vendor and printer type. If your printer is not listed, you may try your luck and select a similar one. If you select "Other", this ' . lc($wizard) . ' will let you set the basic 3D printer parameters.');
- $self->append_text($message_has_legacy) if defined $message_has_legacy;
- # To import an existing configuration instead, cancel this '.lc($wizard).' and use the Open Config menu item found in the File menu.');
- $self->append_text('If you received a configuration file or a config bundle from your 3D printer vendor, cancel this '.lc($wizard).' and use the "File->Load Config" or "File->Load Config Bundle" menu.');
-
- $self->{choice} = my $choice = Wx::Choice->new($self, -1, wxDefaultPosition, wxDefaultSize, []);
- $self->{vsizer}->Add($choice, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
- if (! $fresh_start) {
- $self->{reset_checkbox} = Wx::CheckBox->new($self, -1, "Reset user profile, install from scratch");
- $self->{vsizer}->Add($self->{reset_checkbox}, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
- }
-
- EVT_CHOICE($parent, $choice, sub {
- my $sel = $self->{choice}->GetStringSelection;
- $self->{preset_name} = $sel;
- $self->set_full_wizard_workflow(($sel eq 'Other') || ($sel eq ''));
- });
-
- if (! $fresh_start) {
- EVT_CHECKBOX($self, $self->{reset_checkbox}, sub {
- $self->{reset_user_profile} = $self->{reset_checkbox}->GetValue();
- });
- }
-
- EVT_ACTIVATE($parent, sub {
- $self->set_full_wizard_workflow($self->{preset_name} eq 'Other');
- });
-
- return $self;
-}
-
-sub set_full_wizard_workflow {
- my ($self, $full_workflow) = @_;
- $self->{full_wizard_workflow} = $full_workflow;
- $self->{index}->{just_welcome} = !$full_workflow;
- $self->{index}->Refresh;
- my $next_button = $self->GetParent->FindWindow(wxID_FORWARD);
- $next_button->SetLabel($full_workflow ? "&Next >" : "&Finish");
-}
-
-# Set the preset names, select the first item.
-sub set_selection_presets {
- my ($self, $names) = @_;
- $self->{choice}->Append($names);
- $self->{choice}->SetSelection(0);
- $self->{preset_name} = $names->[0];
-}
-
-sub GetNext {
- my $self = shift;
- return $self->{full_wizard_workflow} ? $self->{next_page} : undef;
-}
-
-package Slic3r::GUI::ConfigWizard::Page::Firmware;
-use base 'Slic3r::GUI::ConfigWizard::Page';
-
-sub new {
- my $class = shift;
- my ($parent) = @_;
- my $self = $class->SUPER::new($parent, 'Firmware Type');
-
- $self->append_text('Choose the type of firmware used by your printer, then click Next.');
- $self->append_option('gcode_flavor');
-
- return $self;
-}
-
-package Slic3r::GUI::ConfigWizard::Page::Bed;
-use base 'Slic3r::GUI::ConfigWizard::Page';
-
-sub new {
- my $class = shift;
- my ($parent) = @_;
- my $self = $class->SUPER::new($parent, 'Bed Size');
-
- $self->append_text('Set the shape of your printer\'s bed, then click Next.');
-
- $self->config->apply(Slic3r::Config::new_from_defaults_keys(['bed_shape']));
- $self->{bed_shape_panel} = my $panel = Slic3r::GUI::BedShapePanel->new($self, $self->config->bed_shape);
- $self->{bed_shape_panel}->on_change(sub {
- $self->config->set('bed_shape', $self->{bed_shape_panel}->GetValue);
- });
- $self->append_panel($self->{bed_shape_panel});
- return $self;
-}
-
-package Slic3r::GUI::ConfigWizard::Page::Nozzle;
-use base 'Slic3r::GUI::ConfigWizard::Page';
-
-sub new {
- my $class = shift;
- my ($parent) = @_;
- my $self = $class->SUPER::new($parent, 'Nozzle Diameter');
-
- $self->append_text('Enter the diameter of your printer\'s hot end nozzle, then click Next.');
- $self->append_option('nozzle_diameter#0');
-
- return $self;
-}
-
-package Slic3r::GUI::ConfigWizard::Page::Filament;
-use base 'Slic3r::GUI::ConfigWizard::Page';
-
-sub new {
- my $class = shift;
- my ($parent) = @_;
- my $self = $class->SUPER::new($parent, 'Filament Diameter');
-
- $self->append_text('Enter the diameter of your filament, then click Next.');
- $self->append_text('Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average.');
- $self->append_option('filament_diameter#0');
-
- return $self;
-}
-
-package Slic3r::GUI::ConfigWizard::Page::Temperature;
-use base 'Slic3r::GUI::ConfigWizard::Page';
-
-sub new {
- my $class = shift;
- my ($parent) = @_;
- my $self = $class->SUPER::new($parent, 'Extrusion Temperature');
-
- $self->append_text('Enter the temperature needed for extruding your filament, then click Next.');
- $self->append_text('A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS.');
- $self->append_option('temperature#0');
-
- return $self;
-}
-
-package Slic3r::GUI::ConfigWizard::Page::BedTemperature;
-use base 'Slic3r::GUI::ConfigWizard::Page';
-
-sub new {
- my $class = shift;
- my ($parent) = @_;
- my $self = $class->SUPER::new($parent, 'Bed Temperature');
-
- $self->append_text('Enter the bed temperature needed for getting your filament to stick to your heated bed, then click Next.');
- $self->append_text('A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed.');
- $self->append_option('bed_temperature#0');
-
- return $self;
-}
-
-package Slic3r::GUI::ConfigWizard::Page::Finished;
-use base 'Slic3r::GUI::ConfigWizard::Page';
-
-sub new {
- my $class = shift;
- my ($parent) = @_;
- my $self = $class->SUPER::new($parent, 'Congratulations!', 'Finish');
-
- $self->append_text("You have successfully completed the Slic3r Configuration $wizard. " .
- 'Slic3r is now configured for your printer and filament.');
- $self->append_text('To close this '.lc($wizard).' and apply the newly created configuration, click Finish.');
-
- return $self;
-}
-
-1;
diff --git a/lib/Slic3r/GUI/Controller.pm b/lib/Slic3r/GUI/Controller.pm
index 6aa7b34cb8..f7d90c7962 100644
--- a/lib/Slic3r/GUI/Controller.pm
+++ b/lib/Slic3r/GUI/Controller.pm
@@ -7,7 +7,7 @@ use strict;
use warnings;
use utf8;
-use Wx qw(wxTheApp :frame :id :misc :sizer :bitmap :button :icon :dialog);
+use Wx qw(wxTheApp :frame :id :misc :sizer :bitmap :button :icon :dialog wxBORDER_NONE);
use Wx::Event qw(EVT_CLOSE EVT_LEFT_DOWN EVT_MENU);
use base qw(Wx::ScrolledWindow Class::Accessor);
use List::Util qw(first);
@@ -34,7 +34,7 @@ sub new {
# button for adding new printer panels
{
my $btn = $self->{btn_add} = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new(Slic3r::var("add.png"), wxBITMAP_TYPE_PNG),
- wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE);
+ wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
$btn->SetToolTipString("Add printer…")
if $btn->can('SetToolTipString');
diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm
index b2f51b9e1d..fbcd34a3f6 100644
--- a/lib/Slic3r/GUI/MainFrame.pm
+++ b/lib/Slic3r/GUI/MainFrame.pm
@@ -81,7 +81,7 @@ sub new {
# declare events
EVT_CLOSE($self, sub {
my (undef, $event) = @_;
- if ($event->CanVeto && !$self->check_unsaved_changes) {
+ if ($event->CanVeto && !Slic3r::GUI::check_unsaved_changes) {
$event->Veto;
return;
}
@@ -95,7 +95,7 @@ sub new {
});
$self->update_ui_from_settings;
-
+
return $self;
}
@@ -149,6 +149,7 @@ sub _init_tabpanel {
if (defined $presets){
my $reload_dependent_tabs = $tab->get_dependent_tabs;
$self->{plater}->update_presets($tab_name, $reload_dependent_tabs, $presets);
+ $self->{plater}->{"selected_item_$tab_name"} = $tab->get_selected_preset_item;
if ($tab_name eq 'printer') {
# Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors.
for my $tab_name_other (qw(print filament)) {
@@ -237,12 +238,6 @@ sub _init_menubar {
$self->repair_stl;
}, undef, 'wrench.png');
$fileMenu->AppendSeparator();
- # Cmd+, is standard on OS X - what about other operating systems?
- $self->_append_menu_item($fileMenu, L("Preferences…\tCtrl+,"), L('Application preferences'), sub {
- # Opening the C++ preferences dialog.
- Slic3r::GUI::open_preferences_dialog($self->{preferences_event});
- }, wxID_PREFERENCES);
- $fileMenu->AppendSeparator();
$self->_append_menu_item($fileMenu, L("&Quit"), L('Quit Slic3r'), sub {
$self->Close(0);
}, wxID_EXIT);
@@ -319,11 +314,6 @@ sub _init_menubar {
# Help menu
my $helpMenu = Wx::Menu->new;
{
- $self->_append_menu_item($helpMenu, L("&Configuration ").$Slic3r::GUI::ConfigWizard::wizard."…", L("Run Configuration ").$Slic3r::GUI::ConfigWizard::wizard, sub {
- # Run the config wizard, offer the "reset user profile" checkbox.
- $self->config_wizard(0);
- });
- $helpMenu->AppendSeparator();
$self->_append_menu_item($helpMenu, L("Prusa 3D Drivers"), L('Open the Prusa3D drivers download page in your browser'), sub {
Wx::LaunchDefaultBrowser('http://www.prusa3d.com/drivers/');
});
@@ -348,7 +338,7 @@ sub _init_menubar {
Wx::LaunchDefaultBrowser('http://github.com/prusa3d/slic3r/issues/new');
});
$self->_append_menu_item($helpMenu, L("&About Slic3r"), L('Show about dialog'), sub {
- wxTheApp->about;
+ Slic3r::GUI::about;
});
}
@@ -362,11 +352,9 @@ sub _init_menubar {
$menubar->Append($self->{object_menu}, L("&Object")) if $self->{object_menu};
$menubar->Append($windowMenu, L("&Window"));
$menubar->Append($self->{viewMenu}, L("&View")) if $self->{viewMenu};
- # Add an optional debug menu
- # (Select application language from the list of installed languages)
- Slic3r::GUI::add_debug_menu($menubar, $self->{lang_ch_event});
+ # Add a configuration menu.
+ Slic3r::GUI::add_config_menu($menubar, $self->{preferences_event}, $self->{lang_ch_event});
$menubar->Append($helpMenu, L("&Help"));
- # Add an optional debug menu. In production code, the add_debug_menu() call should do nothing.
$self->SetMenuBar($menubar);
}
}
@@ -562,7 +550,7 @@ sub export_config {
sub load_config_file {
my ($self, $file) = @_;
if (!$file) {
- return unless $self->check_unsaved_changes;
+ return unless Slic3r::GUI::check_unsaved_changes;
my $dlg = Wx::FileDialog->new($self, L('Select configuration to load:'),
$last_config ? dirname($last_config) : wxTheApp->{app_config}->get_last_dir,
"config.ini",
@@ -581,7 +569,7 @@ sub load_config_file {
sub export_configbundle {
my ($self) = @_;
- return unless $self->check_unsaved_changes;
+ return unless Slic3r::GUI::check_unsaved_changes;
# validate current configuration in case it's dirty
eval { wxTheApp->{preset_bundle}->full_config->validate; };
Slic3r::GUI::catch_error($self) and return;
@@ -605,7 +593,7 @@ sub export_configbundle {
# but that behavior was not documented and likely buggy.
sub load_configbundle {
my ($self, $file, $reset_user_profile) = @_;
- return unless $self->check_unsaved_changes;
+ return unless Slic3r::GUI::check_unsaved_changes;
if (!$file) {
my $dlg = Wx::FileDialog->new($self, L('Select configuration to load:'),
$last_config ? dirname($last_config) : wxTheApp->{app_config}->get_last_dir,
@@ -639,70 +627,6 @@ sub load_config {
$self->{plater}->on_config_change($config) if $self->{plater};
}
-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;
- # Load the currently selected preset into the GUI, update the preset selection box.
- foreach my $tab (values %{$self->{options_tabs}}) {
- $tab->load_current_preset;
- }
- }
-}
-
-# This is called when closing the application, when loading a config file or when starting the config wizard
-# to notify the user whether he is aware that some preset changes will be lost.
-sub check_unsaved_changes {
- my $self = shift;
-
- my @dirty = ();
- foreach my $tab (values %{$self->{options_tabs}}) {
- push @dirty, $tab->title if $tab->current_preset_is_dirty;
- }
-
- if (@dirty) {
- my $titles = join ', ', @dirty;
- my $confirm = Wx::MessageDialog->new($self, L("You have unsaved changes ").($titles).L(". Discard changes and continue anyway?"),
- L('Unsaved Presets'), wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
- return $confirm->ShowModal == wxID_YES;
- }
-
- return 1;
-}
-
sub select_tab {
my ($self, $tab) = @_;
$self->{tabpanel}->SetSelection($tab);
diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm
index d59865491c..08c1065df7 100644
--- a/lib/Slic3r/GUI/Plater.pm
+++ b/lib/Slic3r/GUI/Plater.pm
@@ -486,7 +486,7 @@ sub new {
my $right_sizer = Wx::BoxSizer->new(wxVERTICAL);
$right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets;
- $right_sizer->Add($frequently_changed_parameters_sizer, 0, wxEXPAND | wxTOP, 10) if defined $frequently_changed_parameters_sizer;
+ $right_sizer->Add($frequently_changed_parameters_sizer, 0, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer;
$right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5);
$right_sizer->Add($self->{list}, 1, wxEXPAND, 5);
$right_sizer->Add($object_info_sizer, 0, wxEXPAND, 0);
@@ -514,6 +514,13 @@ sub new {
$self->SetSizer($sizer);
}
+ # Last correct selected item for each preset
+ {
+ $self->{selected_item_print} = 0;
+ $self->{selected_item_filament} = 0;
+ $self->{selected_item_printer} = 0;
+ }
+
$self->update_ui_from_settings();
return $self;
@@ -538,9 +545,21 @@ sub _on_select_preset {
# Only update the platter UI for the 2nd and other filaments.
wxTheApp->{preset_bundle}->update_platter_filament_ui($idx, $choice);
} else {
+ my $selected_item = $choice->GetSelection();
+ return if ($selected_item == $self->{"selected_item_$group"});
+
+ my $selected_string = $choice->GetString($selected_item);
+ if ($selected_string eq ("------- ".L("System presets")." -------") ||
+ $selected_string eq ("------- ".L("User presets")." -------") ){
+ $choice->SetSelection($self->{"selected_item_$group"});
+ return;
+ }
+
# call GetSelection() in scalar context as it's context-aware
- $self->{on_select_preset}->($group, $choice->GetStringSelection)
- if $self->{on_select_preset};
+# $self->{on_select_preset}->($group, $choice->GetStringSelection)
+ $self->{on_select_preset}->($group, $selected_string)
+ if $self->{on_select_preset};
+ $self->{"selected_item_$group"} = $selected_item;
}
# Synchronize config.ini with the current selections.
wxTheApp->{preset_bundle}->export_selections(wxTheApp->{app_config});
@@ -663,6 +682,9 @@ sub load_files {
Slic3r::GUI::show_error($self, $@) if $@;
$_->load_current_preset for (values %{$self->GetFrame->{options_tabs}});
wxTheApp->{app_config}->update_config_dir(dirname($input_file));
+ # forces the update of the config here, or it will invalidate the imported layer heights profile if done using the timer
+ # and if the config contains a "layer_height" different from the current defined one
+ $self->async_apply_config;
}
else
{
@@ -678,7 +700,7 @@ sub load_files {
. "Instead of considering them as multiple objects, should I consider\n"
. "this file as a single object having multiple parts?\n"),
L('Multi-part object detected'), wxICON_WARNING | wxYES | wxNO);
- $model->convert_multipart_object if $dialog->ShowModal() == wxID_YES;
+ $model->convert_multipart_object(scalar(@$nozzle_dmrs)) if $dialog->ShowModal() == wxID_YES;
}
if ($one_by_one) {
@@ -695,7 +717,7 @@ sub load_files {
. "Instead of considering them as multiple objects, should I consider\n"
. "these files to represent a single object having multiple parts?\n"),
L('Multi-part object detected'), wxICON_WARNING | wxYES | wxNO);
- $new_model->convert_multipart_object if $dialog->ShowModal() == wxID_YES;
+ $new_model->convert_multipart_object(scalar(@$nozzle_dmrs)) if $dialog->ShowModal() == wxID_YES;
push @obj_idx, $self->load_model_objects(@{$new_model->objects});
}
@@ -1677,6 +1699,7 @@ sub update {
$self->{canvas}->reload_scene if $self->{canvas};
$self->{canvas3D}->reload_scene if $self->{canvas3D};
+ $self->{preview3D}->reset_gcode_preview_data if $self->{preview3D};
$self->{preview3D}->reload_print if $self->{preview3D};
}
@@ -1782,22 +1805,26 @@ sub on_config_change {
sub list_item_deselected {
my ($self, $event) = @_;
return if $PreventListEvents;
+ $self->{_lecursor} = Wx::BusyCursor->new();
if ($self->{list}->GetFirstSelected == -1) {
$self->select_object(undef);
$self->{canvas}->Refresh;
- #FIXME VBOs are being refreshed just to change a selection color?
- $self->{canvas3D}->reload_scene if $self->{canvas3D};
+ $self->{canvas3D}->deselect_volumes if $self->{canvas3D};
+ $self->{canvas3D}->Render if $self->{canvas3D};
}
+ undef $self->{_lecursor};
}
sub list_item_selected {
my ($self, $event) = @_;
return if $PreventListEvents;
+ $self->{_lecursor} = Wx::BusyCursor->new();
my $obj_idx = $event->GetIndex;
$self->select_object($obj_idx);
$self->{canvas}->Refresh;
- #FIXME VBOs are being refreshed just to change a selection color?
- $self->{canvas3D}->reload_scene if $self->{canvas3D};
+ $self->{canvas3D}->update_volumes_selection if $self->{canvas3D};
+ $self->{canvas3D}->Render if $self->{canvas3D};
+ undef $self->{_lecursor};
}
sub list_item_activated {
@@ -1856,6 +1883,7 @@ sub object_cut_dialog {
$self->remove($obj_idx);
$self->load_model_objects(grep defined($_), @new_objects);
$self->arrange;
+ $self->{canvas3D}->zoom_to_volumes if $self->{canvas3D};
}
}
@@ -1930,7 +1958,8 @@ sub selection_changed {
my ($self) = @_;
my ($obj_idx, $object) = $self->selected_object;
my $have_sel = defined $obj_idx;
-
+
+ $self->Freeze;
if ($self->{htoolbar}) {
# On OSX or Linux
$self->{htoolbar}->EnableTool($_, $have_sel)
@@ -1981,12 +2010,20 @@ sub selection_changed {
# prepagate the event to the frame (a custom Wx event would be cleaner)
$self->GetFrame->on_plater_selection_changed($have_sel);
+ $self->Thaw;
}
sub select_object {
my ($self, $obj_idx) = @_;
+
+ # remove current selection
+ foreach my $o (0..$#{$self->{objects}}) {
+ $PreventListEvents = 1;
+ $self->{objects}->[$o]->selected(0);
+ $self->{list}->Select($o, 0);
+ $PreventListEvents = 0;
+ }
- $_->selected(0) for @{ $self->{objects} };
if (defined $obj_idx) {
$self->{objects}->[$obj_idx]->selected(1);
# We use this flag to avoid circular event handling
diff --git a/lib/Slic3r/GUI/Plater/3D.pm b/lib/Slic3r/GUI/Plater/3D.pm
index dce60e2c44..c9c9542762 100644
--- a/lib/Slic3r/GUI/Plater/3D.pm
+++ b/lib/Slic3r/GUI/Plater/3D.pm
@@ -31,7 +31,9 @@ sub new {
$self->{on_select_object} = sub {};
$self->{on_instances_moved} = sub {};
$self->{on_wipe_tower_moved} = sub {};
-
+
+ $self->{objects_volumes_idxs} = [];
+
$self->on_select(sub {
my ($volume_idx) = @_;
$self->{on_select_object}->(($volume_idx == -1) ? undef : $self->volumes->[$volume_idx]->object_idx)
@@ -181,6 +183,17 @@ sub set_on_enable_action_buttons {
$self->on_enable_action_buttons($cb);
}
+sub update_volumes_selection {
+ my ($self) = @_;
+
+ foreach my $obj_idx (0..$#{$self->{model}->objects}) {
+ if ($self->{objects}[$obj_idx]->selected) {
+ my $volume_idxs = $self->{objects_volumes_idxs}->[$obj_idx];
+ $self->select_volume($_) for @{$volume_idxs};
+ }
+ }
+}
+
sub reload_scene {
my ($self, $force) = @_;
@@ -194,12 +207,14 @@ sub reload_scene {
$self->{reload_delayed} = 0;
+ $self->{objects_volumes_idxs} = [];
foreach my $obj_idx (0..$#{$self->{model}->objects}) {
my @volume_idxs = $self->load_object($self->{model}, $self->{print}, $obj_idx);
- if ($self->{objects}[$obj_idx]->selected) {
- $self->select_volume($_) for @volume_idxs;
- }
+ push(@{$self->{objects_volumes_idxs}}, \@volume_idxs);
}
+
+ $self->update_volumes_selection;
+
if (defined $self->{config}->nozzle_diameter) {
# Should the wipe tower be visualized?
my $extruders_count = scalar @{ $self->{config}->nozzle_diameter };
diff --git a/lib/Slic3r/GUI/Plater/3DPreview.pm b/lib/Slic3r/GUI/Plater/3DPreview.pm
index 537cb0c8f2..9d8b822429 100644
--- a/lib/Slic3r/GUI/Plater/3DPreview.pm
+++ b/lib/Slic3r/GUI/Plater/3DPreview.pm
@@ -10,7 +10,7 @@ use base qw(Wx::Panel Class::Accessor);
use Wx::Locale gettext => 'L';
-__PACKAGE__->mk_accessors(qw(print gcode_preview_data enabled _loaded canvas slider_low slider_high single_layer auto_zoom));
+__PACKAGE__->mk_accessors(qw(print gcode_preview_data enabled _loaded canvas slider_low slider_high single_layer));
sub new {
my $class = shift;
@@ -21,7 +21,6 @@ sub new {
$self->{number_extruders} = 1;
# Show by feature type by default.
$self->{preferred_color_mode} = 'feature';
- $self->auto_zoom(1);
# init GUI elements
my $canvas = Slic3r::GUI::3DScene->new($self);
@@ -73,6 +72,9 @@ sub new {
$choice_view_type->Append(L("Tool"));
$choice_view_type->SetSelection(0);
+ # the following value needs to be changed if new items are added into $choice_view_type before "Tool"
+ $self->{tool_idx} = 5;
+
my $label_show_features = $self->{label_show_features} = Wx::StaticText->new($self, -1, L("Show"));
my $combochecklist_features = $self->{combochecklist_features} = Wx::ComboCtrl->new();
@@ -205,43 +207,31 @@ sub new {
});
EVT_CHOICE($self, $choice_view_type, sub {
my $selection = $choice_view_type->GetCurrentSelection();
- $self->{preferred_color_mode} = ($selection == 4) ? 'tool' : 'feature';
+ $self->{preferred_color_mode} = ($selection == $self->{tool_idx}) ? 'tool' : 'feature';
$self->gcode_preview_data->set_type($selection);
- $self->auto_zoom(0);
$self->reload_print;
- $self->auto_zoom(1);
});
EVT_CHECKLISTBOX($self, $combochecklist_features, sub {
my $flags = Slic3r::GUI::combochecklist_get_flags($combochecklist_features);
$self->gcode_preview_data->set_extrusion_flags($flags);
- $self->auto_zoom(0);
$self->refresh_print;
- $self->auto_zoom(1);
});
EVT_CHECKBOX($self, $checkbox_travel, sub {
$self->gcode_preview_data->set_travel_visible($checkbox_travel->IsChecked());
- $self->auto_zoom(0);
$self->refresh_print;
- $self->auto_zoom(1);
});
EVT_CHECKBOX($self, $checkbox_retractions, sub {
$self->gcode_preview_data->set_retractions_visible($checkbox_retractions->IsChecked());
- $self->auto_zoom(0);
$self->refresh_print;
- $self->auto_zoom(1);
});
EVT_CHECKBOX($self, $checkbox_unretractions, sub {
$self->gcode_preview_data->set_unretractions_visible($checkbox_unretractions->IsChecked());
- $self->auto_zoom(0);
$self->refresh_print;
- $self->auto_zoom(1);
});
EVT_CHECKBOX($self, $checkbox_shells, sub {
$self->gcode_preview_data->set_shells_visible($checkbox_shells->IsChecked());
- $self->auto_zoom(0);
$self->refresh_print;
- $self->auto_zoom(1);
});
$self->SetSizer($main_sizer);
@@ -302,6 +292,12 @@ sub refresh_print {
$self->load_print;
}
+sub reset_gcode_preview_data {
+ my ($self) = @_;
+ $self->gcode_preview_data->reset;
+ $self->canvas->reset_legend_texture();
+}
+
sub load_print {
my ($self) = @_;
@@ -341,7 +337,7 @@ sub load_print {
# It is left to Slic3r to decide whether the print shall be colored by the tool or by the feature.
# Color by feature if it is a single extruder print.
my $extruders = $self->{print}->extruders;
- my $type = (scalar(@{$extruders}) > 1) ? 4 : 0;
+ my $type = (scalar(@{$extruders}) > 1) ? $self->{tool_idx} : 0;
$self->gcode_preview_data->set_type($type);
$self->{choice_view_type}->SetSelection($type);
# If the ->SetSelection changed the following line, revert it to "decide yourself".
@@ -350,7 +346,7 @@ sub load_print {
# Collect colors per extruder.
my @colors = ();
- if (! $self->gcode_preview_data->empty() || $self->gcode_preview_data->type == 4) {
+ if (! $self->gcode_preview_data->empty() || $self->gcode_preview_data->type == $self->{tool_idx}) {
my @extruder_colors = @{$self->{config}->extruder_colour};
my @filament_colors = @{$self->{config}->filament_colour};
for (my $i = 0; $i <= $#extruder_colors; $i += 1) {
@@ -374,7 +370,7 @@ sub load_print {
}
$self->show_hide_ui_elements('simple');
} else {
- $self->{force_sliders_full_range} = (scalar(@{$self->canvas->volumes}) == 0) && $self->auto_zoom;
+ $self->{force_sliders_full_range} = (scalar(@{$self->canvas->volumes}) == 0);
$self->canvas->load_gcode_preview($self->print, $self->gcode_preview_data, \@colors);
$self->show_hide_ui_elements('full');
@@ -384,10 +380,6 @@ sub load_print {
}
$self->update_sliders($n_layers);
-
- if ($self->auto_zoom) {
- $self->canvas->zoom_to_volumes;
- }
$self->_loaded(1);
}
}
@@ -475,11 +467,11 @@ sub set_number_extruders {
if ($self->{number_extruders} != $number_extruders) {
$self->{number_extruders} = $number_extruders;
my $type = ($number_extruders > 1) ?
- 4 # color by a tool number
+ $self->{tool_idx} # color by a tool number
: 0; # color by a feature type
$self->{choice_view_type}->SetSelection($type);
$self->gcode_preview_data->set_type($type);
- $self->{preferred_color_mode} = ($type == 4) ? 'tool_or_feature' : 'feature';
+ $self->{preferred_color_mode} = ($type == $self->{tool_idx}) ? 'tool_or_feature' : 'feature';
}
}
diff --git a/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm b/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm
index 7b5752cd2b..4d55e313a6 100644
--- a/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm
+++ b/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm
@@ -116,7 +116,6 @@ sub new {
$canvas->set_auto_bed_shape;
$canvas->SetSize([500,500]);
$canvas->SetMinSize($canvas->GetSize);
- $canvas->zoom_to_volumes;
}
$self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL);
@@ -227,12 +226,14 @@ sub _update {
push @objects, $self->{model_object};
}
+ my $z_cut = $z + $self->{model_object}->bounding_box->z_min;
+
# get section contour
my @expolygons = ();
foreach my $volume (@{$self->{model_object}->volumes}) {
next if !$volume->mesh;
next if $volume->modifier;
- my $expp = $volume->mesh->slice([ $z + $volume->mesh->bounding_box->z_min ])->[0];
+ my $expp = $volume->mesh->slice([ $z_cut ])->[0];
push @expolygons, @$expp;
}
foreach my $expolygon (@expolygons) {
diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
index f7e38ed873..a632edeeae 100644
--- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
+++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
@@ -163,7 +163,6 @@ sub new {
$canvas->set_auto_bed_shape;
$canvas->SetSize([500,700]);
$canvas->update_volumes_colors_by_extruder($self->GetParent->GetParent->GetParent->{config});
- $canvas->zoom_to_volumes;
}
$self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL);
@@ -476,7 +475,8 @@ sub on_btn_split {
my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') {
my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}];
- $self->{parts_changed} = 1 if $volume->split > 1;
+ my $nozzle_dmrs = $self->GetParent->GetParent->GetParent->{config}->get('nozzle_diameter');
+ $self->{parts_changed} = 1 if $volume->split(scalar(@$nozzle_dmrs)) > 1;
}
$self->_parts_changed;
diff --git a/resources/icons/Slic3r_192px_grayscale.png b/resources/icons/Slic3r_192px_grayscale.png
new file mode 100644
index 0000000000..910f941870
Binary files /dev/null and b/resources/icons/Slic3r_192px_grayscale.png differ
diff --git a/resources/icons/action_undo.png b/resources/icons/action_undo.png
index 877f159868..06bb98b22a 100644
Binary files a/resources/icons/action_undo.png and b/resources/icons/action_undo.png differ
diff --git a/resources/icons/action_undo_grey.png b/resources/icons/action_undo_grey.png
new file mode 100644
index 0000000000..eaa1593e34
Binary files /dev/null and b/resources/icons/action_undo_grey.png differ
diff --git a/resources/icons/printers/BarBaz_M1.png b/resources/icons/printers/BarBaz_M1.png
new file mode 100644
index 0000000000..5924cc88b9
Binary files /dev/null and b/resources/icons/printers/BarBaz_M1.png differ
diff --git a/resources/icons/printers/BarBaz_M2.png b/resources/icons/printers/BarBaz_M2.png
new file mode 100644
index 0000000000..5924cc88b9
Binary files /dev/null and b/resources/icons/printers/BarBaz_M2.png differ
diff --git a/resources/icons/printers/BarBaz_M3.png b/resources/icons/printers/BarBaz_M3.png
new file mode 100644
index 0000000000..5924cc88b9
Binary files /dev/null and b/resources/icons/printers/BarBaz_M3.png differ
diff --git a/resources/icons/printers/Foobar_M1.png b/resources/icons/printers/Foobar_M1.png
new file mode 100644
index 0000000000..61a76a63d1
Binary files /dev/null and b/resources/icons/printers/Foobar_M1.png differ
diff --git a/resources/icons/printers/Foobar_M2.png b/resources/icons/printers/Foobar_M2.png
new file mode 100644
index 0000000000..61a76a63d1
Binary files /dev/null and b/resources/icons/printers/Foobar_M2.png differ
diff --git a/resources/icons/printers/Foobar_M3.png b/resources/icons/printers/Foobar_M3.png
new file mode 100644
index 0000000000..61a76a63d1
Binary files /dev/null and b/resources/icons/printers/Foobar_M3.png differ
diff --git a/resources/icons/printers/PrusaResearch_MK2S.png b/resources/icons/printers/PrusaResearch_MK2S.png
new file mode 100644
index 0000000000..925447cf20
Binary files /dev/null and b/resources/icons/printers/PrusaResearch_MK2S.png differ
diff --git a/resources/icons/printers/PrusaResearch_MK2SMM.png b/resources/icons/printers/PrusaResearch_MK2SMM.png
new file mode 100644
index 0000000000..d6ff161259
Binary files /dev/null and b/resources/icons/printers/PrusaResearch_MK2SMM.png differ
diff --git a/resources/icons/printers/PrusaResearch_MK3.png b/resources/icons/printers/PrusaResearch_MK3.png
new file mode 100644
index 0000000000..5279ba01e0
Binary files /dev/null and b/resources/icons/printers/PrusaResearch_MK3.png differ
diff --git a/resources/icons/question_mark_01.png b/resources/icons/question_mark_01.png
new file mode 100644
index 0000000000..25814a61d4
Binary files /dev/null and b/resources/icons/question_mark_01.png differ
diff --git a/resources/icons/sys_unlock_grey.png b/resources/icons/sys_unlock_grey.png
new file mode 100644
index 0000000000..0dedf4deef
Binary files /dev/null and b/resources/icons/sys_unlock_grey.png differ
diff --git a/resources/localization/Slic3rPE.pot b/resources/localization/Slic3rPE.pot
index 0282e7aae7..e4b9e25671 100644
--- a/resources/localization/Slic3rPE.pot
+++ b/resources/localization/Slic3rPE.pot
@@ -3,20 +3,26 @@
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR , YEAR.
#
-#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-03-14 15:32+0100\n"
+"POT-Creation-Date: 2018-05-02 15:27+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
-"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+#: xs/src/slic3r/GUI/AboutDialog.cpp:32
+msgid "About Slic3r"
+msgstr ""
+
+#: xs/src/slic3r/GUI/AboutDialog.cpp:60
+msgid "Version"
+msgstr ""
+
#: xs/src/slic3r/GUI/BedShapeDialog.cpp:39
msgid "Shape"
msgstr ""
@@ -25,8 +31,8 @@ msgstr ""
msgid "Rectangular"
msgstr ""
-#: xs/src/slic3r/GUI/BedShapeDialog.cpp:50 xs/src/slic3r/GUI/Tab.cpp:1270
-#: lib/Slic3r/GUI/Plater.pm:411
+#: xs/src/slic3r/GUI/BedShapeDialog.cpp:50 xs/src/slic3r/GUI/Tab.cpp:1738
+#: lib/Slic3r/GUI/Plater.pm:421
msgid "Size"
msgstr ""
@@ -48,25 +54,34 @@ msgstr ""
msgid "Circular"
msgstr ""
-#: xs/src/slic3r/GUI/BedShapeDialog.cpp:65 xs/src/libslic3r/PrintConfig.cpp:129
-#: xs/src/libslic3r/PrintConfig.cpp:200 xs/src/libslic3r/PrintConfig.cpp:211
-#: xs/src/libslic3r/PrintConfig.cpp:325 xs/src/libslic3r/PrintConfig.cpp:336
-#: xs/src/libslic3r/PrintConfig.cpp:355 xs/src/libslic3r/PrintConfig.cpp:434
-#: xs/src/libslic3r/PrintConfig.cpp:781 xs/src/libslic3r/PrintConfig.cpp:801
-#: xs/src/libslic3r/PrintConfig.cpp:860 xs/src/libslic3r/PrintConfig.cpp:878
-#: xs/src/libslic3r/PrintConfig.cpp:896 xs/src/libslic3r/PrintConfig.cpp:1051
-#: xs/src/libslic3r/PrintConfig.cpp:1059 xs/src/libslic3r/PrintConfig.cpp:1101
-#: xs/src/libslic3r/PrintConfig.cpp:1110 xs/src/libslic3r/PrintConfig.cpp:1120
-#: xs/src/libslic3r/PrintConfig.cpp:1128 xs/src/libslic3r/PrintConfig.cpp:1136
-#: xs/src/libslic3r/PrintConfig.cpp:1222 xs/src/libslic3r/PrintConfig.cpp:1428
-#: xs/src/libslic3r/PrintConfig.cpp:1498 xs/src/libslic3r/PrintConfig.cpp:1534
-#: xs/src/libslic3r/PrintConfig.cpp:1711 xs/src/libslic3r/PrintConfig.cpp:1718
-#: xs/src/libslic3r/PrintConfig.cpp:1725 xs/src/libslic3r/PrintConfig.cpp:1734
-#: xs/src/libslic3r/PrintConfig.cpp:1744 xs/src/libslic3r/PrintConfig.cpp:1754
+#: xs/src/slic3r/GUI/BedShapeDialog.cpp:65
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:85
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:432
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:446
+#: xs/src/slic3r/GUI/RammingChart.cpp:86
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:84
+#: xs/src/libslic3r/PrintConfig.cpp:129 xs/src/libslic3r/PrintConfig.cpp:172
+#: xs/src/libslic3r/PrintConfig.cpp:180 xs/src/libslic3r/PrintConfig.cpp:228
+#: xs/src/libslic3r/PrintConfig.cpp:239 xs/src/libslic3r/PrintConfig.cpp:353
+#: xs/src/libslic3r/PrintConfig.cpp:364 xs/src/libslic3r/PrintConfig.cpp:383
+#: xs/src/libslic3r/PrintConfig.cpp:496 xs/src/libslic3r/PrintConfig.cpp:850
+#: xs/src/libslic3r/PrintConfig.cpp:870 xs/src/libslic3r/PrintConfig.cpp:878
+#: xs/src/libslic3r/PrintConfig.cpp:936 xs/src/libslic3r/PrintConfig.cpp:954
+#: xs/src/libslic3r/PrintConfig.cpp:972 xs/src/libslic3r/PrintConfig.cpp:1034
+#: xs/src/libslic3r/PrintConfig.cpp:1151 xs/src/libslic3r/PrintConfig.cpp:1159
+#: xs/src/libslic3r/PrintConfig.cpp:1201 xs/src/libslic3r/PrintConfig.cpp:1210
+#: xs/src/libslic3r/PrintConfig.cpp:1220 xs/src/libslic3r/PrintConfig.cpp:1228
+#: xs/src/libslic3r/PrintConfig.cpp:1236 xs/src/libslic3r/PrintConfig.cpp:1322
+#: xs/src/libslic3r/PrintConfig.cpp:1528 xs/src/libslic3r/PrintConfig.cpp:1598
+#: xs/src/libslic3r/PrintConfig.cpp:1632 xs/src/libslic3r/PrintConfig.cpp:1828
+#: xs/src/libslic3r/PrintConfig.cpp:1835 xs/src/libslic3r/PrintConfig.cpp:1842
+#: xs/src/libslic3r/PrintConfig.cpp:1856 xs/src/libslic3r/PrintConfig.cpp:1866
+#: xs/src/libslic3r/PrintConfig.cpp:1876
msgid "mm"
msgstr ""
-#: xs/src/slic3r/GUI/BedShapeDialog.cpp:66 xs/src/libslic3r/PrintConfig.cpp:431
+#: xs/src/slic3r/GUI/BedShapeDialog.cpp:66
+#: xs/src/libslic3r/PrintConfig.cpp:493
msgid "Diameter"
msgstr ""
@@ -77,8 +92,8 @@ msgid ""
msgstr ""
#: xs/src/slic3r/GUI/BedShapeDialog.cpp:71
-#: xs/src/libslic3r/GCode/PreviewData.cpp:150
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:92
+#: xs/src/libslic3r/GCode/PreviewData.cpp:170
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:95
msgid "Custom"
msgstr ""
@@ -90,300 +105,730 @@ msgstr ""
msgid "Settings"
msgstr ""
-#: xs/src/slic3r/GUI/BedShapeDialog.cpp:298
+#: xs/src/slic3r/GUI/BedShapeDialog.cpp:299
msgid "Choose a file to import bed shape from (STL/OBJ/AMF/3MF/PRUSA):"
msgstr ""
-#: xs/src/slic3r/GUI/BedShapeDialog.cpp:315
+#: xs/src/slic3r/GUI/BedShapeDialog.cpp:316
msgid "Error! "
msgstr ""
-#: xs/src/slic3r/GUI/BedShapeDialog.cpp:324
+#: xs/src/slic3r/GUI/BedShapeDialog.cpp:325
msgid "The selected file contains no geometry."
msgstr ""
-#: xs/src/slic3r/GUI/BedShapeDialog.cpp:328
+#: xs/src/slic3r/GUI/BedShapeDialog.cpp:329
msgid ""
"The selected file contains several disjoint areas. This is not supported."
msgstr ""
-#: xs/src/slic3r/GUI/BedShapeDialog.hpp:42
+#: xs/src/slic3r/GUI/BedShapeDialog.hpp:44
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:395
msgid "Bed Shape"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:234
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:53
+msgid "Network lookup"
+msgstr ""
+
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:66
+msgid "Address"
+msgstr ""
+
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:67
+msgid "Hostname"
+msgstr ""
+
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:68
+msgid "Service name"
+msgstr ""
+
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:69
+msgid "OctoPrint version"
+msgstr ""
+
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:187
+msgid "Searching for devices"
+msgstr ""
+
+#: xs/src/slic3r/GUI/BonjourDialog.cpp:194
+msgid "Finished"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ButtonsDescription.cpp:13
+msgid "Buttons And Text Colors Description"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ButtonsDescription.cpp:38
+msgid "Value is the same as the system value"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ButtonsDescription.cpp:55
+msgid ""
+"Value was changed and is not equal to the system value or the last saved "
+"preset"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:15
+msgid "Upgrade"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:17
+msgid "Downgrade"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:19
+msgid "Before roll back"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:21
+msgid "User"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:24
+msgid "Unknown"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:36
+msgid "Active: "
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:42
+msgid "slic3r version"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:43
+msgid "print"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:44
+msgid "filaments"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:45
+msgid "printer"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:49 xs/src/slic3r/GUI/Tab.cpp:755
+msgid "vendor"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:49
+msgid "version"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:50
+msgid "min slic3r version"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:52
+msgid "max slic3r version"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:55
+msgid "model"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:55
+msgid "variants"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:67
+msgid "Incompatible with this Slic3r"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:70
+msgid "Activate"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp:96 xs/src/slic3r/GUI/GUI.cpp:402
+msgid "Configuration Snapshots"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:85
+msgid "nozzle"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:103
+msgid "Select all"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:104
+msgid "Select none"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:205
+#, possible-c-format
+msgid "Welcome to the Slic3r %s"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:205
+msgid "Welcome"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:211 xs/src/slic3r/GUI/GUI.cpp:399
+#, possible-c-format
+msgid "Run %s"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:213
+#, possible-c-format
+msgid ""
+"Hello, welcome to Slic3r Prusa Edition! This %s helps you with the initial "
+"configuration; just a few settings and you will be ready to print."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:217
+msgid ""
+"Remove user profiles - install from scratch (a snapshot will be taken "
+"beforehand)"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:238
+msgid "Other vendors"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:240
+msgid "Custom setup"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:264
+msgid "Automatic updates"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:264
+msgid "Updates"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:272 xs/src/slic3r/GUI/Preferences.cpp:59
+msgid "Check for application updates"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:275 xs/src/slic3r/GUI/Preferences.cpp:61
+msgid ""
+"If enabled, Slic3r checks for new versions of Slic3r PE online. When a new "
+"version becomes available a notification is displayed at the next "
+"application startup (never during program usage). This is only a "
+"notification mechanisms, no automatic installation is done."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:279 xs/src/slic3r/GUI/Preferences.cpp:67
+msgid "Update built-in Presets automatically"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:282 xs/src/slic3r/GUI/Preferences.cpp:69
+msgid ""
+"If enabled, Slic3r downloads updates of built-in system presets in the "
+"background. These updates are downloaded into a separate temporary location. "
+"When a new preset version becomes available it is offered at application "
+"startup."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:283
+msgid ""
+"Updates are never applied without user's consent and never overwrite user's "
+"customized settings."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:288
+msgid ""
+"Additionally a backup snapshot of the whole configuration is created before "
+"an update is applied."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:295
+msgid "Other Vendors"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:297
+msgid "Pick another vendor supported by Slic3r PE:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:356
+msgid "Firmware Type"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:356 xs/src/slic3r/GUI/Tab.cpp:1625
+msgid "Firmware"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:360
+msgid "Choose the type of firmware used by your printer."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:395
+msgid "Bed Shape and Size"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:398
+msgid "Set the shape of your printer's bed."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:412
+msgid "Filament and Nozzle Diameters"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:412
+msgid "Print Diameters"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:428
+msgid "Enter the diameter of your printer's hot end nozzle."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:431
+msgid "Nozzle Diameter:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:441
+msgid "Enter the diameter of your filament."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:442
+msgid ""
+"Good precision is required, so use a caliper and do multiple measurements "
+"along the filament, then compute the average."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:445
+msgid "Filament Diameter:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:463
+msgid "Extruder and Bed Temperatures"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:463
+msgid "Temperatures"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:479
+msgid "Enter the temperature needed for extruding your filament."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:480
+msgid "A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:483
+msgid "Extrusion Temperature:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:484
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:498
+msgid "°C"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:493
+msgid ""
+"Enter the bed temperature needed for getting your filament to stick to your "
+"heated bed."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:494
+msgid ""
+"A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have "
+"no heated bed."
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:497
+msgid "Bed Temperature:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:791
+msgid "&Finish"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:844
+msgid "Configuration Wizard"
+msgstr ""
+
+#: xs/src/slic3r/GUI/ConfigWizard.cpp:846
+msgid "Configuration Assistant"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:285
msgid "Array of language names and identifiers should have the same size."
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:245
+#: xs/src/slic3r/GUI/GUI.cpp:296
msgid "Select the language"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:245
+#: xs/src/slic3r/GUI/GUI.cpp:296
msgid "Language"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:312 xs/src/libslic3r/PrintConfig.cpp:170
+#: xs/src/slic3r/GUI/GUI.cpp:363 xs/src/libslic3r/PrintConfig.cpp:186
msgid "Default"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:337
+#: xs/src/slic3r/GUI/GUI.cpp:402
+msgid "Inspect / activate configuration snapshots"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:403
+msgid "Take Configuration Snapshot"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:403
+msgid "Capture a configuration snapshot"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:404
+msgid "Check for updates"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:404
+msgid "Check for configuration updates"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:406 xs/src/slic3r/GUI/Preferences.cpp:9
+msgid "Preferences"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:406
+msgid "Application preferences"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:408
msgid "Change Application Language"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:344
+#: xs/src/slic3r/GUI/GUI.cpp:417
+msgid "Taking configuration snapshot"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:417
+msgid "Snapshot name"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:456
msgid "Application will be restarted"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:344
+#: xs/src/slic3r/GUI/GUI.cpp:456
msgid "Attention!"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:351
-msgid "&Localization"
+#: xs/src/slic3r/GUI/GUI.cpp:466
+msgid "&Configuration"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:494 lib/Slic3r/GUI/MainFrame.pm:465
-#: lib/Slic3r/GUI/Plater.pm:1304
-msgid "Error"
+#: xs/src/slic3r/GUI/GUI.cpp:485
+msgid "You have unsaved changes "
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:499
+#: xs/src/slic3r/GUI/GUI.cpp:485
+msgid ". Discard changes and continue anyway?"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:486
+msgid "Unsaved Presets"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:683
msgid "Notice"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:504
-msgid "GLUquadricObjPtr | Attempt to free unreferenced scalar"
+#: xs/src/slic3r/GUI/GUI.cpp:688
+msgid "Attempt to free unreferenced scalar"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:506
+#: xs/src/slic3r/GUI/GUI.cpp:690 xs/src/slic3r/GUI/WipeTowerDialog.cpp:44
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:326
msgid "Warning"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:655
+#: xs/src/slic3r/GUI/GUI.cpp:879
msgid "Support"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:658
+#: xs/src/slic3r/GUI/GUI.cpp:882
msgid "Select what kind of support do you need"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:659 xs/src/libslic3r/GCode/PreviewData.cpp:137
+#: xs/src/slic3r/GUI/GUI.cpp:883 xs/src/libslic3r/GCode/PreviewData.cpp:157
msgid "None"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:660 xs/src/libslic3r/PrintConfig.cpp:1415
+#: xs/src/slic3r/GUI/GUI.cpp:884 xs/src/libslic3r/PrintConfig.cpp:1515
msgid "Support on build plate only"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:661
+#: xs/src/slic3r/GUI/GUI.cpp:885
msgid "Everywhere"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:673 xs/src/slic3r/GUI/Tab.cpp:441
+#: xs/src/slic3r/GUI/GUI.cpp:897 xs/src/slic3r/GUI/Tab.cpp:869
msgid "Brim"
msgstr ""
-#: xs/src/slic3r/GUI/GUI.cpp:675
+#: xs/src/slic3r/GUI/GUI.cpp:899
msgid ""
"This flag enables the brim that will be printed around each object on the "
"first layer."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:57
+#: xs/src/slic3r/GUI/GUI.cpp:908
+msgid "Purging volumes"
+msgstr ""
+
+#: xs/src/slic3r/GUI/GUI.cpp:950
+msgid "Export print config"
+msgstr ""
+
+#: xs/src/slic3r/GUI/MsgDialog.cpp:64
+msgid "Slic3r error"
+msgstr ""
+
+#: xs/src/slic3r/GUI/MsgDialog.cpp:64
+msgid "Slic3r has encountered an error"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:100
msgid "Save current "
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:58
+#: xs/src/slic3r/GUI/Tab.cpp:101
msgid "Delete this preset"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:383
+#: xs/src/slic3r/GUI/Tab.cpp:113
+msgid ""
+"Hover the cursor over buttons to find more information \n"
+"or click this button."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:741
+msgid "It's a default preset."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:742
+msgid "It's a system preset."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:743
+msgid "Current preset is inherited from "
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:748
+msgid "It can't be deleted or modified. "
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:749
+msgid ""
+"Any modifications should be saved as a new preset inherited from this one. "
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:750
+msgid "To do that please specify a new name for the preset."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:754
+msgid "Additional information:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:762
+msgid "printer model"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:764
+msgid "default print profile"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:767
+msgid "default filament profile"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:811
msgid "Layers and perimeters"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:384 xs/src/libslic3r/PrintConfig.cpp:777
+#: xs/src/slic3r/GUI/Tab.cpp:812 xs/src/libslic3r/PrintConfig.cpp:846
msgid "Layer height"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:388
+#: xs/src/slic3r/GUI/Tab.cpp:816
msgid "Vertical shells"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:399
+#: xs/src/slic3r/GUI/Tab.cpp:827
msgid "Horizontal shells"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:400 xs/src/libslic3r/PrintConfig.cpp:1321
+#: xs/src/slic3r/GUI/Tab.cpp:828 xs/src/libslic3r/PrintConfig.cpp:1421
msgid "Solid layers"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:405
+#: xs/src/slic3r/GUI/Tab.cpp:833
msgid "Quality (slower slicing)"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:412 xs/src/slic3r/GUI/Tab.cpp:426
-#: xs/src/slic3r/GUI/Tab.cpp:519 xs/src/slic3r/GUI/Tab.cpp:522
-#: xs/src/slic3r/GUI/Tab.cpp:905 xs/src/slic3r/GUI/Tab.cpp:1191
-#: xs/src/libslic3r/PrintConfig.cpp:107 xs/src/libslic3r/PrintConfig.cpp:208
-#: xs/src/libslic3r/PrintConfig.cpp:736 xs/src/libslic3r/PrintConfig.cpp:1740
+#: xs/src/slic3r/GUI/Tab.cpp:840 xs/src/slic3r/GUI/Tab.cpp:854
+#: xs/src/slic3r/GUI/Tab.cpp:948 xs/src/slic3r/GUI/Tab.cpp:951
+#: xs/src/slic3r/GUI/Tab.cpp:1300 xs/src/slic3r/GUI/Tab.cpp:1628
+#: xs/src/libslic3r/PrintConfig.cpp:107 xs/src/libslic3r/PrintConfig.cpp:236
+#: xs/src/libslic3r/PrintConfig.cpp:798 xs/src/libslic3r/PrintConfig.cpp:1862
msgid "Advanced"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:416 xs/src/slic3r/GUI/Tab.cpp:417
-#: xs/src/slic3r/GUI/Tab.cpp:735 xs/src/libslic3r/PrintConfig.cpp:87
-#: xs/src/libslic3r/PrintConfig.cpp:247 xs/src/libslic3r/PrintConfig.cpp:488
-#: xs/src/libslic3r/PrintConfig.cpp:502 xs/src/libslic3r/PrintConfig.cpp:540
-#: xs/src/libslic3r/PrintConfig.cpp:681 xs/src/libslic3r/PrintConfig.cpp:691
-#: xs/src/libslic3r/PrintConfig.cpp:709 xs/src/libslic3r/PrintConfig.cpp:727
-#: xs/src/libslic3r/PrintConfig.cpp:746 xs/src/libslic3r/PrintConfig.cpp:1270
-#: xs/src/libslic3r/PrintConfig.cpp:1287
+#: xs/src/slic3r/GUI/Tab.cpp:844 xs/src/slic3r/GUI/Tab.cpp:845
+#: xs/src/slic3r/GUI/Tab.cpp:1152 xs/src/libslic3r/PrintConfig.cpp:87
+#: xs/src/libslic3r/PrintConfig.cpp:275 xs/src/libslic3r/PrintConfig.cpp:550
+#: xs/src/libslic3r/PrintConfig.cpp:564 xs/src/libslic3r/PrintConfig.cpp:602
+#: xs/src/libslic3r/PrintConfig.cpp:743 xs/src/libslic3r/PrintConfig.cpp:753
+#: xs/src/libslic3r/PrintConfig.cpp:771 xs/src/libslic3r/PrintConfig.cpp:789
+#: xs/src/libslic3r/PrintConfig.cpp:808 xs/src/libslic3r/PrintConfig.cpp:1370
+#: xs/src/libslic3r/PrintConfig.cpp:1387
msgid "Infill"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:422
+#: xs/src/slic3r/GUI/Tab.cpp:850
msgid "Reducing printing time"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:434
+#: xs/src/slic3r/GUI/Tab.cpp:862
msgid "Skirt and brim"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:435 xs/src/libslic3r/GCode/PreviewData.cpp:146
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:88
+#: xs/src/slic3r/GUI/Tab.cpp:863 xs/src/libslic3r/GCode/PreviewData.cpp:166
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:91
msgid "Skirt"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:444 xs/src/slic3r/GUI/Tab.cpp:445
-#: xs/src/libslic3r/PrintConfig.cpp:191 xs/src/libslic3r/PrintConfig.cpp:1037
-#: xs/src/libslic3r/PrintConfig.cpp:1387 xs/src/libslic3r/PrintConfig.cpp:1394
-#: xs/src/libslic3r/PrintConfig.cpp:1406 xs/src/libslic3r/PrintConfig.cpp:1416
-#: xs/src/libslic3r/PrintConfig.cpp:1424 xs/src/libslic3r/PrintConfig.cpp:1439
-#: xs/src/libslic3r/PrintConfig.cpp:1460 xs/src/libslic3r/PrintConfig.cpp:1471
-#: xs/src/libslic3r/PrintConfig.cpp:1487 xs/src/libslic3r/PrintConfig.cpp:1496
-#: xs/src/libslic3r/PrintConfig.cpp:1505 xs/src/libslic3r/PrintConfig.cpp:1516
-#: xs/src/libslic3r/PrintConfig.cpp:1532 xs/src/libslic3r/PrintConfig.cpp:1540
-#: xs/src/libslic3r/PrintConfig.cpp:1541 xs/src/libslic3r/PrintConfig.cpp:1550
-#: xs/src/libslic3r/PrintConfig.cpp:1558 xs/src/libslic3r/PrintConfig.cpp:1572
-#: xs/src/libslic3r/GCode/PreviewData.cpp:147
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:89
+#: xs/src/slic3r/GUI/Tab.cpp:872 xs/src/slic3r/GUI/Tab.cpp:873
+#: xs/src/libslic3r/PrintConfig.cpp:219 xs/src/libslic3r/PrintConfig.cpp:1137
+#: xs/src/libslic3r/PrintConfig.cpp:1487 xs/src/libslic3r/PrintConfig.cpp:1494
+#: xs/src/libslic3r/PrintConfig.cpp:1506 xs/src/libslic3r/PrintConfig.cpp:1516
+#: xs/src/libslic3r/PrintConfig.cpp:1524 xs/src/libslic3r/PrintConfig.cpp:1539
+#: xs/src/libslic3r/PrintConfig.cpp:1560 xs/src/libslic3r/PrintConfig.cpp:1571
+#: xs/src/libslic3r/PrintConfig.cpp:1587 xs/src/libslic3r/PrintConfig.cpp:1596
+#: xs/src/libslic3r/PrintConfig.cpp:1605 xs/src/libslic3r/PrintConfig.cpp:1616
+#: xs/src/libslic3r/PrintConfig.cpp:1630 xs/src/libslic3r/PrintConfig.cpp:1638
+#: xs/src/libslic3r/PrintConfig.cpp:1639 xs/src/libslic3r/PrintConfig.cpp:1648
+#: xs/src/libslic3r/PrintConfig.cpp:1656 xs/src/libslic3r/PrintConfig.cpp:1670
+#: xs/src/libslic3r/GCode/PreviewData.cpp:167
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:92
msgid "Support material"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:450
+#: xs/src/slic3r/GUI/Tab.cpp:878
msgid "Raft"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:454
+#: xs/src/slic3r/GUI/Tab.cpp:882
msgid "Options for support material and raft"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:468 xs/src/libslic3r/PrintConfig.cpp:118
-#: xs/src/libslic3r/PrintConfig.cpp:278 xs/src/libslic3r/PrintConfig.cpp:635
-#: xs/src/libslic3r/PrintConfig.cpp:747 xs/src/libslic3r/PrintConfig.cpp:986
-#: xs/src/libslic3r/PrintConfig.cpp:1208 xs/src/libslic3r/PrintConfig.cpp:1258
-#: xs/src/libslic3r/PrintConfig.cpp:1309 xs/src/libslic3r/PrintConfig.cpp:1632
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:71
+#: xs/src/slic3r/GUI/Tab.cpp:896 xs/src/libslic3r/PrintConfig.cpp:118
+#: xs/src/libslic3r/PrintConfig.cpp:306 xs/src/libslic3r/PrintConfig.cpp:697
+#: xs/src/libslic3r/PrintConfig.cpp:809 xs/src/libslic3r/PrintConfig.cpp:1071
+#: xs/src/libslic3r/PrintConfig.cpp:1308 xs/src/libslic3r/PrintConfig.cpp:1358
+#: xs/src/libslic3r/PrintConfig.cpp:1409 xs/src/libslic3r/PrintConfig.cpp:1730
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:70
msgid "Speed"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:469
+#: xs/src/slic3r/GUI/Tab.cpp:897
msgid "Speed for print moves"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:481
+#: xs/src/slic3r/GUI/Tab.cpp:909
msgid "Speed for non-print moves"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:484
+#: xs/src/slic3r/GUI/Tab.cpp:912
msgid "Modifiers"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:487
+#: xs/src/slic3r/GUI/Tab.cpp:915
msgid "Acceleration control (advanced)"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:494
+#: xs/src/slic3r/GUI/Tab.cpp:922
msgid "Autospeed (advanced)"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:500
+#: xs/src/slic3r/GUI/Tab.cpp:928
msgid "Multiple Extruders"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:501 xs/src/slic3r/GUI/Tab.cpp:1040
-#: xs/src/libslic3r/PrintConfig.cpp:308 xs/src/libslic3r/PrintConfig.cpp:702
-#: xs/src/libslic3r/PrintConfig.cpp:965 xs/src/libslic3r/PrintConfig.cpp:1279
-#: xs/src/libslic3r/PrintConfig.cpp:1452 xs/src/libslic3r/PrintConfig.cpp:1478
+#: xs/src/slic3r/GUI/Tab.cpp:929 xs/src/slic3r/GUI/Tab.cpp:1470
+#: xs/src/libslic3r/PrintConfig.cpp:336 xs/src/libslic3r/PrintConfig.cpp:764
+#: xs/src/libslic3r/PrintConfig.cpp:1050 xs/src/libslic3r/PrintConfig.cpp:1379
+#: xs/src/libslic3r/PrintConfig.cpp:1552 xs/src/libslic3r/PrintConfig.cpp:1578
msgid "Extruders"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:508
+#: xs/src/slic3r/GUI/Tab.cpp:936
msgid "Ooze prevention"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:512 xs/src/libslic3r/GCode/PreviewData.cpp:149
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:91
+#: xs/src/slic3r/GUI/Tab.cpp:940 xs/src/libslic3r/GCode/PreviewData.cpp:169
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:94
msgid "Wipe tower"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:523
+#: xs/src/slic3r/GUI/Tab.cpp:952
msgid "Extrusion width"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:533
+#: xs/src/slic3r/GUI/Tab.cpp:962
msgid "Overlap"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:536
+#: xs/src/slic3r/GUI/Tab.cpp:965
msgid "Flow"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:539
+#: xs/src/slic3r/GUI/Tab.cpp:968
msgid "Other"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:546
+#: xs/src/slic3r/GUI/Tab.cpp:975
msgid "Output options"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:547
+#: xs/src/slic3r/GUI/Tab.cpp:976
msgid "Sequential printing"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:549
+#: xs/src/slic3r/GUI/Tab.cpp:978
msgid "Extruder clearance (mm)"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:558
+#: xs/src/slic3r/GUI/Tab.cpp:987
msgid "Output file"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:564 xs/src/libslic3r/PrintConfig.cpp:1008
+#: xs/src/slic3r/GUI/Tab.cpp:993 xs/src/libslic3r/PrintConfig.cpp:1093
msgid "Post-processing scripts"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:570 xs/src/slic3r/GUI/Tab.cpp:571
-#: xs/src/slic3r/GUI/Tab.cpp:933 xs/src/slic3r/GUI/Tab.cpp:934
-#: xs/src/slic3r/GUI/Tab.cpp:1234 xs/src/slic3r/GUI/Tab.cpp:1235
+#: xs/src/slic3r/GUI/Tab.cpp:999 xs/src/slic3r/GUI/Tab.cpp:1000
+#: xs/src/slic3r/GUI/Tab.cpp:1349 xs/src/slic3r/GUI/Tab.cpp:1350
+#: xs/src/slic3r/GUI/Tab.cpp:1671 xs/src/slic3r/GUI/Tab.cpp:1672
msgid "Notes"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:577 xs/src/slic3r/GUI/Tab.cpp:941
+#: xs/src/slic3r/GUI/Tab.cpp:1006 xs/src/slic3r/GUI/Tab.cpp:1357
+#: xs/src/slic3r/GUI/Tab.cpp:1678
msgid "Dependencies"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:578 xs/src/slic3r/GUI/Tab.cpp:942
+#: xs/src/slic3r/GUI/Tab.cpp:1007 xs/src/slic3r/GUI/Tab.cpp:1358
+#: xs/src/slic3r/GUI/Tab.cpp:1679
msgid "Profile dependencies"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:579 xs/src/slic3r/GUI/Tab.cpp:943
-#: xs/src/slic3r/GUI/Tab.cpp:1746 xs/src/libslic3r/PrintConfig.cpp:143
+#: xs/src/slic3r/GUI/Tab.cpp:1008 xs/src/slic3r/GUI/Tab.cpp:1359
+#: xs/src/slic3r/GUI/Tab.cpp:2241 xs/src/libslic3r/PrintConfig.cpp:143
msgid "Compatible printers"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:603
-#, possible-c-format
+#: xs/src/slic3r/GUI/Tab.cpp:1041
+#, no-c-format
msgid ""
"The Spiral Vase mode requires:\n"
"- one perimeter\n"
@@ -395,25 +840,11 @@ msgid ""
"Shall I adjust those settings in order to enable Spiral Vase?"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:610
+#: xs/src/slic3r/GUI/Tab.cpp:1048
msgid "Spiral Vase"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:630
-msgid ""
-"The Wipe Tower currently supports only:\n"
-"- first layer height 0.2mm\n"
-"- layer height from 0.15mm to 0.35mm\n"
-"\n"
-"Shall I adjust those settings in order to enable the Wipe Tower?"
-msgstr ""
-
-#: xs/src/slic3r/GUI/Tab.cpp:634 xs/src/slic3r/GUI/Tab.cpp:656
-#: xs/src/slic3r/GUI/Tab.cpp:673
-msgid "Wipe Tower"
-msgstr ""
-
-#: xs/src/slic3r/GUI/Tab.cpp:652
+#: xs/src/slic3r/GUI/Tab.cpp:1069
msgid ""
"The Wipe Tower currently supports the non-soluble supports only\n"
"if they are printed with the current extruder without triggering a tool "
@@ -424,7 +855,11 @@ msgid ""
"Shall I adjust those settings in order to enable the Wipe Tower?"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:670
+#: xs/src/slic3r/GUI/Tab.cpp:1073 xs/src/slic3r/GUI/Tab.cpp:1090
+msgid "Wipe Tower"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:1087
msgid ""
"For the Wipe Tower to work with the soluble supports, the support layers\n"
"need to be synchronized with the object layers.\n"
@@ -432,7 +867,7 @@ msgid ""
"Shall I synchronize support layers in order to enable the Wipe Tower?"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:688
+#: xs/src/slic3r/GUI/Tab.cpp:1105
msgid ""
"Supports work better, if the following feature is enabled:\n"
"- Detect bridging perimeters\n"
@@ -440,355 +875,479 @@ msgid ""
"Shall I adjust those settings for supports?"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:691
+#: xs/src/slic3r/GUI/Tab.cpp:1108
msgid "Support Generator"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:733
+#: xs/src/slic3r/GUI/Tab.cpp:1150
msgid "The "
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:733
-#, possible-c-format
+#: xs/src/slic3r/GUI/Tab.cpp:1150
+#, no-c-format
msgid ""
" infill pattern is not supposed to work at 100% density.\n"
"\n"
"Shall I switch to rectilinear fill pattern?"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:860 xs/src/slic3r/GUI/Tab.cpp:861
-#: lib/Slic3r/GUI/Plater.pm:368
+#: xs/src/slic3r/GUI/Tab.cpp:1255 xs/src/slic3r/GUI/Tab.cpp:1256
+#: lib/Slic3r/GUI/Plater.pm:378
msgid "Filament"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:868
+#: xs/src/slic3r/GUI/Tab.cpp:1263
msgid "Temperature "
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:869 xs/src/slic3r/GUI/Tab.cpp:1313
-#: xs/src/libslic3r/PrintConfig.cpp:307
+#: xs/src/slic3r/GUI/Tab.cpp:1264 xs/src/libslic3r/PrintConfig.cpp:335
msgid "Extruder"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:874
+#: xs/src/slic3r/GUI/Tab.cpp:1269
msgid "Bed"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:879
+#: xs/src/slic3r/GUI/Tab.cpp:1274
msgid "Cooling"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:880 xs/src/libslic3r/PrintConfig.cpp:929
-#: xs/src/libslic3r/PrintConfig.cpp:1702
+#: xs/src/slic3r/GUI/Tab.cpp:1275 xs/src/libslic3r/PrintConfig.cpp:1005
+#: xs/src/libslic3r/PrintConfig.cpp:1800
msgid "Enable"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:891
+#: xs/src/slic3r/GUI/Tab.cpp:1286
msgid "Fan settings"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:892
+#: xs/src/slic3r/GUI/Tab.cpp:1287
msgid "Fan speed"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:900
+#: xs/src/slic3r/GUI/Tab.cpp:1295
msgid "Cooling thresholds"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:906
+#: xs/src/slic3r/GUI/Tab.cpp:1301
msgid "Filament properties"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:910
+#: xs/src/slic3r/GUI/Tab.cpp:1305
msgid "Print speed override"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:920 xs/src/slic3r/GUI/Tab.cpp:1197
+#: xs/src/slic3r/GUI/Tab.cpp:1315
+msgid "Toolchange behaviour"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:1319
+msgid "Ramming"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:1321
+msgid "Ramming settings"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:1336 xs/src/slic3r/GUI/Tab.cpp:1634
msgid "Custom G-code"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:921 xs/src/slic3r/GUI/Tab.cpp:1198
-#: xs/src/libslic3r/PrintConfig.cpp:1349 xs/src/libslic3r/PrintConfig.cpp:1364
+#: xs/src/slic3r/GUI/Tab.cpp:1337 xs/src/slic3r/GUI/Tab.cpp:1635
+#: xs/src/libslic3r/PrintConfig.cpp:1449 xs/src/libslic3r/PrintConfig.cpp:1464
msgid "Start G-code"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:927 xs/src/slic3r/GUI/Tab.cpp:1204
-#: xs/src/libslic3r/PrintConfig.cpp:217 xs/src/libslic3r/PrintConfig.cpp:227
+#: xs/src/slic3r/GUI/Tab.cpp:1343 xs/src/slic3r/GUI/Tab.cpp:1641
+#: xs/src/libslic3r/PrintConfig.cpp:245 xs/src/libslic3r/PrintConfig.cpp:255
msgid "End G-code"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1011 xs/src/slic3r/GUI/Preferences.cpp:11
+#: xs/src/slic3r/GUI/Tab.cpp:1438 xs/src/slic3r/GUI/Preferences.cpp:17
msgid "General"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1012
+#: xs/src/slic3r/GUI/Tab.cpp:1439
msgid "Size and coordinates"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1014 xs/src/libslic3r/PrintConfig.cpp:34
+#: xs/src/slic3r/GUI/Tab.cpp:1441 xs/src/libslic3r/PrintConfig.cpp:34
msgid "Bed shape"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1016 xs/src/slic3r/GUI/Tab.cpp:1715
+#: xs/src/slic3r/GUI/Tab.cpp:1443 xs/src/slic3r/GUI/Tab.cpp:2209
msgid " Set "
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1036
+#: xs/src/slic3r/GUI/Tab.cpp:1466
msgid "Capabilities"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1041
+#: xs/src/slic3r/GUI/Tab.cpp:1471
msgid "Number of extruders of the printer."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1063
+#: xs/src/slic3r/GUI/Tab.cpp:1496
msgid "USB/Serial connection"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1064 xs/src/libslic3r/PrintConfig.cpp:1200
+#: xs/src/slic3r/GUI/Tab.cpp:1497 xs/src/libslic3r/PrintConfig.cpp:1300
msgid "Serial port"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1069
+#: xs/src/slic3r/GUI/Tab.cpp:1502
msgid "Rescan serial ports"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1078 xs/src/slic3r/GUI/Tab.cpp:1125
+#: xs/src/slic3r/GUI/Tab.cpp:1511 xs/src/slic3r/GUI/Tab.cpp:1558
msgid "Test"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1091
+#: xs/src/slic3r/GUI/Tab.cpp:1524
msgid "Connection to printer works correctly."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1091 xs/src/slic3r/GUI/Tab.cpp:1135
+#: xs/src/slic3r/GUI/Tab.cpp:1524 xs/src/slic3r/GUI/Tab.cpp:1568
msgid "Success!"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1094
+#: xs/src/slic3r/GUI/Tab.cpp:1527
msgid "Connection failed."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1106
+#: xs/src/slic3r/GUI/Tab.cpp:1539 xs/src/slic3r/Utils/OctoPrint.cpp:50
msgid "OctoPrint upload"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1109 xs/src/slic3r/GUI/Tab.cpp:1156
+#: xs/src/slic3r/GUI/Tab.cpp:1542 xs/src/slic3r/GUI/Tab.cpp:1591
msgid " Browse "
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1135 lib/Slic3r/GUI/MainFrame.pm:209
+#: xs/src/slic3r/GUI/Tab.cpp:1568
msgid "Connection to OctoPrint works correctly."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1138
+#: xs/src/slic3r/GUI/Tab.cpp:1571
msgid "Could not connect to OctoPrint"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1138
+#: xs/src/slic3r/GUI/Tab.cpp:1571
msgid "Note: OctoPrint version at least 1.1.0 is required."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1162
+#: xs/src/slic3r/GUI/Tab.cpp:1597
msgid "Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1163
+#: xs/src/slic3r/GUI/Tab.cpp:1598
msgid "Open CA certificate file"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1177
+#: xs/src/slic3r/GUI/Tab.cpp:1612
msgid ""
"HTTPS CA file is optional. It is only needed if you use HTTPS with a self-"
"signed certificate."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1188
-msgid "Firmware"
-msgstr ""
-
-#: xs/src/slic3r/GUI/Tab.cpp:1210 xs/src/libslic3r/PrintConfig.cpp:48
+#: xs/src/slic3r/GUI/Tab.cpp:1647 xs/src/libslic3r/PrintConfig.cpp:48
msgid "Before layer change G-code"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1216 xs/src/libslic3r/PrintConfig.cpp:766
+#: xs/src/slic3r/GUI/Tab.cpp:1653 xs/src/libslic3r/PrintConfig.cpp:835
msgid "After layer change G-code"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1222 xs/src/libslic3r/PrintConfig.cpp:1609
+#: xs/src/slic3r/GUI/Tab.cpp:1659 xs/src/libslic3r/PrintConfig.cpp:1707
msgid "Tool change G-code"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1228
+#: xs/src/slic3r/GUI/Tab.cpp:1665
msgid "Between objects G-code (for sequential printing)"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1266 xs/src/libslic3r/GCode/PreviewData.cpp:400
+#: xs/src/slic3r/GUI/Tab.cpp:1716 xs/src/slic3r/GUI/Tab.cpp:1722
+msgid "Single extruder MM setup"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:1723
+msgid "Single extruder multimaterial parameters"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:1734 xs/src/libslic3r/GCode/PreviewData.cpp:440
#, possible-c-format
msgid "Extruder %d"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1273
+#: xs/src/slic3r/GUI/Tab.cpp:1741
msgid "Layer height limits"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1278
+#: xs/src/slic3r/GUI/Tab.cpp:1746
msgid "Position (for multi-extruder printers)"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1281
+#: xs/src/slic3r/GUI/Tab.cpp:1749
msgid "Retraction"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1284
+#: xs/src/slic3r/GUI/Tab.cpp:1752
msgid "Only lift Z"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1297
+#: xs/src/slic3r/GUI/Tab.cpp:1765
msgid ""
"Retraction when tool is disabled (advanced settings for multi-extruder "
"setups)"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1301 lib/Slic3r/GUI/Plater.pm:150
-#: lib/Slic3r/GUI/Plater.pm:2095
+#: xs/src/slic3r/GUI/Tab.cpp:1769 lib/Slic3r/GUI/Plater.pm:160
+#: lib/Slic3r/GUI/Plater.pm:2154
msgid "Preview"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1386
+#: xs/src/slic3r/GUI/Tab.cpp:1848
msgid ""
"The Wipe option is not available when using the Firmware Retraction mode.\n"
"\n"
"Shall I disable it in order to enable Firmware Retraction?"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1388
+#: xs/src/slic3r/GUI/Tab.cpp:1850
msgid "Firmware Retraction"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1547
+#: xs/src/slic3r/GUI/Tab.cpp:2022
msgid "Default "
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1547
+#: xs/src/slic3r/GUI/Tab.cpp:2022
msgid " preset"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1548
+#: xs/src/slic3r/GUI/Tab.cpp:2023
msgid " preset\n"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1566
+#: xs/src/slic3r/GUI/Tab.cpp:2041
msgid ""
"\n"
"\n"
"is not compatible with printer\n"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1566
+#: xs/src/slic3r/GUI/Tab.cpp:2041
msgid ""
"\n"
"\n"
"and it has the following unsaved changes:"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1567
+#: xs/src/slic3r/GUI/Tab.cpp:2042
msgid ""
"\n"
"\n"
"has the following unsaved changes:"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1569
+#: xs/src/slic3r/GUI/Tab.cpp:2044
msgid ""
"\n"
"\n"
"Discard changes and continue anyway?"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1570
+#: xs/src/slic3r/GUI/Tab.cpp:2045
msgid "Unsaved Changes"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1638
+#: xs/src/slic3r/GUI/Tab.cpp:2119
msgid "The supplied name is empty. It can't be saved."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1658
+#: xs/src/slic3r/GUI/Tab.cpp:2124
+msgid "Cannot overwrite a system profile."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2128
+msgid "Cannot overwrite an external."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2152
msgid "remove"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1658
+#: xs/src/slic3r/GUI/Tab.cpp:2152
msgid "delete"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1659
+#: xs/src/slic3r/GUI/Tab.cpp:2153
msgid "Are you sure you want to "
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1659
+#: xs/src/slic3r/GUI/Tab.cpp:2153
msgid " the selected preset?"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1660
+#: xs/src/slic3r/GUI/Tab.cpp:2154
msgid "Remove"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1660 lib/Slic3r/GUI/Plater.pm:178
-#: lib/Slic3r/GUI/Plater.pm:196 lib/Slic3r/GUI/Plater.pm:1991
+#: xs/src/slic3r/GUI/Tab.cpp:2154 lib/Slic3r/GUI/Plater.pm:188
+#: lib/Slic3r/GUI/Plater.pm:206 lib/Slic3r/GUI/Plater.pm:2050
msgid "Delete"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1661
+#: xs/src/slic3r/GUI/Tab.cpp:2155
msgid " Preset"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1714
+#: xs/src/slic3r/GUI/Tab.cpp:2208
msgid "All"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1745
+#: xs/src/slic3r/GUI/Tab.cpp:2240
msgid "Select the printers this profile is compatible with."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1834 lib/Slic3r/GUI/MainFrame.pm:509
-#: lib/Slic3r/GUI/Plater.pm:1615
+#: xs/src/slic3r/GUI/Tab.cpp:2286 xs/src/slic3r/GUI/Tab.cpp:2372
+#: xs/src/slic3r/GUI/Preset.cpp:605 xs/src/slic3r/GUI/Preset.cpp:645
+#: xs/src/slic3r/GUI/Preset.cpp:670 xs/src/slic3r/GUI/Preset.cpp:702
+#: xs/src/slic3r/GUI/PresetBundle.cpp:1069
+#: xs/src/slic3r/GUI/PresetBundle.cpp:1122 lib/Slic3r/GUI/Plater.pm:552
+msgid "System presets"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2287 xs/src/slic3r/GUI/Tab.cpp:2373
+msgid "Default presets"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2442
+msgid ""
+"LOCKED LOCK;indicates that the settings are the same as the system values "
+"for the current option group"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2445
+msgid ""
+"UNLOCKED LOCK;indicates that some settings were changed and are not equal to "
+"the system values for the current option group.\n"
+"Click the UNLOCKED LOCK icon to reset all settings for current option group "
+"to the system values."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2451
+msgid ""
+"WHITE BULLET;for the left button: \tindicates a non-system preset,\n"
+"for the right button: \tindicates that the settings hasn't been modified."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2455
+msgid ""
+"BACK ARROW;indicates that the settings were changed and are not equal to the "
+"last saved preset for the current option group.\n"
+"Click the BACK ARROW icon to reset all settings for the current option group "
+"to the last saved preset."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2481
+msgid ""
+"LOCKED LOCK icon indicates that the settings are the same as the system "
+"values for the current option group"
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2483
+msgid ""
+"UNLOCKED LOCK icon indicates that some settings were changed and are not "
+"equal to the system values for the current option group.\n"
+"Click to reset all settings for current option group to the system values."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2486
+msgid "WHITE BULLET icon indicates a non system preset."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2489
+msgid ""
+"WHITE BULLET icon indicates that the settings are the same as in the last "
+"saved preset for the current option group."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2491
+msgid ""
+"BACK ARROW icon indicates that the settings were changed and are not equal "
+"to the last saved preset for the current option group.\n"
+"Click to reset all settings for the current option group to the last saved "
+"preset."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2497
+msgid ""
+"LOCKED LOCK icon indicates that the value is the same as the system value."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2498
+msgid ""
+"UNLOCKED LOCK icon indicates that the value was changed and is not equal to "
+"the system value.\n"
+"Click to reset current value to the system value."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2504
+msgid ""
+"WHITE BULLET icon indicates that the value is the same as in the last saved "
+"preset."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2505
+msgid ""
+"BACK ARROW icon indicates that the value was changed and is not equal to the "
+"last saved preset.\n"
+"Click to reset current value to the last saved preset."
+msgstr ""
+
+#: xs/src/slic3r/GUI/Tab.cpp:2575 lib/Slic3r/GUI/MainFrame.pm:445
+#: lib/Slic3r/GUI/Plater.pm:1660
msgid "Save "
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1834
+#: xs/src/slic3r/GUI/Tab.cpp:2575
msgid " as:"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1868
+#: xs/src/slic3r/GUI/Tab.cpp:2609
msgid ""
"The supplied name is not valid; the following characters are not allowed:"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.cpp:1871
+#: xs/src/slic3r/GUI/Tab.cpp:2612
msgid "The supplied name is not available."
msgstr ""
-#: xs/src/slic3r/GUI/Tab.hpp:185
+#: xs/src/slic3r/GUI/Tab.hpp:283
msgid "Print Settings"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.hpp:205
+#: xs/src/slic3r/GUI/Tab.hpp:303
msgid "Filament Settings"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.hpp:226
+#: xs/src/slic3r/GUI/Tab.hpp:325
msgid "Printer Settings"
msgstr ""
-#: xs/src/slic3r/GUI/Tab.hpp:240
+#: xs/src/slic3r/GUI/Tab.hpp:340
msgid "Save preset"
msgstr ""
-#: xs/src/slic3r/GUI/Field.cpp:59
+#: xs/src/slic3r/GUI/Field.cpp:72
msgid "default"
msgstr ""
+#: xs/src/slic3r/GUI/Preset.cpp:649 xs/src/slic3r/GUI/Preset.cpp:706
+#: xs/src/slic3r/GUI/PresetBundle.cpp:1127 lib/Slic3r/GUI/Plater.pm:553
+msgid "User presets"
+msgstr ""
+
#: xs/src/slic3r/GUI/PresetHints.cpp:27
#, possible-c-format
msgid ""
@@ -915,123 +1474,300 @@ msgstr ""
msgid "%d lines: %.2lf mm"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.hpp:17
-msgid "Preferences"
-msgstr ""
-
-#: xs/src/slic3r/GUI/Preferences.cpp:27
+#: xs/src/slic3r/GUI/Preferences.cpp:34
msgid "Remember output directory"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:29
+#: xs/src/slic3r/GUI/Preferences.cpp:36
msgid ""
"If this is enabled, Slic3r will prompt the last output directory instead of "
"the one containing the input files."
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:35
+#: xs/src/slic3r/GUI/Preferences.cpp:42
msgid "Auto-center parts"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:37
+#: xs/src/slic3r/GUI/Preferences.cpp:44
msgid ""
"If this is enabled, Slic3r will auto-center objects around the print bed "
"center."
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:43
+#: xs/src/slic3r/GUI/Preferences.cpp:50
msgid "Background processing"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:45
+#: xs/src/slic3r/GUI/Preferences.cpp:52
msgid ""
"If this is enabled, Slic3r will pre-process objects as soon as they're "
"loaded in order to save time when exporting G-code."
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:51
+#: xs/src/slic3r/GUI/Preferences.cpp:74
msgid "Disable USB/serial connection"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:53
+#: xs/src/slic3r/GUI/Preferences.cpp:76
msgid ""
"Disable communication with the printer over a serial / USB cable. This "
"simplifies the user interface in case the printer is never attached to the "
"computer."
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:59
+#: xs/src/slic3r/GUI/Preferences.cpp:82
msgid "Suppress \" - default - \" presets"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:61
+#: xs/src/slic3r/GUI/Preferences.cpp:84
msgid ""
"Suppress \" - default - \" presets in the Print / Filament / Printer "
"selections once there are any other valid presets available."
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:67
+#: xs/src/slic3r/GUI/Preferences.cpp:90
msgid "Show incompatible print and filament presets"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:69
+#: xs/src/slic3r/GUI/Preferences.cpp:92
msgid ""
"When checked, the print and filament presets are shown in the preset editor "
"even if they are marked as incompatible with the active printer"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:75
+#: xs/src/slic3r/GUI/Preferences.cpp:98
msgid "Use legacy OpenGL 1.1 rendering"
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:77
+#: xs/src/slic3r/GUI/Preferences.cpp:100
msgid ""
"If you have rendering issues caused by a buggy OpenGL 2.0 driver, you may "
"try to check this checkbox. This will disable the layer height editing and "
"anti aliasing, so it is likely better to upgrade your graphics driver."
msgstr ""
-#: xs/src/slic3r/GUI/Preferences.cpp:101
+#: xs/src/slic3r/GUI/Preferences.cpp:124
msgid "You need to restart Slic3r to make the changes effective."
msgstr ""
-#: xs/src/slic3r/GUI/BonjourDialog.cpp:53
-msgid "Network lookup"
+#: xs/src/slic3r/GUI/RammingChart.cpp:28
+msgid "NO RAMMING AT ALL"
msgstr ""
-#: xs/src/slic3r/GUI/BonjourDialog.cpp:66
-msgid "Address"
+#: xs/src/slic3r/GUI/RammingChart.cpp:81
+msgid "Time"
msgstr ""
-#: xs/src/slic3r/GUI/BonjourDialog.cpp:67
-msgid "Hostname"
+#: xs/src/slic3r/GUI/RammingChart.cpp:81 xs/src/slic3r/GUI/RammingChart.cpp:86
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:82
+#: xs/src/libslic3r/PrintConfig.cpp:480
+msgid "s"
msgstr ""
-#: xs/src/slic3r/GUI/BonjourDialog.cpp:68
-msgid "Service name"
+#: xs/src/slic3r/GUI/RammingChart.cpp:86
+msgid "Volumetric speed"
msgstr ""
-#: xs/src/slic3r/GUI/BonjourDialog.cpp:69
-msgid "OctoPrint version"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:27
+msgid "Update available"
msgstr ""
-#: xs/src/slic3r/GUI/BonjourDialog.cpp:187
-msgid "Searching for devices"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:27
+msgid "New version of Slic3r PE is available"
msgstr ""
-#: xs/src/slic3r/GUI/BonjourDialog.cpp:194
-msgid "Finished."
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:34
+msgid "To download, follow the link below."
msgstr ""
-#: xs/src/slic3r/Utils/OctoPrint.cpp:53
-msgid "G-code file successfully uploaded to the OctoPrint server"
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:41
+msgid "Current version:"
msgstr ""
-#: xs/src/slic3r/Utils/OctoPrint.cpp:67
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:43
+msgid "New version:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:51
+msgid "Don't notify about new releases any more"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:69
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:161
+msgid "Configuration update"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:69
+msgid "Configuration update is available"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:72
+msgid ""
+"Would you like to install it?\n"
+"\n"
+"Note that a full configuration snapshot will be created first. It can then "
+"be restored at any time should there be a problem with the new version.\n"
+"\n"
+"Updated configuration bundles:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:108
+msgid "Slic3r incompatibility"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:108
+msgid "Slic3r configuration is incompatible"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:111
+msgid ""
+"This version of Slic3r PE is not compatible with currently installed "
+"configuration bundles.\n"
+"This probably happened as a result of running an older Slic3r PE after using "
+"a newer one.\n"
+"\n"
+"You may either exit Slic3r and try again with a newer version, or you may re-"
+"run the initial configuration. Doing so will create a backup snapshot of the "
+"existing configuration before installing files compatible with this Slic3r.\n"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:120
+#, possible-c-format
+msgid "This Slic3r PE version: %s"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:125
+msgid "Incompatible bundles:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:141
+msgid "Exit Slic3r"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:144
+msgid "Re-configure"
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:165
+#, possible-c-format
+msgid ""
+"Slic3r PE now uses an updated configuration structure.\n"
+"\n"
+"So called 'System presets' have been introduced, which hold the built-in "
+"default settings for various printers. These System presets cannot be "
+"modified, instead, users now may create their own presets inheriting "
+"settings from one of the System presets.\n"
+"An inheriting preset may either inherit a particular value from its parent "
+"or override it with a customized value.\n"
+"\n"
+"Please proceed with the %s that follows to set up the new presets and to "
+"choose whether to enable automatic preset updates."
+msgstr ""
+
+#: xs/src/slic3r/GUI/UpdateDialogs.cpp:181
+msgid "For more information please visit our wiki page:"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:14
+msgid "Ramming customization"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:40
+msgid ""
+"Ramming denotes the rapid extrusion just before a tool change in a single-"
+"extruder MM printer. Its purpose is to properly shape the end of the "
+"unloaded filament so it does not prevent insertion of the new filament and "
+"can itself be reinserted later. This phase is important and different "
+"materials can require different extrusion speeds to get the good shape. For "
+"this reason, the extrusion rates during ramming are adjustable.\n"
+"\n"
+"This is an expert-level setting, incorrect adjustment will likely lead to "
+"jams, extruder wheel grinding into filament etc."
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:82
+msgid "Total ramming time"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:84
+msgid "Total rammed volume"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:88
+msgid "Ramming line width"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:90
+msgid "Ramming line spacing"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:142
+msgid "Wipe tower - Purging volume adjustment"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:223
+#, possible-c-format
+msgid ""
+"Here you can adjust required purging volume (mm%s) for any given pair of "
+"tools."
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:224
+msgid "Extruder changed to"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:232
+msgid "unloaded"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:233
+msgid "loaded"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:238
+msgid "Tool #"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:245
+msgid ""
+"Total purging volume is calculated by summing two values below, depending on "
+"which tools are loaded/unloaded."
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:246
+#, possible-c-format
+msgid "Volume to purge (mm%s) when the filament is being"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:260
+msgid "From"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:325
+msgid ""
+"Switching to simple settings will discard changes done in the advanced "
+"mode!\n"
+"\n"
+"Do you want to proceed?"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:337
+msgid "Show simplified settings"
+msgstr ""
+
+#: xs/src/slic3r/GUI/WipeTowerDialog.cpp:337
+msgid "Show advanced settings"
+msgstr ""
+
+#: xs/src/slic3r/Utils/OctoPrint.cpp:47
msgid "Error while uploading to the OctoPrint server"
msgstr ""
-#: xs/src/slic3r/Utils/OctoPrint.cpp:102
+#: xs/src/slic3r/Utils/OctoPrint.cpp:51 lib/Slic3r/GUI/Plater.pm:1493
+msgid "Sending G-code file to the OctoPrint server..."
+msgstr ""
+
+#: xs/src/slic3r/Utils/OctoPrint.cpp:120
msgid "Invalid API key"
msgstr ""
@@ -1046,7 +1782,7 @@ msgid ""
"feature slows down both the print and the G-code generation."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:38 xs/src/libslic3r/PrintConfig.cpp:1579
+#: xs/src/libslic3r/PrintConfig.cpp:38 xs/src/libslic3r/PrintConfig.cpp:1677
msgid "Other layers"
msgstr ""
@@ -1077,20 +1813,20 @@ msgid ""
"default extruder and bed temperature are reset using non-wait command; "
"however if M104, M109, M140 or M190 are detected in this custom code, Slic3r "
"will not add temperature commands. Note that you can use placeholder "
-"variables for all Slic3r settings, so you can put a \"M109 "
-"S[first_layer_temperature]\" command wherever you want."
+"variables for all Slic3r settings, so you can put a \"M109 S"
+"[first_layer_temperature]\" command wherever you want."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:68 lib/Slic3r/GUI/MainFrame.pm:364
+#: xs/src/libslic3r/PrintConfig.cpp:68 lib/Slic3r/GUI/MainFrame.pm:307
msgid "Bottom"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:69 xs/src/libslic3r/PrintConfig.cpp:239
-#: xs/src/libslic3r/PrintConfig.cpp:290 xs/src/libslic3r/PrintConfig.cpp:298
-#: xs/src/libslic3r/PrintConfig.cpp:604 xs/src/libslic3r/PrintConfig.cpp:762
-#: xs/src/libslic3r/PrintConfig.cpp:778 xs/src/libslic3r/PrintConfig.cpp:948
-#: xs/src/libslic3r/PrintConfig.cpp:996 xs/src/libslic3r/PrintConfig.cpp:1159
-#: xs/src/libslic3r/PrintConfig.cpp:1590 xs/src/libslic3r/PrintConfig.cpp:1646
+#: xs/src/libslic3r/PrintConfig.cpp:69 xs/src/libslic3r/PrintConfig.cpp:267
+#: xs/src/libslic3r/PrintConfig.cpp:318 xs/src/libslic3r/PrintConfig.cpp:326
+#: xs/src/libslic3r/PrintConfig.cpp:666 xs/src/libslic3r/PrintConfig.cpp:831
+#: xs/src/libslic3r/PrintConfig.cpp:847 xs/src/libslic3r/PrintConfig.cpp:1024
+#: xs/src/libslic3r/PrintConfig.cpp:1081 xs/src/libslic3r/PrintConfig.cpp:1259
+#: xs/src/libslic3r/PrintConfig.cpp:1688 xs/src/libslic3r/PrintConfig.cpp:1744
msgid "Layers and Perimeters"
msgstr ""
@@ -1112,9 +1848,9 @@ msgid ""
"disable acceleration control for bridges."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:80 xs/src/libslic3r/PrintConfig.cpp:174
-#: xs/src/libslic3r/PrintConfig.cpp:576 xs/src/libslic3r/PrintConfig.cpp:684
-#: xs/src/libslic3r/PrintConfig.cpp:959
+#: xs/src/libslic3r/PrintConfig.cpp:80 xs/src/libslic3r/PrintConfig.cpp:190
+#: xs/src/libslic3r/PrintConfig.cpp:638 xs/src/libslic3r/PrintConfig.cpp:746
+#: xs/src/libslic3r/PrintConfig.cpp:1044
msgid "mm/s²"
msgstr ""
@@ -1129,9 +1865,9 @@ msgid ""
"bridges. Use 180° for zero angle."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:91 xs/src/libslic3r/PrintConfig.cpp:492
-#: xs/src/libslic3r/PrintConfig.cpp:1177 xs/src/libslic3r/PrintConfig.cpp:1188
-#: xs/src/libslic3r/PrintConfig.cpp:1408 xs/src/libslic3r/PrintConfig.cpp:1564
+#: xs/src/libslic3r/PrintConfig.cpp:91 xs/src/libslic3r/PrintConfig.cpp:554
+#: xs/src/libslic3r/PrintConfig.cpp:1277 xs/src/libslic3r/PrintConfig.cpp:1288
+#: xs/src/libslic3r/PrintConfig.cpp:1508 xs/src/libslic3r/PrintConfig.cpp:1662
msgid "°"
msgstr ""
@@ -1143,9 +1879,9 @@ msgstr ""
msgid "This fan speed is enforced during all bridges and overhangs."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:99 xs/src/libslic3r/PrintConfig.cpp:504
-#: xs/src/libslic3r/PrintConfig.cpp:789 xs/src/libslic3r/PrintConfig.cpp:850
-#: xs/src/libslic3r/PrintConfig.cpp:1067
+#: xs/src/libslic3r/PrintConfig.cpp:99 xs/src/libslic3r/PrintConfig.cpp:566
+#: xs/src/libslic3r/PrintConfig.cpp:858 xs/src/libslic3r/PrintConfig.cpp:926
+#: xs/src/libslic3r/PrintConfig.cpp:1167
msgid "%"
msgstr ""
@@ -1169,11 +1905,12 @@ msgstr ""
msgid "Speed for printing bridges."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:120 xs/src/libslic3r/PrintConfig.cpp:638
-#: xs/src/libslic3r/PrintConfig.cpp:749 xs/src/libslic3r/PrintConfig.cpp:811
-#: xs/src/libslic3r/PrintConfig.cpp:868 xs/src/libslic3r/PrintConfig.cpp:988
-#: xs/src/libslic3r/PrintConfig.cpp:1144 xs/src/libslic3r/PrintConfig.cpp:1153
-#: xs/src/libslic3r/PrintConfig.cpp:1543 xs/src/libslic3r/PrintConfig.cpp:1656
+#: xs/src/libslic3r/PrintConfig.cpp:120 xs/src/libslic3r/PrintConfig.cpp:461
+#: xs/src/libslic3r/PrintConfig.cpp:470 xs/src/libslic3r/PrintConfig.cpp:700
+#: xs/src/libslic3r/PrintConfig.cpp:811 xs/src/libslic3r/PrintConfig.cpp:887
+#: xs/src/libslic3r/PrintConfig.cpp:944 xs/src/libslic3r/PrintConfig.cpp:1073
+#: xs/src/libslic3r/PrintConfig.cpp:1244 xs/src/libslic3r/PrintConfig.cpp:1253
+#: xs/src/libslic3r/PrintConfig.cpp:1641 xs/src/libslic3r/PrintConfig.cpp:1754
msgid "mm/s"
msgstr ""
@@ -1231,65 +1968,103 @@ msgid ""
"fan speed according to layer printing time."
msgstr ""
+#: xs/src/libslic3r/PrintConfig.cpp:170
+msgid "Cooling tube position"
+msgstr ""
+
#: xs/src/libslic3r/PrintConfig.cpp:171
+msgid "Distance of the center-point of the cooling tube from the extruder tip "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:178
+msgid "Cooling tube length"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:179
+msgid "Length of the cooling tube to limit space for cooling moves inside it "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:187
msgid ""
"This is the acceleration your printer will be reset to after the role-"
"specific acceleration values are used (perimeter/infill). Set zero to "
"prevent resetting acceleration at all."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:180
+#: xs/src/libslic3r/PrintConfig.cpp:196
+msgid "Default filament profile"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:197
+msgid ""
+"Default filament profile associated with the current printer profile. On "
+"selection of the current printer profile, this filament profile will be "
+"activated."
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:202
+msgid "Default print profile"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:203
+msgid ""
+"Default print profile associated with the current printer profile. On "
+"selection of the current printer profile, this print profile will be "
+"activated."
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:208
msgid "Disable fan for the first"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:181
+#: xs/src/libslic3r/PrintConfig.cpp:209
msgid ""
"You can set this to a positive value to disable fan at all during the first "
"layers, so that it does not make adhesion worse."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:183 xs/src/libslic3r/PrintConfig.cpp:694
-#: xs/src/libslic3r/PrintConfig.cpp:1040 xs/src/libslic3r/PrintConfig.cpp:1231
-#: xs/src/libslic3r/PrintConfig.cpp:1292 xs/src/libslic3r/PrintConfig.cpp:1444
-#: xs/src/libslic3r/PrintConfig.cpp:1489
+#: xs/src/libslic3r/PrintConfig.cpp:211 xs/src/libslic3r/PrintConfig.cpp:756
+#: xs/src/libslic3r/PrintConfig.cpp:1140 xs/src/libslic3r/PrintConfig.cpp:1331
+#: xs/src/libslic3r/PrintConfig.cpp:1392 xs/src/libslic3r/PrintConfig.cpp:1544
+#: xs/src/libslic3r/PrintConfig.cpp:1589
msgid "layers"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:190
+#: xs/src/libslic3r/PrintConfig.cpp:218
msgid "Don't support bridges"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:192
+#: xs/src/libslic3r/PrintConfig.cpp:220
msgid ""
"Experimental option for preventing support material from being generated "
"under bridged areas."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:198
+#: xs/src/libslic3r/PrintConfig.cpp:226
msgid "Distance between copies"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:199
+#: xs/src/libslic3r/PrintConfig.cpp:227
msgid "Distance used for the auto-arrange feature of the plater."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:207
+#: xs/src/libslic3r/PrintConfig.cpp:235
msgid "Elephant foot compensation"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:209
+#: xs/src/libslic3r/PrintConfig.cpp:237
msgid ""
"The first layer will be shrunk in the XY plane by the configured value to "
"compensate for the 1st layer squish aka an Elephant Foot effect."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:218
+#: xs/src/libslic3r/PrintConfig.cpp:246
msgid ""
"This end procedure is inserted at the end of the output file. Note that you "
"can use placeholder variables for all Slic3r settings."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:228
+#: xs/src/libslic3r/PrintConfig.cpp:256
msgid ""
"This end procedure is inserted at the end of the output file, before the "
"printer end gcode. Note that you can use placeholder variables for all "
@@ -1297,38 +2072,38 @@ msgid ""
"extruder order."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:238
+#: xs/src/libslic3r/PrintConfig.cpp:266
msgid "Ensure vertical shell thickness"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:240
+#: xs/src/libslic3r/PrintConfig.cpp:268
msgid ""
"Add solid infill near sloping surfaces to guarantee the vertical shell "
"thickness (top+bottom solid layers)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:246
+#: xs/src/libslic3r/PrintConfig.cpp:274
msgid "Top/bottom fill pattern"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:248
+#: xs/src/libslic3r/PrintConfig.cpp:276
msgid ""
"Fill pattern for top/bottom infill. This only affects the external visible "
"layer, and not its adjacent solid shells."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:267 xs/src/libslic3r/PrintConfig.cpp:277
+#: xs/src/libslic3r/PrintConfig.cpp:295 xs/src/libslic3r/PrintConfig.cpp:305
msgid "External perimeters"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:268 xs/src/libslic3r/PrintConfig.cpp:377
-#: xs/src/libslic3r/PrintConfig.cpp:592 xs/src/libslic3r/PrintConfig.cpp:710
-#: xs/src/libslic3r/PrintConfig.cpp:974 xs/src/libslic3r/PrintConfig.cpp:1299
-#: xs/src/libslic3r/PrintConfig.cpp:1461 xs/src/libslic3r/PrintConfig.cpp:1621
+#: xs/src/libslic3r/PrintConfig.cpp:296 xs/src/libslic3r/PrintConfig.cpp:405
+#: xs/src/libslic3r/PrintConfig.cpp:654 xs/src/libslic3r/PrintConfig.cpp:772
+#: xs/src/libslic3r/PrintConfig.cpp:1059 xs/src/libslic3r/PrintConfig.cpp:1399
+#: xs/src/libslic3r/PrintConfig.cpp:1561 xs/src/libslic3r/PrintConfig.cpp:1719
msgid "Extrusion Width"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:269
+#: xs/src/libslic3r/PrintConfig.cpp:297
msgid ""
"Set this to a non-zero value to set a manual extrusion width for external "
"perimeters. If left zero, default extrusion width will be used if set, "
@@ -1336,60 +2111,60 @@ msgid ""
"(for example 200%), it will be computed over layer height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:272 xs/src/libslic3r/PrintConfig.cpp:597
-#: xs/src/libslic3r/PrintConfig.cpp:715 xs/src/libslic3r/PrintConfig.cpp:979
-#: xs/src/libslic3r/PrintConfig.cpp:1303 xs/src/libslic3r/PrintConfig.cpp:1465
-#: xs/src/libslic3r/PrintConfig.cpp:1626
+#: xs/src/libslic3r/PrintConfig.cpp:300 xs/src/libslic3r/PrintConfig.cpp:659
+#: xs/src/libslic3r/PrintConfig.cpp:777 xs/src/libslic3r/PrintConfig.cpp:1064
+#: xs/src/libslic3r/PrintConfig.cpp:1403 xs/src/libslic3r/PrintConfig.cpp:1565
+#: xs/src/libslic3r/PrintConfig.cpp:1724
msgid "mm or % (leave 0 for default)"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:279
+#: xs/src/libslic3r/PrintConfig.cpp:307
msgid ""
"This separate setting will affect the speed of external perimeters (the "
"visible ones). If expressed as percentage (for example: 80%) it will be "
"calculated on the perimeters speed setting above. Set to zero for auto."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:282 xs/src/libslic3r/PrintConfig.cpp:619
-#: xs/src/libslic3r/PrintConfig.cpp:1262 xs/src/libslic3r/PrintConfig.cpp:1313
-#: xs/src/libslic3r/PrintConfig.cpp:1508 xs/src/libslic3r/PrintConfig.cpp:1638
+#: xs/src/libslic3r/PrintConfig.cpp:310 xs/src/libslic3r/PrintConfig.cpp:681
+#: xs/src/libslic3r/PrintConfig.cpp:1362 xs/src/libslic3r/PrintConfig.cpp:1413
+#: xs/src/libslic3r/PrintConfig.cpp:1608 xs/src/libslic3r/PrintConfig.cpp:1736
msgid "mm/s or %"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:289
+#: xs/src/libslic3r/PrintConfig.cpp:317
msgid "External perimeters first"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:291
+#: xs/src/libslic3r/PrintConfig.cpp:319
msgid ""
"Print contour perimeters from the outermost one to the innermost one instead "
"of the default inverse order."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:297
+#: xs/src/libslic3r/PrintConfig.cpp:325
msgid "Extra perimeters if needed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:299
-#, possible-c-format
+#: xs/src/libslic3r/PrintConfig.cpp:327
+#, no-c-format
msgid ""
"Add more perimeters when needed for avoiding gaps in sloping walls. Slic3r "
"keeps adding perimeters, until more than 70% of the loop immediately above "
"is supported."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:309
+#: xs/src/libslic3r/PrintConfig.cpp:337
msgid ""
"The extruder to use (unless more specific extruder settings are specified). "
"This value overrides perimeter and infill extruders, but not the support "
"extruders."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:320 lib/Slic3r/GUI/Plater/3DPreview.pm:69
+#: xs/src/libslic3r/PrintConfig.cpp:348 lib/Slic3r/GUI/Plater/3DPreview.pm:68
msgid "Height"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:321
+#: xs/src/libslic3r/PrintConfig.cpp:349
msgid ""
"Set this to the vertical distance between your nozzle tip and (usually) the "
"X carriage rods. In other words, this is the height of the clearance "
@@ -1397,30 +2172,30 @@ msgid ""
"extruder can peek before colliding with other printed objects."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:331
+#: xs/src/libslic3r/PrintConfig.cpp:359
msgid "Radius"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:332
+#: xs/src/libslic3r/PrintConfig.cpp:360
msgid ""
"Set this to the clearance radius around your extruder. If the extruder is "
"not centered, choose the largest value for safety. This setting is used to "
"check for collisions and to display the graphical preview in the plater."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:342
+#: xs/src/libslic3r/PrintConfig.cpp:370
msgid "Extruder Color"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:343 xs/src/libslic3r/PrintConfig.cpp:406
+#: xs/src/libslic3r/PrintConfig.cpp:371 xs/src/libslic3r/PrintConfig.cpp:434
msgid "This is only used in the Slic3r interface as a visual help."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:350
+#: xs/src/libslic3r/PrintConfig.cpp:378
msgid "Extruder offset"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:351
+#: xs/src/libslic3r/PrintConfig.cpp:379
msgid ""
"If your firmware doesn't handle the extruder displacement you need the G-"
"code to take it into account. This option lets you specify the displacement "
@@ -1428,21 +2203,21 @@ msgid ""
"coordinates (they will be subtracted from the XY coordinate)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:360
+#: xs/src/libslic3r/PrintConfig.cpp:388
msgid "Extrusion axis"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:361
+#: xs/src/libslic3r/PrintConfig.cpp:389
msgid ""
"Use this option to set the axis letter associated to your printer's extruder "
"(usually E but some printers use A)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:367
+#: xs/src/libslic3r/PrintConfig.cpp:395
msgid "Extrusion multiplier"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:368
+#: xs/src/libslic3r/PrintConfig.cpp:396
msgid ""
"This factor changes the amount of flow proportionally. You may need to tweak "
"this setting to get nice surface finish and correct single wall widths. "
@@ -1450,11 +2225,11 @@ msgid ""
"more, check filament diameter and your firmware E steps."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:376
+#: xs/src/libslic3r/PrintConfig.cpp:404
msgid "Default extrusion width"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:378
+#: xs/src/libslic3r/PrintConfig.cpp:406
msgid ""
"Set this to a non-zero value to allow a manual extrusion width. If left to "
"zero, Slic3r derives extrusion widths from the nozzle diameter (see the "
@@ -1463,74 +2238,113 @@ msgid ""
"height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:382
+#: xs/src/libslic3r/PrintConfig.cpp:410
msgid "mm or % (leave 0 for auto)"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:387
+#: xs/src/libslic3r/PrintConfig.cpp:415
msgid "Keep fan always on"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:388
+#: xs/src/libslic3r/PrintConfig.cpp:416
msgid ""
"If this is enabled, fan will never be disabled and will be kept running at "
"least at its minimum speed. Useful for PLA, harmful for ABS."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:394
+#: xs/src/libslic3r/PrintConfig.cpp:422
msgid "Enable fan if layer print time is below"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:395
+#: xs/src/libslic3r/PrintConfig.cpp:423
msgid ""
"If layer print time is estimated below this number of seconds, fan will be "
"enabled and its speed will be calculated by interpolating the minimum and "
"maximum speeds."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:397 xs/src/libslic3r/PrintConfig.cpp:1249
+#: xs/src/libslic3r/PrintConfig.cpp:425 xs/src/libslic3r/PrintConfig.cpp:1349
msgid "approximate seconds"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:405
+#: xs/src/libslic3r/PrintConfig.cpp:433
msgid "Color"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:412
+#: xs/src/libslic3r/PrintConfig.cpp:440
msgid "Filament notes"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:413
+#: xs/src/libslic3r/PrintConfig.cpp:441
msgid "You can put your notes regarding the filament here."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:421 xs/src/libslic3r/PrintConfig.cpp:817
+#: xs/src/libslic3r/PrintConfig.cpp:449 xs/src/libslic3r/PrintConfig.cpp:893
msgid "Max volumetric speed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:422
+#: xs/src/libslic3r/PrintConfig.cpp:450
msgid ""
"Maximum volumetric speed allowed for this filament. Limits the maximum "
"volumetric speed of a print to the minimum of print and filament volumetric "
"speed. Set to zero for no limit."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:425 xs/src/libslic3r/PrintConfig.cpp:820
+#: xs/src/libslic3r/PrintConfig.cpp:453 xs/src/libslic3r/PrintConfig.cpp:896
msgid "mm³/s"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:432
+#: xs/src/libslic3r/PrintConfig.cpp:459
+msgid "Loading speed"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:460
+msgid "Speed used for loading the filament on the wipe tower. "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:467
+msgid "Unloading speed"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:468
+msgid ""
+"Speed used for unloading the filament on the wipe tower (does not affect "
+"initial part of unloading just after ramming). "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:476
+msgid "Delay after unloading"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:477
+msgid ""
+"Time to wait after the filament is unloaded. May help to get reliable "
+"toolchanges with flexible materials that may need more time to shrink to "
+"original dimensions. "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:486
+msgid "Ramming parameters"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:487
+msgid ""
+"This string is edited by RammingDialog and contains ramming specific "
+"parameters "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:494
msgid ""
"Enter your filament diameter here. Good precision is required, so use a "
"caliper and do multiple measurements along the filament, then compute the "
"average."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:440
+#: xs/src/libslic3r/PrintConfig.cpp:502
msgid "Density"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:441
+#: xs/src/libslic3r/PrintConfig.cpp:503
msgid ""
"Enter your filament density here. This is only for statistical information. "
"A decent way is to weigh a known length of filament and compute the ratio of "
@@ -1538,15 +2352,15 @@ msgid ""
"displacement."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:444
+#: xs/src/libslic3r/PrintConfig.cpp:506
msgid "g/cm³"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:450
+#: xs/src/libslic3r/PrintConfig.cpp:512
msgid "Filament type"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:451 xs/src/libslic3r/PrintConfig.cpp:1009
+#: xs/src/libslic3r/PrintConfig.cpp:513 xs/src/libslic3r/PrintConfig.cpp:1094
msgid ""
"If you want to process the output G-code through custom scripts, just list "
"their absolute paths here. Separate multiple scripts with a semicolon. "
@@ -1555,73 +2369,74 @@ msgid ""
"environment variables."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:470
+#: xs/src/libslic3r/PrintConfig.cpp:532
msgid "Soluble material"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:471
+#: xs/src/libslic3r/PrintConfig.cpp:533
msgid "Soluble material is most likely used for a soluble support."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:476 lib/Slic3r/GUI/Plater.pm:453
+#: xs/src/libslic3r/PrintConfig.cpp:538 lib/Slic3r/GUI/Plater.pm:463
msgid "Cost"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:477
+#: xs/src/libslic3r/PrintConfig.cpp:539
msgid ""
"Enter your filament cost per kg here. This is only for statistical "
"information."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:478
+#: xs/src/libslic3r/PrintConfig.cpp:540
msgid "money/kg"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:487
+#: xs/src/libslic3r/PrintConfig.cpp:549
msgid "Fill angle"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:489
+#: xs/src/libslic3r/PrintConfig.cpp:551
msgid ""
"Default base angle for infill orientation. Cross-hatching will be applied to "
"this. Bridges will be infilled using the best direction Slic3r can detect, "
"so this setting does not affect them."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:501
+#: xs/src/libslic3r/PrintConfig.cpp:563
msgid "Fill density"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:503
+#: xs/src/libslic3r/PrintConfig.cpp:565
+#, possible-c-format
msgid "Density of internal infill, expressed in the range 0% - 100%."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:539
+#: xs/src/libslic3r/PrintConfig.cpp:601
msgid "Fill pattern"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:541
+#: xs/src/libslic3r/PrintConfig.cpp:603
msgid "Fill pattern for general low-density infill."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:573 xs/src/libslic3r/PrintConfig.cpp:582
-#: xs/src/libslic3r/PrintConfig.cpp:591 xs/src/libslic3r/PrintConfig.cpp:625
+#: xs/src/libslic3r/PrintConfig.cpp:635 xs/src/libslic3r/PrintConfig.cpp:644
+#: xs/src/libslic3r/PrintConfig.cpp:653 xs/src/libslic3r/PrintConfig.cpp:687
msgid "First layer"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:574
+#: xs/src/libslic3r/PrintConfig.cpp:636
msgid ""
"This is the acceleration your printer will use for first layer. Set zero to "
"disable acceleration control for first layer."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:583
+#: xs/src/libslic3r/PrintConfig.cpp:645
msgid ""
"Heated build plate temperature for the first layer. Set this to zero to "
"disable bed temperature control commands in the output."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:593
+#: xs/src/libslic3r/PrintConfig.cpp:655
msgid ""
"Set this to a non-zero value to set a manual extrusion width for first "
"layer. You can use this to force fatter extrudates for better adhesion. If "
@@ -1629,11 +2444,11 @@ msgid ""
"layer height. If set to zero, it will use the default extrusion width."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:603
+#: xs/src/libslic3r/PrintConfig.cpp:665
msgid "First layer height"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:605
+#: xs/src/libslic3r/PrintConfig.cpp:667
msgid ""
"When printing with very low layer heights, you might still want to print a "
"thicker bottom layer to improve adhesion and tolerance for non perfect build "
@@ -1641,58 +2456,58 @@ msgid ""
"example: 150%) over the default layer height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:609 xs/src/libslic3r/PrintConfig.cpp:740
-#: xs/src/libslic3r/PrintConfig.cpp:1397
+#: xs/src/libslic3r/PrintConfig.cpp:671 xs/src/libslic3r/PrintConfig.cpp:802
+#: xs/src/libslic3r/PrintConfig.cpp:1497
msgid "mm or %"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:615
+#: xs/src/libslic3r/PrintConfig.cpp:677
msgid "First layer speed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:616
+#: xs/src/libslic3r/PrintConfig.cpp:678
msgid ""
"If expressed as absolute value in mm/s, this speed will be applied to all "
"the print moves of the first layer, regardless of their type. If expressed "
"as a percentage (for example: 40%) it will scale the default speeds."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:626
+#: xs/src/libslic3r/PrintConfig.cpp:688
msgid ""
"Extruder temperature for first layer. If you want to control temperature "
"manually during print, set this to zero to disable temperature control "
"commands in the output file."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:634
-#: xs/src/libslic3r/GCode/PreviewData.cpp:145
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:87
+#: xs/src/libslic3r/PrintConfig.cpp:696
+#: xs/src/libslic3r/GCode/PreviewData.cpp:165
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:90
msgid "Gap fill"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:636
+#: xs/src/libslic3r/PrintConfig.cpp:698
msgid ""
"Speed for filling small gaps using short zigzag moves. Keep this reasonably "
"low to avoid too much shaking and resonance issues. Set zero to disable gaps "
"filling."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:644
+#: xs/src/libslic3r/PrintConfig.cpp:706
msgid "Verbose G-code"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:645
+#: xs/src/libslic3r/PrintConfig.cpp:707
msgid ""
"Enable this to get a commented G-code file, with each line explained by a "
"descriptive text. If you print from SD card, the additional weight of the "
"file could make your firmware slow down."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:652
+#: xs/src/libslic3r/PrintConfig.cpp:714
msgid "G-code flavor"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:653
+#: xs/src/libslic3r/PrintConfig.cpp:715
msgid ""
"Some G/M-code commands, including temperature control and others, are not "
"universal. Set this option to your printer's firmware to get a compatible "
@@ -1700,35 +2515,35 @@ msgid ""
"extrusion value at all."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:682
+#: xs/src/libslic3r/PrintConfig.cpp:744
msgid ""
"This is the acceleration your printer will use for infill. Set zero to "
"disable acceleration control for infill."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:690
+#: xs/src/libslic3r/PrintConfig.cpp:752
msgid "Combine infill every"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:692
+#: xs/src/libslic3r/PrintConfig.cpp:754
msgid ""
"This feature allows to combine infill and speed up your print by extruding "
"thicker infill layers while preserving thin perimeters, thus accuracy."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:696
+#: xs/src/libslic3r/PrintConfig.cpp:758
msgid "Combine infill every n layers"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:701
+#: xs/src/libslic3r/PrintConfig.cpp:763
msgid "Infill extruder"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:703
+#: xs/src/libslic3r/PrintConfig.cpp:765
msgid "The extruder to use when printing infill."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:711
+#: xs/src/libslic3r/PrintConfig.cpp:773
msgid ""
"Set this to a non-zero value to set a manual extrusion width for infill. If "
"left zero, default extrusion width will be used if set, otherwise 1.125 x "
@@ -1737,32 +2552,32 @@ msgid ""
"example 90%) it will be computed over layer height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:720
+#: xs/src/libslic3r/PrintConfig.cpp:782
msgid "Infill before perimeters"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:721
+#: xs/src/libslic3r/PrintConfig.cpp:783
msgid ""
"This option will switch the print order of perimeters and infill, making the "
"latter first."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:726
+#: xs/src/libslic3r/PrintConfig.cpp:788
msgid "Only infill where needed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:728
+#: xs/src/libslic3r/PrintConfig.cpp:790
msgid ""
"This option will limit infill to the areas actually needed for supporting "
"ceilings (it will act as internal support material). If enabled, slows down "
"the G-code generation due to the multiple checks involved."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:735
+#: xs/src/libslic3r/PrintConfig.cpp:797
msgid "Infill/perimeters overlap"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:737
+#: xs/src/libslic3r/PrintConfig.cpp:799
msgid ""
"This setting applies an additional overlap between infill and perimeters for "
"better bonding. Theoretically this shouldn't be needed, but backlash might "
@@ -1770,22 +2585,30 @@ msgid ""
"perimeter extrusion width."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:748
+#: xs/src/libslic3r/PrintConfig.cpp:810
msgid "Speed for printing the internal fill. Set to zero for auto."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:757
+#: xs/src/libslic3r/PrintConfig.cpp:819
+msgid "Inherits profile"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:820
+msgid "Name of the profile, from which this profile inherits."
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:826
msgid "Interface shells"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:758
+#: xs/src/libslic3r/PrintConfig.cpp:827
msgid ""
"Force the generation of solid shells between adjacent materials/volumes. "
"Useful for multi-extruder prints with translucent materials or manual "
"soluble support material."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:767
+#: xs/src/libslic3r/PrintConfig.cpp:836
msgid ""
"This custom code is inserted at every layer change, right after the Z move "
"and before the extruder moves to the first layer point. Note that you can "
@@ -1793,22 +2616,22 @@ msgid ""
"[layer_z]."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:779
+#: xs/src/libslic3r/PrintConfig.cpp:848
msgid ""
"This setting controls the height (and thus the total number) of the slices/"
"layers. Thinner layers give better accuracy but take more time to print."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:787 xs/src/libslic3r/PrintConfig.cpp:796
+#: xs/src/libslic3r/PrintConfig.cpp:856 xs/src/libslic3r/PrintConfig.cpp:865
msgid "Max"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:788
+#: xs/src/libslic3r/PrintConfig.cpp:857
msgid "This setting represents the maximum speed of your fan."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:797
-#, possible-c-format
+#: xs/src/libslic3r/PrintConfig.cpp:866
+#, no-c-format
msgid ""
"This is the highest printable layer height for this extruder, used to cap "
"the variable layer height and support layer height. Maximum recommended "
@@ -1816,28 +2639,38 @@ msgid ""
"adhesion. If set to 0, layer height is limited to 75% of the nozzle diameter."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:807
+#: xs/src/libslic3r/PrintConfig.cpp:876
+msgid "Max print height"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:877
+msgid ""
+"Set this to the maximum height that can be reached by your extruder while "
+"printing."
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:883
msgid "Max print speed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:808
+#: xs/src/libslic3r/PrintConfig.cpp:884
msgid ""
"When setting other speed settings to 0 Slic3r will autocalculate the optimal "
"speed in order to keep constant extruder pressure. This experimental setting "
"is used to set the highest print speed you want to allow."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:818
+#: xs/src/libslic3r/PrintConfig.cpp:894
msgid ""
"This experimental setting is used to set the maximum volumetric speed your "
"extruder supports."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:826
+#: xs/src/libslic3r/PrintConfig.cpp:902
msgid "Max volumetric slope positive"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:827 xs/src/libslic3r/PrintConfig.cpp:838
+#: xs/src/libslic3r/PrintConfig.cpp:903 xs/src/libslic3r/PrintConfig.cpp:914
msgid ""
"This experimental setting is used to limit the speed of change in extrusion "
"rate. A value of 1.8 mm³/s² ensures, that a change from the extrusion rate "
@@ -1845,109 +2678,109 @@ msgid ""
"s) to 5.4 mm³/s (feedrate 60 mm/s) will take at least 2 seconds."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:831 xs/src/libslic3r/PrintConfig.cpp:842
+#: xs/src/libslic3r/PrintConfig.cpp:907 xs/src/libslic3r/PrintConfig.cpp:918
msgid "mm³/s²"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:837
+#: xs/src/libslic3r/PrintConfig.cpp:913
msgid "Max volumetric slope negative"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:848 xs/src/libslic3r/PrintConfig.cpp:857
+#: xs/src/libslic3r/PrintConfig.cpp:924 xs/src/libslic3r/PrintConfig.cpp:933
msgid "Min"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:849
+#: xs/src/libslic3r/PrintConfig.cpp:925
msgid "This setting represents the minimum PWM your fan needs to work."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:858
+#: xs/src/libslic3r/PrintConfig.cpp:934
msgid ""
"This is the lowest printable layer height for this extruder and limits the "
"resolution for variable layer height. Typical values are between 0.05 mm and "
"0.1 mm."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:866
+#: xs/src/libslic3r/PrintConfig.cpp:942
msgid "Min print speed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:867
+#: xs/src/libslic3r/PrintConfig.cpp:943
msgid "Slic3r will not scale speed down below this speed."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:874
+#: xs/src/libslic3r/PrintConfig.cpp:950
msgid "Minimum extrusion length"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:875
+#: xs/src/libslic3r/PrintConfig.cpp:951
msgid ""
"Generate no less than the number of skirt loops required to consume the "
"specified amount of filament on the bottom layer. For multi-extruder "
"machines, this minimum applies to each extruder."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:884
+#: xs/src/libslic3r/PrintConfig.cpp:960
msgid "Configuration notes"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:885
+#: xs/src/libslic3r/PrintConfig.cpp:961
msgid ""
"You can put here your personal notes. This text will be added to the G-code "
"header comments."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:894
+#: xs/src/libslic3r/PrintConfig.cpp:970
msgid "Nozzle diameter"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:895
+#: xs/src/libslic3r/PrintConfig.cpp:971
msgid ""
"This is the diameter of your extruder nozzle (for example: 0.5, 0.35 etc.)"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:901
+#: xs/src/libslic3r/PrintConfig.cpp:977
msgid "API Key"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:902
+#: xs/src/libslic3r/PrintConfig.cpp:978
msgid ""
"Slic3r can upload G-code files to OctoPrint. This field should contain the "
"API Key required for authentication."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:915
+#: xs/src/libslic3r/PrintConfig.cpp:991
msgid "Hostname, IP or URL"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:916
+#: xs/src/libslic3r/PrintConfig.cpp:992
msgid ""
"Slic3r can upload G-code files to OctoPrint. This field should contain the "
"hostname, IP address or URL of the OctoPrint instance."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:922
+#: xs/src/libslic3r/PrintConfig.cpp:998
msgid "Only retract when crossing perimeters"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:923
+#: xs/src/libslic3r/PrintConfig.cpp:999
msgid ""
"Disables retraction when the travel path does not exceed the upper layer's "
"perimeters (and thus any ooze will be probably invisible)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:930
+#: xs/src/libslic3r/PrintConfig.cpp:1006
msgid ""
"This option will drop the temperature of the inactive extruders to prevent "
"oozing. It will enable a tall skirt automatically and move extruders outside "
"such skirt when changing temperatures."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:937
+#: xs/src/libslic3r/PrintConfig.cpp:1013
msgid "Output filename format"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:938
+#: xs/src/libslic3r/PrintConfig.cpp:1014
msgid ""
"You can use all configuration options as variables inside this template. For "
"example: [layer_height], [fill_density] etc. You can also use [timestamp], "
@@ -1955,38 +2788,48 @@ msgid ""
"[input_filename], [input_filename_base]."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:947
+#: xs/src/libslic3r/PrintConfig.cpp:1023
msgid "Detect bridging perimeters"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:949
+#: xs/src/libslic3r/PrintConfig.cpp:1025
msgid ""
"Experimental option to adjust flow for overhangs (bridge flow will be used), "
"to apply bridge speed to them and enable fan."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:955 xs/src/libslic3r/PrintConfig.cpp:973
-#: xs/src/libslic3r/PrintConfig.cpp:985 xs/src/libslic3r/PrintConfig.cpp:995
+#: xs/src/libslic3r/PrintConfig.cpp:1031
+msgid "Filament parking position"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1032
+msgid ""
+"Distance of the extruder tip from the position where the filament is parked "
+"when unloaded. This should match the value in printer firmware. "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1040 xs/src/libslic3r/PrintConfig.cpp:1058
+#: xs/src/libslic3r/PrintConfig.cpp:1070 xs/src/libslic3r/PrintConfig.cpp:1080
msgid "Perimeters"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:956
+#: xs/src/libslic3r/PrintConfig.cpp:1041
msgid ""
"This is the acceleration your printer will use for perimeters. A high value "
"like 9000 usually gives good results if your hardware is up to the job. Set "
"zero to disable acceleration control for perimeters."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:964
+#: xs/src/libslic3r/PrintConfig.cpp:1049
msgid "Perimeter extruder"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:966
+#: xs/src/libslic3r/PrintConfig.cpp:1051
msgid ""
"The extruder to use when printing perimeters and brim. First extruder is 1."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:975
+#: xs/src/libslic3r/PrintConfig.cpp:1060
msgid ""
"Set this to a non-zero value to set a manual extrusion width for perimeters. "
"You may want to use thinner extrudates to get more accurate surfaces. If "
@@ -1995,12 +2838,12 @@ msgid ""
"it will be computed over layer height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:987
+#: xs/src/libslic3r/PrintConfig.cpp:1072
msgid ""
"Speed for perimeters (contours, aka vertical shells). Set to zero for auto."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:997
+#: xs/src/libslic3r/PrintConfig.cpp:1082
msgid ""
"This option sets the number of perimeters to generate for each layer. Note "
"that Slic3r may increase this number automatically when it detects sloping "
@@ -2008,33 +2851,59 @@ msgid ""
"Perimeters option is enabled."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1001
+#: xs/src/libslic3r/PrintConfig.cpp:1086
msgid "(minimum)"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1021
+#: xs/src/libslic3r/PrintConfig.cpp:1106
+msgid "Printer type"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1107
+msgid "Type of the printer."
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1111
msgid "Printer notes"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1022
+#: xs/src/libslic3r/PrintConfig.cpp:1112
msgid "You can put your notes regarding the printer here."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1036
+#: xs/src/libslic3r/PrintConfig.cpp:1120
+msgid "Printer vendor"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1121
+msgid "Name of the printer vendor."
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1125
+msgid "Printer variant"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1126
+msgid ""
+"Name of the printer variant. For example, the printer variants may be "
+"differentiated by a nozzle diameter."
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1136
msgid "Raft layers"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1038
+#: xs/src/libslic3r/PrintConfig.cpp:1138
msgid ""
"The object will be raised by this number of layers, and support material "
"will be generated under it."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1046
+#: xs/src/libslic3r/PrintConfig.cpp:1146
msgid "Resolution"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1047
+#: xs/src/libslic3r/PrintConfig.cpp:1147
msgid ""
"Minimum detail resolution, used to simplify the input file for speeding up "
"the slicing job and reducing memory usage. High-resolution models often "
@@ -2042,266 +2911,266 @@ msgid ""
"simplification and use full resolution from input."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1057
+#: xs/src/libslic3r/PrintConfig.cpp:1157
msgid "Minimum travel after retraction"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1058
+#: xs/src/libslic3r/PrintConfig.cpp:1158
msgid ""
"Retraction is not triggered when travel moves are shorter than this length."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1064
+#: xs/src/libslic3r/PrintConfig.cpp:1164
msgid "Retract amount before wipe"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1065
+#: xs/src/libslic3r/PrintConfig.cpp:1165
msgid ""
"With bowden extruders, it may be wise to do some amount of quick retract "
"before doing the wipe movement."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1072
+#: xs/src/libslic3r/PrintConfig.cpp:1172
msgid "Retract on layer change"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1073
+#: xs/src/libslic3r/PrintConfig.cpp:1173
msgid "This flag enforces a retraction whenever a Z move is done."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1078 xs/src/libslic3r/PrintConfig.cpp:1087
+#: xs/src/libslic3r/PrintConfig.cpp:1178 xs/src/libslic3r/PrintConfig.cpp:1187
msgid "Length"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1079
+#: xs/src/libslic3r/PrintConfig.cpp:1179
msgid "Retraction Length"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1080
+#: xs/src/libslic3r/PrintConfig.cpp:1180
msgid ""
"When retraction is triggered, filament is pulled back by the specified "
"amount (the length is measured on raw filament, before it enters the "
"extruder)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1082 xs/src/libslic3r/PrintConfig.cpp:1092
+#: xs/src/libslic3r/PrintConfig.cpp:1182 xs/src/libslic3r/PrintConfig.cpp:1192
msgid "mm (zero to disable)"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1088
+#: xs/src/libslic3r/PrintConfig.cpp:1188
msgid "Retraction Length (Toolchange)"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1089
+#: xs/src/libslic3r/PrintConfig.cpp:1189
msgid ""
"When retraction is triggered before changing tool, filament is pulled back "
"by the specified amount (the length is measured on raw filament, before it "
"enters the extruder)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1097
+#: xs/src/libslic3r/PrintConfig.cpp:1197
msgid "Lift Z"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1098
+#: xs/src/libslic3r/PrintConfig.cpp:1198
msgid ""
"If you set this to a positive value, Z is quickly raised every time a "
"retraction is triggered. When using multiple extruders, only the setting for "
"the first extruder will be considered."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1106
+#: xs/src/libslic3r/PrintConfig.cpp:1206
msgid "Above Z"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1107
+#: xs/src/libslic3r/PrintConfig.cpp:1207
msgid "Only lift Z above"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1108
+#: xs/src/libslic3r/PrintConfig.cpp:1208
msgid ""
"If you set this to a positive value, Z lift will only take place above the "
"specified absolute Z. You can tune this setting for skipping lift on the "
"first layers."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1115
+#: xs/src/libslic3r/PrintConfig.cpp:1215
msgid "Below Z"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1116
+#: xs/src/libslic3r/PrintConfig.cpp:1216
msgid "Only lift Z below"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1117
+#: xs/src/libslic3r/PrintConfig.cpp:1217
msgid ""
"If you set this to a positive value, Z lift will only take place below the "
"specified absolute Z. You can tune this setting for limiting lift to the "
"first layers."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1125 xs/src/libslic3r/PrintConfig.cpp:1133
+#: xs/src/libslic3r/PrintConfig.cpp:1225 xs/src/libslic3r/PrintConfig.cpp:1233
msgid "Extra length on restart"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1126
+#: xs/src/libslic3r/PrintConfig.cpp:1226
msgid ""
"When the retraction is compensated after the travel move, the extruder will "
"push this additional amount of filament. This setting is rarely needed."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1134
+#: xs/src/libslic3r/PrintConfig.cpp:1234
msgid ""
"When the retraction is compensated after changing tool, the extruder will "
"push this additional amount of filament."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1141 xs/src/libslic3r/PrintConfig.cpp:1142
+#: xs/src/libslic3r/PrintConfig.cpp:1241 xs/src/libslic3r/PrintConfig.cpp:1242
msgid "Retraction Speed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1143
+#: xs/src/libslic3r/PrintConfig.cpp:1243
msgid "The speed for retractions (it only applies to the extruder motor)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1149 xs/src/libslic3r/PrintConfig.cpp:1150
+#: xs/src/libslic3r/PrintConfig.cpp:1249 xs/src/libslic3r/PrintConfig.cpp:1250
msgid "Deretraction Speed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1151
+#: xs/src/libslic3r/PrintConfig.cpp:1251
msgid ""
"The speed for loading of a filament into extruder after retraction (it only "
"applies to the extruder motor). If left to zero, the retraction speed is "
"used."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1158
+#: xs/src/libslic3r/PrintConfig.cpp:1258
msgid "Seam position"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1160
+#: xs/src/libslic3r/PrintConfig.cpp:1260
msgid "Position of perimeters starting points."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1176
+#: xs/src/libslic3r/PrintConfig.cpp:1276
msgid "Direction"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1178
+#: xs/src/libslic3r/PrintConfig.cpp:1278
msgid "Preferred direction of the seam"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1179
+#: xs/src/libslic3r/PrintConfig.cpp:1279
msgid "Seam preferred direction"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1187
+#: xs/src/libslic3r/PrintConfig.cpp:1287
msgid "Jitter"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1189
+#: xs/src/libslic3r/PrintConfig.cpp:1289
msgid "Seam preferred direction jitter"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1190
+#: xs/src/libslic3r/PrintConfig.cpp:1290
msgid "Preferred direction of the seam - jitter"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1201
+#: xs/src/libslic3r/PrintConfig.cpp:1301
msgid "USB/serial port for printer connection."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1209
+#: xs/src/libslic3r/PrintConfig.cpp:1309
msgid "Serial port speed"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1210
+#: xs/src/libslic3r/PrintConfig.cpp:1310
msgid "Speed (baud) of USB/serial port for printer connection."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1219
+#: xs/src/libslic3r/PrintConfig.cpp:1319
msgid "Distance from object"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1220
+#: xs/src/libslic3r/PrintConfig.cpp:1320
msgid ""
"Distance between skirt and object(s). Set this to zero to attach the skirt "
"to the object(s) and get a brim for better adhesion."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1228
+#: xs/src/libslic3r/PrintConfig.cpp:1328
msgid "Skirt height"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1229
+#: xs/src/libslic3r/PrintConfig.cpp:1329
msgid ""
"Height of skirt expressed in layers. Set this to a tall value to use skirt "
"as a shield against drafts."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1236
+#: xs/src/libslic3r/PrintConfig.cpp:1336
msgid "Loops (minimum)"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1237
+#: xs/src/libslic3r/PrintConfig.cpp:1337
msgid "Skirt Loops"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1238
+#: xs/src/libslic3r/PrintConfig.cpp:1338
msgid ""
"Number of loops for the skirt. If the Minimum Extrusion Length option is "
"set, the number of loops might be greater than the one configured here. Set "
"this to zero to disable skirt completely."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1246
+#: xs/src/libslic3r/PrintConfig.cpp:1346
msgid "Slow down if layer print time is below"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1247
+#: xs/src/libslic3r/PrintConfig.cpp:1347
msgid ""
"If layer print time is estimated below this number of seconds, print moves "
"speed will be scaled down to extend duration to this value."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1257
+#: xs/src/libslic3r/PrintConfig.cpp:1357
msgid "Small perimeters"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1259
+#: xs/src/libslic3r/PrintConfig.cpp:1359
msgid ""
"This separate setting will affect the speed of perimeters having radius <= "
"6.5mm (usually holes). If expressed as percentage (for example: 80%) it will "
"be calculated on the perimeters speed setting above. Set to zero for auto."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1269
+#: xs/src/libslic3r/PrintConfig.cpp:1369
msgid "Solid infill threshold area"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1271
+#: xs/src/libslic3r/PrintConfig.cpp:1371
msgid ""
"Force solid infill for regions having a smaller area than the specified "
"threshold."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1272
+#: xs/src/libslic3r/PrintConfig.cpp:1372
msgid "mm²"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1278
+#: xs/src/libslic3r/PrintConfig.cpp:1378
msgid "Solid infill extruder"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1280
+#: xs/src/libslic3r/PrintConfig.cpp:1380
msgid "The extruder to use when printing solid infill."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1286
+#: xs/src/libslic3r/PrintConfig.cpp:1386
msgid "Solid infill every"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1288
+#: xs/src/libslic3r/PrintConfig.cpp:1388
msgid ""
"This feature allows to force a solid layer every given number of layers. "
"Zero to disable. You can set this to any value (for example 9999); Slic3r "
@@ -2309,13 +3178,13 @@ msgid ""
"according to nozzle diameter and layer height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1298 xs/src/libslic3r/PrintConfig.cpp:1308
-#: xs/src/libslic3r/GCode/PreviewData.cpp:142
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:84
+#: xs/src/libslic3r/PrintConfig.cpp:1398 xs/src/libslic3r/PrintConfig.cpp:1408
+#: xs/src/libslic3r/GCode/PreviewData.cpp:162
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:87
msgid "Solid infill"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1300
+#: xs/src/libslic3r/PrintConfig.cpp:1400
msgid ""
"Set this to a non-zero value to set a manual extrusion width for infill for "
"solid surfaces. If left zero, default extrusion width will be used if set, "
@@ -2323,22 +3192,22 @@ msgid ""
"(for example 90%) it will be computed over layer height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1310
+#: xs/src/libslic3r/PrintConfig.cpp:1410
msgid ""
"Speed for printing solid regions (top/bottom/internal horizontal shells). "
"This can be expressed as a percentage (for example: 80%) over the default "
"infill speed above. Set to zero for auto."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1322
+#: xs/src/libslic3r/PrintConfig.cpp:1422
msgid "Number of solid layers to generate on top and bottom surfaces."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1329
+#: xs/src/libslic3r/PrintConfig.cpp:1429
msgid "Spiral vase"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1330
+#: xs/src/libslic3r/PrintConfig.cpp:1430
msgid ""
"This feature will raise Z gradually while printing a single-walled object in "
"order to remove any visible seam. This option requires a single perimeter, "
@@ -2347,18 +3216,18 @@ msgid ""
"when printing more than an object."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1339
+#: xs/src/libslic3r/PrintConfig.cpp:1439
msgid "Temperature variation"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1340
+#: xs/src/libslic3r/PrintConfig.cpp:1440
msgid ""
"Temperature difference to be applied when an extruder is not active. Enables "
"a full-height \"sacrificial\" skirt on which the nozzles are periodically "
"wiped."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1350
+#: xs/src/libslic3r/PrintConfig.cpp:1450
msgid ""
"This start procedure is inserted at the beginning, after bed has reached the "
"target temperature and extruder just started heating, and before extruder "
@@ -2369,76 +3238,76 @@ msgid ""
"\"M109 S[first_layer_temperature]\" command wherever you want."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1365
+#: xs/src/libslic3r/PrintConfig.cpp:1465
msgid ""
"This start procedure is inserted at the beginning, after any printer start "
"gcode. This is used to override settings for a specific filament. If Slic3r "
"detects M104, M109, M140 or M190 in your custom codes, such commands will "
"not be prepended automatically so you're free to customize the order of "
"heating commands and other custom actions. Note that you can use placeholder "
-"variables for all Slic3r settings, so you can put a \"M109 "
-"S[first_layer_temperature]\" command wherever you want. If you have multiple "
+"variables for all Slic3r settings, so you can put a \"M109 S"
+"[first_layer_temperature]\" command wherever you want. If you have multiple "
"extruders, the gcode is processed in extruder order."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1380
+#: xs/src/libslic3r/PrintConfig.cpp:1480
msgid "Single Extruder Multi Material"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1381
+#: xs/src/libslic3r/PrintConfig.cpp:1481
msgid "The printer multiplexes filaments into a single hot end."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1386
+#: xs/src/libslic3r/PrintConfig.cpp:1486
msgid "Generate support material"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1388
+#: xs/src/libslic3r/PrintConfig.cpp:1488
msgid "Enable support material generation."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1393
+#: xs/src/libslic3r/PrintConfig.cpp:1493
msgid "XY separation between an object and its support"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1395
+#: xs/src/libslic3r/PrintConfig.cpp:1495
msgid ""
"XY separation between an object and its support. If expressed as percentage "
"(for example 50%), it will be calculated over external perimeter width."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1405
+#: xs/src/libslic3r/PrintConfig.cpp:1505
msgid "Pattern angle"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1407
+#: xs/src/libslic3r/PrintConfig.cpp:1507
msgid ""
"Use this setting to rotate the support material pattern on the horizontal "
"plane."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1417
+#: xs/src/libslic3r/PrintConfig.cpp:1517
msgid ""
"Only create support if it lies on a build plate. Don't create support on a "
"print."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1423
+#: xs/src/libslic3r/PrintConfig.cpp:1523
msgid "Contact Z distance"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1425
+#: xs/src/libslic3r/PrintConfig.cpp:1525
msgid ""
"The vertical distance between object and support material interface. Setting "
"this to 0 will also prevent Slic3r from using bridge flow and speed for the "
"first object layer."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1438
+#: xs/src/libslic3r/PrintConfig.cpp:1538
msgid "Enforce support for the first"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1440
+#: xs/src/libslic3r/PrintConfig.cpp:1540
msgid ""
"Generate support material for the specified number of layers counting from "
"bottom, regardless of whether normal support material is enabled or not and "
@@ -2446,21 +3315,21 @@ msgid ""
"of objects having a very thin or poor footprint on the build plate."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1446
+#: xs/src/libslic3r/PrintConfig.cpp:1546
msgid "Enforce support for the first n layers"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1451
+#: xs/src/libslic3r/PrintConfig.cpp:1551
msgid "Support material/raft/skirt extruder"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1453
+#: xs/src/libslic3r/PrintConfig.cpp:1553
msgid ""
"The extruder to use when printing support material, raft and skirt (1+, 0 to "
"use the current extruder to minimize tool changes)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1462
+#: xs/src/libslic3r/PrintConfig.cpp:1562
msgid ""
"Set this to a non-zero value to set a manual extrusion width for support "
"material. If left zero, default extrusion width will be used if set, "
@@ -2468,91 +3337,91 @@ msgid ""
"example 90%) it will be computed over layer height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1470
+#: xs/src/libslic3r/PrintConfig.cpp:1570
msgid "Interface loops"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1472
+#: xs/src/libslic3r/PrintConfig.cpp:1572
msgid ""
"Cover the top contact layer of the supports with loops. Disabled by default."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1477
+#: xs/src/libslic3r/PrintConfig.cpp:1577
msgid "Support material/raft interface extruder"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1479
+#: xs/src/libslic3r/PrintConfig.cpp:1579
msgid ""
"The extruder to use when printing support material interface (1+, 0 to use "
"the current extruder to minimize tool changes). This affects raft too."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1486
+#: xs/src/libslic3r/PrintConfig.cpp:1586
msgid "Interface layers"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1488
+#: xs/src/libslic3r/PrintConfig.cpp:1588
msgid ""
"Number of interface layers to insert between the object(s) and support "
"material."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1495
+#: xs/src/libslic3r/PrintConfig.cpp:1595
msgid "Interface pattern spacing"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1497
+#: xs/src/libslic3r/PrintConfig.cpp:1597
msgid "Spacing between interface lines. Set zero to get a solid interface."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1504
-#: xs/src/libslic3r/GCode/PreviewData.cpp:148
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:90
+#: xs/src/libslic3r/PrintConfig.cpp:1604
+#: xs/src/libslic3r/GCode/PreviewData.cpp:168
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:93
msgid "Support material interface"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1506
+#: xs/src/libslic3r/PrintConfig.cpp:1606
msgid ""
"Speed for printing support material interface layers. If expressed as "
"percentage (for example 50%) it will be calculated over support material "
"speed."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1515
+#: xs/src/libslic3r/PrintConfig.cpp:1615
msgid "Pattern"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1517
+#: xs/src/libslic3r/PrintConfig.cpp:1617
msgid "Pattern used to generate support material."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1531
+#: xs/src/libslic3r/PrintConfig.cpp:1629
msgid "Pattern spacing"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1533
+#: xs/src/libslic3r/PrintConfig.cpp:1631
msgid "Spacing between support material lines."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1542
+#: xs/src/libslic3r/PrintConfig.cpp:1640
msgid "Speed for printing support material."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1549
+#: xs/src/libslic3r/PrintConfig.cpp:1647
msgid "Synchronize with object layers"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1551
+#: xs/src/libslic3r/PrintConfig.cpp:1649
msgid ""
"Synchronize support layers with the object print layers. This is useful with "
"multi-material printers, where the extruder switch is expensive."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1557
+#: xs/src/libslic3r/PrintConfig.cpp:1655
msgid "Overhang threshold"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1559
+#: xs/src/libslic3r/PrintConfig.cpp:1657
msgid ""
"Support material will not be generated for overhangs whose slope angle (90° "
"= vertical) is above the given threshold. In other words, this value "
@@ -2561,60 +3430,60 @@ msgid ""
"detection (recommended)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1571
+#: xs/src/libslic3r/PrintConfig.cpp:1669
msgid "With sheath around the support"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1573
+#: xs/src/libslic3r/PrintConfig.cpp:1671
msgid ""
"Add a sheath (a single perimeter line) around the base support. This makes "
"the support more reliable, but also more difficult to remove."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1580
+#: xs/src/libslic3r/PrintConfig.cpp:1678
msgid ""
"Extruder temperature for layers after the first one. Set this to zero to "
"disable temperature control commands in the output."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1583
+#: xs/src/libslic3r/PrintConfig.cpp:1681
msgid "Temperature"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1589
+#: xs/src/libslic3r/PrintConfig.cpp:1687
msgid "Detect thin walls"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1591
+#: xs/src/libslic3r/PrintConfig.cpp:1689
msgid ""
"Detect single-width walls (parts where two extrusions don't fit and we need "
"to collapse them into a single trace)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1597
+#: xs/src/libslic3r/PrintConfig.cpp:1695
msgid "Threads"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1598
+#: xs/src/libslic3r/PrintConfig.cpp:1696
msgid ""
"Threads are used to parallelize long-running tasks. Optimal threads number "
"is slightly above the number of available cores/processors."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1610
+#: xs/src/libslic3r/PrintConfig.cpp:1708
msgid ""
"This custom code is inserted right before every extruder change. Note that "
"you can use placeholder variables for all Slic3r settings as well as "
"[previous_extruder] and [next_extruder]."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1620 xs/src/libslic3r/PrintConfig.cpp:1631
-#: xs/src/libslic3r/GCode/PreviewData.cpp:143
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:85
+#: xs/src/libslic3r/PrintConfig.cpp:1718 xs/src/libslic3r/PrintConfig.cpp:1729
+#: xs/src/libslic3r/GCode/PreviewData.cpp:163
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:88
msgid "Top solid infill"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1622
+#: xs/src/libslic3r/PrintConfig.cpp:1720
msgid ""
"Set this to a non-zero value to set a manual extrusion width for infill for "
"top surfaces. You may want to use thinner extrudates to fill all narrow "
@@ -2623,7 +3492,7 @@ msgid ""
"percentage (for example 90%) it will be computed over layer height."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1633
+#: xs/src/libslic3r/PrintConfig.cpp:1731
msgid ""
"Speed for printing top solid layers (it only applies to the uppermost "
"external layers and not to their internal solid layers). You may want to "
@@ -2632,51 +3501,51 @@ msgid ""
"for auto."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1645 lib/Slic3r/GUI/MainFrame.pm:363
+#: xs/src/libslic3r/PrintConfig.cpp:1743 lib/Slic3r/GUI/MainFrame.pm:306
msgid "Top"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1647
+#: xs/src/libslic3r/PrintConfig.cpp:1745
msgid "Number of solid layers to generate on top surfaces."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1649
+#: xs/src/libslic3r/PrintConfig.cpp:1747
msgid "Top solid layers"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1654 lib/Slic3r/GUI/Plater/3DPreview.pm:95
+#: xs/src/libslic3r/PrintConfig.cpp:1752 lib/Slic3r/GUI/Plater/3DPreview.pm:98
msgid "Travel"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1655
+#: xs/src/libslic3r/PrintConfig.cpp:1753
msgid "Speed for travel moves (jumps between distant extrusion points)."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1663
+#: xs/src/libslic3r/PrintConfig.cpp:1761
msgid "Use firmware retraction"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1664
+#: xs/src/libslic3r/PrintConfig.cpp:1762
msgid ""
"This experimental setting uses G10 and G11 commands to have the firmware "
"handle the retraction. This is only supported in recent Marlin."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1670
+#: xs/src/libslic3r/PrintConfig.cpp:1768
msgid "Use relative E distances"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1671
+#: xs/src/libslic3r/PrintConfig.cpp:1769
msgid ""
"If your firmware requires relative E values, check this, otherwise leave it "
"unchecked. Most firmwares use absolute values."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1677
+#: xs/src/libslic3r/PrintConfig.cpp:1775
msgid "Use volumetric E"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1678
+#: xs/src/libslic3r/PrintConfig.cpp:1776
msgid ""
"This experimental setting uses outputs the E values in cubic millimeters "
"instead of linear millimeters. If your firmware doesn't already know "
@@ -2686,83 +3555,113 @@ msgid ""
"only supported in recent Marlin."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1688
+#: xs/src/libslic3r/PrintConfig.cpp:1786
msgid "Enable variable layer height feature"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1689
+#: xs/src/libslic3r/PrintConfig.cpp:1787
msgid ""
"Some printers or printer setups may have difficulties printing with a "
"variable layer height. Enabled by default."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1695
+#: xs/src/libslic3r/PrintConfig.cpp:1793
msgid "Wipe while retracting"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1696
+#: xs/src/libslic3r/PrintConfig.cpp:1794
msgid ""
"This flag will move the nozzle while retracting to minimize the possible "
"blob on leaky extruders."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1703
+#: xs/src/libslic3r/PrintConfig.cpp:1801
msgid ""
"Multi material printers may need to prime or purge extruders on tool "
"changes. Extrude the excess material into the wipe tower."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1709
+#: xs/src/libslic3r/PrintConfig.cpp:1807
+msgid "Purging volumes - load/unload volumes"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1808
+msgid ""
+"This vector saves required volumes to change from/to each tool used on the "
+"wipe tower. These values are used to simplify creation of the full purging "
+"volumes below. "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1815
+msgid "Purging volumes - matrix"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1816
+msgid ""
+"This matrix describes volumes (in cubic milimetres) required to purge the "
+"new filament on the wipe tower for any given pair of tools. "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1826
msgid "Position X"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1710
+#: xs/src/libslic3r/PrintConfig.cpp:1827
msgid "X coordinate of the left front corner of a wipe tower"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1716
+#: xs/src/libslic3r/PrintConfig.cpp:1833
msgid "Position Y"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1717
+#: xs/src/libslic3r/PrintConfig.cpp:1834
msgid "Y coordinate of the left front corner of a wipe tower"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1723 lib/Slic3r/GUI/Plater/3DPreview.pm:70
+#: xs/src/libslic3r/PrintConfig.cpp:1840 lib/Slic3r/GUI/Plater/3DPreview.pm:69
msgid "Width"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1724
+#: xs/src/libslic3r/PrintConfig.cpp:1841
msgid "Width of a wipe tower"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1730
-msgid "Per color change depth"
+#: xs/src/libslic3r/PrintConfig.cpp:1847
+msgid "Wipe tower rotation angle"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1731
-msgid ""
-"Depth of a wipe color per color change. For N colors, there will be maximum "
-"(N-1) tool switches performed, therefore the total depth of the wipe tower "
-"will be (N-1) times this value."
+#: xs/src/libslic3r/PrintConfig.cpp:1848
+msgid "Wipe tower rotation angle with respect to x-axis "
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1739
+#: xs/src/libslic3r/PrintConfig.cpp:1849
+msgid "degrees"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1854
+msgid "Maximal bridging distance"
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1855
+msgid "Maximal distance between supports on sparse infill sections. "
+msgstr ""
+
+#: xs/src/libslic3r/PrintConfig.cpp:1861
msgid "XY Size Compensation"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1741
+#: xs/src/libslic3r/PrintConfig.cpp:1863
msgid ""
"The object will be grown/shrunk in the XY plane by the configured value "
"(negative = inwards, positive = outwards). This might be useful for fine-"
"tuning hole sizes."
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1749
+#: xs/src/libslic3r/PrintConfig.cpp:1871
msgid "Z offset"
msgstr ""
-#: xs/src/libslic3r/PrintConfig.cpp:1750
+#: xs/src/libslic3r/PrintConfig.cpp:1872
msgid ""
"This value will be added (or subtracted) from all the Z coordinates in the "
"output G-code. It is used to compensate for bad Z endstop position: for "
@@ -2770,980 +3669,946 @@ msgid ""
"print bed, set this to -0.3 (or fix your endstop)."
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:138
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:80
+#: xs/src/libslic3r/GCode/PreviewData.cpp:158
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:83
msgid "Perimeter"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:139
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:81
+#: xs/src/libslic3r/GCode/PreviewData.cpp:159
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:84
msgid "External perimeter"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:140
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:82
+#: xs/src/libslic3r/GCode/PreviewData.cpp:160
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:85
msgid "Overhang perimeter"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:141
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:83
+#: xs/src/libslic3r/GCode/PreviewData.cpp:161
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:86
msgid "Internal infill"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:144
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:86
+#: xs/src/libslic3r/GCode/PreviewData.cpp:164
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:89
msgid "Bridge infill"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:151
+#: xs/src/libslic3r/GCode/PreviewData.cpp:171
msgid "Mixed"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:330
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:68
+#: xs/src/libslic3r/GCode/PreviewData.cpp:362
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:67
msgid "Feature type"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:332
+#: xs/src/libslic3r/GCode/PreviewData.cpp:364
msgid "Height (mm)"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:334
+#: xs/src/libslic3r/GCode/PreviewData.cpp:366
msgid "Width (mm)"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:336
+#: xs/src/libslic3r/GCode/PreviewData.cpp:368
msgid "Speed (mm/s)"
msgstr ""
-#: xs/src/libslic3r/GCode/PreviewData.cpp:338
+#: xs/src/libslic3r/GCode/PreviewData.cpp:370
+msgid "Volumetric flow rate (mm3/s)"
+msgstr ""
+
+#: xs/src/libslic3r/GCode/PreviewData.cpp:372
#: lib/Slic3r/GUI/Plater/3DPreview.pm:72
msgid "Tool"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:66
+#: lib/Slic3r/GUI.pm:303
+msgid "Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):"
+msgstr ""
+
+#: lib/Slic3r/GUI/MainFrame.pm:62
msgid "Version "
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:66
+#: lib/Slic3r/GUI/MainFrame.pm:62
msgid ""
" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:118
+#: lib/Slic3r/GUI/MainFrame.pm:114
msgid "Plater"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:120
+#: lib/Slic3r/GUI/MainFrame.pm:116
msgid "Controller"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:191
-msgid "No Bonjour device found"
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:191
-msgid "Device Browser"
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:212
-msgid "I wasn't able to connect to OctoPrint ("
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:213
-msgid "). Check hostname and OctoPrint version (at least 1.1.0 is required)."
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:245
+#: lib/Slic3r/GUI/MainFrame.pm:194
msgid "Open STL/OBJ/AMF…\tCtrl+O"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:245
+#: lib/Slic3r/GUI/MainFrame.pm:194
msgid "Open a model"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:248
+#: lib/Slic3r/GUI/MainFrame.pm:197
msgid "&Load Config…\tCtrl+L"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:248
+#: lib/Slic3r/GUI/MainFrame.pm:197
msgid "Load exported configuration file"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:251
+#: lib/Slic3r/GUI/MainFrame.pm:200
msgid "&Export Config…\tCtrl+E"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:251
+#: lib/Slic3r/GUI/MainFrame.pm:200
msgid "Export current configuration to file"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:254
+#: lib/Slic3r/GUI/MainFrame.pm:203
msgid "&Load Config Bundle…"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:254
+#: lib/Slic3r/GUI/MainFrame.pm:203
msgid "Load presets from a bundle"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:257
+#: lib/Slic3r/GUI/MainFrame.pm:206
msgid "&Export Config Bundle…"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:257
+#: lib/Slic3r/GUI/MainFrame.pm:206
msgid "Export all presets to file"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:262
+#: lib/Slic3r/GUI/MainFrame.pm:211
msgid "Q&uick Slice…\tCtrl+U"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:262
+#: lib/Slic3r/GUI/MainFrame.pm:211
msgid "Slice a file into a G-code"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:268
+#: lib/Slic3r/GUI/MainFrame.pm:217
msgid "Quick Slice and Save &As…\tCtrl+Alt+U"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:268
+#: lib/Slic3r/GUI/MainFrame.pm:217
msgid "Slice a file into a G-code, save as"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:274
+#: lib/Slic3r/GUI/MainFrame.pm:223
msgid "&Repeat Last Quick Slice\tCtrl+Shift+U"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:274
+#: lib/Slic3r/GUI/MainFrame.pm:223
msgid "Repeat last quick slice"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:281
+#: lib/Slic3r/GUI/MainFrame.pm:230
msgid "Slice to SV&G…\tCtrl+G"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:281
+#: lib/Slic3r/GUI/MainFrame.pm:230
msgid "Slice file to a multi-layer SVG"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:285
+#: lib/Slic3r/GUI/MainFrame.pm:234
msgid "(&Re)Slice Now\tCtrl+S"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:285
+#: lib/Slic3r/GUI/MainFrame.pm:234
msgid "Start new slicing process"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:288
+#: lib/Slic3r/GUI/MainFrame.pm:237
msgid "Repair STL file…"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:288
+#: lib/Slic3r/GUI/MainFrame.pm:237
msgid "Automatically repair an STL file"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:293
-msgid "Preferences…\tCtrl+,"
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:293
-msgid "Application preferences"
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:298
+#: lib/Slic3r/GUI/MainFrame.pm:241
msgid "&Quit"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:298
+#: lib/Slic3r/GUI/MainFrame.pm:241
msgid "Quit Slic3r"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:308
+#: lib/Slic3r/GUI/MainFrame.pm:251
msgid "Export G-code..."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:308
+#: lib/Slic3r/GUI/MainFrame.pm:251
msgid "Export current plate as G-code"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:311
+#: lib/Slic3r/GUI/MainFrame.pm:254
msgid "Export plate as STL..."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:311
+#: lib/Slic3r/GUI/MainFrame.pm:254
msgid "Export current plate as STL"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:314
+#: lib/Slic3r/GUI/MainFrame.pm:257
msgid "Export plate as AMF..."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:314
+#: lib/Slic3r/GUI/MainFrame.pm:257
msgid "Export current plate as AMF"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:317
+#: lib/Slic3r/GUI/MainFrame.pm:260
msgid "Export plate as 3MF..."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:317
+#: lib/Slic3r/GUI/MainFrame.pm:260
msgid "Export current plate as 3MF"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:330
+#: lib/Slic3r/GUI/MainFrame.pm:273
msgid "Select &Plater Tab\tCtrl+1"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:330
+#: lib/Slic3r/GUI/MainFrame.pm:273
msgid "Show the plater"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:336
+#: lib/Slic3r/GUI/MainFrame.pm:279
msgid "Select &Controller Tab\tCtrl+T"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:336
+#: lib/Slic3r/GUI/MainFrame.pm:279
msgid "Show the printer controller"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:344
+#: lib/Slic3r/GUI/MainFrame.pm:287
msgid "Select P&rint Settings Tab\tCtrl+2"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:344
+#: lib/Slic3r/GUI/MainFrame.pm:287
msgid "Show the print settings"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:347
+#: lib/Slic3r/GUI/MainFrame.pm:290
msgid "Select &Filament Settings Tab\tCtrl+3"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:347
+#: lib/Slic3r/GUI/MainFrame.pm:290
msgid "Show the filament settings"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:350
+#: lib/Slic3r/GUI/MainFrame.pm:293
msgid "Select Print&er Settings Tab\tCtrl+4"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:350
+#: lib/Slic3r/GUI/MainFrame.pm:293
msgid "Show the printer settings"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:362
+#: lib/Slic3r/GUI/MainFrame.pm:305
msgid "Iso"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:362
+#: lib/Slic3r/GUI/MainFrame.pm:305
msgid "Iso View"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:363
+#: lib/Slic3r/GUI/MainFrame.pm:306
msgid "Top View"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:364
+#: lib/Slic3r/GUI/MainFrame.pm:307
msgid "Bottom View"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:365
+#: lib/Slic3r/GUI/MainFrame.pm:308
msgid "Front"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:365
+#: lib/Slic3r/GUI/MainFrame.pm:308
msgid "Front View"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:366
+#: lib/Slic3r/GUI/MainFrame.pm:309
msgid "Rear"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:366
+#: lib/Slic3r/GUI/MainFrame.pm:309
msgid "Rear View"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:367
+#: lib/Slic3r/GUI/MainFrame.pm:310
msgid "Left"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:367
+#: lib/Slic3r/GUI/MainFrame.pm:310
msgid "Left View"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:368
+#: lib/Slic3r/GUI/MainFrame.pm:311
msgid "Right"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:368
+#: lib/Slic3r/GUI/MainFrame.pm:311
msgid "Right View"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:374
-msgid "&Configuration "
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:374
-msgid "Run Configuration "
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:379
+#: lib/Slic3r/GUI/MainFrame.pm:317
msgid "Prusa 3D Drivers"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:379
+#: lib/Slic3r/GUI/MainFrame.pm:317
msgid "Open the Prusa3D drivers download page in your browser"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:382
+#: lib/Slic3r/GUI/MainFrame.pm:320
msgid "Prusa Edition Releases"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:382
+#: lib/Slic3r/GUI/MainFrame.pm:320
msgid "Open the Prusa Edition releases page in your browser"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:389
+#: lib/Slic3r/GUI/MainFrame.pm:327
msgid "Slic3r &Website"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:389
+#: lib/Slic3r/GUI/MainFrame.pm:327
msgid "Open the Slic3r website in your browser"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:392
+#: lib/Slic3r/GUI/MainFrame.pm:330
msgid "Slic3r &Manual"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:392
+#: lib/Slic3r/GUI/MainFrame.pm:330
msgid "Open the Slic3r manual in your browser"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:396
+#: lib/Slic3r/GUI/MainFrame.pm:334
msgid "System Info"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:396
+#: lib/Slic3r/GUI/MainFrame.pm:334
msgid "Show system information"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:399
+#: lib/Slic3r/GUI/MainFrame.pm:337
msgid "Report an Issue"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:399
+#: lib/Slic3r/GUI/MainFrame.pm:337
msgid "Report an issue on the Slic3r Prusa Edition"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:402
+#: lib/Slic3r/GUI/MainFrame.pm:340
msgid "&About Slic3r"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:402
+#: lib/Slic3r/GUI/MainFrame.pm:340
msgid "Show about dialog"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:412
+#: lib/Slic3r/GUI/MainFrame.pm:350
msgid "&File"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:413
+#: lib/Slic3r/GUI/MainFrame.pm:351
msgid "&Plater"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:414
+#: lib/Slic3r/GUI/MainFrame.pm:352
msgid "&Object"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:415
+#: lib/Slic3r/GUI/MainFrame.pm:353
msgid "&Window"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:416
+#: lib/Slic3r/GUI/MainFrame.pm:354
msgid "&View"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:420
+#: lib/Slic3r/GUI/MainFrame.pm:357
msgid "&Help"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:452
+#: lib/Slic3r/GUI/MainFrame.pm:388
msgid "Choose a file to slice (STL/OBJ/AMF/3MF/PRUSA):"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:464
+#: lib/Slic3r/GUI/MainFrame.pm:400
msgid "No previously sliced file."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:469
+#: lib/Slic3r/GUI/MainFrame.pm:401 lib/Slic3r/GUI/Plater.pm:1342
+msgid "Error"
+msgstr ""
+
+#: lib/Slic3r/GUI/MainFrame.pm:405
msgid "Previously sliced file ("
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:469
+#: lib/Slic3r/GUI/MainFrame.pm:405
msgid ") not found."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:470
+#: lib/Slic3r/GUI/MainFrame.pm:406
msgid "File Not Found"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:509
+#: lib/Slic3r/GUI/MainFrame.pm:445
msgid "SVG"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:509
+#: lib/Slic3r/GUI/MainFrame.pm:445
msgid "G-code"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:509 lib/Slic3r/GUI/Plater.pm:1615
+#: lib/Slic3r/GUI/MainFrame.pm:445 lib/Slic3r/GUI/Plater.pm:1660
msgid " file as:"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:523
+#: lib/Slic3r/GUI/MainFrame.pm:459
msgid "Slicing…"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:523
+#: lib/Slic3r/GUI/MainFrame.pm:459
msgid "Processing "
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:543
+#: lib/Slic3r/GUI/MainFrame.pm:479
msgid " was successfully sliced."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:545
+#: lib/Slic3r/GUI/MainFrame.pm:481
msgid "Slicing Done!"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:561
+#: lib/Slic3r/GUI/MainFrame.pm:497
msgid "Select the STL file to repair:"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:575
+#: lib/Slic3r/GUI/MainFrame.pm:511
msgid "Save OBJ file (less prone to coordinate errors than STL) as:"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:589
+#: lib/Slic3r/GUI/MainFrame.pm:525
msgid "Your file was repaired."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:589
+#: lib/Slic3r/GUI/MainFrame.pm:525
msgid "Repair"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:600
+#: lib/Slic3r/GUI/MainFrame.pm:536
msgid "Save configuration as:"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:618 lib/Slic3r/GUI/MainFrame.pm:662
+#: lib/Slic3r/GUI/MainFrame.pm:554 lib/Slic3r/GUI/MainFrame.pm:598
msgid "Select configuration to load:"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:641
+#: lib/Slic3r/GUI/MainFrame.pm:577
msgid "Save presets bundle as:"
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:682
+#: lib/Slic3r/GUI/MainFrame.pm:618
#, possible-perl-format
msgid "%d presets successfully imported."
msgstr ""
-#: lib/Slic3r/GUI/MainFrame.pm:744
-msgid "You have unsaved changes "
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:744
-msgid ". Discard changes and continue anyway?"
-msgstr ""
-
-#: lib/Slic3r/GUI/MainFrame.pm:745
-msgid "Unsaved Presets"
-msgstr ""
-
-#: lib/Slic3r/GUI/Plater.pm:104 lib/Slic3r/GUI/Plater.pm:2094
+#: lib/Slic3r/GUI/Plater.pm:112 lib/Slic3r/GUI/Plater.pm:2153
msgid "3D"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:138
+#: lib/Slic3r/GUI/Plater.pm:148
msgid "2D"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:157
+#: lib/Slic3r/GUI/Plater.pm:167
msgid "Layers"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:177 lib/Slic3r/GUI/Plater.pm:195
+#: lib/Slic3r/GUI/Plater.pm:187 lib/Slic3r/GUI/Plater.pm:205
msgid "Add…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:179 lib/Slic3r/GUI/Plater.pm:197
+#: lib/Slic3r/GUI/Plater.pm:189 lib/Slic3r/GUI/Plater.pm:207
msgid "Delete All"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:180 lib/Slic3r/GUI/Plater.pm:198
+#: lib/Slic3r/GUI/Plater.pm:190 lib/Slic3r/GUI/Plater.pm:208
msgid "Arrange"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:182
+#: lib/Slic3r/GUI/Plater.pm:192
msgid "More"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:183
+#: lib/Slic3r/GUI/Plater.pm:193
msgid "Fewer"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:185
+#: lib/Slic3r/GUI/Plater.pm:195
msgid "45° ccw"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:186
+#: lib/Slic3r/GUI/Plater.pm:196
msgid "45° cw"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:187 lib/Slic3r/GUI/Plater.pm:203
+#: lib/Slic3r/GUI/Plater.pm:197 lib/Slic3r/GUI/Plater.pm:213
msgid "Scale…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:188 lib/Slic3r/GUI/Plater.pm:204
-#: lib/Slic3r/GUI/Plater.pm:2069
+#: lib/Slic3r/GUI/Plater.pm:198 lib/Slic3r/GUI/Plater.pm:214
+#: lib/Slic3r/GUI/Plater.pm:2128
msgid "Split"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:189 lib/Slic3r/GUI/Plater.pm:205
-#: lib/Slic3r/GUI/Plater.pm:2072
+#: lib/Slic3r/GUI/Plater.pm:199 lib/Slic3r/GUI/Plater.pm:215
+#: lib/Slic3r/GUI/Plater.pm:2131
msgid "Cut…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:191 lib/Slic3r/GUI/Plater.pm:206
-#: lib/Slic3r/GUI/Plater.pm:2076
+#: lib/Slic3r/GUI/Plater.pm:201 lib/Slic3r/GUI/Plater.pm:216
+#: lib/Slic3r/GUI/Plater.pm:2135
msgid "Settings…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:192
+#: lib/Slic3r/GUI/Plater.pm:202
msgid "Layer Editing"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:207
+#: lib/Slic3r/GUI/Plater.pm:217
msgid "Layer editing"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:220
+#: lib/Slic3r/GUI/Plater.pm:230
msgid "Name"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:221 lib/Slic3r/GUI/Plater.pm:904
+#: lib/Slic3r/GUI/Plater.pm:231 lib/Slic3r/GUI/Plater.pm:942
msgid "Copies"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:222 lib/Slic3r/GUI/Plater.pm:1060
-#: lib/Slic3r/GUI/Plater.pm:1065 lib/Slic3r/GUI/Plater.pm:2038
+#: lib/Slic3r/GUI/Plater.pm:232 lib/Slic3r/GUI/Plater.pm:1098
+#: lib/Slic3r/GUI/Plater.pm:1103 lib/Slic3r/GUI/Plater.pm:2097
msgid "Scale"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:236
+#: lib/Slic3r/GUI/Plater.pm:246
msgid "Export G-code…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:237
+#: lib/Slic3r/GUI/Plater.pm:247
msgid "Slice now"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:238
+#: lib/Slic3r/GUI/Plater.pm:248
msgid "Print…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:239
+#: lib/Slic3r/GUI/Plater.pm:249
msgid "Send to printer"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:240
+#: lib/Slic3r/GUI/Plater.pm:250
msgid "Export STL…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:367
+#: lib/Slic3r/GUI/Plater.pm:377
msgid "Print settings"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:369
+#: lib/Slic3r/GUI/Plater.pm:379
msgid "Printer"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:401
+#: lib/Slic3r/GUI/Plater.pm:411
msgid "Info"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:412
+#: lib/Slic3r/GUI/Plater.pm:422
msgid "Volume"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:413
+#: lib/Slic3r/GUI/Plater.pm:423
msgid "Facets"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:414
+#: lib/Slic3r/GUI/Plater.pm:424
msgid "Materials"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:415
+#: lib/Slic3r/GUI/Plater.pm:425
msgid "Manifold"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:441
+#: lib/Slic3r/GUI/Plater.pm:451
msgid "Sliced Info"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:450
+#: lib/Slic3r/GUI/Plater.pm:460
msgid "Used Filament (m)"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:451
+#: lib/Slic3r/GUI/Plater.pm:461
msgid "Used Filament (mm³)"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:452
+#: lib/Slic3r/GUI/Plater.pm:462
msgid "Used Filament (g)"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:454
+#: lib/Slic3r/GUI/Plater.pm:464
msgid "Estimated printing time"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:633
+#: lib/Slic3r/GUI/Plater.pm:662
msgid "Loading…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:633 lib/Slic3r/GUI/Plater.pm:647
+#: lib/Slic3r/GUI/Plater.pm:662 lib/Slic3r/GUI/Plater.pm:676
msgid "Processing input file\n"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:667
+#: lib/Slic3r/GUI/Plater.pm:699
msgid ""
"This file contains several objects positioned at multiple heights. Instead "
"of considering them as multiple objects, should I consider\n"
"this file as a single object having multiple parts?\n"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:670 lib/Slic3r/GUI/Plater.pm:687
+#: lib/Slic3r/GUI/Plater.pm:702 lib/Slic3r/GUI/Plater.pm:719
msgid "Multi-part object detected"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:684
+#: lib/Slic3r/GUI/Plater.pm:716
msgid ""
"Multiple objects were loaded for a multi-material printer.\n"
"Instead of considering them as multiple objects, should I consider\n"
"these files to represent a single object having multiple parts?\n"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:696
+#: lib/Slic3r/GUI/Plater.pm:728
msgid "Loaded "
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:748
+#: lib/Slic3r/GUI/Plater.pm:786
msgid ""
"Your object appears to be too large, so it was automatically scaled down to "
"fit your print bed."
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:749
+#: lib/Slic3r/GUI/Plater.pm:787
msgid "Object too large?"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:904
+#: lib/Slic3r/GUI/Plater.pm:942
msgid "Enter the number of copies of the selected object:"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:931
+#: lib/Slic3r/GUI/Plater.pm:969
msgid ""
"\n"
"Non-positive value."
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:932
+#: lib/Slic3r/GUI/Plater.pm:970
msgid ""
"\n"
"Not a numeric value."
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:933
+#: lib/Slic3r/GUI/Plater.pm:971
msgid "Slic3r Error"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1034
+#: lib/Slic3r/GUI/Plater.pm:992
+msgid "Enter the rotation angle:"
+msgstr ""
+
+#: lib/Slic3r/GUI/Plater.pm:992
+msgid "Rotate around "
+msgstr ""
+
+#: lib/Slic3r/GUI/Plater.pm:992
+msgid "Invalid rotation angle entered"
+msgstr ""
+
+#: lib/Slic3r/GUI/Plater.pm:1072
#, possible-perl-format
msgid "Enter the new size for the selected object (print bed: %smm):"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1035 lib/Slic3r/GUI/Plater.pm:1039
+#: lib/Slic3r/GUI/Plater.pm:1073 lib/Slic3r/GUI/Plater.pm:1077
msgid "Scale along "
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1035 lib/Slic3r/GUI/Plater.pm:1039
-#: lib/Slic3r/GUI/Plater.pm:1060 lib/Slic3r/GUI/Plater.pm:1065
+#: lib/Slic3r/GUI/Plater.pm:1073 lib/Slic3r/GUI/Plater.pm:1077
+#: lib/Slic3r/GUI/Plater.pm:1098 lib/Slic3r/GUI/Plater.pm:1103
msgid "Invalid scaling value entered"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1039 lib/Slic3r/GUI/Plater.pm:1065
-#, possible-perl-format
+#: lib/Slic3r/GUI/Plater.pm:1077 lib/Slic3r/GUI/Plater.pm:1103
+#, no-perl-format
msgid "Enter the scale % for the selected object:"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1060
+#: lib/Slic3r/GUI/Plater.pm:1098
msgid "Enter the new max size for the selected object:"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1116
+#: lib/Slic3r/GUI/Plater.pm:1154
msgid ""
"The selected object can't be split because it contains more than one volume/"
"material."
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1125
+#: lib/Slic3r/GUI/Plater.pm:1163
msgid ""
"The selected object couldn't be split because it contains only one part."
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1290
+#: lib/Slic3r/GUI/Plater.pm:1328
msgid "Slicing cancelled"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1304
+#: lib/Slic3r/GUI/Plater.pm:1342
msgid "Another export job is currently running."
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1335
-msgid "Save G-code file as:"
-msgstr ""
-
-#: lib/Slic3r/GUI/Plater.pm:1352
-msgid "Export cancelled"
-msgstr ""
-
-#: lib/Slic3r/GUI/Plater.pm:1449
+#: lib/Slic3r/GUI/Plater.pm:1490
msgid "File added to print queue"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1452
-msgid "Sending G-code file to the OctoPrint server..."
-msgstr ""
-
-#: lib/Slic3r/GUI/Plater.pm:1455
+#: lib/Slic3r/GUI/Plater.pm:1496
msgid "G-code file exported to "
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1458
+#: lib/Slic3r/GUI/Plater.pm:1499
msgid "Export failed"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1509 lib/Slic3r/GUI/Plater.pm:1551
+#: lib/Slic3r/GUI/Plater.pm:1511
+msgid "OctoPrint upload finished."
+msgstr ""
+
+#: lib/Slic3r/GUI/Plater.pm:1554 lib/Slic3r/GUI/Plater.pm:1596
msgid "STL file exported to "
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1562
+#: lib/Slic3r/GUI/Plater.pm:1607
msgid "AMF file exported to "
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1566
+#: lib/Slic3r/GUI/Plater.pm:1611
msgid "Error exporting AMF file "
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1578
+#: lib/Slic3r/GUI/Plater.pm:1623
msgid "3MF file exported to "
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1582
+#: lib/Slic3r/GUI/Plater.pm:1627
msgid "Error exporting 3MF file "
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1818
-msgid ""
-"Please install the OpenGL modules to use this feature (see build "
-"instructions)."
-msgstr ""
-
-#: lib/Slic3r/GUI/Plater.pm:1928
+#: lib/Slic3r/GUI/Plater.pm:1985
#, possible-perl-format
msgid "%d (%d shells)"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1930
+#: lib/Slic3r/GUI/Plater.pm:1987
#, possible-perl-format
msgid "Auto-repaired (%d errors)"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1935
+#: lib/Slic3r/GUI/Plater.pm:1992
#, possible-perl-format
msgid ""
"%d degenerate facets, %d edges fixed, %d facets removed, %d facets added, %d "
"facets reversed, %d backwards edges"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1940
+#: lib/Slic3r/GUI/Plater.pm:1997
msgid "Yes"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1991
+#: lib/Slic3r/GUI/Plater.pm:2050
msgid "Remove the selected object"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1994
+#: lib/Slic3r/GUI/Plater.pm:2053
msgid "Increase copies"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1994
+#: lib/Slic3r/GUI/Plater.pm:2053
msgid "Place one more copy of the selected object"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1997
+#: lib/Slic3r/GUI/Plater.pm:2056
msgid "Decrease copies"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:1997
+#: lib/Slic3r/GUI/Plater.pm:2056
msgid "Remove one copy of the selected object"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2000
+#: lib/Slic3r/GUI/Plater.pm:2059
msgid "Set number of copies…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2000
+#: lib/Slic3r/GUI/Plater.pm:2059
msgid "Change the number of copies of the selected object"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2004
+#: lib/Slic3r/GUI/Plater.pm:2063
msgid "Rotate 45° clockwise"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2004
+#: lib/Slic3r/GUI/Plater.pm:2063
msgid "Rotate the selected object by 45° clockwise"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2007
+#: lib/Slic3r/GUI/Plater.pm:2066
msgid "Rotate 45° counter-clockwise"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2007
+#: lib/Slic3r/GUI/Plater.pm:2066
msgid "Rotate the selected object by 45° counter-clockwise"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2012
+#: lib/Slic3r/GUI/Plater.pm:2071
msgid "Rotate"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2012
+#: lib/Slic3r/GUI/Plater.pm:2071
msgid "Rotate the selected object by an arbitrary angle"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2014
+#: lib/Slic3r/GUI/Plater.pm:2073
msgid "Around X axis…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2014
+#: lib/Slic3r/GUI/Plater.pm:2073
msgid "Rotate the selected object by an arbitrary angle around X axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2017
+#: lib/Slic3r/GUI/Plater.pm:2076
msgid "Around Y axis…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2017
+#: lib/Slic3r/GUI/Plater.pm:2076
msgid "Rotate the selected object by an arbitrary angle around Y axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2020
+#: lib/Slic3r/GUI/Plater.pm:2079
msgid "Around Z axis…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2020
+#: lib/Slic3r/GUI/Plater.pm:2079
msgid "Rotate the selected object by an arbitrary angle around Z axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2025
+#: lib/Slic3r/GUI/Plater.pm:2084
msgid "Mirror"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2025
+#: lib/Slic3r/GUI/Plater.pm:2084
msgid "Mirror the selected object"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2027 lib/Slic3r/GUI/Plater.pm:2043
-#: lib/Slic3r/GUI/Plater.pm:2059
+#: lib/Slic3r/GUI/Plater.pm:2086 lib/Slic3r/GUI/Plater.pm:2102
+#: lib/Slic3r/GUI/Plater.pm:2118
msgid "Along X axis…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2027
+#: lib/Slic3r/GUI/Plater.pm:2086
msgid "Mirror the selected object along the X axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2030 lib/Slic3r/GUI/Plater.pm:2046
-#: lib/Slic3r/GUI/Plater.pm:2062
+#: lib/Slic3r/GUI/Plater.pm:2089 lib/Slic3r/GUI/Plater.pm:2105
+#: lib/Slic3r/GUI/Plater.pm:2121
msgid "Along Y axis…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2030
+#: lib/Slic3r/GUI/Plater.pm:2089
msgid "Mirror the selected object along the Y axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2033 lib/Slic3r/GUI/Plater.pm:2049
-#: lib/Slic3r/GUI/Plater.pm:2065
+#: lib/Slic3r/GUI/Plater.pm:2092 lib/Slic3r/GUI/Plater.pm:2108
+#: lib/Slic3r/GUI/Plater.pm:2124
msgid "Along Z axis…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2033
+#: lib/Slic3r/GUI/Plater.pm:2092
msgid "Mirror the selected object along the Z axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2038 lib/Slic3r/GUI/Plater.pm:2054
+#: lib/Slic3r/GUI/Plater.pm:2097 lib/Slic3r/GUI/Plater.pm:2113
msgid "Scale the selected object along a single axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2040 lib/Slic3r/GUI/Plater.pm:2056
+#: lib/Slic3r/GUI/Plater.pm:2099 lib/Slic3r/GUI/Plater.pm:2115
msgid "Uniformly…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2040 lib/Slic3r/GUI/Plater.pm:2056
+#: lib/Slic3r/GUI/Plater.pm:2099 lib/Slic3r/GUI/Plater.pm:2115
msgid "Scale the selected object along the XYZ axes"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2043 lib/Slic3r/GUI/Plater.pm:2059
+#: lib/Slic3r/GUI/Plater.pm:2102 lib/Slic3r/GUI/Plater.pm:2118
msgid "Scale the selected object along the X axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2046 lib/Slic3r/GUI/Plater.pm:2062
+#: lib/Slic3r/GUI/Plater.pm:2105 lib/Slic3r/GUI/Plater.pm:2121
msgid "Scale the selected object along the Y axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2049 lib/Slic3r/GUI/Plater.pm:2065
+#: lib/Slic3r/GUI/Plater.pm:2108 lib/Slic3r/GUI/Plater.pm:2124
msgid "Scale the selected object along the Z axis"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2054
+#: lib/Slic3r/GUI/Plater.pm:2113
msgid "Scale to size"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2069
+#: lib/Slic3r/GUI/Plater.pm:2128
msgid "Split the selected object into individual parts"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2072
+#: lib/Slic3r/GUI/Plater.pm:2131
msgid "Open the 3D cutting tool"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2076
+#: lib/Slic3r/GUI/Plater.pm:2135
msgid "Open the object editor dialog"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2080
+#: lib/Slic3r/GUI/Plater.pm:2139
msgid "Reload from Disk"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2080
+#: lib/Slic3r/GUI/Plater.pm:2139
msgid "Reload the selected file from Disk"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2083
+#: lib/Slic3r/GUI/Plater.pm:2142
msgid "Export object as STL…"
msgstr ""
-#: lib/Slic3r/GUI/Plater.pm:2083
+#: lib/Slic3r/GUI/Plater.pm:2142
msgid "Export this single object as STL file"
msgstr ""
@@ -3755,30 +4620,34 @@ msgstr ""
msgid "Drag your objects here"
msgstr ""
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:63
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:62
msgid "1 Layer"
msgstr ""
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:65
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:64
msgid "View"
msgstr ""
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:75
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:71
+msgid "Volumetric flow rate"
+msgstr ""
+
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:78
msgid "Show"
msgstr ""
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:78 lib/Slic3r/GUI/Plater/3DPreview.pm:79
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:81 lib/Slic3r/GUI/Plater/3DPreview.pm:82
msgid "Feature types"
msgstr ""
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:96
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:99
msgid "Retractions"
msgstr ""
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:97
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:100
msgid "Unretractions"
msgstr ""
-#: lib/Slic3r/GUI/Plater/3DPreview.pm:98
+#: lib/Slic3r/GUI/Plater/3DPreview.pm:101
msgid "Shells"
msgstr ""
diff --git a/resources/localization/list.txt b/resources/localization/list.txt
index 2925495450..2112d67c36 100644
--- a/resources/localization/list.txt
+++ b/resources/localization/list.txt
@@ -1,15 +1,23 @@
+xs/src/slic3r/GUI/AboutDialog.cpp
xs/src/slic3r/GUI/BedShapeDialog.cpp
xs/src/slic3r/GUI/BedShapeDialog.hpp
+xs/src/slic3r/GUI/BonjourDialog.cpp
+xs/src/slic3r/GUI/ButtonsDescription.cpp
+xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp
+xs/src/slic3r/GUI/ConfigWizard.cpp
xs/src/slic3r/GUI/GUI.cpp
+xs/src/slic3r/GUI/MsgDialog.cpp
xs/src/slic3r/GUI/Tab.cpp
xs/src/slic3r/GUI/Tab.hpp
xs/src/slic3r/GUI/Field.cpp
xs/src/slic3r/GUI/OptionsGroup.cpp
-xs/src/slic3r/GUI/2DBed.cpp
+xs/src/slic3r/GUI/Preset.cpp
+xs/src/slic3r/GUI/PresetBundle.cpp
xs/src/slic3r/GUI/PresetHints.cpp
-xs/src/slic3r/GUI/Preferences.hpp
xs/src/slic3r/GUI/Preferences.cpp
-xs/src/slic3r/GUI/BonjourDialog.cpp
+xs/src/slic3r/GUI/RammingChart.cpp
+xs/src/slic3r/GUI/UpdateDialogs.cpp
+xs/src/slic3r/GUI/WipeTowerDialog.cpp
xs/src/slic3r/Utils/OctoPrint.cpp
xs/src/libslic3r/PrintConfig.cpp
xs/src/libslic3r/GCode/PreviewData.cpp
diff --git a/resources/profiles/BarBaz.ini b/resources/profiles/BarBaz.ini
new file mode 100644
index 0000000000..ed2686cdc4
--- /dev/null
+++ b/resources/profiles/BarBaz.ini
@@ -0,0 +1,985 @@
+# Print profiles for the BarBaz 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.0
+# 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:BarBaz 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:BarBaz 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:BarBaz 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:BarBaz 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_BarBaz3D\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 = BarBaz 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_BarBaz3D\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_BarBaz3D\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:BarBaz i3 MK2]
+inherits = *common*
+
+[printer:BarBaz 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:BarBaz 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:BarBaz i3 MK2 MM Single Mode]
+inherits = *mm-single*
+
+[printer:BarBaz i3 MK2 MM Single Mode 0.6 nozzle]
+inherits = *mm-single*
+nozzle_diameter = 0.6
+printer_variant = 0.6
+
+[printer:BarBaz i3 MK2 MultiMaterial]
+inherits = *mm-multi*
+nozzle_diameter = 0.4,0.4,0.4,0.4
+
+[printer:BarBaz i3 MK2 MultiMaterial 0.6 nozzle]
+inherits = *mm-multi*
+nozzle_diameter = 0.6,0.6,0.6,0.6
+printer_variant = 0.6
+
+[printer:BarBaz 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_BarBaz3D\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:BarBaz 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_BarBaz3D\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:BarBaz 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_BarBaz3D\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 0000000000..6f31401ea7
--- /dev/null
+++ b/resources/profiles/Foobar.ini
@@ -0,0 +1,985 @@
+# Print profiles for the Foobar 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.0
+# 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:Foobar 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:Foobar 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:Foobar 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:Foobar 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_Foobar3D\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 = Foobar 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_Foobar3D\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_Foobar3D\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:Foobar i3 MK2]
+inherits = *common*
+
+[printer:Foobar 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:Foobar 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:Foobar i3 MK2 MM Single Mode]
+inherits = *mm-single*
+
+[printer:Foobar i3 MK2 MM Single Mode 0.6 nozzle]
+inherits = *mm-single*
+nozzle_diameter = 0.6
+printer_variant = 0.6
+
+[printer:Foobar i3 MK2 MultiMaterial]
+inherits = *mm-multi*
+nozzle_diameter = 0.4,0.4,0.4,0.4
+
+[printer:Foobar i3 MK2 MultiMaterial 0.6 nozzle]
+inherits = *mm-multi*
+nozzle_diameter = 0.6,0.6,0.6,0.6
+printer_variant = 0.6
+
+[printer:Foobar 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_Foobar3D\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:Foobar 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_Foobar3D\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:Foobar 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_Foobar3D\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.idx b/resources/profiles/PrusaResearch.idx
new file mode 100644
index 0000000000..e3b1e6ef54
--- /dev/null
+++ b/resources/profiles/PrusaResearch.idx
@@ -0,0 +1,3 @@
+0.1.2 Wipe tower changes
+0.1.1 Minor print speed adjustments
+0.1.0 Initial
diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini
index de23bf0ad3..ba8e55ad41 100644
--- a/resources/profiles/PrusaResearch.ini
+++ b/resources/profiles/PrusaResearch.ini
@@ -5,23 +5,25 @@
name = Prusa Research
# 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
+config_version = 0.1.2
# Where to get the updates from?
-config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch.ini
+config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch/
# 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 name will be shown by the installation wizard.
[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
@@ -66,6 +68,7 @@ infill_first = 0
infill_only_where_needed = 0
infill_overlap = 25%
interface_shells = 0
+max_print_height = 200
max_print_speed = 100
max_volumetric_extrusion_rate_slope_negative = 0
max_volumetric_extrusion_rate_slope_positive = 0
@@ -87,7 +90,7 @@ seam_position = nearest
skirts = 1
skirt_distance = 2
skirt_height = 3
-small_perimeter_speed = 20
+small_perimeter_speed = 25
solid_infill_below_area = 0
solid_infill_every_layers = 0
solid_infill_extruder = 1
@@ -117,8 +120,9 @@ 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 = 1
+wipe_tower_bridging = 10
+wipe_tower_rotation_angle = 0
wipe_tower_width = 60
wipe_tower_x = 180
wipe_tower_y = 140
@@ -176,7 +180,7 @@ gap_fill_speed = 20
infill_acceleration = 800
infill_speed = 30
max_print_speed = 80
-small_perimeter_speed = 15
+small_perimeter_speed = 20
solid_infill_speed = 30
support_material_extrusion_width = 0.3
support_material_spacing = 1.5
@@ -211,7 +215,7 @@ infill_speed = 20
max_print_speed = 100
perimeter_extrusion_width = 0
perimeter_speed = 20
-small_perimeter_speed = 10
+small_perimeter_speed = 15
solid_infill_extrusion_width = 0
solid_infill_speed = 20
support_material_speed = 20
@@ -264,7 +268,7 @@ infill_acceleration = 1600
infill_speed = 40
perimeter_acceleration = 600
perimeter_speed = 25
-small_perimeter_speed = 10
+small_perimeter_speed = 15
solid_infill_speed = 40
top_solid_infill_speed = 30
@@ -337,7 +341,7 @@ infill_acceleration = 1600
infill_speed = 40
perimeter_acceleration = 600
perimeter_speed = 25
-small_perimeter_speed = 10
+small_perimeter_speed = 15
solid_infill_speed = 40
support_material_extrusion_width = 0.2
top_solid_infill_speed = 30
@@ -535,13 +539,17 @@ compatible_printers =
compatible_printers_condition =
end_filament_gcode = "; Filament-specific end gcode"
extrusion_multiplier = 1
+filament_loading_speed = 28
+filament_unloading_speed = 90
+filament_toolchange_delay = 0
+filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
filament_cost = 0
filament_density = 0
filament_diameter = 1.75
filament_notes = ""
filament_settings_id =
filament_soluble = 0
-min_print_speed = 5
+min_print_speed = 15
slowdown_below_layer_time = 20
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
@@ -588,6 +596,7 @@ fan_always_on = 0
fan_below_layer_time = 20
filament_colour = #3A80CA
filament_max_volumetric_speed = 11
+filament_ramming_parameters = "120 100 5.70968 6.03226 7 8.25806 9 9.19355 9.3871 9.77419 10.129 10.3226 10.4516 10.5161| 0.05 5.69677 0.45 6.15484 0.95 8.76774 1.45 9.20323 1.95 9.95806 2.45 10.3871 2.95 10.5677 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
filament_type = ABS
first_layer_bed_temperature = 100
first_layer_temperature = 255
@@ -634,7 +643,6 @@ 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
@@ -648,7 +656,6 @@ 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
@@ -760,6 +767,7 @@ 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_ramming_parameters = "120 100 8.3871 8.6129 8.93548 9.22581 9.48387 9.70968 9.87097 10.0323 10.2258 10.4194 10.6452 10.8065| 0.05 8.34193 0.45 8.73548 0.95 9.34836 1.45 9.78385 1.95 10.0871 2.45 10.5161 2.95 10.8903 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
filament_soluble = 1
filament_type = PVA
first_layer_temperature = 195
@@ -813,7 +821,6 @@ 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
@@ -846,7 +853,6 @@ 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
@@ -867,7 +873,6 @@ 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
@@ -928,6 +933,9 @@ retract_lift_below = 199
retract_restart_extra = 0
retract_restart_extra_toolchange = 0
retract_speed = 80
+parking_pos_retraction = 92
+cooling_tube_length = 5
+cooling_tube_retraction = 91.5
single_extruder_multi_material = 1
printer_model = MK2SMM
@@ -936,6 +944,8 @@ 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
+default_print_profile = 0.15mm OPTIMAL
+default_filament_profile = Prusa PLA
[printer:*mm-multi*]
inherits = *multimaterial*
@@ -945,10 +955,11 @@ 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
+default_print_profile = 0.15mm OPTIMAL
+default_filament_profile = Prusa PLA
[printer:Original Prusa i3 MK2]
inherits = *common*
-default_print_profile = 0.15mm OPTIMAL
[printer:Original Prusa i3 MK2 0.25 nozzle]
inherits = *common*
@@ -986,12 +997,14 @@ nozzle_diameter = 0.4,0.4,0.4,0.4
inherits = *mm-multi*
nozzle_diameter = 0.6,0.6,0.6,0.6
printer_variant = 0.6
+default_print_profile = 0.20mm NORMAL 0.6 nozzle
[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
+max_print_height = 210
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
@@ -1002,9 +1015,10 @@ nozzle_diameter = 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
+max_print_height = 210
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.10mm DETAIL MK3
+default_print_profile = 0.10mm DETAIL 0.25 nozzle MK3
[printer:Original Prusa i3 MK3 0.6 nozzle]
inherits = *common*
@@ -1012,11 +1026,7 @@ nozzle_diameter = 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
+max_print_height = 210
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
+default_print_profile = 0.15mm OPTIMAL 0.6 nozzle MK3
diff --git a/t/cooling.t b/t/cooling.t
index ee4f6abea5..2f444cf9d1 100644
--- a/t/cooling.t
+++ b/t/cooling.t
@@ -2,7 +2,7 @@ use Test::More;
use strict;
use warnings;
-plan tests => 15;
+plan tests => 14;
BEGIN {
use FindBin;
@@ -79,6 +79,7 @@ $config->set('disable_fan_first_layers', [ 0 ]);
"G1 X50 F2500\n" .
"G1 F3000;_EXTRUDE_SET_SPEED\n" .
"G1 X100 E1\n" .
+ ";_EXTRUDE_END\n" .
"G1 E4 F400",
# Print time of $gcode.
my $print_time = 50 / (2500 / 60) + 100 / (3000 / 60) + 4 / (400 / 60);
@@ -203,8 +204,8 @@ $config->set('disable_fan_first_layers', [ 0 ]);
ok $all_below, 'slowdown_below_layer_time is honored';
# check that all layers have at least one unaltered external perimeter speed
- my $external = all { $_ > 0 } values %layer_external;
- ok $external, 'slowdown_below_layer_time does not alter external perimeters';
+# my $external = all { $_ > 0 } values %layer_external;
+# ok $external, 'slowdown_below_layer_time does not alter external perimeters';
}
__END__
diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt
index abd9c3617a..4f44fc7bf7 100644
--- a/xs/CMakeLists.txt
+++ b/xs/CMakeLists.txt
@@ -170,10 +170,14 @@ add_library(libslic3r STATIC
)
add_library(libslic3r_gui STATIC
+ ${LIBDIR}/slic3r/GUI/AboutDialog.cpp
+ ${LIBDIR}/slic3r/GUI/AboutDialog.hpp
${LIBDIR}/slic3r/GUI/AppConfig.cpp
${LIBDIR}/slic3r/GUI/AppConfig.hpp
${LIBDIR}/slic3r/GUI/BitmapCache.cpp
${LIBDIR}/slic3r/GUI/BitmapCache.hpp
+ ${LIBDIR}/slic3r/GUI/ConfigSnapshotDialog.cpp
+ ${LIBDIR}/slic3r/GUI/ConfigSnapshotDialog.hpp
${LIBDIR}/slic3r/GUI/3DScene.cpp
${LIBDIR}/slic3r/GUI/3DScene.hpp
${LIBDIR}/slic3r/GUI/GLShader.cpp
@@ -208,18 +212,30 @@ add_library(libslic3r_gui STATIC
${LIBDIR}/slic3r/GUI/RammingChart.hpp
${LIBDIR}/slic3r/GUI/BonjourDialog.cpp
${LIBDIR}/slic3r/GUI/BonjourDialog.hpp
+ ${LIBDIR}/slic3r/GUI/ButtonsDescription.cpp
+ ${LIBDIR}/slic3r/GUI/ButtonsDescription.hpp
${LIBDIR}/slic3r/Config/Snapshot.cpp
${LIBDIR}/slic3r/Config/Snapshot.hpp
${LIBDIR}/slic3r/Config/Version.cpp
${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/GUI/MsgDialog.cpp
+ ${LIBDIR}/slic3r/GUI/MsgDialog.hpp
+ ${LIBDIR}/slic3r/GUI/UpdateDialogs.cpp
+ ${LIBDIR}/slic3r/GUI/UpdateDialogs.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
)
add_library(admesh STATIC
@@ -365,6 +381,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})
@@ -410,7 +427,7 @@ if(APPLE)
# Ignore undefined symbols of the perl interpreter, they will be found in the caller image.
target_link_libraries(XS "-undefined dynamic_lookup")
endif()
-target_link_libraries(XS libslic3r libslic3r_gui admesh miniz clipper nowide polypartition poly2tri)
+target_link_libraries(XS libslic3r libslic3r_gui admesh miniz clipper nowide polypartition poly2tri semver)
if(SLIC3R_PROFILE)
target_link_libraries(XS Shiny)
endif()
@@ -458,10 +475,6 @@ if (SLIC3R_PROFILE)
add_definitions(-DSLIC3R_PROFILE)
endif ()
-if (SLIC3R_HAS_BROKEN_CROAK)
- target_compile_definitions(XS PRIVATE -DSLIC3R_HAS_BROKEN_CROAK)
-endif ()
-
if (CMAKE_BUILD_TYPE MATCHES DEBUG)
target_compile_definitions(XS PRIVATE -DSLIC3R_DEBUG -DDEBUG -D_DEBUG)
else ()
@@ -537,13 +550,13 @@ if (SLIC3R_PRUSACONTROL)
set(wxWidgets_UseAlienWx 1)
if (wxWidgets_UseAlienWx)
set(AlienWx_DEBUG 1)
- find_package(AlienWx REQUIRED COMPONENTS base core adv)
+ find_package(AlienWx REQUIRED COMPONENTS base core adv html)
include_directories(${AlienWx_INCLUDE_DIRS})
#add_compile_options(${AlienWx_CXX_FLAGS})
add_definitions(${AlienWx_DEFINITIONS})
set(wxWidgets_LIBRARIES ${AlienWx_LIBRARIES})
else ()
- find_package(wxWidgets REQUIRED COMPONENTS base core adv)
+ find_package(wxWidgets REQUIRED COMPONENTS base core adv html)
include(${wxWidgets_USE_FILE})
endif ()
add_definitions(-DSLIC3R_GUI -DSLIC3R_PRUS)
@@ -623,6 +636,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E copy "$" "${PERL_LOCAL_LIB_DIR}/auto/Slic3r/XS/"
COMMAND ${CMAKE_COMMAND} -E make_directory "${PERL_LOCAL_LIB_DIR}/Slic3r/"
COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/xs/lib/Slic3r/XS.pm" "${PERL_LOCAL_LIB_DIR}/Slic3r/"
+ COMMENT "Installing XS.pm and XS.{so,dll,bundle} into the local-lib directory ..."
)
if(APPLE)
add_custom_command(
@@ -647,7 +661,12 @@ endif ()
if (MSVC)
# Here we associate some additional properties with the MSVC project to enable compilation and debugging out of the box.
- set_target_properties(XS PROPERTIES VS_USER_PROPS "${PROJECT_SOURCE_DIR}/cmake/msvc/xs.wperl64d.props")
+ get_filename_component(PROPS_PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
+ string(REPLACE "/" "\\" PROPS_PERL_BIN_PATH "${PROPS_PERL_BIN_PATH}")
+ string(REPLACE "/" "\\" PROPS_PERL_EXECUTABLE "${PERL_EXECUTABLE}")
+ string(REPLACE "/" "\\" PROPS_CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}")
+ configure_file("${PROJECT_SOURCE_DIR}/cmake/msvc/xs.wperl.props.in" "${CMAKE_BINARY_DIR}/xs.wperl.props" NEWLINE_STYLE CRLF)
+ set_target_properties(XS PROPERTIES VS_USER_PROPS "${CMAKE_BINARY_DIR}/xs.wperl.props")
endif()
# l10n
diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm
index 47a584343e..06eb041dfb 100644
--- a/xs/lib/Slic3r/XS.pm
+++ b/xs/lib/Slic3r/XS.pm
@@ -12,7 +12,7 @@ our $VERSION = '0.01';
BEGIN {
if ($^O eq 'MSWin32') {
eval "use Wx";
-# eval "use Wx::Html";
+ eval "use Wx::Html";
eval "use Wx::Print"; # because of some Wx bug, thread creation fails if we don't have this (looks like Wx::Printout is hard-coded in some thread cleanup code)
}
}
diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp
index a4eaf3072a..8c1349e085 100644
--- a/xs/src/libslic3r/Config.cpp
+++ b/xs/src/libslic3r/Config.cpp
@@ -206,6 +206,44 @@ t_config_option_keys ConfigBase::diff(const ConfigBase &other) const
return diff;
}
+template
+void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys& vec, const ConfigBase &other, const ConfigBase *this_c)
+{
+ const T* opt_init = static_cast(other.option(opt_key));
+ const T* opt_cur = static_cast(this_c->option(opt_key));
+ int opt_init_max_id = opt_init->values.size() - 1;
+ for (int i = 0; i < opt_cur->values.size(); i++)
+ {
+ int init_id = i <= opt_init_max_id ? i : 0;
+ if (opt_cur->values[i] != opt_init->values[init_id])
+ vec.emplace_back(opt_key + "#" + std::to_string(i));
+ }
+}
+
+t_config_option_keys ConfigBase::deep_diff(const ConfigBase &other) const
+{
+ t_config_option_keys diff;
+ for (const t_config_option_key &opt_key : this->keys()) {
+ const ConfigOption *this_opt = this->option(opt_key);
+ const ConfigOption *other_opt = other.option(opt_key);
+ if (this_opt != nullptr && other_opt != nullptr && *this_opt != *other_opt)
+ {
+ if (opt_key == "bed_shape"){ diff.emplace_back(opt_key); continue; }
+ switch (other_opt->type())
+ {
+ case coInts: add_correct_opts_to_diff(opt_key, diff, other, this); break;
+ case coBools: add_correct_opts_to_diff(opt_key, diff, other, this); break;
+ case coFloats: add_correct_opts_to_diff(opt_key, diff, other, this); break;
+ case coStrings: add_correct_opts_to_diff(opt_key, diff, other, this); break;
+ case coPercents:add_correct_opts_to_diff(opt_key, diff, other, this); break;
+ case coPoints: add_correct_opts_to_diff(opt_key, diff, other, this); break;
+ default: diff.emplace_back(opt_key); break;
+ }
+ }
+ }
+ return diff;
+}
+
t_config_option_keys ConfigBase::equal(const ConfigBase &other) const
{
t_config_option_keys equal;
diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp
index 6eb307c5ce..14050c6cc5 100644
--- a/xs/src/libslic3r/Config.hpp
+++ b/xs/src/libslic3r/Config.hpp
@@ -659,6 +659,7 @@ public:
ConfigOptionPoints() : ConfigOptionVector() {}
explicit ConfigOptionPoints(size_t n, const Pointf &value) : ConfigOptionVector(n, value) {}
explicit ConfigOptionPoints(std::initializer_list il) : ConfigOptionVector(std::move(il)) {}
+ explicit ConfigOptionPoints(const std::vector &values) : ConfigOptionVector(values) {}
static ConfigOptionType static_type() { return coPoints; }
ConfigOptionType type() const override { return static_type(); }
@@ -1046,6 +1047,9 @@ public:
void apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false);
bool equals(const ConfigBase &other) const { return this->diff(other).empty(); }
t_config_option_keys diff(const ConfigBase &other) const;
+ // Use deep_diff to correct return of changed options,
+ // considering individual options for each extruder
+ t_config_option_keys deep_diff(const ConfigBase &other) const;
t_config_option_keys equal(const ConfigBase &other) const;
std::string serialize(const t_config_option_key &opt_key) const;
// Set a configuration value from a string, it will call an overridable handle_legacy()
diff --git a/xs/src/libslic3r/FileParserError.hpp b/xs/src/libslic3r/FileParserError.hpp
index 82a6b328e8..3f560fa4f5 100644
--- a/xs/src/libslic3r/FileParserError.hpp
+++ b/xs/src/libslic3r/FileParserError.hpp
@@ -4,6 +4,7 @@
#include "libslic3r.h"
#include
+#include
#include
namespace Slic3r {
@@ -15,6 +16,9 @@ public:
file_parser_error(const std::string &msg, const std::string &file, unsigned long line = 0) :
std::runtime_error(format_what(msg, file, line)),
m_message(msg), m_filename(file), m_line(line) {}
+ file_parser_error(const std::string &msg, const boost::filesystem::path &file, unsigned long line = 0) :
+ std::runtime_error(format_what(msg, file.string(), line)),
+ m_message(msg), m_filename(file.string()), m_line(line) {}
// gcc 3.4.2 complains about lack of throw specifier on compiler
// generated dtor
~file_parser_error() throw() {}
diff --git a/xs/src/libslic3r/Format/3mf.cpp b/xs/src/libslic3r/Format/3mf.cpp
index 7b5bf7e8a6..0467962c3d 100644
--- a/xs/src/libslic3r/Format/3mf.cpp
+++ b/xs/src/libslic3r/Format/3mf.cpp
@@ -16,6 +16,12 @@
#include
#include
+// VERSION NUMBERS
+// 0 : .3mf, files saved by older slic3r or other applications. No version definition in them.
+// 1 : Introduction of 3mf versioning. No other change in data saved into 3mf files.
+const unsigned int VERSION_3MF = 1;
+const char* SLIC3RPE_3MF_VERSION = "slic3rpe:Version3mf"; // definition of the metadata name saved into .model file
+
const std::string MODEL_FOLDER = "3D/";
const std::string MODEL_EXTENSION = ".model";
const std::string MODEL_FILE = "3D/3dmodel.model"; // << this is the only format of the string which works with CURA
@@ -23,6 +29,7 @@ const std::string CONTENT_TYPES_FILE = "[Content_Types].xml";
const std::string RELATIONSHIPS_FILE = "_rels/.rels";
const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config";
const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config";
+const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt";
const char* MODEL_TAG = "model";
const char* RESOURCES_TAG = "resources";
@@ -36,9 +43,9 @@ const char* COMPONENTS_TAG = "components";
const char* COMPONENT_TAG = "component";
const char* BUILD_TAG = "build";
const char* ITEM_TAG = "item";
+const char* METADATA_TAG = "metadata";
const char* CONFIG_TAG = "config";
-const char* METADATA_TAG = "metadata";
const char* VOLUME_TAG = "volume";
const char* UNIT_ATTR = "unit";
@@ -315,6 +322,10 @@ namespace Slic3r {
typedef std::vector InstancesList;
typedef std::map IdToMetadataMap;
typedef std::map IdToGeometryMap;
+ typedef std::map> IdToLayerHeightsProfileMap;
+
+ // Version of the 3mf file
+ unsigned int m_version;
XML_Parser m_xml_parser;
Model* m_model;
@@ -326,6 +337,9 @@ namespace Slic3r {
IdToGeometryMap m_geometries;
CurrentConfig m_curr_config;
IdToMetadataMap m_objects_metadata;
+ IdToLayerHeightsProfileMap m_layer_heights_profiles;
+ std::string m_curr_metadata_name;
+ std::string m_curr_characters;
public:
_3MF_Importer();
@@ -339,12 +353,14 @@ namespace Slic3r {
bool _load_model_from_file(const std::string& filename, Model& model, PresetBundle& bundle);
bool _extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);
- bool _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename);
+ void _extract_layer_heights_profile_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);
+ void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename);
bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model);
// handlers to parse the .model file
void _handle_start_model_xml_element(const char* name, const char** attributes);
void _handle_end_model_xml_element(const char* name);
+ void _handle_model_xml_characters(const XML_Char* s, int len);
// handlers to parse the MODEL_CONFIG_FILE file
void _handle_start_config_xml_element(const char* name, const char** attributes);
@@ -386,6 +402,9 @@ namespace Slic3r {
bool _handle_start_item(const char** attributes, unsigned int num_attributes);
bool _handle_end_item();
+ bool _handle_start_metadata(const char** attributes, unsigned int num_attributes);
+ bool _handle_end_metadata();
+
bool _create_object_instance(int object_id, const Matrix4x4& matrix, unsigned int recur_counter);
void _apply_transform(ModelInstance& instance, const Matrix4x4& matrix);
@@ -407,6 +426,7 @@ namespace Slic3r {
// callbacks to parse the .model file
static void XMLCALL _handle_start_model_xml_element(void* userData, const char* name, const char** attributes);
static void XMLCALL _handle_end_model_xml_element(void* userData, const char* name);
+ static void XMLCALL _handle_model_xml_characters(void* userData, const XML_Char* s, int len);
// callbacks to parse the MODEL_CONFIG_FILE file
static void XMLCALL _handle_start_config_xml_element(void* userData, const char* name, const char** attributes);
@@ -414,9 +434,12 @@ namespace Slic3r {
};
_3MF_Importer::_3MF_Importer()
- : m_xml_parser(nullptr)
+ : m_version(0)
+ , m_xml_parser(nullptr)
, m_model(nullptr)
, m_unit_factor(1.0f)
+ , m_curr_metadata_name("")
+ , m_curr_characters("")
{
}
@@ -427,6 +450,7 @@ namespace Slic3r {
bool _3MF_Importer::load_model_from_file(const std::string& filename, Model& model, PresetBundle& bundle)
{
+ m_version = 0;
m_model = &model;
m_unit_factor = 1.0f;
m_curr_object.reset();
@@ -437,6 +461,9 @@ namespace Slic3r {
m_curr_config.object_id = -1;
m_curr_config.volume_id = -1;
m_objects_metadata.clear();
+ m_layer_heights_profiles.clear();
+ m_curr_metadata_name.clear();
+ m_curr_characters.clear();
clear_errors();
return _load_model_from_file(filename, model, bundle);
@@ -472,6 +499,8 @@ namespace Slic3r {
mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
mz_zip_archive_file_stat stat;
+
+ // we first loop the entries to read from the archive the .model file only, in order to extract the version from it
for (mz_uint i = 0; i < num_entries; ++i)
{
if (mz_zip_reader_file_stat(&archive, i, &stat))
@@ -489,15 +518,26 @@ namespace Slic3r {
return false;
}
}
+ }
+ }
+
+ // we then loop again the entries to read other files stored in the archive
+ for (mz_uint i = 0; i < num_entries; ++i)
+ {
+ if (mz_zip_reader_file_stat(&archive, i, &stat))
+ {
+ std::string name(stat.m_filename);
+ std::replace(name.begin(), name.end(), '\\', '/');
+
+ if (boost::algorithm::iequals(name, LAYER_HEIGHTS_PROFILE_FILE))
+ {
+ // extract slic3r lazer heights profile file
+ _extract_layer_heights_profile_config_from_archive(archive, stat);
+ }
else if (boost::algorithm::iequals(name, PRINT_CONFIG_FILE))
{
// extract slic3r print config file
- if (!_extract_print_config_from_archive(archive, stat, bundle, filename))
- {
- mz_zip_reader_end(&archive);
- add_error("Archive does not contain a valid print config");
- return false;
- }
+ _extract_print_config_from_archive(archive, stat, bundle, filename);
}
else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE))
{
@@ -526,6 +566,13 @@ namespace Slic3r {
return false;
}
+ IdToLayerHeightsProfileMap::iterator obj_layer_heights_profile = m_layer_heights_profiles.find(object.first);
+ if (obj_layer_heights_profile != m_layer_heights_profiles.end())
+ {
+ object.second->layer_height_profile = obj_layer_heights_profile->second;
+ object.second->layer_height_profile_valid = true;
+ }
+
IdToMetadataMap::iterator obj_metadata = m_objects_metadata.find(object.first);
if (obj_metadata != m_objects_metadata.end())
{
@@ -583,6 +630,7 @@ namespace Slic3r {
XML_SetUserData(m_xml_parser, (void*)this);
XML_SetElementHandler(m_xml_parser, _3MF_Importer::_handle_start_model_xml_element, _3MF_Importer::_handle_end_model_xml_element);
+ XML_SetCharacterDataHandler(m_xml_parser, _3MF_Importer::_handle_model_xml_characters);
void* parser_buffer = XML_GetBuffer(m_xml_parser, (int)stat.m_uncomp_size);
if (parser_buffer == nullptr)
@@ -609,23 +657,90 @@ namespace Slic3r {
return true;
}
- bool _3MF_Importer::_extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename)
+ void _3MF_Importer::_extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename)
{
if (stat.m_uncomp_size > 0)
{
- std::vector buffer((size_t)stat.m_uncomp_size + 1, 0);
+ std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0)
{
add_error("Error while reading config data to buffer");
- return false;
+ return;
}
-
- buffer.back() = '\0';
bundle.load_config_string(buffer.data(), archive_filename.c_str());
}
+ }
- return true;
+ void _3MF_Importer::_extract_layer_heights_profile_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat)
+ {
+ if (stat.m_uncomp_size > 0)
+ {
+ std::string buffer((size_t)stat.m_uncomp_size, 0);
+ mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
+ if (res == 0)
+ {
+ add_error("Error while reading layer heights profile data to buffer");
+ return;
+ }
+
+ if (buffer.back() == '\n')
+ buffer.pop_back();
+
+ std::vector objects;
+ boost::split(objects, buffer, boost::is_any_of("\n"), boost::token_compress_off);
+
+ for (const std::string& object : objects)
+ {
+ std::vector object_data;
+ boost::split(object_data, object, boost::is_any_of("|"), boost::token_compress_off);
+ if (object_data.size() != 2)
+ {
+ add_error("Error while reading object data");
+ continue;
+ }
+
+ std::vector object_data_id;
+ boost::split(object_data_id, object_data[0], boost::is_any_of("="), boost::token_compress_off);
+ if (object_data_id.size() != 2)
+ {
+ add_error("Error while reading object id");
+ continue;
+ }
+
+ int object_id = std::atoi(object_data_id[1].c_str());
+ if (object_id == 0)
+ {
+ add_error("Found invalid object id");
+ continue;
+ }
+
+ IdToLayerHeightsProfileMap::iterator object_item = m_layer_heights_profiles.find(object_id);
+ if (object_item != m_layer_heights_profiles.end())
+ {
+ add_error("Found duplicated layer heights profile");
+ continue;
+ }
+
+ std::vector object_data_profile;
+ boost::split(object_data_profile, object_data[1], boost::is_any_of(";"), boost::token_compress_off);
+ if ((object_data_profile.size() <= 4) || (object_data_profile.size() % 2 != 0))
+ {
+ add_error("Found invalid layer heights profile");
+ continue;
+ }
+
+ std::vector profile;
+ profile.reserve(object_data_profile.size());
+
+ for (const std::string& value : object_data_profile)
+ {
+ profile.push_back((coordf_t)std::atof(value.c_str()));
+ }
+
+ m_layer_heights_profiles.insert(IdToLayerHeightsProfileMap::value_type(object_id, profile));
+ }
+ }
}
bool _3MF_Importer::_extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model)
@@ -705,6 +820,8 @@ namespace Slic3r {
res = _handle_start_build(attributes, num_attributes);
else if (::strcmp(ITEM_TAG, name) == 0)
res = _handle_start_item(attributes, num_attributes);
+ else if (::strcmp(METADATA_TAG, name) == 0)
+ res = _handle_start_metadata(attributes, num_attributes);
if (!res)
_stop_xml_parser();
@@ -741,11 +858,18 @@ namespace Slic3r {
res = _handle_end_build();
else if (::strcmp(ITEM_TAG, name) == 0)
res = _handle_end_item();
+ else if (::strcmp(METADATA_TAG, name) == 0)
+ res = _handle_end_metadata();
if (!res)
_stop_xml_parser();
}
+ void _3MF_Importer::_handle_model_xml_characters(const XML_Char* s, int len)
+ {
+ m_curr_characters.append(s, len);
+ }
+
void _3MF_Importer::_handle_start_config_xml_element(const char* name, const char** attributes)
{
if (m_xml_parser == nullptr)
@@ -1052,6 +1176,25 @@ namespace Slic3r {
return true;
}
+ bool _3MF_Importer::_handle_start_metadata(const char** attributes, unsigned int num_attributes)
+ {
+ m_curr_characters.clear();
+
+ std::string name = get_attribute_value_string(attributes, num_attributes, NAME_ATTR);
+ if (!name.empty())
+ m_curr_metadata_name = name;
+
+ return true;
+ }
+
+ bool _3MF_Importer::_handle_end_metadata()
+ {
+ if (m_curr_metadata_name == SLIC3RPE_3MF_VERSION)
+ m_version = (unsigned int)atoi(m_curr_characters.c_str());
+
+ return true;
+ }
+
bool _3MF_Importer::_create_object_instance(int object_id, const Matrix4x4& matrix, unsigned int recur_counter)
{
static const unsigned int MAX_RECURSIONS = 10;
@@ -1358,6 +1501,13 @@ namespace Slic3r {
importer->_handle_end_model_xml_element(name);
}
+ void XMLCALL _3MF_Importer::_handle_model_xml_characters(void* userData, const XML_Char* s, int len)
+ {
+ _3MF_Importer* importer = (_3MF_Importer*)userData;
+ if (importer != nullptr)
+ importer->_handle_model_xml_characters(s, len);
+ }
+
void XMLCALL _3MF_Importer::_handle_start_config_xml_element(void* userData, const char* name, const char** attributes)
{
_3MF_Importer* importer = (_3MF_Importer*)userData;
@@ -1429,6 +1579,7 @@ namespace Slic3r {
bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets);
bool _add_mesh_to_object_stream(std::stringstream& stream, ModelObject& object, VolumeToOffsetsMap& volumes_offsets);
bool _add_build_to_model_stream(std::stringstream& stream, const BuildItemsList& build_items);
+ bool _add_layer_height_profile_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_print_config_file_to_archive(mz_zip_archive& archive, const Print& print);
bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model);
};
@@ -1477,6 +1628,14 @@ namespace Slic3r {
return false;
}
+ // adds layer height profile file
+ if (!_add_layer_height_profile_file_to_archive(archive, model))
+ {
+ mz_zip_writer_end(&archive);
+ boost::filesystem::remove(filename);
+ return false;
+ }
+
// adds slic3r print config file
if (export_print_config)
{
@@ -1552,7 +1711,8 @@ namespace Slic3r {
{
std::stringstream stream;
stream << "\n";
- stream << "<" << MODEL_TAG << " unit=\"millimeter\" xml:lang=\"en-US\" xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">\n";
+ stream << "<" << MODEL_TAG << " unit=\"millimeter\" xml:lang=\"en-US\" xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\" xmlns:slic3rpe=\"http://schemas.slic3r.org/3mf/2017/06\">\n";
+ stream << " <" << METADATA_TAG << " name=\"" << SLIC3RPE_3MF_VERSION << "\">" << VERSION_3MF << "" << METADATA_TAG << ">\n";
stream << " <" << RESOURCES_TAG << ">\n";
BuildItemsList build_items;
@@ -1736,6 +1896,44 @@ namespace Slic3r {
return true;
}
+ bool _3MF_Exporter::_add_layer_height_profile_file_to_archive(mz_zip_archive& archive, Model& model)
+ {
+ std::string out = "";
+ char buffer[1024];
+
+ unsigned int count = 0;
+ for (const ModelObject* object : model.objects)
+ {
+ ++count;
+ std::vector layer_height_profile = object->layer_height_profile_valid ? object->layer_height_profile : std::vector();
+ if ((layer_height_profile.size() >= 4) && ((layer_height_profile.size() % 2) == 0))
+ {
+ sprintf(buffer, "object_id=%d|", count);
+ out += buffer;
+
+ // Store the layer height profile as a single semicolon separated list.
+ for (size_t i = 0; i < layer_height_profile.size(); ++i)
+ {
+ sprintf(buffer, (i == 0) ? "%f" : ";%f", layer_height_profile[i]);
+ out += buffer;
+ }
+
+ out += "\n";
+ }
+ }
+
+ if (!out.empty())
+ {
+ if (!mz_zip_writer_add_mem(&archive, LAYER_HEIGHTS_PROFILE_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
+ {
+ add_error("Unable to add layer heights profile file to archive");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
bool _3MF_Exporter::_add_print_config_file_to_archive(mz_zip_archive& archive, const Print& print)
{
char buffer[1024];
@@ -1744,10 +1942,13 @@ namespace Slic3r {
GCode::append_full_config(print, out);
- if (!mz_zip_writer_add_mem(&archive, PRINT_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
+ if (!out.empty())
{
- add_error("Unable to add print config file to archive");
- return false;
+ if (!mz_zip_writer_add_mem(&archive, PRINT_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
+ {
+ add_error("Unable to add print config file to archive");
+ return false;
+ }
}
return true;
@@ -1832,10 +2033,7 @@ namespace Slic3r {
_3MF_Importer importer;
bool res = importer.load_model_from_file(path, *model, *bundle);
-
- if (!res)
- importer.log_errors();
-
+ importer.log_errors();
return res;
}
diff --git a/xs/src/libslic3r/Format/AMF.cpp b/xs/src/libslic3r/Format/AMF.cpp
index 98683cd8aa..b446f456b2 100644
--- a/xs/src/libslic3r/Format/AMF.cpp
+++ b/xs/src/libslic3r/Format/AMF.cpp
@@ -24,6 +24,12 @@
#include
+// VERSION NUMBERS
+// 0 : .amf, .amf.xml and .zip.amf files saved by older slic3r. No version definition in them.
+// 1 : Introduction of amf versioning. No other change in data saved into amf files.
+const unsigned int VERSION_AMF = 1;
+const char* SLIC3RPE_AMF_VERSION = "slic3rpe_amf_version";
+
const char* SLIC3R_CONFIG_TYPE = "slic3rpe_config";
namespace Slic3r
@@ -32,6 +38,7 @@ namespace Slic3r
struct AMFParserContext
{
AMFParserContext(XML_Parser parser, const std::string& archive_filename, PresetBundle* preset_bundle, Model *model) :
+ m_version(0),
m_parser(parser),
m_model(*model),
m_object(nullptr),
@@ -137,6 +144,8 @@ struct AMFParserContext
std::vector instances;
};
+ // Version of the amf file
+ unsigned int m_version;
// Current Expat XML parser instance.
XML_Parser m_parser;
// Model to receive objects extracted from an AMF file.
@@ -360,9 +369,9 @@ void AMFParserContext::endElement(const char * /* name */)
case NODE_TYPE_VERTEX:
assert(m_object);
// Parse the vertex data
- m_object_vertices.emplace_back(atof(m_value[0].c_str()));
- m_object_vertices.emplace_back(atof(m_value[1].c_str()));
- m_object_vertices.emplace_back(atof(m_value[2].c_str()));
+ m_object_vertices.emplace_back((float)atof(m_value[0].c_str()));
+ m_object_vertices.emplace_back((float)atof(m_value[1].c_str()));
+ m_object_vertices.emplace_back((float)atof(m_value[2].c_str()));
m_value[0].clear();
m_value[1].clear();
m_value[2].clear();
@@ -462,6 +471,10 @@ void AMFParserContext::endElement(const char * /* name */)
if (m_volume && m_value[0] == "name")
m_volume->name = std::move(m_value[1]);
}
+ else if (strncmp(m_value[0].c_str(), SLIC3RPE_AMF_VERSION, strlen(SLIC3RPE_AMF_VERSION)) == 0) {
+ m_version = (unsigned int)atoi(m_value[1].c_str());
+ }
+
m_value[0].clear();
m_value[1].clear();
break;
@@ -543,46 +556,8 @@ bool load_amf_file(const char *path, PresetBundle* bundle, Model *model)
return result;
}
-// Load an AMF archive into a provided model.
-bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
+bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, const char* path, PresetBundle* bundle, Model* model, unsigned int& version)
{
- if ((path == nullptr) || (model == nullptr))
- return false;
-
- mz_zip_archive archive;
- mz_zip_zero_struct(&archive);
-
- mz_bool res = mz_zip_reader_init_file(&archive, path, 0);
- if (res == 0)
- {
- printf("Unable to init zip reader\n");
- return false;
- }
-
- mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
- if (num_entries != 1)
- {
- printf("Found invalid number of entries\n");
- mz_zip_reader_end(&archive);
- return false;
- }
-
- mz_zip_archive_file_stat stat;
- res = mz_zip_reader_file_stat(&archive, 0, &stat);
- if (res == 0)
- {
- printf("Unable to extract entry statistics\n");
- mz_zip_reader_end(&archive);
- return false;
- }
-
- if (!boost::iends_with(stat.m_filename, ".amf"))
- {
- printf("Found invalid internal filename\n");
- mz_zip_reader_end(&archive);
- return false;
- }
-
if (stat.m_uncomp_size == 0)
{
printf("Found invalid size\n");
@@ -610,7 +585,7 @@ bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
return false;
}
- res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t)stat.m_uncomp_size, 0);
+ mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t)stat.m_uncomp_size, 0);
if (res == 0)
{
printf("Error while reading model data to buffer\n");
@@ -627,6 +602,62 @@ bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
ctx.endDocument();
+ version = ctx.m_version;
+
+ return true;
+}
+
+// Load an AMF archive into a provided model.
+bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
+{
+ if ((path == nullptr) || (model == nullptr))
+ return false;
+
+ unsigned int version = 0;
+
+ mz_zip_archive archive;
+ mz_zip_zero_struct(&archive);
+
+ mz_bool res = mz_zip_reader_init_file(&archive, path, 0);
+ if (res == 0)
+ {
+ printf("Unable to init zip reader\n");
+ return false;
+ }
+
+ mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
+
+ mz_zip_archive_file_stat stat;
+ // we first loop the entries to read from the archive the .amf file only, in order to extract the version from it
+ for (mz_uint i = 0; i < num_entries; ++i)
+ {
+ if (mz_zip_reader_file_stat(&archive, i, &stat))
+ {
+ if (boost::iends_with(stat.m_filename, ".amf"))
+ {
+ if (!extract_model_from_archive(archive, stat, path, bundle, model, version))
+ {
+ mz_zip_reader_end(&archive);
+ printf("Archive does not contain a valid model");
+ return false;
+ }
+
+ break;
+ }
+ }
+ }
+
+#if 0 // forward compatibility
+ // we then loop again the entries to read other files stored in the archive
+ for (mz_uint i = 0; i < num_entries; ++i)
+ {
+ if (mz_zip_reader_file_stat(&archive, i, &stat))
+ {
+ // add code to extract the file
+ }
+ }
+#endif // forward compatibility
+
mz_zip_reader_end(&archive);
return true;
}
@@ -664,6 +695,7 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c
stream << "\n";
stream << "\n";
stream << "Slic3r " << SLIC3R_VERSION << "\n";
+ stream << "" << VERSION_AMF << "\n";
if (export_print_config)
{
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp
index 8ad479532b..dc8e5d6918 100644
--- a/xs/src/libslic3r/GCode.cpp
+++ b/xs/src/libslic3r/GCode.cpp
@@ -1287,6 +1287,10 @@ void GCode::process_layer(
m_wipe_tower->tool_change(*this, extruder_id, extruder_id == layer_tools.extruders.back()) :
this->set_extruder(extruder_id);
+ // let analyzer tag generator aware of a role type change
+ if (m_enable_analyzer && layer_tools.has_wipe_tower && m_wipe_tower)
+ m_last_analyzer_extrusion_role = erWipeTower;
+
if (extrude_skirt) {
auto loops_it = skirt_loops_per_extruder.find(extruder_id);
if (loops_it != skirt_loops_per_extruder.end()) {
@@ -2170,7 +2174,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
double F = speed * 60; // convert mm/sec to mm/min
// extrude arc or line
- if (m_enable_extrusion_role_markers || m_enable_analyzer)
+ if (m_enable_extrusion_role_markers)
{
if (path.role() != m_last_extrusion_role)
{
@@ -2181,18 +2185,20 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
sprintf(buf, ";_EXTRUSION_ROLE:%d\n", int(m_last_extrusion_role));
gcode += buf;
}
- if (m_enable_analyzer)
- {
- char buf[32];
- sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_extrusion_role));
- gcode += buf;
- }
}
}
// adds analyzer tags and updates analyzer's tracking data
if (m_enable_analyzer)
{
+ if (path.role() != m_last_analyzer_extrusion_role)
+ {
+ m_last_analyzer_extrusion_role = path.role();
+ char buf[32];
+ sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role));
+ gcode += buf;
+ }
+
if (m_last_mm3_per_mm != path.mm3_per_mm)
{
m_last_mm3_per_mm = path.mm3_per_mm;
@@ -2230,6 +2236,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (path.role() == erExternalPerimeter)
comment += ";_EXTERNAL_PERIMETER";
}
+
// F is mm per minute.
gcode += m_writer.set_speed(F, "", comment);
double path_length = 0.;
diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp
index 968cd14dec..d028e90aac 100644
--- a/xs/src/libslic3r/GCode.hpp
+++ b/xs/src/libslic3r/GCode.hpp
@@ -121,6 +121,7 @@ public:
m_enable_cooling_markers(false),
m_enable_extrusion_role_markers(false),
m_enable_analyzer(false),
+ m_last_analyzer_extrusion_role(erNone),
m_layer_count(0),
m_layer_index(-1),
m_layer(nullptr),
@@ -253,6 +254,7 @@ protected:
// Extended markers will be added during G-code generation.
// The G-code Analyzer will remove these comments from the final G-code.
bool m_enable_analyzer;
+ ExtrusionRole m_last_analyzer_extrusion_role;
// How many times will change_layer() be called?
// change_layer() will update the progress bar.
unsigned int m_layer_count;
diff --git a/xs/src/libslic3r/GCode/Analyzer.cpp b/xs/src/libslic3r/GCode/Analyzer.cpp
index 799bd6661e..b7ecee5a4c 100644
--- a/xs/src/libslic3r/GCode/Analyzer.cpp
+++ b/xs/src/libslic3r/GCode/Analyzer.cpp
@@ -718,10 +718,10 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
Helper::store_polyline(polyline, data, z, preview_data);
// updates preview ranges data
- preview_data.ranges.height.set_from(height_range);
- preview_data.ranges.width.set_from(width_range);
- preview_data.ranges.feedrate.set_from(feedrate_range);
- preview_data.ranges.volumetric_rate.set_from(volumetric_rate_range);
+ preview_data.ranges.height.update_from(height_range);
+ preview_data.ranges.width.update_from(width_range);
+ preview_data.ranges.feedrate.update_from(feedrate_range);
+ preview_data.ranges.volumetric_rate.update_from(volumetric_rate_range);
}
void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
@@ -790,9 +790,9 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
Helper::store_polyline(polyline, type, direction, feedrate, extruder_id, preview_data);
// updates preview ranges data
- preview_data.ranges.height.set_from(height_range);
- preview_data.ranges.width.set_from(width_range);
- preview_data.ranges.feedrate.set_from(feedrate_range);
+ preview_data.ranges.height.update_from(height_range);
+ preview_data.ranges.width.update_from(width_range);
+ preview_data.ranges.feedrate.update_from(feedrate_range);
}
void GCodeAnalyzer::_calc_gcode_preview_retractions(GCodePreviewData& preview_data)
diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.cpp b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
index cd2baeffbd..a15247693c 100644
--- a/xs/src/libslic3r/GCode/CoolingBuffer.cpp
+++ b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
@@ -30,359 +30,579 @@ void CoolingBuffer::reset()
m_current_pos[4] = float(m_gcodegen.config().travel_speed.value);
}
-#define EXTRUDER_CONFIG(OPT) config.OPT.get_at(m_current_extruder)
+struct CoolingLine
+{
+ enum Type {
+ TYPE_SET_TOOL = 1 << 0,
+ TYPE_EXTRUDE_END = 1 << 1,
+ TYPE_BRIDGE_FAN_START = 1 << 2,
+ TYPE_BRIDGE_FAN_END = 1 << 3,
+ TYPE_G0 = 1 << 4,
+ TYPE_G1 = 1 << 5,
+ TYPE_ADJUSTABLE = 1 << 6,
+ TYPE_EXTERNAL_PERIMETER = 1 << 7,
+ // The line sets a feedrate.
+ TYPE_HAS_F = 1 << 8,
+ TYPE_WIPE = 1 << 9,
+ TYPE_G4 = 1 << 10,
+ TYPE_G92 = 1 << 11,
+ };
+
+ CoolingLine(unsigned int type, size_t line_start, size_t line_end) :
+ type(type), line_start(line_start), line_end(line_end),
+ length(0.f), feedrate(0.f), time(0.f), time_max(0.f), slowdown(false) {}
+
+ bool adjustable(bool slowdown_external_perimeters) const {
+ return (this->type & TYPE_ADJUSTABLE) &&
+ (! (this->type & TYPE_EXTERNAL_PERIMETER) || slowdown_external_perimeters) &&
+ this->time < this->time_max;
+ }
+
+ bool adjustable() const {
+ return (this->type & TYPE_ADJUSTABLE) && this->time < this->time_max;
+ }
+
+ size_t type;
+ // Start of this line at the G-code snippet.
+ size_t line_start;
+ // End of this line at the G-code snippet.
+ size_t line_end;
+ // XY Euclidian length of this segment.
+ float length;
+ // Current feedrate, possibly adjusted.
+ float feedrate;
+ // Current duration of this segment.
+ float time;
+ // Maximum duration of this segment.
+ float time_max;
+ // If marked with the "slowdown" flag, the line has been slowed down.
+ bool slowdown;
+};
+
+// Calculate the required per extruder time stretches.
+struct PerExtruderAdjustments
+{
+ // Calculate the total elapsed time per this extruder, adjusted for the slowdown.
+ float elapsed_time_total() {
+ float time_total = 0.f;
+ for (const CoolingLine &line : lines)
+ time_total += line.time;
+ return time_total;
+ }
+ // Calculate the total elapsed time when slowing down
+ // to the minimum extrusion feed rate defined for the current material.
+ float maximum_time_after_slowdown(bool slowdown_external_perimeters) {
+ float time_total = 0.f;
+ for (const CoolingLine &line : lines)
+ if (line.adjustable(slowdown_external_perimeters)) {
+ if (line.time_max == FLT_MAX)
+ return FLT_MAX;
+ else
+ time_total += line.time_max;
+ } else
+ time_total += line.time;
+ return time_total;
+ }
+ // Calculate the adjustable part of the total time.
+ float adjustable_time(bool slowdown_external_perimeters) {
+ float time_total = 0.f;
+ for (const CoolingLine &line : lines)
+ if (line.adjustable(slowdown_external_perimeters))
+ time_total += line.time;
+ return time_total;
+ }
+ // Calculate the non-adjustable part of the total time.
+ float non_adjustable_time(bool slowdown_external_perimeters) {
+ float time_total = 0.f;
+ for (const CoolingLine &line : lines)
+ if (! line.adjustable(slowdown_external_perimeters))
+ time_total += line.time;
+ return time_total;
+ }
+ // Slow down the adjustable extrusions to the minimum feedrate allowed for the current extruder material.
+ // Used by both proportional and non-proportional slow down.
+ float slowdown_to_minimum_feedrate(bool slowdown_external_perimeters) {
+ float time_total = 0.f;
+ for (CoolingLine &line : lines) {
+ if (line.adjustable(slowdown_external_perimeters)) {
+ assert(line.time_max >= 0.f && line.time_max < FLT_MAX);
+ line.slowdown = true;
+ line.time = line.time_max;
+ line.feedrate = line.length / line.time;
+ }
+ time_total += line.time;
+ }
+ return time_total;
+ }
+ // Slow down each adjustable G-code line proportionally by a factor.
+ // Used by the proportional slow down.
+ float slow_down_proportional(float factor, bool slowdown_external_perimeters) {
+ assert(factor >= 1.f);
+ float time_total = 0.f;
+ for (CoolingLine &line : lines) {
+ if (line.adjustable(slowdown_external_perimeters)) {
+ line.slowdown = true;
+ line.time = std::min(line.time_max, line.time * factor);
+ line.feedrate = line.length / line.time;
+ }
+ time_total += line.time;
+ }
+ return time_total;
+ }
+
+ // Sort the lines, adjustable first, higher feedrate first.
+ // Used by non-proportional slow down.
+ void sort_lines_by_decreasing_feedrate() {
+ std::sort(lines.begin(), lines.end(), [](const CoolingLine &l1, const CoolingLine &l2) {
+ bool adj1 = l1.adjustable();
+ bool adj2 = l2.adjustable();
+ return (adj1 == adj2) ? l1.feedrate > l2.feedrate : adj1;
+ });
+ for (n_lines_adjustable = 0;
+ n_lines_adjustable < lines.size() && this->lines[n_lines_adjustable].adjustable();
+ ++ n_lines_adjustable);
+ time_non_adjustable = 0.f;
+ for (size_t i = n_lines_adjustable; i < lines.size(); ++ i)
+ time_non_adjustable += lines[i].time;
+ }
+
+ // Calculate the maximum time stretch when slowing down to min_feedrate.
+ // Slowdown to min_feedrate shall be allowed for this extruder's material.
+ // Used by non-proportional slow down.
+ float time_stretch_when_slowing_down_to_feedrate(float min_feedrate) {
+ float time_stretch = 0.f;
+ assert(this->min_print_speed < min_feedrate + EPSILON);
+ for (size_t i = 0; i < n_lines_adjustable; ++ i) {
+ const CoolingLine &line = lines[i];
+ if (line.feedrate > min_feedrate)
+ time_stretch += line.time * (line.feedrate / min_feedrate - 1.f);
+ }
+ return time_stretch;
+ }
+
+ // Slow down all adjustable lines down to min_feedrate.
+ // Slowdown to min_feedrate shall be allowed for this extruder's material.
+ // Used by non-proportional slow down.
+ void slow_down_to_feedrate(float min_feedrate) {
+ assert(this->min_print_speed < min_feedrate + EPSILON);
+ for (size_t i = 0; i < n_lines_adjustable; ++ i) {
+ CoolingLine &line = lines[i];
+ if (line.feedrate > min_feedrate) {
+ line.time *= std::max(1.f, line.feedrate / min_feedrate);
+ line.feedrate = min_feedrate;
+ line.slowdown = true;
+ }
+ }
+ }
+
+ // Extruder, for which the G-code will be adjusted.
+ unsigned int extruder_id = 0;
+ // Is the cooling slow down logic enabled for this extruder's material?
+ bool cooling_slow_down_enabled = false;
+ // Slow down the print down to min_print_speed if the total layer time is below slowdown_below_layer_time.
+ float slowdown_below_layer_time = 0.f;
+ // Minimum print speed allowed for this extruder.
+ float min_print_speed = 0.f;
+
+ // Parsed lines.
+ std::vector lines;
+ // The following two values are set by sort_lines_by_decreasing_feedrate():
+ // Number of adjustable lines, at the start of lines.
+ size_t n_lines_adjustable = 0;
+ // Non-adjustable time of lines starting with n_lines_adjustable.
+ float time_non_adjustable = 0;
+ // Current total time for this extruder.
+ float time_total = 0;
+ // Maximum time for this extruder, when the maximum slow down is applied.
+ float time_maximum = 0;
+
+ // Temporaries for processing the slow down. Both thresholds go from 0 to n_lines_adjustable.
+ size_t idx_line_begin = 0;
+ size_t idx_line_end = 0;
+};
std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id)
+{
+ std::vector per_extruder_adjustments = this->parse_layer_gcode(gcode, m_current_pos);
+ float layer_time_stretched = this->calculate_layer_slowdown(per_extruder_adjustments);
+ return this->apply_layer_cooldown(gcode, layer_id, layer_time_stretched, per_extruder_adjustments);
+}
+
+// Parse the layer G-code for the moves, which could be adjusted.
+// Return the list of parsed lines, bucketed by an extruder.
+std::vector CoolingBuffer::parse_layer_gcode(const std::string &gcode, std::vector ¤t_pos) const
{
const FullPrintConfig &config = m_gcodegen.config();
const std::vector &extruders = m_gcodegen.writer().extruders();
- const size_t num_extruders = extruders.size();
-
- // Calculate the required per extruder time stretches.
- struct Adjustment {
- Adjustment(unsigned int extruder_id = 0) : extruder_id(extruder_id) {}
- // Calculate the total elapsed time per this extruder, adjusted for the slowdown.
- float elapsed_time_total() {
- float time_total = 0.f;
- for (const Line &line : lines)
- time_total += line.time;
- return time_total;
- }
- // Calculate the maximum time when slowing down.
- float maximum_time(bool slowdown_external_perimeters) {
- float time_total = 0.f;
- for (const Line &line : lines)
- if (line.adjustable(slowdown_external_perimeters)) {
- if (line.time_max == FLT_MAX)
- return FLT_MAX;
- else
- time_total += line.time_max;
- } else
- time_total += line.time;
- return time_total;
- }
- // Calculate the non-adjustable part of the total time.
- float non_adjustable_time(bool slowdown_external_perimeters) {
- float time_total = 0.f;
- for (const Line &line : lines)
- if (! line.adjustable(slowdown_external_perimeters))
- time_total += line.time;
- return time_total;
- }
- float slow_down_maximum(bool slowdown_external_perimeters) {
- float time_total = 0.f;
- for (Line &line : lines) {
- if (line.adjustable(slowdown_external_perimeters)) {
- assert(line.time_max >= 0.f && line.time_max < FLT_MAX);
- line.slowdown = true;
- line.time = line.time_max;
- }
- time_total += line.time;
- }
- return time_total;
- }
- float slow_down_proportional(float factor, bool slowdown_external_perimeters) {
- assert(factor >= 1.f);
- float time_total = 0.f;
- for (Line &line : lines) {
- if (line.adjustable(slowdown_external_perimeters)) {
- line.slowdown = true;
- line.time = std::min(line.time_max, line.time * factor);
- }
- time_total += line.time;
- }
- return time_total;
- }
-
- bool operator<(const Adjustment &rhs) const { return this->extruder_id < rhs.extruder_id; }
-
- struct Line
- {
- enum Type {
- TYPE_SET_TOOL = 1 << 0,
- TYPE_EXTRUDE_END = 1 << 1,
- TYPE_BRIDGE_FAN_START = 1 << 2,
- TYPE_BRIDGE_FAN_END = 1 << 3,
- TYPE_G0 = 1 << 4,
- TYPE_G1 = 1 << 5,
- TYPE_ADJUSTABLE = 1 << 6,
- TYPE_EXTERNAL_PERIMETER = 1 << 7,
- // The line sets a feedrate.
- TYPE_HAS_F = 1 << 8,
- TYPE_WIPE = 1 << 9,
- TYPE_G4 = 1 << 10,
- TYPE_G92 = 1 << 11,
- };
-
- Line(unsigned int type, size_t line_start, size_t line_end) :
- type(type), line_start(line_start), line_end(line_end),
- length(0.f), time(0.f), time_max(0.f), slowdown(false) {}
-
- bool adjustable(bool slowdown_external_perimeters) const {
- return (this->type & TYPE_ADJUSTABLE) &&
- (! (this->type & TYPE_EXTERNAL_PERIMETER) || slowdown_external_perimeters) &&
- this->time < this->time_max;
- }
-
- size_t type;
- // Start of this line at the G-code snippet.
- size_t line_start;
- // End of this line at the G-code snippet.
- size_t line_end;
- // XY Euclidian length of this segment.
- float length;
- // Current duration of this segment.
- float time;
- // Maximum duration of this segment.
- float time_max;
- // If marked with the "slowdown" flag, the line has been slowed down.
- bool slowdown;
- };
-
- // Extruder, for which the G-code will be adjusted.
- unsigned int extruder_id;
- // Parsed lines.
- std::vector lines;
- };
- std::vector adjustments(num_extruders, Adjustment());
- for (size_t i = 0; i < num_extruders; ++ i)
- adjustments[i].extruder_id = extruders[i].id();
- const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix();
- // Parse the layer G-code for the moves, which could be adjusted.
- {
- float min_print_speed = float(EXTRUDER_CONFIG(min_print_speed));
- auto adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder));
- unsigned int initial_extruder = m_current_extruder;
- const char *line_start = gcode.c_str();
- const char *line_end = line_start;
- const char extrusion_axis = config.get_extrusion_axis()[0];
- // Index of an existing Adjustment::Line of the current adjustment, which holds the feedrate setting command
- // for a sequence of extrusion moves.
- size_t active_speed_modifier = size_t(-1);
- for (; *line_start != 0; line_start = line_end) {
- while (*line_end != '\n' && *line_end != 0)
- ++ line_end;
- // sline will not contain the trailing '\n'.
- std::string sline(line_start, line_end);
- // Adjustment::Line will contain the trailing '\n'.
- if (*line_end == '\n')
- ++ line_end;
- Adjustment::Line line(0, line_start - gcode.c_str(), line_end - gcode.c_str());
- if (boost::starts_with(sline, "G0 "))
- line.type = Adjustment::Line::TYPE_G0;
- else if (boost::starts_with(sline, "G1 "))
- line.type = Adjustment::Line::TYPE_G1;
- else if (boost::starts_with(sline, "G92 "))
- line.type = Adjustment::Line::TYPE_G92;
- if (line.type) {
- // G0, G1 or G92
- // Parse the G-code line.
- std::vector new_pos(m_current_pos);
- const char *c = sline.data() + 3;
- for (;;) {
- // Skip whitespaces.
- for (; *c == ' ' || *c == '\t'; ++ c);
- if (*c == 0 || *c == ';')
- break;
- // Parse the axis.
- size_t axis = (*c >= 'X' && *c <= 'Z') ? (*c - 'X') :
- (*c == extrusion_axis) ? 3 : (*c == 'F') ? 4 : size_t(-1);
- if (axis != size_t(-1)) {
- new_pos[axis] = float(atof(++c));
- if (axis == 4) {
- // Convert mm/min to mm/sec.
- new_pos[4] /= 60.f;
- if ((line.type & Adjustment::Line::TYPE_G92) == 0)
- // This is G0 or G1 line and it sets the feedrate. This mark is used for reducing the duplicate F calls.
- line.type |= Adjustment::Line::TYPE_HAS_F;
- }
- }
- // Skip this word.
- for (; *c != ' ' && *c != '\t' && *c != 0; ++ c);
- }
- bool external_perimeter = boost::contains(sline, ";_EXTERNAL_PERIMETER");
- bool wipe = boost::contains(sline, ";_WIPE");
- if (external_perimeter)
- line.type |= Adjustment::Line::TYPE_EXTERNAL_PERIMETER;
- if (wipe)
- line.type |= Adjustment::Line::TYPE_WIPE;
- if (boost::contains(sline, ";_EXTRUDE_SET_SPEED") && ! wipe) {
- line.type |= Adjustment::Line::TYPE_ADJUSTABLE;
- active_speed_modifier = adjustment->lines.size();
- }
- if ((line.type & Adjustment::Line::TYPE_G92) == 0) {
- // G0 or G1. Calculate the duration.
- if (config.use_relative_e_distances.value)
- // Reset extruder accumulator.
- m_current_pos[3] = 0.f;
- float dif[4];
- for (size_t i = 0; i < 4; ++ i)
- dif[i] = new_pos[i] - m_current_pos[i];
- float dxy2 = dif[0] * dif[0] + dif[1] * dif[1];
- float dxyz2 = dxy2 + dif[2] * dif[2];
- if (dxyz2 > 0.f) {
- // Movement in xyz, calculate time from the xyz Euclidian distance.
- line.length = sqrt(dxyz2);
- } else if (std::abs(dif[3]) > 0.f) {
- // Movement in the extruder axis.
- line.length = std::abs(dif[3]);
- }
- if (line.length > 0)
- line.time = line.length / new_pos[4]; // current F
- line.time_max = line.time;
- if ((line.type & Adjustment::Line::TYPE_ADJUSTABLE) || active_speed_modifier != size_t(-1))
- line.time_max = (min_print_speed == 0.f) ? FLT_MAX : std::max(line.time, line.length / min_print_speed);
- if (active_speed_modifier < adjustment->lines.size() && (line.type & Adjustment::Line::TYPE_G1)) {
- // Inside the ";_EXTRUDE_SET_SPEED" blocks, there must not be a G1 Fxx entry.
- assert((line.type & Adjustment::Line::TYPE_HAS_F) == 0);
- Adjustment::Line &sm = adjustment->lines[active_speed_modifier];
- sm.length += line.length;
- sm.time += line.time;
- if (sm.time_max != FLT_MAX) {
- if (line.time_max == FLT_MAX)
- sm.time_max = FLT_MAX;
- else
- sm.time_max += line.time_max;
- }
- // Don't store this line.
- line.type = 0;
- }
- }
- m_current_pos = std::move(new_pos);
- } else if (boost::starts_with(sline, ";_EXTRUDE_END")) {
- line.type = Adjustment::Line::TYPE_EXTRUDE_END;
- active_speed_modifier = size_t(-1);
- } else if (boost::starts_with(sline, toolchange_prefix)) {
- // Switch the tool.
- line.type = Adjustment::Line::TYPE_SET_TOOL;
- unsigned int new_extruder = (unsigned int)atoi(sline.c_str() + toolchange_prefix.size());
- if (new_extruder != m_current_extruder) {
- m_current_extruder = new_extruder;
- min_print_speed = float(EXTRUDER_CONFIG(min_print_speed));
- adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder));
- }
- } else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) {
- line.type = Adjustment::Line::TYPE_BRIDGE_FAN_START;
- } else if (boost::starts_with(sline, ";_BRIDGE_FAN_END")) {
- line.type = Adjustment::Line::TYPE_BRIDGE_FAN_END;
- } else if (boost::starts_with(sline, "G4 ")) {
- // Parse the wait time.
- line.type = Adjustment::Line::TYPE_G4;
- size_t pos_S = sline.find('S', 3);
- size_t pos_P = sline.find('P', 3);
- line.time = line.time_max = float(
- (pos_S > 0) ? atof(sline.c_str() + pos_S + 1) :
- (pos_P > 0) ? atof(sline.c_str() + pos_P + 1) * 0.001 : 0.);
- }
- if (line.type != 0)
- adjustment->lines.emplace_back(std::move(line));
- }
- m_current_extruder = initial_extruder;
+ unsigned int num_extruders = 0;
+ for (const Extruder &ex : extruders)
+ num_extruders = std::max(ex.id() + 1, num_extruders);
+
+ std::vector per_extruder_adjustments(extruders.size());
+ std::vector map_extruder_to_per_extruder_adjustment(num_extruders, 0);
+ for (size_t i = 0; i < extruders.size(); ++ i) {
+ PerExtruderAdjustments &adj = per_extruder_adjustments[i];
+ unsigned int extruder_id = extruders[i].id();
+ adj.extruder_id = extruder_id;
+ adj.cooling_slow_down_enabled = config.cooling.get_at(extruder_id);
+ adj.slowdown_below_layer_time = config.slowdown_below_layer_time.get_at(extruder_id);
+ adj.min_print_speed = config.min_print_speed.get_at(extruder_id);
+ map_extruder_to_per_extruder_adjustment[extruder_id] = i;
}
- // Sort the extruders by the increasing slowdown_below_layer_time.
- std::vector by_slowdown_layer_time;
- by_slowdown_layer_time.reserve(num_extruders);
+ const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix();
+ unsigned int current_extruder = m_current_extruder;
+ PerExtruderAdjustments *adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
+ const char *line_start = gcode.c_str();
+ const char *line_end = line_start;
+ const char extrusion_axis = config.get_extrusion_axis()[0];
+ // Index of an existing CoolingLine of the current adjustment, which holds the feedrate setting command
+ // for a sequence of extrusion moves.
+ size_t active_speed_modifier = size_t(-1);
+
+ for (; *line_start != 0; line_start = line_end)
+ {
+ while (*line_end != '\n' && *line_end != 0)
+ ++ line_end;
+ // sline will not contain the trailing '\n'.
+ std::string sline(line_start, line_end);
+ // CoolingLine will contain the trailing '\n'.
+ if (*line_end == '\n')
+ ++ line_end;
+ CoolingLine line(0, line_start - gcode.c_str(), line_end - gcode.c_str());
+ if (boost::starts_with(sline, "G0 "))
+ line.type = CoolingLine::TYPE_G0;
+ else if (boost::starts_with(sline, "G1 "))
+ line.type = CoolingLine::TYPE_G1;
+ else if (boost::starts_with(sline, "G92 "))
+ line.type = CoolingLine::TYPE_G92;
+ if (line.type) {
+ // G0, G1 or G92
+ // Parse the G-code line.
+ std::vector new_pos(current_pos);
+ const char *c = sline.data() + 3;
+ for (;;) {
+ // Skip whitespaces.
+ for (; *c == ' ' || *c == '\t'; ++ c);
+ if (*c == 0 || *c == ';')
+ break;
+ // Parse the axis.
+ size_t axis = (*c >= 'X' && *c <= 'Z') ? (*c - 'X') :
+ (*c == extrusion_axis) ? 3 : (*c == 'F') ? 4 : size_t(-1);
+ if (axis != size_t(-1)) {
+ new_pos[axis] = float(atof(++c));
+ if (axis == 4) {
+ // Convert mm/min to mm/sec.
+ new_pos[4] /= 60.f;
+ if ((line.type & CoolingLine::TYPE_G92) == 0)
+ // This is G0 or G1 line and it sets the feedrate. This mark is used for reducing the duplicate F calls.
+ line.type |= CoolingLine::TYPE_HAS_F;
+ }
+ }
+ // Skip this word.
+ for (; *c != ' ' && *c != '\t' && *c != 0; ++ c);
+ }
+ bool external_perimeter = boost::contains(sline, ";_EXTERNAL_PERIMETER");
+ bool wipe = boost::contains(sline, ";_WIPE");
+ if (external_perimeter)
+ line.type |= CoolingLine::TYPE_EXTERNAL_PERIMETER;
+ if (wipe)
+ line.type |= CoolingLine::TYPE_WIPE;
+ if (boost::contains(sline, ";_EXTRUDE_SET_SPEED") && ! wipe) {
+ line.type |= CoolingLine::TYPE_ADJUSTABLE;
+ active_speed_modifier = adjustment->lines.size();
+ }
+ if ((line.type & CoolingLine::TYPE_G92) == 0) {
+ // G0 or G1. Calculate the duration.
+ if (config.use_relative_e_distances.value)
+ // Reset extruder accumulator.
+ current_pos[3] = 0.f;
+ float dif[4];
+ for (size_t i = 0; i < 4; ++ i)
+ dif[i] = new_pos[i] - current_pos[i];
+ float dxy2 = dif[0] * dif[0] + dif[1] * dif[1];
+ float dxyz2 = dxy2 + dif[2] * dif[2];
+ if (dxyz2 > 0.f) {
+ // Movement in xyz, calculate time from the xyz Euclidian distance.
+ line.length = sqrt(dxyz2);
+ } else if (std::abs(dif[3]) > 0.f) {
+ // Movement in the extruder axis.
+ line.length = std::abs(dif[3]);
+ }
+ line.feedrate = new_pos[4];
+ assert((line.type & CoolingLine::TYPE_ADJUSTABLE) == 0 || line.feedrate > 0.f);
+ if (line.length > 0)
+ line.time = line.length / line.feedrate;
+ line.time_max = line.time;
+ if ((line.type & CoolingLine::TYPE_ADJUSTABLE) || active_speed_modifier != size_t(-1))
+ line.time_max = (adjustment->min_print_speed == 0.f) ? FLT_MAX : std::max(line.time, line.length / adjustment->min_print_speed);
+ if (active_speed_modifier < adjustment->lines.size() && (line.type & CoolingLine::TYPE_G1)) {
+ // Inside the ";_EXTRUDE_SET_SPEED" blocks, there must not be a G1 Fxx entry.
+ assert((line.type & CoolingLine::TYPE_HAS_F) == 0);
+ CoolingLine &sm = adjustment->lines[active_speed_modifier];
+ assert(sm.feedrate > 0.f);
+ sm.length += line.length;
+ sm.time += line.time;
+ if (sm.time_max != FLT_MAX) {
+ if (line.time_max == FLT_MAX)
+ sm.time_max = FLT_MAX;
+ else
+ sm.time_max += line.time_max;
+ }
+ // Don't store this line.
+ line.type = 0;
+ }
+ }
+ current_pos = std::move(new_pos);
+ } else if (boost::starts_with(sline, ";_EXTRUDE_END")) {
+ line.type = CoolingLine::TYPE_EXTRUDE_END;
+ active_speed_modifier = size_t(-1);
+ } else if (boost::starts_with(sline, toolchange_prefix)) {
+ // Switch the tool.
+ line.type = CoolingLine::TYPE_SET_TOOL;
+ unsigned int new_extruder = (unsigned int)atoi(sline.c_str() + toolchange_prefix.size());
+ if (new_extruder != current_extruder) {
+ current_extruder = new_extruder;
+ adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
+ }
+ } else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) {
+ line.type = CoolingLine::TYPE_BRIDGE_FAN_START;
+ } else if (boost::starts_with(sline, ";_BRIDGE_FAN_END")) {
+ line.type = CoolingLine::TYPE_BRIDGE_FAN_END;
+ } else if (boost::starts_with(sline, "G4 ")) {
+ // Parse the wait time.
+ line.type = CoolingLine::TYPE_G4;
+ size_t pos_S = sline.find('S', 3);
+ size_t pos_P = sline.find('P', 3);
+ line.time = line.time_max = float(
+ (pos_S > 0) ? atof(sline.c_str() + pos_S + 1) :
+ (pos_P > 0) ? atof(sline.c_str() + pos_P + 1) * 0.001 : 0.);
+ }
+ if (line.type != 0)
+ adjustment->lines.emplace_back(std::move(line));
+ }
+
+ return per_extruder_adjustments;
+}
+
+// Slow down an extruder range proportionally down to slowdown_below_layer_time.
+// Return the total time for the complete layer.
+static inline float extruder_range_slow_down_proportional(
+ std::vector::iterator it_begin,
+ std::vector::iterator it_end,
+ // Elapsed time for the extruders already processed.
+ float elapsed_time_total0,
+ // Initial total elapsed time before slow down.
+ float elapsed_time_before_slowdown,
+ // Target time for the complete layer (all extruders applied).
+ float slowdown_below_layer_time)
+{
+ // Total layer time after the slow down has been applied.
+ float total_after_slowdown = elapsed_time_before_slowdown;
+ // Now decide, whether the external perimeters shall be slowed down as well.
+ float max_time_nep = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ max_time_nep += (*it)->maximum_time_after_slowdown(false);
+ if (max_time_nep > slowdown_below_layer_time) {
+ // It is sufficient to slow down the non-external perimeter moves to reach the target layer time.
+ // Slow down the non-external perimeters proportionally.
+ float non_adjustable_time = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ non_adjustable_time += (*it)->non_adjustable_time(false);
+ // The following step is a linear programming task due to the minimum movement speeds of the print moves.
+ // Run maximum 5 iterations until a good enough approximation is reached.
+ for (size_t iter = 0; iter < 5; ++ iter) {
+ float factor = (slowdown_below_layer_time - non_adjustable_time) / (total_after_slowdown - non_adjustable_time);
+ assert(factor > 1.f);
+ total_after_slowdown = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ total_after_slowdown += (*it)->slow_down_proportional(factor, false);
+ if (total_after_slowdown > 0.95f * slowdown_below_layer_time)
+ break;
+ }
+ } else {
+ // Slow down everything. First slow down the non-external perimeters to maximum.
+ for (auto it = it_begin; it != it_end; ++ it)
+ (*it)->slowdown_to_minimum_feedrate(false);
+ // Slow down the external perimeters proportionally.
+ float non_adjustable_time = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ non_adjustable_time += (*it)->non_adjustable_time(true);
+ for (size_t iter = 0; iter < 5; ++ iter) {
+ float factor = (slowdown_below_layer_time - non_adjustable_time) / (total_after_slowdown - non_adjustable_time);
+ assert(factor > 1.f);
+ total_after_slowdown = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ total_after_slowdown += (*it)->slow_down_proportional(factor, true);
+ if (total_after_slowdown > 0.95f * slowdown_below_layer_time)
+ break;
+ }
+ }
+ return total_after_slowdown;
+}
+
+// Slow down an extruder range to slowdown_below_layer_time.
+// Return the total time for the complete layer.
+static inline void extruder_range_slow_down_non_proportional(
+ std::vector::iterator it_begin,
+ std::vector::iterator it_end,
+ float time_stretch)
+{
+ // Slow down. Try to equalize the feedrates.
+ std::vector by_min_print_speed(it_begin, it_end);
+ // Find the next highest adjustable feedrate among the extruders.
+ float feedrate = 0;
+ for (PerExtruderAdjustments *adj : by_min_print_speed) {
+ adj->idx_line_begin = 0;
+ adj->idx_line_end = 0;
+ assert(adj->idx_line_begin < adj->n_lines_adjustable);
+ if (adj->lines[adj->idx_line_begin].feedrate > feedrate)
+ feedrate = adj->lines[adj->idx_line_begin].feedrate;
+ }
+ assert(feedrate > 0.f);
+ // Sort by min_print_speed, maximum speed first.
+ std::sort(by_min_print_speed.begin(), by_min_print_speed.end(),
+ [](const PerExtruderAdjustments *p1, const PerExtruderAdjustments *p2){ return p1->min_print_speed > p2->min_print_speed; });
+ // Slow down, fast moves first.
+ for (;;) {
+ // For each extruder, find the span of lines with a feedrate close to feedrate.
+ for (PerExtruderAdjustments *adj : by_min_print_speed) {
+ for (adj->idx_line_end = adj->idx_line_begin;
+ adj->idx_line_end < adj->n_lines_adjustable && adj->lines[adj->idx_line_end].feedrate > feedrate - EPSILON;
+ ++ adj->idx_line_end) ;
+ }
+ // Find the next highest adjustable feedrate among the extruders.
+ float feedrate_next = 0.f;
+ for (PerExtruderAdjustments *adj : by_min_print_speed)
+ if (adj->idx_line_end < adj->n_lines_adjustable && adj->lines[adj->idx_line_end].feedrate > feedrate_next)
+ feedrate_next = adj->lines[adj->idx_line_end].feedrate;
+ // Slow down, limited by max(feedrate_next, min_print_speed).
+ for (auto adj = by_min_print_speed.begin(); adj != by_min_print_speed.end();) {
+ // Slow down at most by time_stretch.
+ if ((*adj)->min_print_speed == 0.f) {
+ // All the adjustable speeds are now lowered to the same speed,
+ // and the minimum speed is set to zero.
+ float time_adjustable = 0.f;
+ for (auto it = adj; it != by_min_print_speed.end(); ++ it)
+ time_adjustable += (*it)->adjustable_time(true);
+ float rate = (time_adjustable + time_stretch) / time_adjustable;
+ for (auto it = adj; it != by_min_print_speed.end(); ++ it)
+ (*it)->slow_down_proportional(rate, true);
+ return;
+ } else {
+ float feedrate_limit = std::max(feedrate_next, (*adj)->min_print_speed);
+ bool done = false;
+ float time_stretch_max = 0.f;
+ for (auto it = adj; it != by_min_print_speed.end(); ++ it)
+ time_stretch_max += (*it)->time_stretch_when_slowing_down_to_feedrate(feedrate_limit);
+ if (time_stretch_max >= time_stretch) {
+ feedrate_limit = feedrate - (feedrate - feedrate_limit) * time_stretch / time_stretch_max;
+ done = true;
+ } else
+ time_stretch -= time_stretch_max;
+ for (auto it = adj; it != by_min_print_speed.end(); ++ it)
+ (*it)->slow_down_to_feedrate(feedrate_limit);
+ if (done)
+ return;
+ }
+ // Skip the other extruders with nearly the same min_print_speed, as they have been processed already.
+ auto next = adj;
+ for (++ next; next != by_min_print_speed.end() && (*next)->min_print_speed > (*adj)->min_print_speed - EPSILON; ++ next);
+ adj = next;
+ }
+ if (feedrate_next == 0.f)
+ // There are no other extrusions available for slow down.
+ break;
+ for (PerExtruderAdjustments *adj : by_min_print_speed) {
+ adj->idx_line_begin = adj->idx_line_end;
+ feedrate = feedrate_next;
+ }
+ }
+}
+
+// Calculate slow down for all the extruders.
+float CoolingBuffer::calculate_layer_slowdown(std::vector &per_extruder_adjustments)
+{
+ // Sort the extruders by an increasing slowdown_below_layer_time.
+ // The layers with a lower slowdown_below_layer_time are slowed down
+ // together with all the other layers with slowdown_below_layer_time above.
+ std::vector by_slowdown_time;
+ by_slowdown_time.reserve(per_extruder_adjustments.size());
// Only insert entries, which are adjustable (have cooling enabled and non-zero stretchable time).
// Collect total print time of non-adjustable extruders.
- float elapsed_time_total_non_adjustable = 0.f;
- for (size_t i = 0; i < num_extruders; ++ i) {
- if (config.cooling.get_at(extruders[i].id()))
- by_slowdown_layer_time.emplace_back(i);
- else
- elapsed_time_total_non_adjustable += adjustments[i].elapsed_time_total();
+ float elapsed_time_total0 = 0.f;
+ for (PerExtruderAdjustments &adj : per_extruder_adjustments) {
+ // Curren total time for this extruder.
+ adj.time_total = adj.elapsed_time_total();
+ // Maximum time for this extruder, when all extrusion moves are slowed down to min_extrusion_speed.
+ adj.time_maximum = adj.maximum_time_after_slowdown(true);
+ if (adj.cooling_slow_down_enabled && adj.lines.size() > 0) {
+ by_slowdown_time.emplace_back(&adj);
+ if (! m_cooling_logic_proportional)
+ // sorts the lines, also sets adj.time_non_adjustable
+ adj.sort_lines_by_decreasing_feedrate();
+ } else
+ elapsed_time_total0 += adj.elapsed_time_total();
}
- std::sort(by_slowdown_layer_time.begin(), by_slowdown_layer_time.end(),
- [&config, &extruders](const size_t idx1, const size_t idx2){
- return config.slowdown_below_layer_time.get_at(extruders[idx1].id()) <
- config.slowdown_below_layer_time.get_at(extruders[idx2].id());
- });
+ std::sort(by_slowdown_time.begin(), by_slowdown_time.end(),
+ [](const PerExtruderAdjustments *adj1, const PerExtruderAdjustments *adj2)
+ { return adj1->slowdown_below_layer_time < adj2->slowdown_below_layer_time; });
- // Elapsed time after adjustment.
- float elapsed_time_total = 0.f;
- {
- // Elapsed time for the already adjusted extruders.
- float elapsed_time_total0 = elapsed_time_total_non_adjustable;
- for (size_t i_by_slowdown_layer_time = 0; i_by_slowdown_layer_time < by_slowdown_layer_time.size(); ++ i_by_slowdown_layer_time) {
- // Idx in adjustments.
- size_t idx = by_slowdown_layer_time[i_by_slowdown_layer_time];
- // Macro to sum or adjust all sections starting with i_by_slowdown_layer_time.
- #define FORALL_UNPROCESSED(ACCUMULATOR, ACTION) \
- ACCUMULATOR = elapsed_time_total0;\
- for (size_t j = i_by_slowdown_layer_time; j < by_slowdown_layer_time.size(); ++ j) \
- ACCUMULATOR += adjustments[by_slowdown_layer_time[j]].ACTION
- // Calculate the current adjusted elapsed_time_total over the non-finalized extruders.
- float total;
- FORALL_UNPROCESSED(total, elapsed_time_total());
- float slowdown_below_layer_time = float(config.slowdown_below_layer_time.get_at(adjustments[idx].extruder_id)) * 1.001f;
- if (total > slowdown_below_layer_time) {
- // The current total time is above the minimum threshold of the rest of the extruders, don't adjust anything.
+ for (auto cur_begin = by_slowdown_time.begin(); cur_begin != by_slowdown_time.end(); ++ cur_begin) {
+ PerExtruderAdjustments &adj = *(*cur_begin);
+ // Calculate the current adjusted elapsed_time_total over the non-finalized extruders.
+ float total = elapsed_time_total0;
+ for (auto it = cur_begin; it != by_slowdown_time.end(); ++ it)
+ total += (*it)->time_total;
+ float slowdown_below_layer_time = adj.slowdown_below_layer_time * 1.001f;
+ if (total > slowdown_below_layer_time) {
+ // The current total time is above the minimum threshold of the rest of the extruders, don't adjust anything.
+ } else {
+ // Adjust this and all the following (higher config.slowdown_below_layer_time) extruders.
+ // Sum maximum slow down time as if everything was slowed down including the external perimeters.
+ float max_time = elapsed_time_total0;
+ for (auto it = cur_begin; it != by_slowdown_time.end(); ++ it)
+ max_time += (*it)->time_maximum;
+ if (max_time > slowdown_below_layer_time) {
+ if (m_cooling_logic_proportional)
+ extruder_range_slow_down_proportional(cur_begin, by_slowdown_time.end(), elapsed_time_total0, total, slowdown_below_layer_time);
+ else
+ extruder_range_slow_down_non_proportional(cur_begin, by_slowdown_time.end(), slowdown_below_layer_time - total);
} else {
- // Adjust this and all the following (higher config.slowdown_below_layer_time) extruders.
- // Sum maximum slow down time as if everything was slowed down including the external perimeters.
- float max_time;
- FORALL_UNPROCESSED(max_time, maximum_time(true));
- if (max_time > slowdown_below_layer_time) {
- // By slowing every possible movement, the layer time could be reached. Now decide
- // whether the external perimeters shall be slowed down as well.
- float max_time_nep;
- FORALL_UNPROCESSED(max_time_nep, maximum_time(false));
- if (max_time_nep > slowdown_below_layer_time) {
- // It is sufficient to slow down the non-external perimeter moves to reach the target layer time.
- // Slow down the non-external perimeters proportionally.
- float non_adjustable_time;
- FORALL_UNPROCESSED(non_adjustable_time, non_adjustable_time(false));
- // The following step is a linear programming task due to the minimum movement speeds of the print moves.
- // Run maximum 5 iterations until a good enough approximation is reached.
- for (size_t iter = 0; iter < 5; ++ iter) {
- float factor = (slowdown_below_layer_time - non_adjustable_time) / (total - non_adjustable_time);
- assert(factor > 1.f);
- FORALL_UNPROCESSED(total, slow_down_proportional(factor, false));
- if (total > 0.95f * slowdown_below_layer_time)
- break;
- }
- } else {
- // Slow down everything. First slow down the non-external perimeters to maximum.
- FORALL_UNPROCESSED(total, slow_down_maximum(false));
- // Slow down the external perimeters proportionally.
- float non_adjustable_time;
- FORALL_UNPROCESSED(non_adjustable_time, non_adjustable_time(true));
- for (size_t iter = 0; iter < 5; ++ iter) {
- float factor = (slowdown_below_layer_time - non_adjustable_time) / (total - non_adjustable_time);
- assert(factor > 1.f);
- FORALL_UNPROCESSED(total, slow_down_proportional(factor, true));
- if (total > 0.95f * slowdown_below_layer_time)
- break;
- }
- }
- } else {
- // Slow down to maximum possible.
- FORALL_UNPROCESSED(total, slow_down_maximum(true));
- }
+ // Slow down to maximum possible.
+ for (auto it = cur_begin; it != by_slowdown_time.end(); ++ it)
+ (*it)->slowdown_to_minimum_feedrate(true);
}
- #undef FORALL_UNPROCESSED
- // Sum the final elapsed time for all extruders up to i_by_slowdown_layer_time.
- if (i_by_slowdown_layer_time + 1 == by_slowdown_layer_time.size())
- // Optimization for single extruder prints.
- elapsed_time_total0 = total;
- else
- elapsed_time_total0 += adjustments[idx].elapsed_time_total();
}
- elapsed_time_total = elapsed_time_total0;
+ elapsed_time_total0 += adj.elapsed_time_total();
}
- // Transform the G-code.
- // First sort the adjustment lines by their position in the source G-code.
- std::vector lines;
+ return elapsed_time_total0;
+}
+
+// Apply slow down over G-code lines stored in per_extruder_adjustments, enable fan if needed.
+// Returns the adjusted G-code.
+std::string CoolingBuffer::apply_layer_cooldown(
+ // Source G-code for the current layer.
+ const std::string &gcode,
+ // ID of the current layer, used to disable fan for the first n layers.
+ size_t layer_id,
+ // Total time of this layer after slow down, used to control the fan.
+ float layer_time,
+ // Per extruder list of G-code lines and their cool down attributes.
+ std::vector &per_extruder_adjustments)
+{
+ // First sort the adjustment lines by of multiple extruders by their position in the source G-code.
+ std::vector lines;
{
size_t n_lines = 0;
- for (const Adjustment &adj : adjustments)
+ for (const PerExtruderAdjustments &adj : per_extruder_adjustments)
n_lines += adj.lines.size();
lines.reserve(n_lines);
- for (const Adjustment &adj : adjustments)
- for (const Adjustment::Line &line : adj.lines)
+ for (const PerExtruderAdjustments &adj : per_extruder_adjustments)
+ for (const CoolingLine &line : adj.lines)
lines.emplace_back(&line);
- std::sort(lines.begin(), lines.end(), [](const Adjustment::Line *ln1, const Adjustment::Line *ln2) { return ln1->line_start < ln2->line_start; } );
+ std::sort(lines.begin(), lines.end(), [](const CoolingLine *ln1, const CoolingLine *ln2) { return ln1->line_start < ln2->line_start; } );
}
// Second generate the adjusted G-code.
std::string new_gcode;
@@ -390,8 +610,9 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
int fan_speed = -1;
bool bridge_fan_control = false;
int bridge_fan_speed = 0;
- auto change_extruder_set_fan = [ this, layer_id, elapsed_time_total, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed ]() {
+ auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed ]() {
const FullPrintConfig &config = m_gcodegen.config();
+#define EXTRUDER_CONFIG(OPT) config.OPT.get_at(m_current_extruder)
int min_fan_speed = EXTRUDER_CONFIG(min_fan_speed);
int fan_speed_new = EXTRUDER_CONFIG(fan_always_on) ? min_fan_speed : 0;
if (layer_id >= EXTRUDER_CONFIG(disable_fan_first_layers)) {
@@ -399,17 +620,18 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
float slowdown_below_layer_time = float(EXTRUDER_CONFIG(slowdown_below_layer_time));
float fan_below_layer_time = float(EXTRUDER_CONFIG(fan_below_layer_time));
if (EXTRUDER_CONFIG(cooling)) {
- if (elapsed_time_total < slowdown_below_layer_time) {
+ if (layer_time < slowdown_below_layer_time) {
// Layer time very short. Enable the fan to a full throttle.
fan_speed_new = max_fan_speed;
- } else if (elapsed_time_total < fan_below_layer_time) {
+ } else if (layer_time < fan_below_layer_time) {
// Layer time quite short. Enable the fan proportionally according to the current layer time.
- assert(elapsed_time_total >= slowdown_below_layer_time);
- double t = (elapsed_time_total - slowdown_below_layer_time) / (fan_below_layer_time - slowdown_below_layer_time);
+ assert(layer_time >= slowdown_below_layer_time);
+ double t = (layer_time - slowdown_below_layer_time) / (fan_below_layer_time - slowdown_below_layer_time);
fan_speed_new = int(floor(t * min_fan_speed + (1. - t) * max_fan_speed) + 0.5);
}
}
bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed);
+#undef EXTRUDER_CONFIG
bridge_fan_control = bridge_fan_speed > fan_speed_new;
} else {
bridge_fan_control = false;
@@ -421,49 +643,50 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
new_gcode += m_gcodegen.writer().set_fan(fan_speed);
}
};
- change_extruder_set_fan();
- const char *pos = gcode.c_str();
- int current_feedrate = 0;
- for (const Adjustment::Line *line : lines) {
+ const char *pos = gcode.c_str();
+ int current_feedrate = 0;
+ const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix();
+ change_extruder_set_fan();
+ for (const CoolingLine *line : lines) {
const char *line_start = gcode.c_str() + line->line_start;
const char *line_end = gcode.c_str() + line->line_end;
if (line_start > pos)
new_gcode.append(pos, line_start - pos);
- if (line->type & Adjustment::Line::TYPE_SET_TOOL) {
+ if (line->type & CoolingLine::TYPE_SET_TOOL) {
unsigned int new_extruder = (unsigned int)atoi(line_start + toolchange_prefix.size());
if (new_extruder != m_current_extruder) {
m_current_extruder = new_extruder;
change_extruder_set_fan();
}
new_gcode.append(line_start, line_end - line_start);
- } else if (line->type & Adjustment::Line::TYPE_BRIDGE_FAN_START) {
+ } else if (line->type & CoolingLine::TYPE_BRIDGE_FAN_START) {
if (bridge_fan_control)
new_gcode += m_gcodegen.writer().set_fan(bridge_fan_speed, true);
- } else if (line->type & Adjustment::Line::TYPE_BRIDGE_FAN_END) {
+ } else if (line->type & CoolingLine::TYPE_BRIDGE_FAN_END) {
if (bridge_fan_control)
new_gcode += m_gcodegen.writer().set_fan(fan_speed, true);
- } else if (line->type & Adjustment::Line::TYPE_EXTRUDE_END) {
+ } else if (line->type & CoolingLine::TYPE_EXTRUDE_END) {
// Just remove this comment.
- } else if (line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE | Adjustment::Line::TYPE_HAS_F)) {
+ } else if (line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE | CoolingLine::TYPE_HAS_F)) {
// Find the start of a comment, or roll to the end of line.
- const char *end = line_start;
- for (; end < line_end && *end != ';'; ++ end);
- // Find the 'F' word.
+ const char *end = line_start;
+ for (; end < line_end && *end != ';'; ++ end);
+ // Find the 'F' word.
const char *fpos = strstr(line_start + 2, " F") + 2;
int new_feedrate = current_feedrate;
bool modify = false;
assert(fpos != nullptr);
if (line->slowdown) {
modify = true;
- new_feedrate = int(floor(60. * (line->length / line->time) + 0.5));
+ new_feedrate = int(floor(60. * line->feedrate + 0.5));
} else {
new_feedrate = atoi(fpos);
if (new_feedrate != current_feedrate) {
// Append the line without the comment.
new_gcode.append(line_start, end - line_start);
current_feedrate = new_feedrate;
- } else if ((line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE)) || line->length == 0.) {
+ } else if ((line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE)) || line->length == 0.) {
// Feedrate does not change and this line does not move the print head. Skip the complete G-code line including the G-code comment.
end = line_end;
} else {
@@ -488,7 +711,7 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
new_gcode.append(line_start, f - line_start + 1);
}
// Skip the non-whitespaces of the F parameter up the comment or end of line.
- for (; fpos != end && *fpos != ' ' && *fpos != ';' && *fpos != '\n'; ++fpos);
+ for (; fpos != end && *fpos != ' ' && *fpos != ';' && *fpos != '\n'; ++fpos);
// Append the rest of the line without the comment.
if (fpos < end)
new_gcode.append(fpos, end - fpos);
@@ -497,22 +720,22 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
}
// Process the rest of the line.
if (end < line_end) {
- if (line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE)) {
- // Process comments, remove ";_EXTRUDE_SET_SPEED", ";_EXTERNAL_PERIMETER", ";_WIPE"
- std::string comment(end, line_end);
- boost::replace_all(comment, ";_EXTRUDE_SET_SPEED", "");
- if (line->type & Adjustment::Line::TYPE_EXTERNAL_PERIMETER)
+ if (line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE)) {
+ // Process comments, remove ";_EXTRUDE_SET_SPEED", ";_EXTERNAL_PERIMETER", ";_WIPE"
+ std::string comment(end, line_end);
+ boost::replace_all(comment, ";_EXTRUDE_SET_SPEED", "");
+ if (line->type & CoolingLine::TYPE_EXTERNAL_PERIMETER)
boost::replace_all(comment, ";_EXTERNAL_PERIMETER", "");
- if (line->type & Adjustment::Line::TYPE_WIPE)
+ if (line->type & CoolingLine::TYPE_WIPE)
boost::replace_all(comment, ";_WIPE", "");
- new_gcode += comment;
- } else {
- // Just attach the rest of the source line.
- new_gcode.append(end, line_end - end);
- }
+ new_gcode += comment;
+ } else {
+ // Just attach the rest of the source line.
+ new_gcode.append(end, line_end - end);
+ }
}
} else {
- new_gcode.append(line_start, line_end - line_start);
+ new_gcode.append(line_start, line_end - line_start);
}
pos = line_end;
}
diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.hpp b/xs/src/libslic3r/GCode/CoolingBuffer.hpp
index f85c470b30..bf4b082e25 100644
--- a/xs/src/libslic3r/GCode/CoolingBuffer.hpp
+++ b/xs/src/libslic3r/GCode/CoolingBuffer.hpp
@@ -9,13 +9,17 @@ namespace Slic3r {
class GCode;
class Layer;
+class PerExtruderAdjustments;
-/*
-A standalone G-code filter, to control cooling of the print.
-The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
-and the print is modified to stretch over a minimum layer time.
-*/
-
+// A standalone G-code filter, to control cooling of the print.
+// The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
+// and the print is modified to stretch over a minimum layer time.
+//
+// The simple it sounds, the actual implementation is significantly more complex.
+// Namely, for a multi-extruder print, each material may require a different cooling logic.
+// For example, some materials may not like to print too slowly, while with some materials
+// we may slow down significantly.
+//
class CoolingBuffer {
public:
CoolingBuffer(GCode &gcodegen);
@@ -25,7 +29,12 @@ public:
GCode* gcodegen() { return &m_gcodegen; }
private:
- CoolingBuffer& operator=(const CoolingBuffer&);
+ CoolingBuffer& operator=(const CoolingBuffer&) = delete;
+ std::vector parse_layer_gcode(const std::string &gcode, std::vector ¤t_pos) const;
+ float calculate_layer_slowdown(std::vector &per_extruder_adjustments);
+ // Apply slow down over G-code lines stored in per_extruder_adjustments, enable fan if needed.
+ // Returns the adjusted G-code.
+ std::string apply_layer_cooldown(const std::string &gcode, size_t layer_id, float layer_time, std::vector &per_extruder_adjustments);
GCode& m_gcodegen;
std::string m_gcode;
@@ -34,6 +43,9 @@ private:
std::vector m_axis;
std::vector m_current_pos;
unsigned int m_current_extruder;
+
+ // Old logic: proportional.
+ bool m_cooling_logic_proportional = false;
};
}
diff --git a/xs/src/libslic3r/GCode/PreviewData.cpp b/xs/src/libslic3r/GCode/PreviewData.cpp
index 69fd3524da..40f0747b28 100644
--- a/xs/src/libslic3r/GCode/PreviewData.cpp
+++ b/xs/src/libslic3r/GCode/PreviewData.cpp
@@ -99,17 +99,31 @@ void GCodePreviewData::Range::set_from(const Range& other)
float GCodePreviewData::Range::step_size() const
{
- return (max - min) / (float)Colors_Count;
+ return (max - min) / (float)(Colors_Count - 1);
}
-const GCodePreviewData::Color& GCodePreviewData::Range::get_color_at_max() const
+GCodePreviewData::Color GCodePreviewData::Range::get_color_at(float value) const
{
- return colors[Colors_Count - 1];
-}
+ if (empty())
+ return Color::Dummy;
-const GCodePreviewData::Color& GCodePreviewData::Range::get_color_at(float value) const
-{
- return empty() ? get_color_at_max() : colors[clamp((unsigned int)0, Colors_Count - 1, (unsigned int)((value - min) / step_size()))];
+ float global_t = (value - min) / step_size();
+
+ unsigned int low = (unsigned int)global_t;
+ unsigned int high = clamp((unsigned int)0, Colors_Count - 1, low + 1);
+
+ Color color_low = colors[low];
+ Color color_high = colors[high];
+
+ float local_t = global_t - (float)low;
+
+ // interpolate in RGB space
+ Color ret;
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ ret.rgba[i] = lerp(color_low.rgba[i], color_high.rgba[i], local_t);
+ }
+ return ret;
}
GCodePreviewData::LegendItem::LegendItem(const std::string& text, const GCodePreviewData::Color& color)
@@ -261,27 +275,27 @@ bool GCodePreviewData::empty() const
return extrusion.layers.empty() && travel.polylines.empty() && retraction.positions.empty() && unretraction.positions.empty();
}
-const GCodePreviewData::Color& GCodePreviewData::get_extrusion_role_color(ExtrusionRole role) const
+GCodePreviewData::Color GCodePreviewData::get_extrusion_role_color(ExtrusionRole role) const
{
return extrusion.role_colors[role];
}
-const GCodePreviewData::Color& GCodePreviewData::get_height_color(float height) const
+GCodePreviewData::Color GCodePreviewData::get_height_color(float height) const
{
return ranges.height.get_color_at(height);
}
-const GCodePreviewData::Color& GCodePreviewData::get_width_color(float width) const
+GCodePreviewData::Color GCodePreviewData::get_width_color(float width) const
{
return ranges.width.get_color_at(width);
}
-const GCodePreviewData::Color& GCodePreviewData::get_feedrate_color(float feedrate) const
+GCodePreviewData::Color GCodePreviewData::get_feedrate_color(float feedrate) const
{
return ranges.feedrate.get_color_at(feedrate);
}
-const GCodePreviewData::Color& GCodePreviewData::get_volumetric_rate_color(float rate) const
+GCodePreviewData::Color GCodePreviewData::get_volumetric_rate_color(float rate) const
{
return ranges.volumetric_rate.get_color_at(rate);
}
@@ -370,10 +384,10 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
list.reserve(Range::Colors_Count);
float step = range.step_size();
- for (unsigned int i = 0; i < Range::Colors_Count; ++i)
+ for (int i = Range::Colors_Count - 1; i >= 0; --i)
{
char buf[1024];
- sprintf(buf, "%.*f/%.*f", decimals, scale_factor * (range.min + (float)i * step), decimals, scale_factor * (range.min + (float)(i + 1) * step));
+ sprintf(buf, "%.*f", decimals, scale_factor * (range.min + (float)i * step));
list.emplace_back(buf, range.colors[i]);
}
}
@@ -408,7 +422,7 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
}
case Extrusion::Feedrate:
{
- Helper::FillListFromRange(items, ranges.feedrate, 0, 1.0f);
+ Helper::FillListFromRange(items, ranges.feedrate, 1, 1.0f);
break;
}
case Extrusion::VolumetricRate:
diff --git a/xs/src/libslic3r/GCode/PreviewData.hpp b/xs/src/libslic3r/GCode/PreviewData.hpp
index e9c5f75154..ea8ca6d58a 100644
--- a/xs/src/libslic3r/GCode/PreviewData.hpp
+++ b/xs/src/libslic3r/GCode/PreviewData.hpp
@@ -41,8 +41,7 @@ public:
void set_from(const Range& other);
float step_size() const;
- const Color& get_color_at(float value) const;
- const Color& get_color_at_max() const;
+ Color get_color_at(float value) const;
};
struct Ranges
@@ -188,11 +187,11 @@ public:
void reset();
bool empty() const;
- const Color& get_extrusion_role_color(ExtrusionRole role) const;
- const Color& get_height_color(float height) const;
- const Color& get_width_color(float width) const;
- const Color& get_feedrate_color(float feedrate) const;
- const Color& get_volumetric_rate_color(float rate) const;
+ Color get_extrusion_role_color(ExtrusionRole role) const;
+ Color get_height_color(float height) const;
+ Color get_width_color(float width) const;
+ Color get_feedrate_color(float feedrate) const;
+ Color get_volumetric_rate_color(float rate) const;
void set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha);
void set_extrusion_paths_colors(const std::vector& colors);
diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
index f328d839f8..731dcbbd98 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
@@ -126,6 +126,11 @@ public:
m_extrusions.emplace_back(WipeTower::Extrusion(WipeTower::xy(rot.x, rot.y), width, m_current_tool));
}
+ // adds tag for analyzer
+ char buf[64];
+ sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
+ m_gcode += buf;
+
m_gcode += "G1";
if (rot.x != rotated_current_pos.x) {
m_gcode += set_format_X(rot.x); // Transform current position back to wipe tower coordinates (was updated by set_format_X)
@@ -494,11 +499,6 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
.travel(cleaning_box.ld, 7200)
.set_extruder_trimpot(750); // Increase the extruder driver current to allow fast ramming.
- // adds tag for analyzer
- char buf[32];
- sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
- writer.append(buf);
-
for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
unsigned int tool = tools[idx_tool];
m_left_to_right = true;
@@ -591,12 +591,6 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
xy initial_position = cleaning_box.ld + WipeTower::xy(0.f,m_depth_traversed);
writer.set_initial_position(initial_position);
-
- // adds tag for analyzer
- char buf[32];
- sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
- writer.append(buf);
-
// Increase the extruder driver current to allow fast ramming.
writer.set_extruder_trimpot(750);
@@ -664,12 +658,8 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, flo
xy initial_position = wipeTower_box.lu - xy(m_perimeter_width * 6.f, 0);
writer.set_initial_position(initial_position);
- // adds tag for analyzer
- char buf[32];
- sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
- writer.append(buf)
- .extrude_explicit(wipeTower_box.ld - xy(m_perimeter_width * 6.f, 0), // Prime the extruder left of the wipe tower.
- 1.5f * m_extrusion_flow * (wipeTower_box.lu.y - wipeTower_box.ld.y), 2400);
+ writer.extrude_explicit(wipeTower_box.ld - xy(m_perimeter_width * 6.f, 0), // Prime the extruder left of the wipe tower.
+ 1.5f * m_extrusion_flow * (wipeTower_box.lu.y - wipeTower_box.ld.y), 2400);
// The tool is supposed to be active and primed at the time when the wipe tower brim is extruded.
// Extrude 4 rounds of a brim around the future wipe tower.
diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp
index aaea863e83..7559411448 100644
--- a/xs/src/libslic3r/Model.cpp
+++ b/xs/src/libslic3r/Model.cpp
@@ -269,6 +269,10 @@ TriangleMesh Model::mesh() const
static bool _arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf* bb, Pointfs &out)
{
+ if (sizes.empty())
+ // return if the list is empty or the following call to BoundingBoxf constructor will lead to a crash
+ return true;
+
// we supply unscaled data to arrange()
bool result = Slic3r::Geometry::arrange(
sizes.size(), // number of parts
@@ -400,7 +404,7 @@ bool Model::looks_like_multipart_object() const
return false;
}
-void Model::convert_multipart_object()
+void Model::convert_multipart_object(unsigned int max_extruders)
{
if (this->objects.empty())
return;
@@ -417,7 +421,7 @@ void Model::convert_multipart_object()
if (new_v != nullptr)
{
new_v->name = o->name;
- new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string());
+ new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string(max_extruders));
}
}
@@ -477,20 +481,20 @@ bool Model::fits_print_volume(const FullPrintConfig &config) const
return print_volume.contains(transformed_bounding_box());
}
-unsigned int Model::get_auto_extruder_id()
+unsigned int Model::get_auto_extruder_id(unsigned int max_extruders)
{
unsigned int id = s_auto_extruder_id;
- if (++s_auto_extruder_id > 4)
+ if (++s_auto_extruder_id > max_extruders)
reset_auto_extruder_id();
return id;
}
-std::string Model::get_auto_extruder_id_as_string()
+std::string Model::get_auto_extruder_id_as_string(unsigned int max_extruders)
{
char str_extruder[64];
- sprintf(str_extruder, "%ud", get_auto_extruder_id());
+ sprintf(str_extruder, "%ud", get_auto_extruder_id(max_extruders));
return str_extruder;
}
@@ -992,7 +996,7 @@ ModelMaterial* ModelVolume::assign_unique_material()
// Split this volume, append the result to the object owning this volume.
// Return the number of volumes created from this one.
// This is useful to assign different materials to different volumes of an object.
-size_t ModelVolume::split()
+size_t ModelVolume::split(unsigned int max_extruders)
{
TriangleMeshPtrs meshptrs = this->mesh.split();
if (meshptrs.size() <= 1) {
@@ -1015,7 +1019,7 @@ size_t ModelVolume::split()
char str_idx[64];
sprintf(str_idx, "_%d", idx + 1);
this->object->volumes[ivolume]->name = name + str_idx;
- this->object->volumes[ivolume]->config.set_deserialize("extruder", Model::get_auto_extruder_id_as_string());
+ this->object->volumes[ivolume]->config.set_deserialize("extruder", Model::get_auto_extruder_id_as_string(max_extruders));
delete mesh;
++ idx;
}
diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp
index 0c0ffe7769..4835028b98 100644
--- a/xs/src/libslic3r/Model.hpp
+++ b/xs/src/libslic3r/Model.hpp
@@ -173,8 +173,8 @@ public:
// Split this volume, append the result to the object owning this volume.
// Return the number of volumes created from this one.
// This is useful to assign different materials to different volumes of an object.
- size_t split();
-
+ size_t split(unsigned int max_extruders);
+
ModelMaterial* assign_unique_material();
private:
@@ -280,7 +280,7 @@ public:
void duplicate_objects_grid(size_t x, size_t y, coordf_t dist);
bool looks_like_multipart_object() const;
- void convert_multipart_object();
+ void convert_multipart_object(unsigned int max_extruders);
// Ensures that the min z of the model is not negative
void adjust_min_z();
@@ -291,8 +291,8 @@ public:
void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); }
- static unsigned int get_auto_extruder_id();
- static std::string get_auto_extruder_id_as_string();
+ static unsigned int get_auto_extruder_id(unsigned int max_extruders);
+ static std::string get_auto_extruder_id_as_string(unsigned int max_extruders);
static void reset_auto_extruder_id();
};
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index 8ba0e7cd69..005e286f94 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -111,7 +111,8 @@ PrintConfigDef::PrintConfigDef()
"with cooling (use a fan) before tweaking this.");
def->cli = "bridge-flow-ratio=f";
def->min = 0;
- def->default_value = new ConfigOptionFloat(1);
+ def->max = 2;
+ def->default_value = new ConfigOptionFloat(1);
def = this->add("bridge_speed", coFloat);
def->label = L("Bridges");
@@ -1713,7 +1714,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/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp
index aecb39662e..45e4b6f5dc 100644
--- a/xs/src/libslic3r/TriangleMesh.cpp
+++ b/xs/src/libslic3r/TriangleMesh.cpp
@@ -51,9 +51,6 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector& fa
for (int i = 0; i < stl.stats.number_of_facets; i++) {
stl_facet facet;
- facet.normal.x = 0;
- facet.normal.y = 0;
- facet.normal.z = 0;
const Pointf3& ref_f1 = points[facets[i].x];
facet.vertex[0].x = ref_f1.x;
@@ -73,6 +70,13 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector& fa
facet.extra[0] = 0;
facet.extra[1] = 0;
+ float normal[3];
+ stl_calculate_normal(normal, &facet);
+ stl_normalize_vector(normal);
+ facet.normal.x = normal[0];
+ facet.normal.y = normal[1];
+ facet.normal.z = normal[2];
+
stl.facet_start[i] = facet;
}
stl_get_size(&stl);
diff --git a/xs/src/libslic3r/Utils.hpp b/xs/src/libslic3r/Utils.hpp
index 5727d6c89f..e5157741ec 100644
--- a/xs/src/libslic3r/Utils.hpp
+++ b/xs/src/libslic3r/Utils.hpp
@@ -3,6 +3,8 @@
#include
+#include "libslic3r.h"
+
namespace Slic3r {
extern void set_logging_level(unsigned int level);
@@ -60,6 +62,9 @@ extern std::string timestamp_str();
// to be placed at the top of Slic3r generated files.
inline std::string header_slic3r_generated() { return std::string("generated by " SLIC3R_FORK_NAME " " SLIC3R_VERSION " " ) + timestamp_str(); }
+// getpid platform wrapper
+extern unsigned get_current_pid();
+
// Compute the next highest power of 2 of 32-bit v
// http://graphics.stanford.edu/~seander/bithacks.html
template
@@ -79,6 +84,21 @@ inline T next_highest_power_of_2(T v)
return ++ v;
}
+class PerlCallback {
+public:
+ PerlCallback(void *sv) : m_callback(nullptr) { this->register_callback(sv); }
+ PerlCallback() : m_callback(nullptr) {}
+ ~PerlCallback() { this->deregister_callback(); }
+ void register_callback(void *sv);
+ void deregister_callback();
+ void call();
+ void call(int i);
+ void call(int i, int j);
+// void call(const std::vector &ints);
+private:
+ void *m_callback;
+};
+
} // namespace Slic3r
#endif // slic3r_Utils_hpp_
diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h
index 0f192c37c6..e7b858e8b8 100644
--- a/xs/src/libslic3r/libslic3r.h
+++ b/xs/src/libslic3r/libslic3r.h
@@ -14,7 +14,7 @@
#include
#define SLIC3R_FORK_NAME "Slic3r Prusa Edition"
-#define SLIC3R_VERSION "1.39.0"
+#define SLIC3R_VERSION "1.40.0-alpha"
#define SLIC3R_BUILD "UNKNOWN"
typedef int32_t coord_t;
diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp
index 733757e25a..2978783a63 100644
--- a/xs/src/libslic3r/utils.cpp
+++ b/xs/src/libslic3r/utils.cpp
@@ -1,6 +1,14 @@
+#include "Utils.hpp"
+
#include
#include
+#ifdef WIN32
+#include
+#else
+#include
+#endif
+
#include
#include
#include
@@ -129,44 +137,6 @@ const std::string& data_dir()
} // namespace Slic3r
-#ifdef SLIC3R_HAS_BROKEN_CROAK
-
-// Some Strawberry Perl builds (mainly the latest 64bit builds) have a broken mechanism
-// for emiting Perl exception after handling a C++ exception. Perl interpreter
-// simply hangs. Better to show a message box in that case and stop the application.
-
-#include
-#include
-#include
-#include
-
-#ifdef WIN32
-#include
-#endif
-
-void confess_at(const char *file, int line, const char *func, const char *format, ...)
-{
- char dest[1024*8];
- va_list argptr;
- va_start(argptr, format);
- vsprintf(dest, format, argptr);
- va_end(argptr);
-
- char filelinefunc[1024*8];
- sprintf(filelinefunc, "\r\nin function: %s\r\nfile: %s\r\nline: %d\r\n", func, file, line);
- strcat(dest, filelinefunc);
- strcat(dest, "\r\n Closing the application.\r\n");
- #ifdef WIN32
- ::MessageBoxA(NULL, dest, "Slic3r Prusa Edition", MB_OK | MB_ICONERROR);
- #endif
-
- // Give up.
- printf(dest);
- exit(-1);
-}
-
-#else
-
#include
void
@@ -196,7 +166,88 @@ confess_at(const char *file, int line, const char *func,
#endif
}
-#endif
+void PerlCallback::register_callback(void *sv)
+{
+ if (! SvROK((SV*)sv) || SvTYPE(SvRV((SV*)sv)) != SVt_PVCV)
+ croak("Not a Callback %_ for PerlFunction", (SV*)sv);
+ if (m_callback)
+ SvSetSV((SV*)m_callback, (SV*)sv);
+ else
+ m_callback = newSVsv((SV*)sv);
+}
+
+void PerlCallback::deregister_callback()
+{
+ if (m_callback) {
+ sv_2mortal((SV*)m_callback);
+ m_callback = nullptr;
+ }
+}
+
+void PerlCallback::call()
+{
+ if (! m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(int i)
+{
+ if (! m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSViv(i)));
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(int i, int j)
+{
+ if (! m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSViv(i)));
+ XPUSHs(sv_2mortal(newSViv(j)));
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+/*
+void PerlCallback::call(const std::vector &ints)
+{
+ if (! m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ AV* av = newAV();
+ for (int i : ints)
+ av_push(av, newSViv(i));
+ XPUSHs(av);
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+*/
#ifdef WIN32
#ifndef NOMINMAX
@@ -271,4 +322,13 @@ std::string timestamp_str()
return buf;
}
+unsigned get_current_pid()
+{
+#ifdef WIN32
+ return GetCurrentProcessId();
+#else
+ return ::getpid();
+#endif
+}
+
}; // namespace Slic3r
diff --git a/xs/src/perlglue.cpp b/xs/src/perlglue.cpp
index d7c9a590a0..205eec2188 100644
--- a/xs/src/perlglue.cpp
+++ b/xs/src/perlglue.cpp
@@ -62,8 +62,8 @@ REGISTER_CLASS(GLVolumeCollection, "GUI::_3DScene::GLVolume::Collection");
REGISTER_CLASS(Preset, "GUI::Preset");
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/semver/semver.c b/xs/src/semver/semver.c
index 29bc1868d3..527738644d 100644
--- a/xs/src/semver/semver.c
+++ b/xs/src/semver/semver.c
@@ -175,6 +175,9 @@ semver_parse_version (const char *str, semver_t *ver) {
slice = (char *) str;
index = 0;
+ // non mandatory
+ ver->patch = 0;
+
while (slice != NULL && index++ < 4) {
next = strchr(slice, DELIMITER[0]);
if (next == NULL)
@@ -200,7 +203,8 @@ semver_parse_version (const char *str, semver_t *ver) {
slice = next + 1;
}
- return 0;
+ // Major and minor versions are mandatory, patch version is not mandatory.
+ return (index == 2 || index == 3) ? 0 : -1;
}
static int
@@ -615,3 +619,22 @@ semver_numeric (semver_t *x) {
return num;
}
+
+char *semver_strdup(const char *src) {
+ if (src == NULL) return NULL;
+ size_t len = strlen(src) + 1;
+ char *res = malloc(len);
+ return res != NULL ? (char *) memcpy(res, src, len) : NULL;
+}
+
+semver_t
+semver_copy(const semver_t *ver) {
+ semver_t res = *ver;
+ if (ver->metadata != NULL) {
+ res.metadata = strdup(ver->metadata);
+ }
+ if (ver->prerelease != NULL) {
+ res.prerelease = strdup(ver->prerelease);
+ }
+ return res;
+}
diff --git a/xs/src/semver/semver.h b/xs/src/semver/semver.h
index 1b48670ca3..01a15fc43e 100644
--- a/xs/src/semver/semver.h
+++ b/xs/src/semver/semver.h
@@ -98,6 +98,12 @@ semver_is_valid (const char *s);
int
semver_clean (char *s);
+char *
+semver_strdup(const char *src);
+
+semver_t
+semver_copy(const semver_t *ver);
+
#ifdef __cplusplus
}
#endif
diff --git a/xs/src/slic3r/Config/Snapshot.cpp b/xs/src/slic3r/Config/Snapshot.cpp
index 559e4c63cb..704fbcfa1b 100644
--- a/xs/src/slic3r/Config/Snapshot.cpp
+++ b/xs/src/slic3r/Config/Snapshot.cpp
@@ -1,11 +1,13 @@
#include "Snapshot.hpp"
#include "../GUI/AppConfig.hpp"
+#include "../GUI/PresetBundle.hpp"
#include "../Utils/Time.hpp"
#include
#include
#include
+#include
#include
#include
#include
@@ -56,6 +58,7 @@ void Snapshot::load_ini(const std::string &path)
// Parse snapshot.ini
std::string group_name_vendor = "Vendor:";
std::string key_filament = "filament";
+ std::string key_prefix_model = "model_";
for (auto §ion : tree) {
if (section.first == "snapshot") {
// Parse the common section.
@@ -79,6 +82,8 @@ void Snapshot::load_ini(const std::string &path)
this->reason = SNAPSHOT_UPGRADE;
else if (rsn == "downgrade")
this->reason = SNAPSHOT_DOWNGRADE;
+ else if (rsn == "before_rollback")
+ this->reason = SNAPSHOT_BEFORE_ROLLBACK;
else if (rsn == "user")
this->reason = SNAPSHOT_USER;
else
@@ -106,24 +111,49 @@ void Snapshot::load_ini(const std::string &path)
VendorConfig vc;
vc.name = section.first.substr(group_name_vendor.size());
for (auto &kvp : section.second) {
- if (boost::starts_with(kvp.first, "model_")) {
- //model:MK2S = 0.4;xxx
- //model:MK3 = 0.4;xxx
- } else if (kvp.first == "version" || kvp.first == "min_slic3r_version" || kvp.first == "max_slic3r_version") {
+ if (kvp.first == "version" || kvp.first == "min_slic3r_version" || kvp.first == "max_slic3r_version") {
// Version of the vendor specific config bundle bundled with this snapshot.
auto semver = Semver::parse(kvp.second.data());
if (! semver)
throw_on_parse_error("invalid " + kvp.first + " format for " + section.first);
if (kvp.first == "version")
- vc.version = *semver;
+ vc.version.config_version = *semver;
else if (kvp.first == "min_slic3r_version")
- vc.min_slic3r_version = *semver;
+ vc.version.min_slic3r_version = *semver;
else
- vc.max_slic3r_version = *semver;
- }
+ vc.version.max_slic3r_version = *semver;
+ } else if (boost::starts_with(kvp.first, key_prefix_model) && kvp.first.size() > key_prefix_model.size()) {
+ // Parse the printer variants installed for the current model.
+ auto &set_variants = vc.models_variants_installed[kvp.first.substr(key_prefix_model.size())];
+ std::vector variants;
+ if (unescape_strings_cstyle(kvp.second.data(), variants))
+ for (auto &variant : variants)
+ set_variants.insert(std::move(variant));
+ }
}
+ this->vendor_configs.emplace_back(std::move(vc));
}
}
+ // Sort the vendors lexicographically.
+ std::sort(this->vendor_configs.begin(), this->vendor_configs.begin(),
+ [](const VendorConfig &cfg1, const VendorConfig &cfg2) { return cfg1.name < cfg2.name; });
+}
+
+static std::string reason_string(const Snapshot::Reason reason)
+{
+ switch (reason) {
+ case Snapshot::SNAPSHOT_UPGRADE:
+ return "upgrade";
+ case Snapshot::SNAPSHOT_DOWNGRADE:
+ return "downgrade";
+ case Snapshot::SNAPSHOT_BEFORE_ROLLBACK:
+ return "before_rollback";
+ case Snapshot::SNAPSHOT_USER:
+ return "user";
+ case Snapshot::SNAPSHOT_UNKNOWN:
+ default:
+ return "unknown";
+ }
}
void Snapshot::save_ini(const std::string &path)
@@ -138,7 +168,7 @@ void Snapshot::save_ini(const std::string &path)
c << "time_captured = " << Slic3r::Utils::format_time_ISO8601Z(this->time_captured) << std::endl;
c << "slic3r_version_captured = " << this->slic3r_version_captured.to_string() << std::endl;
c << "comment = " << this->comment << std::endl;
- c << "reason = " << this->reason << std::endl;
+ c << "reason = " << reason_string(this->reason) << std::endl;
// Export the active presets at the time of the snapshot.
c << std::endl << "[presets]" << std::endl;
@@ -151,9 +181,17 @@ void Snapshot::save_ini(const std::string &path)
// Export the vendor configs.
for (const VendorConfig &vc : this->vendor_configs) {
c << std::endl << "[Vendor:" << vc.name << "]" << std::endl;
- c << "version = " << vc.version.to_string() << std::endl;
- c << "min_slic3r_version = " << vc.min_slic3r_version.to_string() << std::endl;
- c << "max_slic3r_version = " << vc.max_slic3r_version.to_string() << std::endl;
+ c << "version = " << vc.version.config_version.to_string() << std::endl;
+ c << "min_slic3r_version = " << vc.version.min_slic3r_version.to_string() << std::endl;
+ c << "max_slic3r_version = " << vc.version.max_slic3r_version.to_string() << std::endl;
+ // Export installed printer models and their variants.
+ for (const auto &model : vc.models_variants_installed) {
+ if (model.second.size() == 0)
+ continue;
+ const std::vector variants(model.second.begin(), model.second.end());
+ const auto escaped = escape_strings_cstyle(variants);
+ c << "model_" << model.first << " = " << escaped << std::endl;
+ }
}
c.close();
}
@@ -172,6 +210,82 @@ void Snapshot::export_selections(AppConfig &config) const
config.set("presets", "printer", printer);
}
+void Snapshot::export_vendor_configs(AppConfig &config) const
+{
+ std::map>> vendors;
+ for (const VendorConfig &vc : vendor_configs)
+ vendors[vc.name] = vc.models_variants_installed;
+ config.set_vendors(std::move(vendors));
+}
+
+// Perform a deep compare of the active print / filament / printer / vendor directories.
+// Return true if the content of the current print / filament / printer / vendor directories
+// matches the state stored in this snapshot.
+bool Snapshot::equal_to_active(const AppConfig &app_config) const
+{
+ // 1) Check, whether this snapshot contains the same set of active vendors, printer models and variants
+ // as app_config.
+ {
+ std::set matched;
+ for (const VendorConfig &vc : this->vendor_configs) {
+ auto it_vendor_models_variants = app_config.vendors().find(vc.name);
+ if (it_vendor_models_variants == app_config.vendors().end() ||
+ it_vendor_models_variants->second != vc.models_variants_installed)
+ // There are more vendors enabled in the snapshot than currently installed.
+ return false;
+ matched.insert(vc.name);
+ }
+ for (const std::pair>> &v : app_config.vendors())
+ if (matched.find(v.first) == matched.end() && ! v.second.empty())
+ // There are more vendors currently installed than enabled in the snapshot.
+ return false;
+ }
+
+ // 2) Check, whether this snapshot references the same set of ini files as the current state.
+ boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
+ boost::filesystem::path snapshot_dir = boost::filesystem::path(Slic3r::data_dir()) / SLIC3R_SNAPSHOTS_DIR / this->id;
+ for (const char *subdir : { "print", "filament", "printer", "vendor" }) {
+ boost::filesystem::path path1 = data_dir / subdir;
+ boost::filesystem::path path2 = snapshot_dir / subdir;
+ std::vector files1, files2;
+ for (auto &dir_entry : boost::filesystem::directory_iterator(path1))
+ if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
+ files1.emplace_back(dir_entry.path().filename().string());
+ for (auto &dir_entry : boost::filesystem::directory_iterator(path2))
+ if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
+ files2.emplace_back(dir_entry.path().filename().string());
+ std::sort(files1.begin(), files1.end());
+ std::sort(files2.begin(), files2.end());
+ if (files1 != files2)
+ return false;
+ for (const std::string &filename : files1) {
+ FILE *f1 = boost::nowide::fopen((path1 / filename).string().c_str(), "rb");
+ FILE *f2 = boost::nowide::fopen((path2 / filename).string().c_str(), "rb");
+ bool same = true;
+ if (f1 && f2) {
+ char buf1[4096];
+ char buf2[4096];
+ do {
+ size_t r1 = fread(buf1, 1, 4096, f1);
+ size_t r2 = fread(buf2, 1, 4096, f2);
+ if (r1 != r2 || memcmp(buf1, buf2, r1)) {
+ same = false;
+ break;
+ }
+ } while (! feof(f1) || ! feof(f2));
+ } else
+ same = false;
+ if (f1)
+ fclose(f1);
+ if (f2)
+ fclose(f2);
+ if (! same)
+ return false;
+ }
+ }
+ return true;
+}
+
size_t SnapshotDB::load_db()
{
boost::filesystem::path snapshots_dir = SnapshotDB::create_db_dir();
@@ -199,12 +313,29 @@ size_t SnapshotDB::load_db()
}
m_snapshots.emplace_back(std::move(snapshot));
}
-
+ // Sort the snapshots by their date/time.
+ std::sort(m_snapshots.begin(), m_snapshots.end(), [](const Snapshot &s1, const Snapshot &s2) { return s1.time_captured < s2.time_captured; });
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
return m_snapshots.size();
}
+void SnapshotDB::update_slic3r_versions(std::vector &index_db)
+{
+ for (Snapshot &snapshot : m_snapshots) {
+ for (Snapshot::VendorConfig &vendor_config : snapshot.vendor_configs) {
+ auto it = std::find_if(index_db.begin(), index_db.end(), [&vendor_config](const Index &idx) { return idx.vendor() == vendor_config.name; });
+ if (it != index_db.end()) {
+ Index::const_iterator it_version = it->find(vendor_config.version.config_version);
+ if (it_version != it->end()) {
+ vendor_config.version.min_slic3r_version = it_version->min_slic3r_version;
+ vendor_config.version.max_slic3r_version = it_version->max_slic3r_version;
+ }
+ }
+ }
+ }
+}
+
static void copy_config_dir_single_level(const boost::filesystem::path &path_src, const boost::filesystem::path &path_dst)
{
if (! boost::filesystem::is_directory(path_dst) &&
@@ -225,7 +356,7 @@ static void delete_existing_ini_files(const boost::filesystem::path &path)
boost::filesystem::remove(dir_entry.path());
}
-const Snapshot& SnapshotDB::make_snapshot(const AppConfig &app_config, Snapshot::Reason reason, const std::string &comment)
+const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot::Reason reason, const std::string &comment)
{
boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
boost::filesystem::path snapshot_db_dir = SnapshotDB::create_db_dir();
@@ -235,7 +366,7 @@ const Snapshot& SnapshotDB::make_snapshot(const AppConfig &app_config, Snapshot:
// Snapshot header.
snapshot.time_captured = Slic3r::Utils::get_current_time_utc();
snapshot.id = Slic3r::Utils::format_time_ISO8601Z(snapshot.time_captured);
- snapshot.slic3r_version_captured = *Semver::parse(SLIC3R_VERSION);
+ snapshot.slic3r_version_captured = *Semver::parse(SLIC3R_VERSION); // XXX: have Semver Slic3r version
snapshot.comment = comment;
snapshot.reason = reason;
// Active presets at the time of the snapshot.
@@ -250,22 +381,54 @@ const Snapshot& SnapshotDB::make_snapshot(const AppConfig &app_config, Snapshot:
snapshot.filaments.emplace_back(app_config.get("presets", name));
}
// Vendor specific config bundles and installed printers.
+ for (const std::pair>> &vendor : app_config.vendors()) {
+ Snapshot::VendorConfig cfg;
+ cfg.name = vendor.first;
+ cfg.models_variants_installed = vendor.second;
+ for (auto it = cfg.models_variants_installed.begin(); it != cfg.models_variants_installed.end();)
+ if (it->second.empty())
+ cfg.models_variants_installed.erase(it ++);
+ else
+ ++ it;
+ // Read the active config bundle, parse the config version.
+ PresetBundle bundle;
+ bundle.load_configbundle((data_dir / "vendor" / (cfg.name + ".ini")).string(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY);
+ for (const VendorProfile &vp : bundle.vendors)
+ if (vp.id == cfg.name)
+ cfg.version.config_version = vp.config_version;
+ // Fill-in the min/max slic3r version from the config index, if possible.
+ try {
+ // Load the config index for the vendor.
+ Index index;
+ index.load(data_dir / "vendor" / (cfg.name + ".idx"));
+ auto it = index.find(cfg.version.config_version);
+ if (it != index.end()) {
+ cfg.version.min_slic3r_version = it->min_slic3r_version;
+ cfg.version.max_slic3r_version = it->max_slic3r_version;
+ }
+ } catch (const std::runtime_error &err) {
+ }
+ snapshot.vendor_configs.emplace_back(std::move(cfg));
+ }
+
+ boost::filesystem::path snapshot_dir = snapshot_db_dir / snapshot.id;
+ boost::filesystem::create_directory(snapshot_dir);
// Backup the presets.
- boost::filesystem::path snapshot_dir = snapshot_db_dir / snapshot.id;
for (const char *subdir : { "print", "filament", "printer", "vendor" })
copy_config_dir_single_level(data_dir / subdir, snapshot_dir / subdir);
snapshot.save_ini((snapshot_dir / "snapshot.ini").string());
+ assert(m_snapshots.empty() || m_snapshots.back().time_captured <= snapshot.time_captured);
m_snapshots.emplace_back(std::move(snapshot));
return m_snapshots.back();
}
-void SnapshotDB::restore_snapshot(const std::string &id, AppConfig &app_config)
+const Snapshot& SnapshotDB::restore_snapshot(const std::string &id, AppConfig &app_config)
{
for (const Snapshot &snapshot : m_snapshots)
if (snapshot.id == id) {
this->restore_snapshot(snapshot, app_config);
- return;
+ return snapshot;
}
throw std::runtime_error(std::string("Snapshot with id " + id + " was not found."));
}
@@ -275,18 +438,59 @@ void SnapshotDB::restore_snapshot(const Snapshot &snapshot, AppConfig &app_confi
boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
boost::filesystem::path snapshot_db_dir = SnapshotDB::create_db_dir();
boost::filesystem::path snapshot_dir = snapshot_db_dir / snapshot.id;
-
// Remove existing ini files and restore the ini files from the snapshot.
for (const char *subdir : { "print", "filament", "printer", "vendor" }) {
delete_existing_ini_files(data_dir / subdir);
copy_config_dir_single_level(snapshot_dir / subdir, data_dir / subdir);
}
-
- // Update app_config from the snapshot.
+ // Update AppConfig with the selections of the print / filament / printer profiles
+ // and about the installed printer types and variants.
snapshot.export_selections(app_config);
+ snapshot.export_vendor_configs(app_config);
+}
- // Store information about the snapshot.
+bool SnapshotDB::is_on_snapshot(AppConfig &app_config) const
+{
+ // Is the "on_snapshot" configuration value set?
+ std::string on_snapshot = app_config.get("on_snapshot");
+ if (on_snapshot.empty())
+ // No, we are not on a snapshot.
+ return false;
+ // Is the "on_snapshot" equal to the current configuration state?
+ auto it_snapshot = this->snapshot(on_snapshot);
+ if (it_snapshot != this->end() && it_snapshot->equal_to_active(app_config))
+ // Yes, we are on the snapshot.
+ return true;
+ // No, we are no more on a snapshot. Reset the state.
+ app_config.set("on_snapshot", "");
+ return false;
+}
+SnapshotDB::const_iterator SnapshotDB::snapshot_with_vendor_preset(const std::string &vendor_name, const Semver &config_version)
+{
+ auto it_found = m_snapshots.end();
+ Snapshot::VendorConfig key;
+ key.name = vendor_name;
+ for (auto it = m_snapshots.begin(); it != m_snapshots.end(); ++ it) {
+ const Snapshot &snapshot = *it;
+ auto it_vendor_config = std::lower_bound(snapshot.vendor_configs.begin(), snapshot.vendor_configs.end(),
+ key, [](const Snapshot::VendorConfig &cfg1, const Snapshot::VendorConfig &cfg2) { return cfg1.name < cfg2.name; });
+ if (it_vendor_config != snapshot.vendor_configs.end() && it_vendor_config->name == vendor_name &&
+ config_version == it_vendor_config->version.config_version) {
+ // Vendor config found with the correct version.
+ // Save it, but continue searching, as we want the newest snapshot.
+ it_found = it;
+ }
+ }
+ return it_found;
+}
+
+SnapshotDB::const_iterator SnapshotDB::snapshot(const std::string &id) const
+{
+ for (const_iterator it = m_snapshots.begin(); it != m_snapshots.end(); ++ it)
+ if (it->id == id)
+ return it;
+ return m_snapshots.end();
}
boost::filesystem::path SnapshotDB::create_db_dir()
@@ -303,6 +507,26 @@ boost::filesystem::path SnapshotDB::create_db_dir()
return snapshots_dir;
}
+SnapshotDB& SnapshotDB::singleton()
+{
+ static SnapshotDB instance;
+ static bool loaded = false;
+ if (! loaded) {
+ try {
+ loaded = true;
+ // Load the snapshot database.
+ instance.load_db();
+ // Load the vendor specific configuration indices.
+ std::vector index_db = Index::load_db();
+ // Update the min / max slic3r versions compatible with the configurations stored inside the snapshots
+ // based on the min / max slic3r versions defined by the vendor specific config indices.
+ instance.update_slic3r_versions(index_db);
+ } catch (std::exception &ex) {
+ }
+ }
+ return instance;
+}
+
} // namespace Config
} // namespace GUI
} // namespace Slic3r
diff --git a/xs/src/slic3r/Config/Snapshot.hpp b/xs/src/slic3r/Config/Snapshot.hpp
index 358797bf76..a916dfe92a 100644
--- a/xs/src/slic3r/Config/Snapshot.hpp
+++ b/xs/src/slic3r/Config/Snapshot.hpp
@@ -1,11 +1,14 @@
#ifndef slic3r_GUI_Snapshot_
#define slic3r_GUI_Snapshot_
+#include